summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerdim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/Sema/SemaDeclAttr.cpp
parentc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (diff)
downloadFreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.zip
FreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.tar.gz
Vendor import of clang trunk r135360:
http://llvm.org/svn/llvm-project/cfe/trunk@135360
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp1115
1 files changed, 620 insertions, 495 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 7f93ab7..61b7b3e 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/DelayedDiagnostic.h"
@@ -48,14 +49,14 @@ enum {
// Helper functions
//===----------------------------------------------------------------------===//
-static const FunctionType *getFunctionType(const Decl *d,
+static const FunctionType *getFunctionType(const Decl *D,
bool blocksToo = true) {
QualType Ty;
- if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
+ if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
Ty = decl->getType();
- else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
+ else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
Ty = decl->getType();
- else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(d))
+ else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
Ty = decl->getUnderlyingType();
else
return 0;
@@ -73,46 +74,47 @@ static const FunctionType *getFunctionType(const Decl *d,
/// isFunction - Return true if the given decl has function
/// type (function or function-typed variable).
-static bool isFunction(const Decl *d) {
- return getFunctionType(d, false) != NULL;
+static bool isFunction(const Decl *D) {
+ return getFunctionType(D, false) != NULL;
}
/// isFunctionOrMethod - Return true if the given decl has function
/// type (function or function-typed variable) or an Objective-C
/// method.
-static bool isFunctionOrMethod(const Decl *d) {
- return isFunction(d)|| isa<ObjCMethodDecl>(d);
+static bool isFunctionOrMethod(const Decl *D) {
+ return isFunction(D)|| isa<ObjCMethodDecl>(D);
}
/// isFunctionOrMethodOrBlock - Return true if the given decl has function
/// type (function or function-typed variable) or an Objective-C
/// method or a block.
-static bool isFunctionOrMethodOrBlock(const Decl *d) {
- if (isFunctionOrMethod(d))
+static bool isFunctionOrMethodOrBlock(const Decl *D) {
+ if (isFunctionOrMethod(D))
return true;
// check for block is more involved.
- if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
+ if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
QualType Ty = V->getType();
return Ty->isBlockPointerType();
}
- return isa<BlockDecl>(d);
+ return isa<BlockDecl>(D);
}
/// Return true if the given decl has a declarator that should have
/// been processed by Sema::GetTypeForDeclarator.
-static bool hasDeclarator(const Decl *d) {
- // In some sense, TypedefNameDecl really *ought* to be a DeclaratorDecl.
- return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefNameDecl>(d);
+static bool hasDeclarator(const Decl *D) {
+ // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
+ return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
+ isa<ObjCPropertyDecl>(D);
}
/// hasFunctionProto - Return true if the given decl has a argument
/// information. This decl should have already passed
/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
-static bool hasFunctionProto(const Decl *d) {
- if (const FunctionType *FnTy = getFunctionType(d))
+static bool hasFunctionProto(const Decl *D) {
+ if (const FunctionType *FnTy = getFunctionType(D))
return isa<FunctionProtoType>(FnTy);
else {
- assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
+ assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
return true;
}
}
@@ -120,42 +122,42 @@ static bool hasFunctionProto(const Decl *d) {
/// getFunctionOrMethodNumArgs - Return number of function or method
/// arguments. It is an error to call this on a K&R function (use
/// hasFunctionProto first).
-static unsigned getFunctionOrMethodNumArgs(const Decl *d) {
- if (const FunctionType *FnTy = getFunctionType(d))
+static unsigned getFunctionOrMethodNumArgs(const Decl *D) {
+ if (const FunctionType *FnTy = getFunctionType(D))
return cast<FunctionProtoType>(FnTy)->getNumArgs();
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
return BD->getNumParams();
- return cast<ObjCMethodDecl>(d)->param_size();
+ return cast<ObjCMethodDecl>(D)->param_size();
}
-static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
- if (const FunctionType *FnTy = getFunctionType(d))
+static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
+ if (const FunctionType *FnTy = getFunctionType(D))
return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
return BD->getParamDecl(Idx)->getType();
- return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
+ return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
}
-static QualType getFunctionOrMethodResultType(const Decl *d) {
- if (const FunctionType *FnTy = getFunctionType(d))
+static QualType getFunctionOrMethodResultType(const Decl *D) {
+ if (const FunctionType *FnTy = getFunctionType(D))
return cast<FunctionProtoType>(FnTy)->getResultType();
- return cast<ObjCMethodDecl>(d)->getResultType();
+ return cast<ObjCMethodDecl>(D)->getResultType();
}
-static bool isFunctionOrMethodVariadic(const Decl *d) {
- if (const FunctionType *FnTy = getFunctionType(d)) {
+static bool isFunctionOrMethodVariadic(const Decl *D) {
+ if (const FunctionType *FnTy = getFunctionType(D)) {
const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
return proto->isVariadic();
- } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
+ } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
return BD->isVariadic();
else {
- return cast<ObjCMethodDecl>(d)->isVariadic();
+ return cast<ObjCMethodDecl>(D)->isVariadic();
}
}
-static bool isInstanceMethod(const Decl *d) {
- if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d))
+static bool isInstanceMethod(const Decl *D) {
+ if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
return MethodDecl->isInstance();
return false;
}
@@ -192,6 +194,16 @@ static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
}
+static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
+ unsigned int Num) {
+ if (Attr.getNumArgs() != Num) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
+ return false;
+ }
+
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Attribute Implementations
//===----------------------------------------------------------------------===//
@@ -200,9 +212,9 @@ static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
// least add some helper functions to check most argument patterns (#
// and types of args).
-static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
- const AttributeList &Attr, Sema &S) {
- TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(d);
+static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
+ const AttributeList &Attr) {
+ TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
if (tDecl == 0) {
S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
return;
@@ -217,13 +229,17 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
CXXScopeSpec SS;
UnqualifiedId id;
id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
- sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
+
+ ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
+ if (Size.isInvalid())
+ return;
+
+ sizeExpr = Size.get();
} else {
// check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
- }
+
sizeExpr = Attr.getArg(0);
}
@@ -239,16 +255,14 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
}
}
-static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (TagDecl *TD = dyn_cast<TagDecl>(d))
+ if (TagDecl *TD = dyn_cast<TagDecl>(D))
TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
- else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
+ else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
// If the alignment is less than or equal to 8 bits, the packed attribute
// has no effect.
if (!FD->getType()->isIncompleteType() &&
@@ -261,49 +275,45 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
-static void HandleMsStructAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- if (TagDecl *TD = dyn_cast<TagDecl>(d))
+static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (TagDecl *TD = dyn_cast<TagDecl>(D))
TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
-static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
// The IBAction attributes only apply to instance methods.
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
+ if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
if (MD->isInstanceMethod()) {
- d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
return;
}
S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
}
-static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
// The IBOutlet attributes only apply to instance variables of
// Objective-C classes.
- if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
- d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
+ if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
+ D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
return;
}
S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
}
-static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleIBOutletCollection(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// The iboutletcollection attribute can have zero or one arguments.
if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
@@ -313,17 +323,17 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
// The IBOutletCollection attributes only apply to instance variables of
// Objective-C classes.
- if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
+ if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
return;
}
- if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
<< VD->getType() << 0;
return;
}
- if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
+ if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
<< PD->getType() << 1;
@@ -335,7 +345,7 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
II = &S.Context.Idents.get("id");
ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
- S.getScopeForContext(d->getDeclContext()->getParent()));
+ S.getScopeForContext(D->getDeclContext()->getParent()));
if (!TypeRep) {
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
return;
@@ -350,14 +360,29 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
return;
}
- d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
QT));
}
-static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void possibleTransparentUnionPointerType(QualType &T) {
+ if (const RecordType *UT = T->getAsUnionType())
+ if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
+ RecordDecl *UD = UT->getDecl();
+ for (RecordDecl::field_iterator it = UD->field_begin(),
+ itend = UD->field_end(); it != itend; ++it) {
+ QualType QT = it->getType();
+ if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
+ T = QT;
+ return;
+ }
+ }
+ }
+}
+
+static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// GCC ignores the nonnull attribute on K&R style function prototypes, so we
// ignore it as well
- if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
+ if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
@@ -365,8 +390,8 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
- bool HasImplicitThisParam = isInstanceMethod(d);
- unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
+ bool HasImplicitThisParam = isInstanceMethod(D);
+ unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
// The nonnull attribute only applies to pointers.
llvm::SmallVector<unsigned, 10> NonNullArgs;
@@ -405,7 +430,9 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// Is the function argument a pointer type?
- QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
+ QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
+ possibleTransparentUnionPointerType(T);
+
if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
// FIXME: Should also highlight argument in decl.
S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
@@ -419,23 +446,11 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// If no arguments were specified to __attribute__((nonnull)) then all pointer
// arguments have a nonnull attribute.
if (NonNullArgs.empty()) {
- for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
- QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
+ for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
+ QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
+ possibleTransparentUnionPointerType(T);
if (T->isAnyPointerType() || T->isBlockPointerType())
NonNullArgs.push_back(I);
- else if (const RecordType *UT = T->getAsUnionType()) {
- if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
- RecordDecl *UD = UT->getDecl();
- for (RecordDecl::field_iterator it = UD->field_begin(),
- itend = UD->field_end(); it != itend; ++it) {
- T = it->getType();
- if (T->isAnyPointerType() || T->isBlockPointerType()) {
- NonNullArgs.push_back(I);
- break;
- }
- }
- }
- }
}
// No pointer arguments?
@@ -451,11 +466,11 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
llvm::array_pod_sort(start, start + size);
- d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+ D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
size));
}
-static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
+static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
// This attribute must be applied to a function declaration.
// The first argument to the attribute must be a string,
// the name of the resource, for example "malloc".
@@ -500,7 +515,7 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
llvm_unreachable("Unknown ownership attribute");
}
- if (!isFunction(d) || !hasFunctionProto(d)) {
+ if (!isFunction(D) || !hasFunctionProto(D)) {
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
<< AL.getName() << ExpectedFunction;
return;
@@ -508,8 +523,8 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
- bool HasImplicitThisParam = isInstanceMethod(d);
- unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
+ bool HasImplicitThisParam = isInstanceMethod(D);
+ unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
llvm::StringRef Module = AL.getParameterName()->getName();
@@ -552,7 +567,7 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
case OwnershipAttr::Takes:
case OwnershipAttr::Holds: {
// Is the function argument a pointer type?
- QualType T = getFunctionOrMethodArgType(d, x);
+ QualType T = getFunctionOrMethodArgType(D, x);
if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
// FIXME: Should also highlight argument in decl.
S.Diag(AL.getLoc(), diag::err_ownership_type)
@@ -584,8 +599,8 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
// Check we don't have a conflict with another ownership attribute.
for (specific_attr_iterator<OwnershipAttr>
- i = d->specific_attr_begin<OwnershipAttr>(),
- e = d->specific_attr_end<OwnershipAttr>();
+ i = D->specific_attr_begin<OwnershipAttr>(),
+ e = D->specific_attr_end<OwnershipAttr>();
i != e; ++i) {
if ((*i)->getOwnKind() != K) {
for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
@@ -609,7 +624,7 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+ D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
start, size));
}
@@ -633,20 +648,20 @@ static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
return false;
}
-static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Check the attribute arguments.
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
}
- if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
+ if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariableOrFunction;
return;
}
- NamedDecl *nd = cast<NamedDecl>(d);
+ NamedDecl *nd = cast<NamedDecl>(D);
// gcc rejects
// class c {
@@ -658,7 +673,7 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// static int a __attribute__((weakref ("v2")));
// }
// we reject them
- const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
+ const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
if (!Ctx->isFileContext()) {
S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
nd->getNameAsString();
@@ -704,14 +719,14 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
- d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
Str->getString()));
}
- d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
}
-static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -735,55 +750,52 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: check if target symbol exists in current file
- d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
Str->getString()));
}
-static void HandleNakedAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<FunctionDecl>(d)) {
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
}
-static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleAlwaysInlineAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// Check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- if (!isa<FunctionDecl>(d)) {
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
}
-static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
QualType RetTy = FD->getResultType();
if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
- d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
return;
}
}
@@ -791,46 +803,44 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
}
-static void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
}
-static void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- assert(Attr.isInvalid() == false);
- if (isa<VarDecl>(d))
- d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
+static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ assert(!Attr.isInvalid());
+ if (isa<VarDecl>(D))
+ D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
}
-static void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- assert(Attr.isInvalid() == false);
- if (isa<VarDecl>(d))
- d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
+static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ assert(!Attr.isInvalid());
+ if (isa<VarDecl>(D))
+ D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
}
-static void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
- if (hasDeclarator(d)) return;
+static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
+ if (hasDeclarator(D)) return;
if (S.CheckNoReturnAttr(attr)) return;
- if (!isa<ObjCMethodDecl>(d)) {
+ if (!isa<ObjCMethodDecl>(D)) {
S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< attr.getName() << ExpectedFunctionOrMethod;
return;
}
- d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
}
bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
@@ -843,19 +853,17 @@ bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
return false;
}
-static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// The checking path for 'noreturn' and 'analyzer_noreturn' are different
// because 'analyzer_noreturn' does not impact the type.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
- return;
- }
+ if(!checkAttributeNumArgs(S, Attr, 0))
+ return;
- if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
- ValueDecl *VD = dyn_cast<ValueDecl>(d);
+ if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
+ ValueDecl *VD = dyn_cast<ValueDecl>(D);
if (VD == 0 || (!VD->getType()->isBlockPointerType()
&& !VD->getType()->isFunctionPointerType())) {
S.Diag(Attr.getLoc(),
@@ -866,12 +874,11 @@ static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
}
}
- d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
}
// PS3 PPU-specific.
-static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
/*
Returning a Vector Class in Registers
@@ -895,18 +902,18 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
return result; // This will be returned in a register
}
*/
- if (!isa<RecordDecl>(d)) {
+ if (!isa<RecordDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedClass;
return;
}
- if (d->getAttr<VecReturnAttr>()) {
+ if (D->getAttr<VecReturnAttr>()) {
S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
return;
}
- RecordDecl *record = cast<RecordDecl>(d);
+ RecordDecl *record = cast<RecordDecl>(D);
int count = 0;
if (!isa<CXXRecordDecl>(record)) {
@@ -928,11 +935,11 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
count++;
}
- d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}
-static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
+static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunctionMethodOrParameter;
return;
@@ -940,45 +947,45 @@ static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: Actually store the attribute on the declaration
}
-static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
- !isa<TypeDecl>(d) && !isa<LabelDecl>(d)) {
+ if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
+ !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariableFunctionOrLabel;
return;
}
- d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
}
-static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
return;
}
- } else if (!isFunctionOrMethod(d)) {
+ } else if (!isFunctionOrMethod(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariableOrFunction;
return;
}
- d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
-static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
@@ -998,17 +1005,17 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
priority = Idx.getZExtValue();
}
- if (!isa<FunctionDecl>(d)) {
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
priority));
}
-static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
@@ -1028,17 +1035,17 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
priority = Idx.getZExtValue();
}
- if (!isa<FunctionDecl>(d)) {
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
priority));
}
-static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
unsigned NumArgs = Attr.getNumArgs();
if (NumArgs > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
@@ -1057,10 +1064,10 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
Str = SE->getString();
}
- d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
+ D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
}
-static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
unsigned NumArgs = Attr.getNumArgs();
if (NumArgs > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
@@ -1078,11 +1085,23 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
Str = SE->getString();
}
- d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
+ D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
+}
+
+static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ unsigned NumArgs = Attr.getNumArgs();
+ if (NumArgs > 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
+ Attr.getLoc(), S.Context));
}
-static void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleAvailabilityAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
IdentifierInfo *Platform = Attr.getParameterName();
SourceLocation PlatformLoc = Attr.getParameterLoc();
@@ -1126,7 +1145,7 @@ static void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr,
return;
}
- d->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
Platform,
Introduced.Version,
Deprecated.Version,
@@ -1134,12 +1153,10 @@ static void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr,
IsUnavailable));
}
-static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if(!checkAttributeNumArgs(S, Attr, 1))
return;
- }
Expr *Arg = Attr.getArg(0);
Arg = Arg->IgnoreParenCasts();
@@ -1167,30 +1184,30 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
+ D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
}
-static void HandleObjCMethodFamilyAttr(Decl *decl, const AttributeList &attr,
- Sema &S) {
+static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
+ const AttributeList &Attr) {
ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
if (!method) {
- S.Diag(attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< ExpectedMethod;
return;
}
- if (attr.getNumArgs() != 0 || !attr.getParameterName()) {
- if (!attr.getParameterName() && attr.getNumArgs() == 1) {
- S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
+ if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
+ if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
<< "objc_method_family" << 1;
} else {
- S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
}
- attr.setInvalid();
+ Attr.setInvalid();
return;
}
- llvm::StringRef param = attr.getParameterName()->getName();
+ llvm::StringRef param = Attr.getParameterName()->getName();
ObjCMethodFamilyAttr::FamilyKind family;
if (param == "none")
family = ObjCMethodFamilyAttr::OMF_None;
@@ -1207,20 +1224,26 @@ static void HandleObjCMethodFamilyAttr(Decl *decl, const AttributeList &attr,
else {
// Just warn and ignore it. This is future-proof against new
// families being used in system headers.
- S.Diag(attr.getParameterLoc(), diag::warn_unknown_method_family);
+ S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
return;
}
- decl->addAttr(new (S.Context) ObjCMethodFamilyAttr(attr.getLoc(),
- S.Context, family));
+ if (family == ObjCMethodFamilyAttr::OMF_init &&
+ !method->getResultType()->isObjCObjectPointerType()) {
+ S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
+ << method->getResultType();
+ // Ignore the attribute.
+ return;
+ }
+
+ method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
+ S.Context, family));
}
-static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
- Sema &S) {
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+static void handleObjCExceptionAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
if (OCI == 0) {
@@ -1231,7 +1254,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
}
-static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
@@ -1248,7 +1271,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
}
static void
-HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
@@ -1262,7 +1285,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
}
-static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
<< "blocks" << 1;
@@ -1283,10 +1306,10 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
+ D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
}
-static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.getNumArgs() > 2) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
@@ -1333,7 +1356,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
}
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
const FunctionType *FT = FD->getType()->getAs<FunctionType>();
assert(FT && "FunctionDecl has non-function type?");
@@ -1346,19 +1369,19 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
return;
}
- } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
+ } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
if (!MD->isVariadic()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
return;
}
- } else if (isa<BlockDecl>(d)) {
+ } else if (isa<BlockDecl>(D)) {
// Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
// caller.
;
- } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
+ } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
QualType Ty = V->getType();
if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
- const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
+ const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
: Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
if (!cast<FunctionProtoType>(FT)->isVariadic()) {
int m = Ty->isFunctionPointerType() ? 0 : 1;
@@ -1375,16 +1398,14 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
<< Attr.getName() << ExpectedFunctionMethodOrBlock;
return;
}
- d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
+ D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
nullPos));
}
-static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -1407,36 +1428,35 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
}
-static void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
+static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (attr.hasParameterOrArguments()) {
- S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (Attr.hasParameterOrArguments()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
- S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << attr.getName() << ExpectedVariableOrFunction;
+ if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedVariableOrFunction;
return;
}
- NamedDecl *nd = cast<NamedDecl>(d);
+ NamedDecl *nd = cast<NamedDecl>(D);
// 'weak' only applies to declarations with external linkage.
if (hasEffectivelyInternalLinkage(nd)) {
- S.Diag(attr.getLoc(), diag::err_attribute_weak_static);
+ S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
return;
}
- nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
+ nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
}
-static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
+
// weak_import only applies to variable & function declarations.
bool isDef = false;
@@ -1459,13 +1479,11 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
}
-static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
- Sema &S) {
+static void handleReqdWorkGroupSize(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// Attribute has 3 arguments.
- if (Attr.getNumArgs() != 3) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if (!checkAttributeNumArgs(S, Attr, 3))
return;
- }
unsigned WGSize[3];
for (unsigned i = 0; i < 3; ++i) {
@@ -1484,12 +1502,10 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
WGSize[2]));
}
-static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Attribute has no arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
- }
// Make sure that there is a string literal as the sections's single
// argument.
@@ -1519,37 +1535,45 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
}
-static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
-
- d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
+
+ if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
+ if (Existing->getLocation().isInvalid())
+ Existing->setLocation(Attr.getLoc());
+ } else {
+ D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
+ }
}
-static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return;
}
- d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
+ if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
+ if (Existing->getLocation().isInvalid())
+ Existing->setLocation(Attr.getLoc());
+ } else {
+ D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
+ }
}
-static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
}
-static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
@@ -1560,7 +1584,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- VarDecl *VD = dyn_cast<VarDecl>(d);
+ VarDecl *VD = dyn_cast<VarDecl>(D);
if (!VD || !VD->hasLocalStorage()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
@@ -1605,18 +1629,17 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
+ D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
- }
- if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
+
+ if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
@@ -1624,8 +1647,8 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
- bool HasImplicitThisParam = isInstanceMethod(d);
- unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
+ bool HasImplicitThisParam = isInstanceMethod(D);
+ unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
unsigned FirstIdx = 1;
// checks for the 2nd argument
@@ -1656,7 +1679,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// make sure the format string is really a string
- QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
+ QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
bool not_nsstring_type = !isNSStringType(Ty, S.Context);
if (not_nsstring_type &&
@@ -1669,7 +1692,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
<< IdxExpr->getSourceRange();
return;
}
- Ty = getFunctionOrMethodResultType(d);
+ Ty = getFunctionOrMethodResultType(D);
if (!isNSStringType(Ty, S.Context) &&
!isCFStringType(Ty, S.Context) &&
(!Ty->isPointerType() ||
@@ -1681,7 +1704,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
Idx.getZExtValue()));
}
@@ -1722,19 +1745,19 @@ static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
/// Handle __attribute__((init_priority(priority))) attributes based on
/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
-static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleInitPriorityAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
if (!S.getLangOptions().CPlusPlus) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
return;
}
- if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
+ if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
Attr.setInvalid();
return;
}
- QualType T = dyn_cast<VarDecl>(d)->getType();
+ QualType T = dyn_cast<VarDecl>(D)->getType();
if (S.Context.getAsArrayType(T))
T = S.Context.getBaseElementType(T);
if (!T->getAs<RecordType>()) {
@@ -1765,13 +1788,13 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
Attr.setInvalid();
return;
}
- d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
prioritynum));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.getParameterName()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
@@ -1784,7 +1807,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
+ if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
@@ -1792,8 +1815,8 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
- bool HasImplicitThisParam = isInstanceMethod(d);
- unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
+ bool HasImplicitThisParam = isInstanceMethod(D);
+ unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
unsigned FirstIdx = 1;
llvm::StringRef Format = Attr.getParameterName()->getName();
@@ -1844,7 +1867,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// make sure the format string is really a string
- QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
+ QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
if (Kind == CFStringFormat) {
if (!isCFStringType(Ty, S.Context)) {
@@ -1881,10 +1904,10 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check if the function is variadic if the 3rd argument non-zero
if (FirstArg != 0) {
- if (isFunctionOrMethodVariadic(d)) {
+ if (isFunctionOrMethodVariadic(D)) {
++NumArgs; // +1 for ...
} else {
- S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
+ S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
return;
}
}
@@ -1904,26 +1927,42 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+ // Check whether we already have an equivalent format attribute.
+ for (specific_attr_iterator<FormatAttr>
+ i = D->specific_attr_begin<FormatAttr>(),
+ e = D->specific_attr_end<FormatAttr>();
+ i != e ; ++i) {
+ FormatAttr *f = *i;
+ if (f->getType() == Format &&
+ f->getFormatIdx() == (int)Idx.getZExtValue() &&
+ f->getFirstArg() == (int)FirstArg.getZExtValue()) {
+ // If we don't have a valid location for this attribute, adopt the
+ // location.
+ if (f->getLocation().isInvalid())
+ f->setLocation(Attr.getLoc());
+ return;
+ }
+ }
+
+ D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
Idx.getZExtValue(),
FirstArg.getZExtValue()));
}
-static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleTransparentUnionAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
+
// Try to find the underlying union declaration.
RecordDecl *RD = 0;
- TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(d);
+ TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
if (TD && TD->getUnderlyingType()->isUnionType())
RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
else
- RD = dyn_cast<RecordDecl>(d);
+ RD = dyn_cast<RecordDecl>(D);
if (!RD || !RD->isUnion()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -1977,12 +2016,11 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
}
-static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
- }
+
Expr *ArgExpr = Attr.getArg(0);
StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
@@ -1992,11 +2030,11 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
- d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
SE->getString()));
}
-static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -2045,21 +2083,20 @@ void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
return;
}
-/// HandleModeAttr - This attribute modifies the width of a decl with primitive
+/// handleModeAttr - This attribute modifies the width of a decl with primitive
/// type.
///
/// Despite what would be logical, the mode attribute is a decl attribute, not a
/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
/// HImode, not an intermediate pointer.
-static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// This attribute isn't documented, but glibc uses it. It changes
// the width of an int or unsigned int to the specified size.
// Check that there aren't any arguments
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
+
IdentifierInfo *Name = Attr.getParameterName();
if (!Name) {
@@ -2216,57 +2253,53 @@ static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
cast<ValueDecl>(D)->setType(NewTy);
}
-static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isFunctionOrMethod(d)) {
+ if (!isFunctionOrMethod(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
}
-static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<FunctionDecl>(d)) {
+
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
}
-static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<FunctionDecl>(d)) {
+
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
+ D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
S.Context));
}
-static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.CUDA) {
// check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
@@ -2274,19 +2307,19 @@ static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- if (!isa<VarDecl>(d)) {
+ if (!isa<VarDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
return;
}
- d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
}
}
-static void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.CUDA) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
@@ -2294,33 +2327,31 @@ static void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
+ if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariableOrFunction;
return;
}
- d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
}
}
-static void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.CUDA) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<FunctionDecl>(d)) {
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- FunctionDecl *FD = cast<FunctionDecl>(d);
+ FunctionDecl *FD = cast<FunctionDecl>(D);
if (!FD->getResultType()->isVoidType()) {
TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
@@ -2335,60 +2366,56 @@ static void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
}
}
-static void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.CUDA) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<FunctionDecl>(d)) {
+
+ if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
return;
}
- d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
}
}
-static void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.CUDA) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- if (!isa<VarDecl>(d)) {
+
+ if (!isa<VarDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
return;
}
- d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
}
}
-static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (!checkAttributeNumArgs(S, Attr, 0))
return;
- }
- FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
+ FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
if (Fn == 0) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunction;
@@ -2400,47 +2427,47 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
}
-static void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
- if (hasDeclarator(d)) return;
+static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (hasDeclarator(D)) return;
- // Diagnostic is emitted elsewhere: here we store the (valid) attr
+ // Diagnostic is emitted elsewhere: here we store the (valid) Attr
// in the Decl node for syntactic reasoning, e.g., pretty-printing.
CallingConv CC;
- if (S.CheckCallingConvAttr(attr, CC))
+ if (S.CheckCallingConvAttr(Attr, CC))
return;
- if (!isa<ObjCMethodDecl>(d)) {
- S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << attr.getName() << ExpectedFunctionOrMethod;
+ if (!isa<ObjCMethodDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedFunctionOrMethod;
return;
}
- switch (attr.getKind()) {
+ switch (Attr.getKind()) {
case AttributeList::AT_fastcall:
- d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_stdcall:
- d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_thiscall:
- d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_cdecl:
- d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_pascal:
- d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_pcs: {
- Expr *Arg = attr.getArg(0);
+ Expr *Arg = Attr.getArg(0);
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (Str == 0 || Str->isWide()) {
- S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
<< "pcs" << 1;
- attr.setInvalid();
+ Attr.setInvalid();
return;
}
@@ -2451,12 +2478,12 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
else if (StrRef == "aapcs-vfp")
PCS = PcsAttr::AAPCS_VFP;
else {
- S.Diag(attr.getLoc(), diag::err_invalid_pcs);
- attr.setInvalid();
+ S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
+ Attr.setInvalid();
return;
}
- d->addAttr(::new (S.Context) PcsAttr(attr.getLoc(), S.Context, PCS));
+ D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
}
default:
llvm_unreachable("unexpected attribute kind");
@@ -2464,9 +2491,9 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
}
}
-static void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){
- assert(Attr.isInvalid() == false);
- d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
+static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
+ assert(!Attr.isInvalid());
+ D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
}
bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
@@ -2515,63 +2542,63 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
return false;
}
-static void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) {
- if (hasDeclarator(d)) return;
+static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (hasDeclarator(D)) return;
unsigned numParams;
- if (S.CheckRegparmAttr(attr, numParams))
+ if (S.CheckRegparmAttr(Attr, numParams))
return;
- if (!isa<ObjCMethodDecl>(d)) {
- S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << attr.getName() << ExpectedFunctionOrMethod;
+ if (!isa<ObjCMethodDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedFunctionOrMethod;
return;
}
- d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams));
+ D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
}
/// Checks a regparm attribute, returning true if it is ill-formed and
/// otherwise setting numParams to the appropriate value.
-bool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) {
- if (attr.isInvalid())
+bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
+ if (Attr.isInvalid())
return true;
- if (attr.getNumArgs() != 1) {
- Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
- attr.setInvalid();
+ if (Attr.getNumArgs() != 1) {
+ Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ Attr.setInvalid();
return true;
}
- Expr *NumParamsExpr = attr.getArg(0);
+ Expr *NumParamsExpr = Attr.getArg(0);
llvm::APSInt NumParams(32);
if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
!NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
- Diag(attr.getLoc(), diag::err_attribute_argument_not_int)
+ Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
<< "regparm" << NumParamsExpr->getSourceRange();
- attr.setInvalid();
+ Attr.setInvalid();
return true;
}
if (Context.Target.getRegParmMax() == 0) {
- Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
+ Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
<< NumParamsExpr->getSourceRange();
- attr.setInvalid();
+ Attr.setInvalid();
return true;
}
numParams = NumParams.getZExtValue();
if (numParams > Context.Target.getRegParmMax()) {
- Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number)
+ Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
<< Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
- attr.setInvalid();
+ Attr.setInvalid();
return true;
}
return false;
}
-static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
+static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
if (S.LangOpts.CUDA) {
// check the attribute arguments.
if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
@@ -2580,7 +2607,7 @@ static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
return;
}
- if (!isFunctionOrMethod(d)) {
+ if (!isFunctionOrMethod(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunctionOrMethod;
return;
@@ -2608,7 +2635,7 @@ static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
}
}
- d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
MaxThreads.getZExtValue(),
MinBlocks.getZExtValue()));
} else {
@@ -2627,16 +2654,16 @@ static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
}
-static void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
- ParmVarDecl *param = dyn_cast<ParmVarDecl>(d);
+static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
if (!param) {
- S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
- << SourceRange(attr.getLoc()) << attr.getName() << ExpectedParameter;
+ S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
+ << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
return;
}
bool typeOK, cf;
- if (attr.getKind() == AttributeList::AT_ns_consumed) {
+ if (Attr.getKind() == AttributeList::AT_ns_consumed) {
typeOK = isValidSubjectOfNSAttribute(S, param->getType());
cf = false;
} else {
@@ -2645,47 +2672,52 @@ static void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
}
if (!typeOK) {
- S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
- << SourceRange(attr.getLoc()) << attr.getName() << cf;
+ S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
+ << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
return;
}
if (cf)
- param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context));
+ param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
else
- param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context));
+ param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
}
-static void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr,
- Sema &S) {
- if (!isa<ObjCMethodDecl>(d)) {
- S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
- << SourceRange(attr.getLoc()) << attr.getName() << ExpectedMethod;
+static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!isa<ObjCMethodDecl>(D)) {
+ S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
+ << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
return;
}
- d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context));
+ D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
}
-static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
- Sema &S) {
+static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
QualType returnType;
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
+ if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
returnType = MD->getResultType();
- else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
+ else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
+ returnType = PD->getType();
+ else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
+ (Attr.getKind() == AttributeList::AT_ns_returns_retained))
+ return; // ignore: was handled as a type attribute
+ else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
returnType = FD->getResultType();
else {
- S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
- << SourceRange(attr.getLoc()) << attr.getName()
+ S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
+ << SourceRange(Attr.getLoc()) << Attr.getName()
<< ExpectedFunctionOrMethod;
return;
}
bool typeOK;
bool cf;
- switch (attr.getKind()) {
+ switch (Attr.getKind()) {
default: llvm_unreachable("invalid ownership attribute"); return;
case AttributeList::AT_ns_returns_autoreleased:
case AttributeList::AT_ns_returns_retained:
@@ -2702,39 +2734,95 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
}
if (!typeOK) {
- S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
- << SourceRange(attr.getLoc())
- << attr.getName() << isa<ObjCMethodDecl>(d) << cf;
+ S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
+ << SourceRange(Attr.getLoc())
+ << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
return;
}
- switch (attr.getKind()) {
+ switch (Attr.getKind()) {
default:
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_ns_returns_autoreleased:
- d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(),
+ D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
S.Context));
return;
case AttributeList::AT_cf_returns_not_retained:
- d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(),
+ D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
S.Context));
return;
case AttributeList::AT_ns_returns_not_retained:
- d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(),
+ D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
S.Context));
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(),
+ D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
S.Context));
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(),
+ D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
S.Context));
return;
};
}
+static void handleObjCOwnershipAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (hasDeclarator(D)) return;
+
+ SourceLocation L = Attr.getLoc();
+ S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
+ << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
+}
+
+static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
+ SourceLocation L = Attr.getLoc();
+ S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
+ << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
+ return;
+ }
+
+ ValueDecl *vd = cast<ValueDecl>(D);
+ QualType type = vd->getType();
+
+ if (!type->isDependentType() &&
+ !type->isObjCLifetimeType()) {
+ S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
+ << type;
+ return;
+ }
+
+ Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
+
+ // If we have no lifetime yet, check the lifetime we're presumably
+ // going to infer.
+ if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
+ lifetime = type->getObjCARCImplicitLifetime();
+
+ switch (lifetime) {
+ case Qualifiers::OCL_None:
+ assert(type->isDependentType() &&
+ "didn't infer lifetime for non-dependent type?");
+ break;
+
+ case Qualifiers::OCL_Weak: // meaningful
+ case Qualifiers::OCL_Strong: // meaningful
+ break;
+
+ case Qualifiers::OCL_ExplicitNone:
+ case Qualifiers::OCL_Autoreleasing:
+ S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
+ << (lifetime == Qualifiers::OCL_Autoreleasing);
+ break;
+ }
+
+ D->addAttr(::new (S.Context)
+ ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
+}
+
static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
return Attr.getKind() == AttributeList::AT_dllimport ||
Attr.getKind() == AttributeList::AT_dllexport ||
@@ -2745,13 +2833,12 @@ static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
// Microsoft specific attribute handlers.
//===----------------------------------------------------------------------===//
-static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
// check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
- }
+
Expr *Arg = Attr.getArg(0);
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
if (Str == 0 || Str->isWide()) {
@@ -2794,7 +2881,7 @@ static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
I++;
}
- d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
+ D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
Str->getString()));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
@@ -2804,24 +2891,24 @@ static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
-static void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) {
+static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
+ const AttributeList &Attr) {
switch (Attr.getKind()) {
- case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break;
- case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break;
- case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
+ case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break;
+ case AttributeList::AT_host: handleHostAttr (S, D, Attr); break;
+ case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
default:
break;
}
}
-static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) {
+static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
+ const AttributeList &Attr) {
switch (Attr.getKind()) {
- case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break;
- case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break;
+ case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
+ case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
case AttributeList::AT_IBOutletCollection:
- HandleIBOutletCollection(D, Attr, S); break;
+ handleIBOutletCollection(S, D, Attr); break;
case AttributeList::AT_address_space:
case AttributeList::AT_opencl_image_access:
case AttributeList::AT_objc_gc:
@@ -2837,100 +2924,108 @@ static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
// Ignore, this is a non-inheritable attribute, handled
// by ProcessNonInheritableDeclAttr.
break;
- case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
- case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
+ case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break;
+ case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break;
case AttributeList::AT_always_inline:
- HandleAlwaysInlineAttr (D, Attr, S); break;
+ handleAlwaysInlineAttr (S, D, Attr); break;
case AttributeList::AT_analyzer_noreturn:
- HandleAnalyzerNoReturnAttr (D, Attr, S); break;
- case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
- case AttributeList::AT_availability:HandleAvailabilityAttr(D, Attr, S); break;
+ handleAnalyzerNoReturnAttr (S, D, Attr); break;
+ case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break;
+ case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
case AttributeList::AT_carries_dependency:
- HandleDependencyAttr (D, Attr, S); break;
- case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break;
- case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break;
- case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
- case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break;
- case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break;
+ handleDependencyAttr (S, D, Attr); break;
+ case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break;
+ case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break;
+ case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
+ case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break;
+ case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break;
case AttributeList::AT_ext_vector_type:
- HandleExtVectorTypeAttr(scope, D, Attr, S);
+ handleExtVectorTypeAttr(S, scope, D, Attr);
break;
- case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
- case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
- case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break;
- case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break;
+ case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break;
+ case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break;
+ case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break;
+ case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break;
case AttributeList::AT_launch_bounds:
- HandleLaunchBoundsAttr(D, Attr, S);
+ handleLaunchBoundsAttr(S, D, Attr);
break;
- case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
- case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
- case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break;
- case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break;
- case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
+ case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break;
+ case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break;
+ case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break;
+ case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break;
+ case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break;
case AttributeList::AT_ownership_returns:
case AttributeList::AT_ownership_takes:
case AttributeList::AT_ownership_holds:
- HandleOwnershipAttr (D, Attr, S); break;
- case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break;
- case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
- case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
- case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break;
- case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break;
+ handleOwnershipAttr (S, D, Attr); break;
+ case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break;
+ case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break;
+ case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break;
+ case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break;
+ case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break;
+
+ case AttributeList::AT_objc_ownership:
+ handleObjCOwnershipAttr(S, D, Attr); break;
+ case AttributeList::AT_objc_precise_lifetime:
+ handleObjCPreciseLifetimeAttr(S, D, Attr); break;
// Checker-specific.
case AttributeList::AT_cf_consumed:
- case AttributeList::AT_ns_consumed: HandleNSConsumedAttr (D, Attr, S); break;
+ case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break;
case AttributeList::AT_ns_consumes_self:
- HandleNSConsumesSelfAttr(D, Attr, S); break;
+ handleNSConsumesSelfAttr(S, D, Attr); break;
case AttributeList::AT_ns_returns_autoreleased:
case AttributeList::AT_ns_returns_not_retained:
case AttributeList::AT_cf_returns_not_retained:
case AttributeList::AT_ns_returns_retained:
case AttributeList::AT_cf_returns_retained:
- HandleNSReturnsRetainedAttr(D, Attr, S); break;
+ handleNSReturnsRetainedAttr(S, D, Attr); break;
case AttributeList::AT_reqd_wg_size:
- HandleReqdWorkGroupSize(D, Attr, S); break;
+ handleReqdWorkGroupSize(S, D, Attr); break;
case AttributeList::AT_init_priority:
- HandleInitPriorityAttr(D, Attr, S); break;
+ handleInitPriorityAttr(S, D, Attr); break;
- case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
- case AttributeList::AT_MsStruct: HandleMsStructAttr (D, Attr, S); break;
- case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
- case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
- case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
- case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
- case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break;
- case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
+ case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break;
+ case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break;
+ case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break;
+ case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
+ case AttributeList::AT_arc_weakref_unavailable:
+ handleArcWeakrefUnavailableAttr (S, D, Attr);
break;
- case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
- case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break;
- case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break;
+ case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break;
+ case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break;
+ case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break;
+ case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
+ break;
+ case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break;
+ case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break;
+ case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break;
case AttributeList::AT_transparent_union:
- HandleTransparentUnionAttr(D, Attr, S);
+ handleTransparentUnionAttr(S, D, Attr);
break;
case AttributeList::AT_objc_exception:
- HandleObjCExceptionAttr(D, Attr, S);
+ handleObjCExceptionAttr(S, D, Attr);
break;
case AttributeList::AT_objc_method_family:
- HandleObjCMethodFamilyAttr(D, Attr, S);
+ handleObjCMethodFamilyAttr(S, D, Attr);
break;
- case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
- case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
- case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
- case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
- case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
- case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
- case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break;
- case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break;
- case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break;
+ case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break;
+ case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break;
+ case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break;
+ case AttributeList::AT_const: handleConstAttr (S, D, Attr); break;
+ case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break;
+ case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break;
+ case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break;
+ case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break;
+ case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break;
case AttributeList::IgnoredAttribute:
// Just ignore
break;
case AttributeList::AT_no_instrument_function: // Interacts with -pg.
- HandleNoInstrumentFunctionAttr(D, Attr, S);
+ handleNoInstrumentFunctionAttr(S, D, Attr);
break;
case AttributeList::AT_stdcall:
case AttributeList::AT_cdecl:
@@ -2938,13 +3033,13 @@ static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
case AttributeList::AT_thiscall:
case AttributeList::AT_pascal:
case AttributeList::AT_pcs:
- HandleCallConvAttr(D, Attr, S);
+ handleCallConvAttr(S, D, Attr);
break;
case AttributeList::AT_opencl_kernel_function:
- HandleOpenCLKernelAttr(D, Attr, S);
+ handleOpenCLKernelAttr(S, D, Attr);
break;
case AttributeList::AT_uuid:
- HandleUuidAttr(D, Attr, S);
+ handleUuidAttr(S, D, Attr);
break;
default:
// Ask target about the attribute.
@@ -2960,8 +3055,8 @@ static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
/// the attribute applies to decls. If the attribute is a type attribute, just
/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
-static void ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S,
+static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
+ const AttributeList &Attr,
bool NonInheritable, bool Inheritable) {
if (Attr.isInvalid())
return;
@@ -2971,10 +3066,10 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
return;
if (NonInheritable)
- ProcessNonInheritableDeclAttr(scope, D, Attr, S);
+ ProcessNonInheritableDeclAttr(S, scope, D, Attr);
if (Inheritable)
- ProcessInheritableDeclAttr(scope, D, Attr, S);
+ ProcessInheritableDeclAttr(S, scope, D, Attr);
}
/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
@@ -2983,7 +3078,7 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
const AttributeList *AttrList,
bool NonInheritable, bool Inheritable) {
for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable);
+ ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
}
// GCC accepts
@@ -3085,6 +3180,32 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
}
+/// Is the given declaration allowed to use a forbidden type?
+static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
+ // Private ivars are always okay. Unfortunately, people don't
+ // always properly make their ivars private, even in system headers.
+ // Plus we need to make fields okay, too.
+ if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
+ return false;
+
+ // Require it to be declared in a system header.
+ return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
+}
+
+/// Handle a delayed forbidden-type diagnostic.
+static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
+ Decl *decl) {
+ if (decl && isForbiddenTypeAllowed(S, decl)) {
+ decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
+ "this system declaration uses an unsupported type"));
+ return;
+ }
+
+ S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
+ << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
+ diag.Triggered = true;
+}
+
// This duplicates a vector push_back but hides the need to know the
// size of the type.
void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
@@ -3126,7 +3247,7 @@ void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
// We only want to actually emit delayed diagnostics when we
// successfully parsed a decl.
- if (decl) {
+ if (decl && !decl->isInvalidDecl()) {
// We emit all the active diagnostics, not just those starting
// from the saved state. The idea is this: we get one push for a
// decl spec and another for each declarator; in a decl group like:
@@ -3147,6 +3268,10 @@ void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
case DelayedDiagnostic::Access:
S.HandleDelayedAccessCheck(diag, decl);
break;
+
+ case DelayedDiagnostic::ForbiddenType:
+ handleDelayedForbiddenType(S, diag, decl);
+ break;
}
}
}
OpenPOWER on IntegriCloud