aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp1240
1 files changed, 854 insertions, 386 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index e326a20c87d0..982e7a5dd81b 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -16,14 +16,17 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/Mangle.h"
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
#include "llvm/ADT/StringExtras.h"
using namespace clang;
using namespace sema;
@@ -37,6 +40,7 @@ enum AttributeDeclKind {
ExpectedFunctionOrMethod,
ExpectedParameter,
ExpectedFunctionMethodOrBlock,
+ ExpectedFunctionMethodOrClass,
ExpectedFunctionMethodOrParameter,
ExpectedClass,
ExpectedVariable,
@@ -44,7 +48,11 @@ enum AttributeDeclKind {
ExpectedVariableFunctionOrLabel,
ExpectedFieldOrGlobalVar,
ExpectedStruct,
- ExpectedTLSVar
+ ExpectedVariableFunctionOrTag,
+ ExpectedTLSVar,
+ ExpectedVariableOrField,
+ ExpectedVariableFieldOrTag,
+ ExpectedTypeOrNamespace
};
//===----------------------------------------------------------------------===//
@@ -293,12 +301,12 @@ static bool isIntOrBool(Expr *Exp) {
static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
- if (Res1.first == Res1.second)
+ if (Res1.empty())
return false;
DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
- if (Res2.first == Res2.second)
+ if (Res2.empty())
return false;
return true;
@@ -503,18 +511,22 @@ static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkGuardedVarAttrCommon(S, D, Attr))
return;
- D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ GuardedVarAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handlePtGuardedVarAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
+ const AttributeList &Attr) {
if (!checkGuardedVarAttrCommon(S, D, Attr))
return;
if (!threadSafetyCheckIsPointer(S, D, Attr))
return;
- D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ PtGuardedVarAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
@@ -594,11 +606,13 @@ static void handleScopedLockableAttr(Sema &S, Decl *D,
if (!checkLockableAttrCommon(S, D, Attr))
return;
- D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ScopedLockableAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
-static void handleNoThreadSafetyAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
+static void handleNoThreadSafetyAnalysis(Sema &S, Decl *D,
+ const AttributeList &Attr) {
assert(!Attr.isInvalid());
if (!checkAttributeNumArgs(S, Attr, 0))
@@ -614,7 +628,7 @@ static void handleNoThreadSafetyAttr(Sema &S, Decl *D,
S.Context));
}
-static void handleNoAddressSafetyAttr(Sema &S, Decl *D,
+static void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
assert(!Attr.isInvalid());
@@ -622,13 +636,48 @@ static void handleNoAddressSafetyAttr(Sema &S, Decl *D,
return;
if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedFunctionOrMethod;
+ return;
+ }
+
+ D->addAttr(::new (S.Context)
+ NoSanitizeAddressAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleNoSanitizeMemory(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ assert(!Attr.isInvalid());
+
+ if (!checkAttributeNumArgs(S, Attr, 0))
+ return;
+
+ if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedFunctionOrMethod;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) NoSanitizeMemoryAttr(Attr.getRange(),
+ S.Context));
+}
+
+static void handleNoSanitizeThread(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ assert(!Attr.isInvalid());
+
+ if (!checkAttributeNumArgs(S, Attr, 0))
+ return;
+
+ if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunctionOrMethod;
return;
}
- D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context) NoSanitizeThreadAttr(Attr.getRange(),
+ S.Context));
}
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
@@ -673,8 +722,10 @@ static void handleAcquiredAfterAttr(Sema &S, Decl *D,
return;
Expr **StartArg = &Args[0];
- D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
- StartArg, Args.size()));
+ D->addAttr(::new (S.Context)
+ AcquiredAfterAttr(Attr.getRange(), S.Context,
+ StartArg, Args.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
@@ -684,8 +735,10 @@ static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
return;
Expr **StartArg = &Args[0];
- D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
- StartArg, Args.size()));
+ D->addAttr(::new (S.Context)
+ AcquiredBeforeAttr(Attr.getRange(), S.Context,
+ StartArg, Args.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static bool checkLockFunAttrCommon(Sema &S, Decl *D,
@@ -716,9 +769,9 @@ static void handleSharedLockFunctionAttr(Sema &S, Decl *D,
unsigned Size = Args.size();
Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
- S.Context,
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
@@ -729,9 +782,10 @@ static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
unsigned Size = Args.size();
Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
- S.Context,
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
+ StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
@@ -768,10 +822,10 @@ static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
unsigned Size = Args.size();
Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
- S.Context,
- Attr.getArg(0),
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
+ Attr.getArg(0), StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
@@ -782,10 +836,10 @@ static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
unsigned Size = Args.size();
Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
- S.Context,
- Attr.getArg(0),
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
+ Attr.getArg(0), StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static bool checkLocksRequiredCommon(Sema &S, Decl *D,
@@ -817,10 +871,10 @@ static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
return;
Expr **StartArg = &Args[0];
- D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
- S.Context,
- StartArg,
- Args.size()));
+ D->addAttr(::new (S.Context)
+ ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
+ StartArg, Args.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
@@ -830,10 +884,10 @@ static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
return;
Expr **StartArg = &Args[0];
- D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
- S.Context,
- StartArg,
- Args.size()));
+ D->addAttr(::new (S.Context)
+ SharedLocksRequiredAttr(Attr.getRange(), S.Context,
+ StartArg, Args.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleUnlockFunAttr(Sema &S, Decl *D,
@@ -854,8 +908,9 @@ static void handleUnlockFunAttr(Sema &S, Decl *D,
unsigned Size = Args.size();
Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleLockReturnedAttr(Sema &S, Decl *D,
@@ -878,8 +933,9 @@ static void handleLockReturnedAttr(Sema &S, Decl *D,
if (Size == 0)
return;
- D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
- Args[0]));
+ D->addAttr(::new (S.Context)
+ LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
+ Attr.getAttributeSpellingListIndex()));
}
static void handleLocksExcludedAttr(Sema &S, Decl *D,
@@ -903,54 +959,24 @@ static void handleLocksExcludedAttr(Sema &S, Decl *D,
return;
Expr **StartArg = &Args[0];
- D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
- StartArg, Size));
+ D->addAttr(::new (S.Context)
+ LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
const AttributeList &Attr) {
- TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
- if (tDecl == 0) {
+ TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
+ if (TD == 0) {
+ // __attribute__((ext_vector_type(N))) can only be applied to typedefs
+ // and type-ids.
S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
return;
}
- QualType curType = tDecl->getUnderlyingType();
-
- Expr *sizeExpr;
-
- // Special case where the argument is a template id.
- if (Attr.getParameterName()) {
- CXXScopeSpec SS;
- SourceLocation TemplateKWLoc;
- UnqualifiedId id;
- id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
-
- ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
- false, false);
- if (Size.isInvalid())
- return;
-
- sizeExpr = Size.get();
- } else {
- // check the attribute arguments.
- if (!checkAttributeNumArgs(S, Attr, 1))
- return;
-
- sizeExpr = Attr.getArg(0);
- }
-
- // Instantiate/Install the vector type, and let Sema build the type for us.
- // This will run the reguired checks.
- QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
- if (!T.isNull()) {
- // FIXME: preserve the old source info.
- tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
-
- // Remember this typedef decl, we will need it later for diagnostics.
- S.ExtVectorDecls.push_back(tDecl);
- }
+ // Remember this typedef decl, we will need it later for diagnostics.
+ S.ExtVectorDecls.push_back(TD);
}
static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -969,14 +995,18 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
+ FD->addAttr(::new (S.Context)
+ PackedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
- RD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
+ RD->addAttr(::new (S.Context)
+ MsStructAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -989,7 +1019,9 @@ static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
// The IBAction attributes only apply to instance methods.
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
if (MD->isInstanceMethod()) {
- D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ IBActionAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
}
@@ -1030,7 +1062,9 @@ static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkIBOutletCommon(S, D, Attr))
return;
- D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ IBOutletAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleIBOutletCollection(Sema &S, Decl *D,
@@ -1064,8 +1098,10 @@ static void handleIBOutletCollection(Sema &S, Decl *D,
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
return;
}
- D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
- QT, Attr.getParameterLoc()));
+ D->addAttr(::new (S.Context)
+ IBOutletCollectionAttr(Attr.getRange(),S.Context,
+ QT, Attr.getParameterLoc(),
+ Attr.getAttributeSpellingListIndex()));
}
static void possibleTransparentUnionPointerType(QualType &T) {
@@ -1096,7 +1132,11 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
bool HasImplicitThisParam = isInstanceMethod(D);
- unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
+ unsigned NumArgs;
+ if (hasFunctionProto(D))
+ NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
+ else
+ NumArgs = 0;
SmallVector<unsigned, 8> SizeArgs;
@@ -1148,8 +1188,10 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
<< "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
}
- D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context,
- SizeArgs.data(), SizeArgs.size()));
+ D->addAttr(::new (S.Context)
+ AllocSizeAttr(Attr.getRange(), S.Context,
+ SizeArgs.data(), SizeArgs.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1164,15 +1206,13 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// In C++ the implicit 'this' function parameter also counts, and they are
// counted from one.
bool HasImplicitThisParam = isInstanceMethod(D);
- unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
+ unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
// The nonnull attribute only applies to pointers.
SmallVector<unsigned, 10> NonNullArgs;
- for (AttributeList::arg_iterator I=Attr.arg_begin(),
- E=Attr.arg_end(); I!=E; ++I) {
-
-
+ for (AttributeList::arg_iterator I = Attr.arg_begin(),
+ E = Attr.arg_end(); I != E; ++I) {
// The argument must be an integer constant expression.
Expr *Ex = *I;
llvm::APSInt ArgNum(32);
@@ -1219,11 +1259,11 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// 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);
+ NonNullArgs.push_back(i);
}
// No pointer arguments?
@@ -1236,11 +1276,12 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
}
}
- unsigned* start = &NonNullArgs[0];
+ unsigned *start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
llvm::array_pod_sort(start, start + size);
- D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
- size));
+ D->addAttr(::new (S.Context)
+ NonNullAttr(Attr.getRange(), S.Context, start, size,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
@@ -1395,27 +1436,9 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
return;
}
- D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
- start, size));
-}
-
-/// Whether this declaration has internal linkage for the purposes of
-/// things that want to complain about things not have internal linkage.
-static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
- switch (D->getLinkage()) {
- case NoLinkage:
- case InternalLinkage:
- return true;
-
- // Template instantiations that go from external to unique-external
- // shouldn't get diagnosed.
- case UniqueExternalLinkage:
- return true;
-
- case ExternalLinkage:
- return false;
- }
- llvm_unreachable("unknown linkage kind!");
+ D->addAttr(::new (S.Context)
+ OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
+ AL.getAttributeSpellingListIndex()));
}
static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1468,11 +1491,6 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// This looks like a bug in gcc. We reject that for now. We should revisit
// it if this behaviour is actually used.
- if (!hasEffectivelyInternalLinkage(nd)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
- return;
- }
-
// GCC rejects
// static ((alias ("y"), weakref)).
// Should we? How to check that weakref is before or after alias?
@@ -1493,7 +1511,9 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Str->getString()));
}
- D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ WeakRefAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1521,7 +1541,8 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// FIXME: check if target symbol exists in current file
D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
- Str->getString()));
+ Str->getString(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1535,7 +1556,9 @@ static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) MinSizeAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ MinSizeAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1555,7 +1578,8 @@ static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1575,7 +1599,8 @@ static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1589,7 +1614,9 @@ static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NakedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleAlwaysInlineAttr(Sema &S, Decl *D,
@@ -1606,7 +1633,9 @@ static void handleAlwaysInlineAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ AlwaysInlineAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleTLSModelAttr(Sema &S, Decl *D,
@@ -1641,8 +1670,9 @@ static void handleTLSModelAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context,
- Model));
+ D->addAttr(::new (S.Context)
+ TLSModelAttr(Attr.getRange(), S.Context, Model,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1655,7 +1685,9 @@ static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
QualType RetTy = FD->getResultType();
if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
- D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ MallocAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
}
}
@@ -1668,13 +1700,17 @@ static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkAttributeNumArgs(S, Attr, 0))
return;
- D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ MayAliasAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
assert(!Attr.isInvalid());
if (isa<VarDecl>(D))
- D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NoCommonAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
@@ -1683,7 +1719,9 @@ static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
assert(!Attr.isInvalid());
if (isa<VarDecl>(D))
- D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CommonAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedVariable;
@@ -1700,7 +1738,9 @@ static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
return;
}
- D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NoReturnAttr(attr.getRange(), S.Context,
+ attr.getAttributeSpellingListIndex()));
}
bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
@@ -1727,14 +1767,33 @@ static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
if (VD == 0 || (!VD->getType()->isBlockPointerType()
&& !VD->getType()->isFunctionPointerType())) {
S.Diag(Attr.getLoc(),
- Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+ Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
: diag::warn_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunctionMethodOrBlock;
return;
}
}
- D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleCXX11NoReturnAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ // C++11 [dcl.attr.noreturn]p1:
+ // The attribute may be applied to the declarator-id in a function
+ // declaration.
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ if (!FD) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedFunctionOrMethod;
+ return;
+ }
+
+ D->addAttr(::new (S.Context)
+ CXX11NoReturnAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
// PS3 PPU-specific.
@@ -1795,16 +1854,30 @@ static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
count++;
}
- D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ VecReturnAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
-static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
+static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
+ const AttributeList &Attr) {
+ if (isa<ParmVarDecl>(D)) {
+ // [[carries_dependency]] can only be applied to a parameter if it is a
+ // parameter of a function declaration or lambda.
+ if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
+ S.Diag(Attr.getLoc(),
+ diag::err_carries_dependency_param_not_function_decl);
+ return;
+ }
+ } else if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedFunctionMethodOrParameter;
return;
}
- // FIXME: Actually store the attribute on the declaration
+
+ D->addAttr(::new (S.Context) CarriesDependencyAttr(
+ Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1821,7 +1894,9 @@ static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ UnusedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleReturnsTwiceAttr(Sema &S, Decl *D,
@@ -1838,7 +1913,9 @@ static void handleReturnsTwiceAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ReturnsTwiceAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1859,7 +1936,9 @@ static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ UsedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1888,8 +1967,9 @@ static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
- priority));
+ D->addAttr(::new (S.Context)
+ ConstructorAttr(Attr.getRange(), S.Context, priority,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1918,8 +1998,9 @@ static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
- priority));
+ D->addAttr(::new (S.Context)
+ DestructorAttr(Attr.getRange(), S.Context, priority,
+ Attr.getAttributeSpellingListIndex()));
}
template <typename AttrTy>
@@ -1943,7 +2024,8 @@ static void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
Str = SE->getString();
}
- D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str));
+ D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
@@ -1954,8 +2036,9 @@ static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
- Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleObjCRootClassAttr(Sema &S, Decl *D,
@@ -1971,11 +2054,13 @@ static void handleObjCRootClassAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ObjCRootClassAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
-static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
+static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
if (!isa<ObjCInterfaceDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
return;
@@ -1987,8 +2072,9 @@ static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
- Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
@@ -2030,13 +2116,33 @@ static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
return false;
}
-AvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
+/// \brief Check whether the two versions match.
+///
+/// If either version tuple is empty, then they are assumed to match. If
+/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
+static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
+ bool BeforeIsOkay) {
+ if (X.empty() || Y.empty())
+ return true;
+
+ if (X == Y)
+ return true;
+
+ if (BeforeIsOkay && X < Y)
+ return true;
+
+ return false;
+}
+
+AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
IdentifierInfo *Platform,
VersionTuple Introduced,
VersionTuple Deprecated,
VersionTuple Obsoleted,
bool IsUnavailable,
- StringRef Message) {
+ StringRef Message,
+ bool Override,
+ unsigned AttrSpellingListIndex) {
VersionTuple MergedIntroduced = Introduced;
VersionTuple MergedDeprecated = Deprecated;
VersionTuple MergedObsoleted = Obsoleted;
@@ -2062,18 +2168,47 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
VersionTuple OldDeprecated = OldAA->getDeprecated();
VersionTuple OldObsoleted = OldAA->getObsoleted();
bool OldIsUnavailable = OldAA->getUnavailable();
- StringRef OldMessage = OldAA->getMessage();
-
- if ((!OldIntroduced.empty() && !Introduced.empty() &&
- OldIntroduced != Introduced) ||
- (!OldDeprecated.empty() && !Deprecated.empty() &&
- OldDeprecated != Deprecated) ||
- (!OldObsoleted.empty() && !Obsoleted.empty() &&
- OldObsoleted != Obsoleted) ||
- (OldIsUnavailable != IsUnavailable) ||
- (OldMessage != Message)) {
- Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
- Diag(Range.getBegin(), diag::note_previous_attribute);
+
+ if (!versionsMatch(OldIntroduced, Introduced, Override) ||
+ !versionsMatch(Deprecated, OldDeprecated, Override) ||
+ !versionsMatch(Obsoleted, OldObsoleted, Override) ||
+ !(OldIsUnavailable == IsUnavailable ||
+ (Override && !OldIsUnavailable && IsUnavailable))) {
+ if (Override) {
+ int Which = -1;
+ VersionTuple FirstVersion;
+ VersionTuple SecondVersion;
+ if (!versionsMatch(OldIntroduced, Introduced, Override)) {
+ Which = 0;
+ FirstVersion = OldIntroduced;
+ SecondVersion = Introduced;
+ } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) {
+ Which = 1;
+ FirstVersion = Deprecated;
+ SecondVersion = OldDeprecated;
+ } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) {
+ Which = 2;
+ FirstVersion = Obsoleted;
+ SecondVersion = OldObsoleted;
+ }
+
+ if (Which == -1) {
+ Diag(OldAA->getLocation(),
+ diag::warn_mismatched_availability_override_unavail)
+ << AvailabilityAttr::getPrettyPlatformName(Platform->getName());
+ } else {
+ Diag(OldAA->getLocation(),
+ diag::warn_mismatched_availability_override)
+ << Which
+ << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
+ << FirstVersion.getAsString() << SecondVersion.getAsString();
+ }
+ Diag(Range.getBegin(), diag::note_overridden_method);
+ } else {
+ Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
+ Diag(Range.getBegin(), diag::note_previous_attribute);
+ }
+
Attrs.erase(Attrs.begin() + i);
--e;
continue;
@@ -2115,7 +2250,8 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
MergedDeprecated, MergedObsoleted)) {
return ::new (Context) AvailabilityAttr(Range, Context, Platform,
Introduced, Deprecated,
- Obsoleted, IsUnavailable, Message);
+ Obsoleted, IsUnavailable, Message,
+ AttrSpellingListIndex);
}
return NULL;
}
@@ -2124,11 +2260,18 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
IdentifierInfo *Platform = Attr.getParameterName();
SourceLocation PlatformLoc = Attr.getParameterLoc();
-
+ unsigned Index = Attr.getAttributeSpellingListIndex();
+
if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
<< Platform;
+ NamedDecl *ND = dyn_cast<NamedDecl>(D);
+ if (!ND) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ return;
+ }
+
AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
@@ -2139,37 +2282,69 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
if (SE)
Str = SE->getString();
- AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(),
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(),
Platform,
Introduced.Version,
Deprecated.Version,
Obsoleted.Version,
- IsUnavailable, Str);
+ IsUnavailable, Str,
+ /*Override=*/false,
+ Index);
if (NewAttr)
D->addAttr(NewAttr);
}
+template <class T>
+static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
+ typename T::VisibilityType value,
+ unsigned attrSpellingListIndex) {
+ T *existingAttr = D->getAttr<T>();
+ if (existingAttr) {
+ typename T::VisibilityType existingValue = existingAttr->getVisibility();
+ if (existingValue == value)
+ return NULL;
+ S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
+ S.Diag(range.getBegin(), diag::note_previous_attribute);
+ D->dropAttr<T>();
+ }
+ return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
+}
+
VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
- VisibilityAttr::VisibilityType Vis) {
+ VisibilityAttr::VisibilityType Vis,
+ unsigned AttrSpellingListIndex) {
+ return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
+ AttrSpellingListIndex);
+}
+
+TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
+ TypeVisibilityAttr::VisibilityType Vis,
+ unsigned AttrSpellingListIndex) {
+ return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
+ AttrSpellingListIndex);
+}
+
+static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
+ bool isTypeVisibility) {
+ // Visibility attributes don't mean anything on a typedef.
if (isa<TypedefNameDecl>(D)) {
- Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
- return NULL;
+ S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
+ << Attr.getName();
+ return;
}
- VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>();
- if (ExistingAttr) {
- VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility();
- if (ExistingVis == Vis)
- return NULL;
- Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
- Diag(Range.getBegin(), diag::note_previous_attribute);
- D->dropAttr<VisibilityAttr>();
+
+ // 'type_visibility' can only go on a type or namespace.
+ if (isTypeVisibility &&
+ !(isa<TagDecl>(D) ||
+ isa<ObjCInterfaceDecl>(D) ||
+ isa<NamespaceDecl>(D))) {
+ S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedTypeOrNamespace;
+ return;
}
- return ::new (Context) VisibilityAttr(Range, Context, Vis);
-}
-static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// check the attribute arguments.
- if(!checkAttributeNumArgs(S, Attr, 1))
+ if (!checkAttributeNumArgs(S, Attr, 1))
return;
Expr *Arg = Attr.getArg(0);
@@ -2178,13 +2353,13 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Str || !Str->isAscii()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
- << "visibility" << 1;
+ << (isTypeVisibility ? "type_visibility" : "visibility") << 1;
return;
}
StringRef TypeStr = Str->getString();
VisibilityAttr::VisibilityType type;
-
+
if (TypeStr == "default")
type = VisibilityAttr::Default;
else if (TypeStr == "hidden")
@@ -2205,9 +2380,17 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
- if (NewAttr)
- D->addAttr(NewAttr);
+ unsigned Index = Attr.getAttributeSpellingListIndex();
+ clang::Attr *newAttr;
+ if (isTypeVisibility) {
+ newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(),
+ (TypeVisibilityAttr::VisibilityType) type,
+ Index);
+ } else {
+ newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index);
+ }
+ if (newAttr)
+ D->addAttr(newAttr);
}
static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
@@ -2274,7 +2457,9 @@ static void handleObjCExceptionAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ObjCExceptionAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2305,7 +2490,9 @@ static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
// case.
S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
}
- D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ObjCNSObjectAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void
@@ -2320,7 +2507,9 @@ handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ OverloadableAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2344,7 +2533,9 @@ static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
+ D->addAttr(::new (S.Context)
+ BlocksAttr(Attr.getRange(), S.Context, type,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2436,8 +2627,9 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
<< Attr.getName() << ExpectedFunctionMethodOrBlock;
return;
}
- D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
- nullPos));
+ D->addAttr(::new (S.Context)
+ SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2445,9 +2637,9 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr)
if (!checkAttributeNumArgs(S, Attr, 0))
return;
- if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
+ if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << ExpectedFunctionOrMethod;
+ << Attr.getName() << ExpectedFunctionMethodOrClass;
return;
}
@@ -2463,7 +2655,9 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr)
return;
}
- D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ WarnUnusedResultAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2485,13 +2679,9 @@ static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
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);
- return;
- }
-
- nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
+ nd->addAttr(::new (S.Context)
+ WeakAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2518,7 +2708,9 @@ static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ WeakImportAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
// Handles reqd_work_group_size and work_group_size_hint.
@@ -2568,15 +2760,57 @@ static void handleWorkGroupSize(Sema &S, Decl *D,
if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
D->addAttr(::new (S.Context)
ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
- WGSize[0], WGSize[1], WGSize[2]));
+ WGSize[0], WGSize[1], WGSize[2],
+ Attr.getAttributeSpellingListIndex()));
else
D->addAttr(::new (S.Context)
WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
- WGSize[0], WGSize[1], WGSize[2]));
+ WGSize[0], WGSize[1], WGSize[2],
+ Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
+ assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
+
+ // Attribute has 1 argument.
+ if (!checkAttributeNumArgs(S, Attr, 1))
+ return;
+
+ QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg());
+
+ if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
+ (ParmType->isBooleanType() ||
+ !ParmType->isIntegralType(S.getASTContext()))) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint)
+ << ParmType;
+ return;
+ }
+
+ if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
+ D->hasAttr<VecTypeHintAttr>()) {
+ VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
+ if (A->getTypeHint() != ParmType) {
+ S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
+ return;
+ }
+ }
+
+ D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
+ ParmType, Attr.getLoc()));
+}
+
+static void handleEndianAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (!dyn_cast<VarDecl>(D))
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "endian"
+ << 9;
+ StringRef EndianType = Attr.getParameterName()->getName();
+ if (EndianType != "host" && EndianType != "device")
+ S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_endian) << EndianType;
}
SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
- StringRef Name) {
+ StringRef Name,
+ unsigned AttrSpellingListIndex) {
if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
if (ExistingAttr->getName() == Name)
return NULL;
@@ -2584,7 +2818,8 @@ SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
Diag(Range.getBegin(), diag::note_previous_attribute);
return NULL;
}
- return ::new (Context) SectionAttr(Range, Context, Name);
+ return ::new (Context) SectionAttr(Range, Context, Name,
+ AttrSpellingListIndex);
}
static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2614,8 +2849,10 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
return;
}
+
+ unsigned Index = Attr.getAttributeSpellingListIndex();
SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
- SE->getString());
+ SE->getString(), Index);
if (NewAttr)
D->addAttr(NewAttr);
}
@@ -2632,7 +2869,9 @@ static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (Existing->getLocation().isInvalid())
Existing->setRange(Attr.getRange());
} else {
- D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NoThrowAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
}
@@ -2647,7 +2886,9 @@ static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (Existing->getLocation().isInvalid())
Existing->setRange(Attr.getRange());
} else {
- D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ConstAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex() ));
}
}
@@ -2656,7 +2897,9 @@ static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkAttributeNumArgs(S, Attr, 0))
return;
- D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ PureAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2715,8 +2958,11 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
+ D->addAttr(::new (S.Context)
+ CleanupAttr(Attr.getRange(), S.Context, FD,
+ Attr.getAttributeSpellingListIndex()));
S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
+ S.DiagnoseUseOfDecl(FD, Attr.getParameterLoc());
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -2790,8 +3036,9 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
- Idx.getZExtValue()));
+ D->addAttr(::new (S.Context)
+ FormatArgAttr(Attr.getRange(), S.Context, Idx.getZExtValue(),
+ Attr.getAttributeSpellingListIndex()));
}
enum FormatAttrKind {
@@ -2866,12 +3113,14 @@ static void handleInitPriorityAttr(Sema &S, Decl *D,
Attr.setInvalid();
return;
}
- D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
- prioritynum));
+ D->addAttr(::new (S.Context)
+ InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
+ Attr.getAttributeSpellingListIndex()));
}
FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
- int FormatIdx, int FirstArg) {
+ int FormatIdx, int FirstArg,
+ unsigned AttrSpellingListIndex) {
// Check whether we already have an equivalent format attribute.
for (specific_attr_iterator<FormatAttr>
i = D->specific_attr_begin<FormatAttr>(),
@@ -2889,8 +3138,8 @@ FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
}
}
- return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
- FirstArg);
+ return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg,
+ AttrSpellingListIndex);
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -3030,7 +3279,8 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
Idx.getZExtValue(),
- FirstArg.getZExtValue());
+ FirstArg.getZExtValue(),
+ Attr.getAttributeSpellingListIndex());
if (NewAttr)
D->addAttr(NewAttr);
}
@@ -3099,7 +3349,9 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D,
}
}
- RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
+ RD->addAttr(::new (S.Context)
+ TransparentUnionAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3124,8 +3376,10 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if ((*i)->getAnnotation() == SE->getString())
return;
}
- D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
- SE->getString()));
+
+ D->addAttr(::new (S.Context)
+ AnnotateAttr(Attr.getRange(), S.Context, SE->getString(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3135,34 +3389,77 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- //FIXME: The C++0x version of this attribute has more limited applicabilty
- // than GNU's, and should error out when it is used to specify a
- // weaker alignment, rather than being silently ignored.
-
if (Attr.getNumArgs() == 0) {
- D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
- true, 0, Attr.isDeclspecAttribute()));
+ D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
+ true, 0, Attr.getAttributeSpellingListIndex()));
return;
}
- S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
- Attr.isDeclspecAttribute());
-}
+ Expr *E = Attr.getArg(0);
+ if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
+ S.Diag(Attr.getEllipsisLoc(),
+ diag::err_pack_expansion_without_parameter_packs);
+ return;
+ }
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
- bool isDeclSpec) {
- // FIXME: Handle pack-expansions here.
- if (DiagnoseUnexpandedParameterPack(E))
+ if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
return;
+ S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
+ Attr.isPackExpansion());
+}
+
+void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
+ unsigned SpellingListIndex, bool IsPackExpansion) {
+ AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
+ SourceLocation AttrLoc = AttrRange.getBegin();
+
+ // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
+ if (TmpAttr.isAlignas()) {
+ // C++11 [dcl.align]p1:
+ // An alignment-specifier may be applied to a variable or to a class
+ // data member, but it shall not be applied to a bit-field, a function
+ // parameter, the formal parameter of a catch clause, or a variable
+ // declared with the register storage class specifier. An
+ // alignment-specifier may also be applied to the declaration of a class
+ // or enumeration type.
+ // C11 6.7.5/2:
+ // An alignment attribute shall not be specified in a declaration of
+ // a typedef, or a bit-field, or a function, or a parameter, or an
+ // object declared with the register storage-class specifier.
+ int DiagKind = -1;
+ if (isa<ParmVarDecl>(D)) {
+ DiagKind = 0;
+ } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (VD->getStorageClass() == SC_Register)
+ DiagKind = 1;
+ if (VD->isExceptionVariable())
+ DiagKind = 2;
+ } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
+ if (FD->isBitField())
+ DiagKind = 3;
+ } else if (!isa<TagDecl>(D)) {
+ Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
+ << (TmpAttr.isC11() ? "'_Alignas'" : "'alignas'")
+ << (TmpAttr.isC11() ? ExpectedVariableOrField
+ : ExpectedVariableFieldOrTag);
+ return;
+ }
+ if (DiagKind != -1) {
+ Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
+ << TmpAttr.isC11() << DiagKind;
+ return;
+ }
+ }
+
if (E->isTypeDependent() || E->isValueDependent()) {
// Save dependent expressions in the AST to be instantiated.
- D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
- isDeclSpec));
+ AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
+ AA->setPackExpansion(IsPackExpansion);
+ D->addAttr(AA);
return;
}
-
- SourceLocation AttrLoc = AttrRange.getBegin();
+
// FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
ExprResult ICE
@@ -3171,32 +3468,79 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
/*AllowFold*/ false);
if (ICE.isInvalid())
return;
- if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
+
+ // C++11 [dcl.align]p2:
+ // -- if the constant expression evaluates to zero, the alignment
+ // specifier shall have no effect
+ // C11 6.7.5p6:
+ // An alignment specification of zero has no effect.
+ if (!(TmpAttr.isAlignas() && !Alignment) &&
+ !llvm::isPowerOf2_64(Alignment.getZExtValue())) {
Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
<< E->getSourceRange();
return;
}
- if (isDeclSpec) {
+
+ if (TmpAttr.isDeclspec()) {
// We've already verified it's a power of 2, now let's make sure it's
// 8192 or less.
if (Alignment.getZExtValue() > 8192) {
- Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
+ Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
<< E->getSourceRange();
return;
}
}
- D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(),
- isDeclSpec));
+ AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
+ ICE.take(), SpellingListIndex);
+ AA->setPackExpansion(IsPackExpansion);
+ D->addAttr(AA);
}
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
- bool isDeclSpec) {
+void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
+ unsigned SpellingListIndex, bool IsPackExpansion) {
// FIXME: Cache the number on the Attr object if non-dependent?
// FIXME: Perform checking of type validity
- D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
- isDeclSpec));
- return;
+ AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
+ SpellingListIndex);
+ AA->setPackExpansion(IsPackExpansion);
+ D->addAttr(AA);
+}
+
+void Sema::CheckAlignasUnderalignment(Decl *D) {
+ assert(D->hasAttrs() && "no attributes on decl");
+
+ QualType Ty;
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ Ty = VD->getType();
+ else
+ Ty = Context.getTagDeclType(cast<TagDecl>(D));
+ if (Ty->isDependentType() || Ty->isIncompleteType())
+ return;
+
+ // C++11 [dcl.align]p5, C11 6.7.5/4:
+ // The combined effect of all alignment attributes in a declaration shall
+ // not specify an alignment that is less strict than the alignment that
+ // would otherwise be required for the entity being declared.
+ AlignedAttr *AlignasAttr = 0;
+ unsigned Align = 0;
+ for (specific_attr_iterator<AlignedAttr>
+ I = D->specific_attr_begin<AlignedAttr>(),
+ E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+ if (I->isAlignmentDependent())
+ return;
+ if (I->isAlignas())
+ AlignasAttr = *I;
+ Align = std::max(Align, I->getAlignment(Context));
+ }
+
+ if (AlignasAttr && Align) {
+ CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
+ CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty);
+ if (NaturalAlign > RequestedAlign)
+ Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
+ << Ty << (unsigned)NaturalAlign.getQuantity();
+ }
}
/// handleModeAttr - This attribute modifies the width of a decl with primitive
@@ -3260,6 +3604,10 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (Str == "pointer")
DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
break;
+ case 11:
+ if (Str == "unwind_word")
+ DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
+ break;
}
QualType OldTy;
@@ -3386,7 +3734,9 @@ static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NoDebugAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3401,7 +3751,9 @@ static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NoInlineAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
@@ -3417,8 +3769,9 @@ static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3435,7 +3788,9 @@ static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CUDAConstantAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
}
@@ -3455,7 +3810,9 @@ static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CUDADeviceAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
}
@@ -3476,10 +3833,10 @@ static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
FunctionDecl *FD = cast<FunctionDecl>(D);
if (!FD->getResultType()->isVoidType()) {
TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
- if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
+ if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
<< FD->getType()
- << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
+ << FixItHint::CreateReplacement(FTL.getResultLoc().getSourceRange(),
"void");
} else {
S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
@@ -3488,7 +3845,9 @@ static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CUDAGlobalAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
}
@@ -3507,7 +3866,9 @@ static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CUDAHostAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
}
@@ -3519,14 +3880,15 @@ static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkAttributeNumArgs(S, Attr, 0))
return;
-
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.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CUDASharedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
}
@@ -3549,16 +3911,19 @@ static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ GNUInlineAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (hasDeclarator(D)) return;
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
// 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, FD))
return;
if (!isa<ObjCMethodDecl>(D)) {
@@ -3569,19 +3934,29 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
switch (Attr.getKind()) {
case AttributeList::AT_FastCall:
- D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ FastCallAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_StdCall:
- D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ StdCallAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_ThisCall:
- D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ThisCallAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_CDecl:
- D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CDeclAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_Pascal:
- D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ PascalAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_Pcs: {
PcsAttr::PCSType PCS;
@@ -3596,11 +3971,20 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
llvm_unreachable("unexpected calling convention in pcs attribute");
}
- D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
+ D->addAttr(::new (S.Context)
+ PcsAttr(Attr.getRange(), S.Context, PCS,
+ Attr.getAttributeSpellingListIndex()));
return;
}
case AttributeList::AT_PnaclCall:
- D->addAttr(::new (S.Context) PnaclCallAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ PnaclCallAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
+ return;
+ case AttributeList::AT_IntelOclBicc:
+ D->addAttr(::new (S.Context)
+ IntelOclBiccAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
default:
@@ -3613,7 +3997,24 @@ static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
}
-bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
+static void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){
+ assert(!Attr.isInvalid());
+
+ Expr *E = Attr.getArg(0);
+ llvm::APSInt ArgNum(32);
+ if (E->isTypeDependent() || E->isValueDependent() ||
+ !E->isIntegerConstantExpr(ArgNum, S.Context)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+ << Attr.getName()->getName() << E->getSourceRange();
+ return;
+ }
+
+ D->addAttr(::new (S.Context) OpenCLImageAccessAttr(
+ Attr.getRange(), S.Context, ArgNum.getZExtValue()));
+}
+
+bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
+ const FunctionDecl *FD) {
if (attr.isInvalid())
return true;
@@ -3656,6 +4057,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
return true;
}
case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
+ case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
default: llvm_unreachable("unexpected attribute kind");
}
@@ -3663,7 +4065,12 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
if (A == TargetInfo::CCCR_Warning) {
Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
- CC = TI.getDefaultCallingConv();
+
+ TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
+ if (FD)
+ MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
+ TargetInfo::CCMT_NonMember;
+ CC = TI.getDefaultCallingConv(MT);
}
return false;
@@ -3682,7 +4089,9 @@ static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
+ D->addAttr(::new (S.Context)
+ RegparmAttr(Attr.getRange(), S.Context, numParams,
+ Attr.getAttributeSpellingListIndex()));
}
/// Checks a regparm attribute, returning true if it is ill-formed and
@@ -3762,9 +4171,11 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
}
}
- D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
- MaxThreads.getZExtValue(),
- MinBlocks.getZExtValue()));
+ D->addAttr(::new (S.Context)
+ CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
+ MaxThreads.getZExtValue(),
+ MinBlocks.getZExtValue(),
+ Attr.getAttributeSpellingListIndex()));
} else {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
}
@@ -3815,12 +4226,10 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
}
}
- D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(),
- S.Context,
- ArgumentKind,
- ArgumentIdx,
- TypeTagIdx,
- IsPointer));
+ D->addAttr(::new (S.Context)
+ ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
+ ArgumentIdx, TypeTagIdx, IsPointer,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
@@ -3834,13 +4243,12 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
- D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
- Attr.getRange(),
- S.Context,
- PointerKind,
- MatchingCType,
- Attr.getLayoutCompatible(),
- Attr.getMustBeNull()));
+ D->addAttr(::new (S.Context)
+ TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
+ MatchingCType,
+ Attr.getLayoutCompatible(),
+ Attr.getMustBeNull(),
+ Attr.getAttributeSpellingListIndex()));
}
//===----------------------------------------------------------------------===//
@@ -3882,9 +4290,13 @@ static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
}
if (cf)
- param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
+ param->addAttr(::new (S.Context)
+ CFConsumedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else
- param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
+ param->addAttr(::new (S.Context)
+ NSConsumedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
@@ -3895,7 +4307,9 @@ static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
return;
}
- D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ NSConsumesSelfAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
@@ -3947,24 +4361,29 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
default:
llvm_unreachable("invalid ownership attribute");
case AttributeList::AT_NSReturnsAutoreleased:
- D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_CFReturnsNotRetained:
- D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_NSReturnsNotRetained:
- D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_CFReturnsRetained:
- D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ CFReturnsRetainedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
case AttributeList::AT_NSReturnsRetained:
- D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
- S.Context));
+ D->addAttr(::new (S.Context)
+ NSReturnsRetainedAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
return;
};
}
@@ -3994,8 +4413,9 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
return;
}
- method->addAttr(
- ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
+ method->addAttr(::new (S.Context)
+ ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
+ attr.getAttributeSpellingListIndex()));
}
static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
@@ -4021,8 +4441,9 @@ static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
return;
}
- method->addAttr(
- ::new (S.Context) ObjCRequiresSuperAttr(attr.getRange(), S.Context));
+ method->addAttr(::new (S.Context)
+ ObjCRequiresSuperAttr(attr.getRange(), S.Context,
+ attr.getAttributeSpellingListIndex()));
}
/// Handle cf_audited_transfer and cf_unknown_transfer.
@@ -4052,11 +4473,13 @@ static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
// All clear; add the attribute.
if (IsAudited) {
- D->addAttr(
- ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CFAuditedTransferAttr(A.getRange(), S.Context,
+ A.getAttributeSpellingListIndex()));
} else {
- D->addAttr(
- ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ CFUnknownTransferAttr(A.getRange(), S.Context,
+ A.getAttributeSpellingListIndex()));
}
}
@@ -4086,8 +4509,9 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
}
}
- D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
- ParmName));
+ D->addAttr(::new (S.Context)
+ NSBridgedAttr(Attr.getRange(), S.Context, ParmName,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleObjCOwnershipAttr(Sema &S, Decl *D,
@@ -4141,7 +4565,8 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
}
D->addAttr(::new (S.Context)
- ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
+ ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
//===----------------------------------------------------------------------===//
@@ -4189,15 +4614,16 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
return;
}
- } else if (!isxdigit(*I)) {
+ } else if (!isHexDigit(*I)) {
S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
return;
}
I++;
}
- D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
- Str->getString()));
+ D->addAttr(::new (S.Context)
+ UuidAttr(Attr.getRange(), S.Context, Str->getString(),
+ Attr.getAttributeSpellingListIndex()));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
}
@@ -4211,13 +4637,19 @@ static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
AttributeList::Kind Kind = Attr.getKind();
if (Kind == AttributeList::AT_SingleInheritance)
D->addAttr(
- ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
+ ::new (S.Context)
+ SingleInheritanceAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else if (Kind == AttributeList::AT_MultipleInheritance)
D->addAttr(
- ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
+ ::new (S.Context)
+ MultipleInheritanceAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else if (Kind == AttributeList::AT_VirtualInheritance)
D->addAttr(
- ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
+ ::new (S.Context)
+ VirtualInheritanceAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
}
static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -4225,20 +4657,25 @@ static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
AttributeList::Kind Kind = Attr.getKind();
if (Kind == AttributeList::AT_Ptr32)
D->addAttr(
- ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
+ ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else if (Kind == AttributeList::AT_Ptr64)
D->addAttr(
- ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
+ ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else if (Kind == AttributeList::AT_Win64)
D->addAttr(
- ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
+ ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (S.LangOpts.MicrosoftExt)
- D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
+ D->addAttr(::new (S.Context)
+ ForceInlineAttr(Attr.getRange(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -4261,12 +4698,11 @@ static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
const AttributeList &Attr) {
switch (Attr.getKind()) {
- case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
- case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
- case AttributeList::AT_IBOutletCollection:
- handleIBOutletCollection(S, D, Attr); break;
+ case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
+ case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
+ case AttributeList::AT_IBOutletCollection:
+ handleIBOutletCollection(S, D, Attr); break;
case AttributeList::AT_AddressSpace:
- case AttributeList::AT_OpenCLImageAccess:
case AttributeList::AT_ObjCGC:
case AttributeList::AT_VectorSize:
case AttributeList::AT_NeonVectorType:
@@ -4291,10 +4727,14 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break;
case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
case AttributeList::AT_CarriesDependency:
- handleDependencyAttr (S, D, Attr); break;
+ handleDependencyAttr(S, scope, D, Attr);
+ break;
case AttributeList::AT_Common: handleCommonAttr (S, D, Attr); break;
case AttributeList::AT_CUDAConstant:handleConstantAttr (S, D, Attr); break;
case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
+ case AttributeList::AT_CXX11NoReturn:
+ handleCXX11NoReturnAttr(S, D, Attr);
+ break;
case AttributeList::AT_Deprecated:
handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
break;
@@ -4364,6 +4804,13 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_ReqdWorkGroupSize:
handleWorkGroupSize(S, D, Attr); break;
+ case AttributeList::AT_VecTypeHint:
+ handleVecTypeHint(S, D, Attr); break;
+
+ case AttributeList::AT_Endian:
+ handleEndianAttr(S, D, Attr);
+ break;
+
case AttributeList::AT_InitPriority:
handleInitPriorityAttr(S, D, Attr); break;
@@ -4386,7 +4833,12 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
handleReturnsTwiceAttr(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_Visibility:
+ handleVisibilityAttr(S, D, Attr, false);
+ break;
+ case AttributeList::AT_TypeVisibility:
+ handleVisibilityAttr(S, D, Attr, true);
+ break;
case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
break;
case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break;
@@ -4423,11 +4875,15 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_Pascal:
case AttributeList::AT_Pcs:
case AttributeList::AT_PnaclCall:
+ case AttributeList::AT_IntelOclBicc:
handleCallConvAttr(S, D, Attr);
break;
case AttributeList::AT_OpenCLKernel:
handleOpenCLKernelAttr(S, D, Attr);
break;
+ case AttributeList::AT_OpenCLImageAccess:
+ handleOpenCLImageAccessAttr(S, D, Attr);
+ break;
// Microsoft attributes:
case AttributeList::AT_MsStruct:
@@ -4460,11 +4916,17 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_ScopedLockable:
handleScopedLockableAttr(S, D, Attr);
break;
- case AttributeList::AT_NoAddressSafetyAnalysis:
- handleNoAddressSafetyAttr(S, D, Attr);
+ case AttributeList::AT_NoSanitizeAddress:
+ handleNoSanitizeAddressAttr(S, D, Attr);
break;
case AttributeList::AT_NoThreadSafetyAnalysis:
- handleNoThreadSafetyAttr(S, D, Attr);
+ handleNoThreadSafetyAnalysis(S, D, Attr);
+ break;
+ case AttributeList::AT_NoSanitizeThread:
+ handleNoSanitizeThread(S, D, Attr);
+ break;
+ case AttributeList::AT_NoSanitizeMemory:
+ handleNoSanitizeMemory(S, D, Attr);
break;
case AttributeList::AT_Lockable:
handleLockableAttr(S, D, Attr);
@@ -4530,19 +4992,17 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
/// 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).
+/// silently ignore it if a GNU attribute.
static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
const AttributeList &Attr,
- bool NonInheritable, bool Inheritable) {
+ bool NonInheritable, bool Inheritable,
+ bool IncludeCXX11Attributes) {
if (Attr.isInvalid())
return;
- // Type attributes are still treated as declaration attributes by
- // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes. We don't
- // want to process them, however, because we will simply warn about ignoring
- // them. So instead, we will bail out early.
- if (Attr.isMSTypespecAttribute())
+ // Ignore C++11 attributes on declarator chunks: they appertain to the type
+ // instead.
+ if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
return;
if (NonInheritable)
@@ -4556,17 +5016,19 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
/// attribute list to the specified decl, ignoring any type attributes.
void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
const AttributeList *AttrList,
- bool NonInheritable, bool Inheritable) {
- for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
- }
+ bool NonInheritable, bool Inheritable,
+ bool IncludeCXX11Attributes) {
+ for (const AttributeList* l = AttrList; l; l = l->getNext())
+ ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable,
+ IncludeCXX11Attributes);
// GCC accepts
// static int a9 __attribute__((weakref));
// but that looks really pointless. We reject it.
if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
- dyn_cast<NamedDecl>(D)->getNameAsString();
+ cast<NamedDecl>(D)->getNameAsString();
+ D->dropAttr<WeakRefAttr>();
return;
}
}
@@ -4592,7 +5054,7 @@ bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
for ( ; A; A = A->getNext()) {
// Only warn if the attribute is an unignored, non-type attribute.
- if (A->isUsedAsTypeAttr()) continue;
+ if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
if (A->getKind() == AttributeList::IgnoredAttribute) continue;
if (A->getKind() == AttributeList::UnknownAttribute) {
@@ -4630,8 +5092,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
Loc, Loc, DeclarationName(II),
FD->getType(), FD->getTypeSourceInfo(),
- SC_None, SC_None,
- false/*isInlineSpecified*/,
+ SC_None, false/*isInlineSpecified*/,
FD->hasPrototype(),
false/*isConstexprSpecified*/);
NewD = NewFD;
@@ -4656,8 +5117,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
VD->getInnerLocStart(), VD->getLocation(), II,
VD->getType(), VD->getTypeSourceInfo(),
- VD->getStorageClass(),
- VD->getStorageClassAsWritten());
+ VD->getStorageClass());
if (VD->getQualifier()) {
VarDecl *NewVD = cast<VarDecl>(NewD);
NewVD->setQualifierInfo(VD->getQualifierLoc());
@@ -4689,30 +5149,37 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
}
}
-/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
-/// it, apply them to D. This is a bit tricky because PD can have attributes
-/// specified in many different places, and we need to find and apply them all.
-void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
- bool NonInheritable, bool Inheritable) {
+void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
// It's valid to "forward-declare" #pragma weak, in which case we
// have to do this.
- if (Inheritable) {
- LoadExternalWeakUndeclaredIdentifiers();
- if (!WeakUndeclaredIdentifiers.empty()) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
- if (IdentifierInfo *Id = ND->getIdentifier()) {
- llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
- = WeakUndeclaredIdentifiers.find(Id);
- if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
- WeakInfo W = I->second;
- DeclApplyPragmaWeak(S, ND, W);
- WeakUndeclaredIdentifiers[Id] = W;
- }
+ LoadExternalWeakUndeclaredIdentifiers();
+ if (!WeakUndeclaredIdentifiers.empty()) {
+ NamedDecl *ND = NULL;
+ if (VarDecl *VD = dyn_cast<VarDecl>(D))
+ if (VD->isExternC())
+ ND = VD;
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isExternC())
+ ND = FD;
+ if (ND) {
+ if (IdentifierInfo *Id = ND->getIdentifier()) {
+ llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
+ = WeakUndeclaredIdentifiers.find(Id);
+ if (I != WeakUndeclaredIdentifiers.end()) {
+ WeakInfo W = I->second;
+ DeclApplyPragmaWeak(S, ND, W);
+ WeakUndeclaredIdentifiers[Id] = W;
}
}
}
}
+}
+/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
+/// it, apply them to D. This is a bit tricky because PD can have attributes
+/// specified in many different places, and we need to find and apply them all.
+void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
+ bool NonInheritable, bool Inheritable) {
// Apply decl attributes from the DeclSpec if present.
if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
@@ -4723,7 +5190,8 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
// when X is a decl attribute.
for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
- ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
+ ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable,
+ /*IncludeCXX11Attributes=*/false);
// Finally, apply any attributes on the decl itself.
if (const AttributeList *Attrs = PD.getAttributes())