r262551 - Improve some infrastructure for extended parameter infos and
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 2 16:10:03 PST 2016
Author: rjmccall
Date: Wed Mar 2 18:10:03 2016
New Revision: 262551
URL: http://llvm.org/viewvc/llvm-project?rev=262551&view=rev
Log:
Improve some infrastructure for extended parameter infos and
fix a bug with the instantiation of ns_consumed parameter
attributes in ARC.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/AttributeList.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp
cfe/trunk/test/SemaObjCXX/arc-nsconsumed-errors.mm
cfe/trunk/test/SemaObjCXX/arc-templates.mm
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 2 18:10:03 2016
@@ -2934,6 +2934,9 @@ def warn_ns_attribute_wrong_return_type
"%0 attribute only applies to %select{functions|methods|properties}1 that "
"return %select{an Objective-C object|a pointer|a non-retainable pointer}2">,
InGroup<IgnoredAttributes>;
+def err_ns_attribute_wrong_parameter_type : Error<
+ "%0 attribute only applies to "
+ "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">;
def warn_ns_attribute_wrong_parameter_type : Warning<
"%0 attribute only applies to "
"%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">,
Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Mar 2 18:10:03 2016
@@ -94,9 +94,11 @@ private:
SourceLocation ScopeLoc;
SourceLocation EllipsisLoc;
+ unsigned AttrKind : 16;
+
/// The number of expression arguments this attribute has.
/// The expressions themselves are stored after the object.
- unsigned NumArgs : 15;
+ unsigned NumArgs : 16;
/// Corresponds to the Syntax enum.
unsigned SyntaxUsed : 3;
@@ -122,7 +124,11 @@ private:
/// True if this has a ParsedType
unsigned HasParsedType : 1;
- unsigned AttrKind : 8;
+ /// True if the processing cache is valid.
+ mutable unsigned HasProcessingCache : 1;
+
+ /// A cached value.
+ mutable unsigned ProcessingCache : 8;
/// \brief The location of the 'unavailable' keyword in an
/// availability attribute.
@@ -231,7 +237,8 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
+ HasParsedType(false), HasProcessingCache(false),
+ NextInPosition(nullptr), NextInPool(nullptr) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -249,8 +256,8 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- UnavailableLoc(unavailable), MessageExpr(messageExpr),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ HasProcessingCache(false), UnavailableLoc(unavailable),
+ MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
@@ -271,7 +278,7 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
ArgsVector Args;
Args.push_back(Parm1);
Args.push_back(Parm2);
@@ -289,7 +296,7 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -307,7 +314,7 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
new (&getTypeBuffer()) ParsedType(typeArg);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -321,7 +328,7 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -373,6 +380,16 @@ public:
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
+ bool hasProcessingCache() const { return HasProcessingCache; }
+ unsigned getProcessingCache() const {
+ assert(hasProcessingCache());
+ return ProcessingCache;
+ }
+ void setProcessingCache(unsigned value) const {
+ ProcessingCache = value;
+ HasProcessingCache = true;
+ }
+
bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 2 18:10:03 2016
@@ -7786,6 +7786,10 @@ public:
void AddModeAttr(SourceRange AttrRange, Decl *D, IdentifierInfo *Name,
unsigned SpellingListIndex, bool InInstantiation = false);
+ void AddNSConsumedAttr(SourceRange AttrRange, Decl *D,
+ unsigned SpellingListIndex, bool isNSConsumed,
+ bool isTemplateInstantiation);
+
//===--------------------------------------------------------------------===//
// C++ Coroutines TS
//
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Wed Mar 2 18:10:03 2016
@@ -641,6 +641,10 @@ void TypePrinter::printFunctionProtoAfte
ParamPolicyRAII ParamPolicy(Policy);
for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
if (i) OS << ", ";
+
+ auto EPI = T->getExtParameterInfo(i);
+ if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
+
print(T->getParamType(i), OS, StringRef());
}
}
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Mar 2 18:10:03 2016
@@ -3777,6 +3777,11 @@ bool Sema::CheckCallingConvAttr(const At
if (attr.isInvalid())
return true;
+ if (attr.hasProcessingCache()) {
+ CC = (CallingConv) attr.getProcessingCache();
+ return false;
+ }
+
unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
if (!checkAttributeNumArgs(*this, attr, ReqArgs)) {
attr.setInvalid();
@@ -3836,6 +3841,7 @@ bool Sema::CheckCallingConvAttr(const At
CC = TI.getDefaultCallingConv(MT);
}
+ attr.setProcessingCache((unsigned) CC);
return false;
}
@@ -4030,31 +4036,45 @@ static bool isValidSubjectOfCFAttribute(
}
static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ S.AddNSConsumedAttr(Attr.getRange(), D, Attr.getAttributeSpellingListIndex(),
+ Attr.getKind() == AttributeList::AT_NSConsumed,
+ /*template instantiation*/ false);
+}
+
+void Sema::AddNSConsumedAttr(SourceRange attrRange, Decl *D,
+ unsigned spellingIndex, bool isNSConsumed,
+ bool isTemplateInstantiation) {
ParmVarDecl *param = cast<ParmVarDecl>(D);
- bool typeOK, cf;
+ bool typeOK;
- if (Attr.getKind() == AttributeList::AT_NSConsumed) {
- typeOK = isValidSubjectOfNSAttribute(S, param->getType());
- cf = false;
+ if (isNSConsumed) {
+ typeOK = isValidSubjectOfNSAttribute(*this, param->getType());
} else {
- typeOK = isValidSubjectOfCFAttribute(S, param->getType());
- cf = true;
+ typeOK = isValidSubjectOfCFAttribute(*this, param->getType());
}
if (!typeOK) {
- S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
- << Attr.getRange() << Attr.getName() << cf;
+ // These attributes are normally just advisory, but in ARC, ns_consumed
+ // is significant. Allow non-dependent code to contain inappropriate
+ // attributes even in ARC, but require template instantiations to be
+ // set up correctly.
+ Diag(D->getLocStart(),
+ (isTemplateInstantiation && isNSConsumed &&
+ getLangOpts().ObjCAutoRefCount
+ ? diag::err_ns_attribute_wrong_parameter_type
+ : diag::warn_ns_attribute_wrong_parameter_type))
+ << attrRange
+ << (isNSConsumed ? "ns_consumed" : "cf_consumed")
+ << (isNSConsumed ? /*objc pointers*/ 0 : /*cf pointers*/ 1);
return;
}
- if (cf)
- param->addAttr(::new (S.Context)
- CFConsumedAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
+ if (isNSConsumed)
+ param->addAttr(::new (Context)
+ NSConsumedAttr(attrRange, Context, spellingIndex));
else
- param->addAttr(::new (S.Context)
- NSConsumedAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
+ param->addAttr(::new (Context)
+ CFConsumedAttr(attrRange, Context, spellingIndex));
}
static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Mar 2 18:10:03 2016
@@ -286,6 +286,14 @@ void Sema::InstantiateAttrs(const MultiL
}
}
+ if (isa<NSConsumedAttr>(TmplAttr) || isa<CFConsumedAttr>(TmplAttr)) {
+ AddNSConsumedAttr(TmplAttr->getRange(), New,
+ TmplAttr->getSpellingListIndex(),
+ isa<NSConsumedAttr>(TmplAttr),
+ /*template instantiation*/ true);
+ continue;
+ }
+
assert(!TmplAttr->isPackExpansion());
if (TmplAttr->isLateParsed() && LateAttrs) {
// Late parsed attributes must be instantiated and attached after the
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Mar 2 18:10:03 2016
@@ -100,9 +100,8 @@ static void diagnoseBadTypeAttribute(Sem
case AttributeList::AT_ObjCGC: \
case AttributeList::AT_ObjCOwnership
-// Function type attributes.
-#define FUNCTION_TYPE_ATTRS_CASELIST \
- case AttributeList::AT_NoReturn: \
+// Calling convention attributes.
+#define CALLING_CONV_ATTRS_CASELIST \
case AttributeList::AT_CDecl: \
case AttributeList::AT_FastCall: \
case AttributeList::AT_StdCall: \
@@ -111,10 +110,15 @@ static void diagnoseBadTypeAttribute(Sem
case AttributeList::AT_VectorCall: \
case AttributeList::AT_MSABI: \
case AttributeList::AT_SysVABI: \
- case AttributeList::AT_Regparm: \
case AttributeList::AT_Pcs: \
case AttributeList::AT_IntelOclBicc
+// Function type attributes.
+#define FUNCTION_TYPE_ATTRS_CASELIST \
+ case AttributeList::AT_NoReturn: \
+ case AttributeList::AT_Regparm: \
+ CALLING_CONV_ATTRS_CASELIST
+
// Microsoft-specific type qualifiers.
#define MS_TYPE_ATTRS_CASELIST \
case AttributeList::AT_Ptr32: \
@@ -2957,6 +2961,26 @@ getCCForDeclaratorChunk(Sema &S, Declara
unsigned ChunkIndex) {
assert(D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function);
+ // Check for an explicit CC attribute.
+ for (auto Attr = FTI.AttrList; Attr; Attr = Attr->getNext()) {
+ switch (Attr->getKind()) {
+ CALLING_CONV_ATTRS_CASELIST: {
+ // Ignore attributes that don't validate or can't apply to the
+ // function type. We'll diagnose the failure to apply them in
+ // handleFunctionTypeAttr.
+ CallingConv CC;
+ if (!S.CheckCallingConvAttr(*Attr, CC) &&
+ (!FTI.isVariadic || supportsVariadicCall(CC))) {
+ return CC;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
bool IsCXXInstanceMethod = false;
if (S.getLangOpts().CPlusPlus) {
@@ -5986,9 +6010,14 @@ static bool handleFunctionTypeAttr(TypeP
// Modify the CC from the wrapped function type, wrap it all back, and then
// wrap the whole thing in an AttributedType as written. The modified type
// might have a different CC if we ignored the attribute.
- FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withCallingConv(CC);
- QualType Equivalent =
+ QualType Equivalent;
+ if (CCOld == CC) {
+ Equivalent = type;
+ } else {
+ auto EI = unwrapped.get()->getExtInfo().withCallingConv(CC);
+ Equivalent =
unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
+ }
type = S.Context.getAttributedType(CCAttrKind, type, Equivalent);
return true;
}
Modified: cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp Wed Mar 2 18:10:03 2016
@@ -19,6 +19,7 @@ int *[[gnu::unused]] attr_on_ptr;
[[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]];
// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
// expected-warning at -2 {{attribute 'stdcall' ignored, because it cannot be applied to a type}}
+// expected-warning at -3 {{calling convention 'stdcall' ignored for this target}}
void pr17424_5 [[gnu::fastcall]]();
// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
Modified: cfe/trunk/test/SemaObjCXX/arc-nsconsumed-errors.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-nsconsumed-errors.mm?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-nsconsumed-errors.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-nsconsumed-errors.mm Wed Mar 2 18:10:03 2016
@@ -29,9 +29,9 @@ void releaser(__attribute__((ns_consumed
releaser_t r2 = releaser; // no-warning
template <typename T>
-void templateFunction(T) { } // expected-note {{candidate template ignored: could not match 'void (__strong id)' against 'void (id)'}} \
+void templateFunction(T) { } // expected-note {{candidate template ignored: could not match 'void (__strong id)' against 'void (__attribute__((ns_consumed)) id)'}} \
// expected-note {{candidate template ignored: failed template argument deduction}}
-releaser_t r3 = templateFunction<id>; // expected-error {{address of overloaded function 'templateFunction' does not match required type 'void (id)'}}
+releaser_t r3 = templateFunction<id>; // expected-error {{address of overloaded function 'templateFunction' does not match required type 'void (__attribute__((ns_consumed)) id)'}}
template <typename T>
void templateReleaser(__attribute__((ns_consumed)) T) { } // expected-note 2{{candidate template ignored: failed template argument deduction}}
Modified: cfe/trunk/test/SemaObjCXX/arc-templates.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-templates.mm?rev=262551&r1=262550&r2=262551&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-templates.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-templates.mm Wed Mar 2 18:10:03 2016
@@ -442,3 +442,11 @@ namespace produced_nested {
take_no(produces<4>::fn); // expected-error {{no matching function}}
}
}
+
+namespace instantiate_consumed {
+ template <class T> void take(CONSUMED T t) {} // expected-note {{candidate template ignored: substitution failure [with T = int]: ns_consumed attribute only applies to Objective-C object parameters}}
+ void test() {
+ take((id) 0);
+ take((int) 0); // expected-error {{no matching function for call to 'take'}}
+ }
+}
More information about the cfe-commits
mailing list