Generate Attr subclasses with TableGen.
Now all classes derived from Attr are generated from TableGen.
Additionally, Attr* is no longer its own linked list; SmallVectors or
Attr* are used. The accompanying LLVM commit contains the updates to
TableGen necessary for this.
Some other notes about newly-generated attribute classes:
- The constructor arguments are a SourceLocation and a Context&,
followed by the attributes arguments in the order that they were
defined in Attr.td
- Every argument in Attr.td has an appropriate accessor named getFoo,
and there are sometimes a few extra ones (such as to get the length
of a variadic argument).
Additionally, specific_attr_iterator has been introduced, which will
iterate over an AttrVec, but only over attributes of a certain type. It
can be accessed through either Decl::specific_attr_begin/end or
the global functions of the same name.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111455 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 96793d5..66d31dd 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -14,6 +14,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
@@ -120,9 +121,11 @@
// Otherwise, check to see if we need a max field alignment attribute.
if (unsigned Alignment = Stack->getAlignment()) {
if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
- RD->addAttr(::new (Context) AlignMac68kAttr());
+ RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
else
- RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
+ RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+ Context,
+ Alignment * 8));
}
}
@@ -285,11 +288,12 @@
continue;
}
- VD->addAttr(::new (Context) UnusedAttr());
+ VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
}
}
-typedef std::vector<VisibilityAttr::VisibilityTypes> VisStack;
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+ SourceLocation> > VisStack;
void Sema::AddPushedVisibilityAttribute(Decl *D) {
if (!VisContext)
@@ -299,9 +303,10 @@
return;
VisStack *Stack = static_cast<VisStack*>(VisContext);
- VisibilityAttr::VisibilityTypes type = Stack->back();
+ VisibilityAttr::VisibilityType type = Stack->back().first;
+ SourceLocation loc = Stack->back().second;
- D->addAttr(::new (Context) VisibilityAttr(type, true));
+ D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
}
/// FreeVisContext - Deallocate and null out VisContext.
@@ -314,33 +319,34 @@
SourceLocation PragmaLoc) {
if (IsPush) {
// Compute visibility to use.
- VisibilityAttr::VisibilityTypes type;
+ VisibilityAttr::VisibilityType type;
if (VisType->isStr("default"))
- type = VisibilityAttr::DefaultVisibility;
+ type = VisibilityAttr::Default;
else if (VisType->isStr("hidden"))
- type = VisibilityAttr::HiddenVisibility;
+ type = VisibilityAttr::Hidden;
else if (VisType->isStr("internal"))
- type = VisibilityAttr::HiddenVisibility; // FIXME
+ type = VisibilityAttr::Hidden; // FIXME
else if (VisType->isStr("protected"))
- type = VisibilityAttr::ProtectedVisibility;
+ type = VisibilityAttr::Protected;
else {
Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
VisType->getName();
return;
}
- PushPragmaVisibility(type);
+ PushPragmaVisibility(type, PragmaLoc);
} else {
PopPragmaVisibility();
}
}
-void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityTypes type) {
+void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityType type,
+ SourceLocation loc) {
// Put visibility on stack.
if (!VisContext)
VisContext = new VisStack;
VisStack *Stack = static_cast<VisStack*>(VisContext);
- Stack->push_back(type);
+ Stack->push_back(std::make_pair(type, loc));
}
void Sema::PopPragmaVisibility() {
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9a48493..4e8c82f 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -347,9 +347,12 @@
}
}
- for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
- NonNull = NonNull->getNext<NonNullAttr>())
- CheckNonNullArguments(NonNull, TheCall);
+ specific_attr_iterator<NonNullAttr>
+ i = FDecl->specific_attr_begin<NonNullAttr>(),
+ e = FDecl->specific_attr_end<NonNullAttr>();
+
+ for (; i != e; ++i)
+ CheckNonNullArguments(*i, TheCall);
return false;
}
@@ -1041,7 +1044,8 @@
void
Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
const CallExpr *TheCall) {
- for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+ for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+ e = NonNull->args_end();
i != e; ++i) {
const Expr *ArgExpr = TheCall->getArg(*i);
if (ArgExpr->isNullPointerConstant(Context,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index dfbc7e1..f6d6e6b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -997,19 +997,32 @@
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
static bool
-DeclHasAttr(const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
- if (attr->getKind() == target->getKind())
+DeclHasAttr(const Decl *D, const Attr *A) {
+ const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+ for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+ if ((*i)->getKind() == A->getKind()) {
+ // FIXME: Don't hardcode this check
+ if (OA && isa<OwnershipAttr>(*i))
+ return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
return true;
+ }
return false;
}
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(New, attr) && attr->isMerged()) {
- Attr *NewAttr = attr->clone(C);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+ if (!Old->hasAttrs())
+ return;
+ // Ensure that any moving of objects within the allocated map is done before
+ // we process them.
+ if (!New->hasAttrs())
+ New->setAttrs(AttrVec());
+ for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+ ++i) {
+ // FIXME: Make this more general than just checking for Overloadable.
+ if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+ Attr *NewAttr = (*i)->clone(C);
NewAttr->setInherited(true);
New->addAttr(NewAttr);
}
@@ -1402,7 +1415,7 @@
/// \returns false
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
// Merge the attributes
- MergeAttributes(New, Old, Context);
+ MergeDeclAttributes(New, Old, Context);
// Merge the storage class.
if (Old->getStorageClass() != FunctionDecl::Extern &&
@@ -1447,7 +1460,7 @@
return New->setInvalidDecl();
}
- MergeAttributes(New, Old, Context);
+ MergeDeclAttributes(New, Old, Context);
// Merge the types
QualType MergedT;
@@ -1611,9 +1624,7 @@
}
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- // If there are attributes in the DeclSpec, apply them to the record.
- if (const AttributeList *AL = DS.getAttributes())
- ProcessDeclAttributeList(S, Record, AL);
+ ProcessDeclAttributeList(S, Record, DS.getAttributes());
if (!Record->getDeclName() && Record->isDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -2770,7 +2781,8 @@
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
+ Context, SE->getString()));
}
// Diagnose shadowed variables before filtering for scope.
@@ -2810,6 +2822,8 @@
NewVD->setInvalidDecl();
// attributes declared post-definition are currently ignored
+ // FIXME: This should be handled in attribute merging, not
+ // here.
if (Previous.isSingleResult()) {
VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
if (Def && (Def = Def->getDefinition()) &&
@@ -3447,7 +3461,8 @@
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+ SE->getString()));
}
// Copy the parameter declarations from the declarator D to the function
@@ -3673,6 +3688,7 @@
ProcessDeclAttributes(S, NewFD, D);
// attributes declared post-definition are currently ignored
+ // FIXME: This should happen during attribute merging
if (Redeclaration && Previous.isSingleResult()) {
const FunctionDecl *Def;
FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
@@ -3684,7 +3700,7 @@
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+ if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -3692,7 +3708,7 @@
if (!Previous.empty())
Diag(Previous.getRepresentativeDecl()->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr());
+ NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
}
if (NewFD->hasAttr<OverloadableAttr>() &&
@@ -4792,10 +4808,10 @@
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>() &&
- (!FD->getAttr<DLLExportAttr>())) {
- // dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+ DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+ if (DA && (!FD->getAttr<DLLExportAttr>())) {
+ // dllimport attribute cannot be directly applied to definition.
+ if (!DA->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
@@ -5041,7 +5057,7 @@
CurContext = Context.getTranslationUnitDecl();
FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+ dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
FD->setImplicit();
CurContext = PrevDC;
@@ -5069,13 +5085,15 @@
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
HasVAListArg)) {
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "scanf", FormatIdx+1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "scanf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
@@ -5085,15 +5103,15 @@
if (!getLangOptions().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
if (!FD->getAttr<ConstAttr>())
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
if (Context.BuiltinInfo.isNoReturn(BuiltinID))
FD->setType(Context.getNoReturnType(FD->getType()));
if (Context.BuiltinInfo.isNoThrow(BuiltinID))
- FD->addAttr(::new (Context) NoThrowAttr());
+ FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
if (Context.BuiltinInfo.isConst(BuiltinID))
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
IdentifierInfo *Name = FD->getIdentifier();
@@ -5115,13 +5133,15 @@
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType(Context, "printf");
} else
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps?
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -7009,7 +7029,7 @@
Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
} else {
(void)WeakUndeclaredIdentifiers.insert(
std::pair<IdentifierInfo*,WeakInfo>
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 7125c36..1776d46 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -211,7 +211,7 @@
}
if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(::new (S.Context) PackedAttr);
+ TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
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.
@@ -220,7 +220,7 @@
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(::new (S.Context) PackedAttr);
+ FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -235,7 +235,7 @@
// The IBAction attributes only apply to instance methods.
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
if (MD->isInstanceMethod()) {
- d->addAttr(::new (S.Context) IBActionAttr());
+ d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
return;
}
@@ -252,7 +252,7 @@
// 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());
+ d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
return;
}
@@ -307,7 +307,8 @@
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
return;
}
- d->addAttr(::new (S.Context) IBOutletCollectionAttr(QT));
+ d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+ QT));
}
static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -378,7 +379,8 @@
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
llvm::array_pod_sort(start, start + size);
- d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+ d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+ size));
}
static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
@@ -397,24 +399,24 @@
return;
}
// Figure out our Kind, and check arguments while we're at it.
- attr::Kind K;
+ OwnershipAttr::OwnershipKind K;
switch (AL.getKind()) {
case AttributeList::AT_ownership_takes:
- K = attr::OwnershipTakes;
+ K = OwnershipAttr::Takes;
if (AL.getNumArgs() < 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
return;
}
break;
case AttributeList::AT_ownership_holds:
- K = attr::OwnershipHolds;
+ K = OwnershipAttr::Holds;
if (AL.getNumArgs() < 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
return;
}
break;
case AttributeList::AT_ownership_returns:
- K = attr::OwnershipReturns;
+ K = OwnershipAttr::Returns;
if (AL.getNumArgs() > 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
<< AL.getNumArgs() + 1;
@@ -463,21 +465,21 @@
}
--x;
switch (K) {
- case attr::OwnershipTakes:
- case attr::OwnershipHolds: {
+ case OwnershipAttr::Takes:
+ case OwnershipAttr::Holds: {
// Is the function argument a pointer type?
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)
- << ((K==attr::OwnershipTakes)?"ownership_takes":"ownership_holds")
+ << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
<< "pointer"
<< IdxExpr->getSourceRange();
continue;
}
break;
}
- case attr::OwnershipReturns: {
+ case OwnershipAttr::Returns: {
if (AL.getNumArgs() > 1) {
// Is the function argument an integer type?
Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
@@ -497,18 +499,16 @@
} // switch
// Check we don't have a conflict with another ownership attribute.
- if (K != attr::OwnershipReturns && d->hasAttrs()) {
- for (const Attr *attr = d->getAttrs(); attr; attr = attr->getNext()) {
- if (const OwnershipAttr* Att = dyn_cast<OwnershipAttr>(attr)) {
- // Two ownership attributes of the same kind can't conflict,
- // except returns attributes.
- if (Att->getKind() != K) {
- for (const unsigned *I = Att->begin(), *E = Att->end(); I!=E; ++I) {
- if (x == *I) {
- S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
- << AL.getName()->getName() << "ownership_*";
- }
- }
+ for (specific_attr_iterator<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();
+ I!=E; ++I) {
+ if (x == *I) {
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+ << AL.getName()->getName() << "ownership_*";
}
}
}
@@ -519,33 +519,14 @@
unsigned* start = OwnershipArgs.data();
unsigned size = OwnershipArgs.size();
llvm::array_pod_sort(start, start + size);
- switch (K) {
- case attr::OwnershipTakes: {
- if (OwnershipArgs.empty()) {
- S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
- return;
- }
- d->addAttr(::new (S.Context) OwnershipTakesAttr(S.Context, start, size,
- Module));
- break;
+
+ if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+ return;
}
- case attr::OwnershipHolds: {
- if (OwnershipArgs.empty()) {
- S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
- return;
- }
- d->addAttr(::new (S.Context) OwnershipHoldsAttr(S.Context, start, size,
- Module));
- break;
- }
- case attr::OwnershipReturns: {
- d->addAttr(::new (S.Context) OwnershipReturnsAttr(S.Context, start, size,
- Module));
- break;
- }
- default:
- llvm_unreachable("Unknown ownership attribute");
- }
+
+ d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+ start, size));
}
static bool isStaticVarOrStaticFunciton(Decl *D) {
@@ -622,10 +603,10 @@
}
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
- d->addAttr(::new (S.Context) WeakRefAttr());
+ d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -647,7 +628,7 @@
// FIXME: check if target symbol exists in current file
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -664,7 +645,7 @@
return;
}
- d->addAttr(::new (S.Context) AlwaysInlineAttr());
+ d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -677,7 +658,7 @@
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
QualType RetTy = FD->getResultType();
if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
- d->addAttr(::new (S.Context) MallocAttr());
+ d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
return;
}
}
@@ -711,13 +692,13 @@
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
/* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
assert(Attr.isInvalid() == false);
- d->addAttr(::new (S.Context) NoReturnAttr());
+ d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
}
// PS3 PPU-specific.
@@ -756,7 +737,7 @@
return;
}
- d->addAttr(::new (S.Context) VecReturnAttr());
+ d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}
static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -782,7 +763,7 @@
return;
}
- d->addAttr(::new (S.Context) UnusedAttr());
+ d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
}
static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -803,7 +784,7 @@
return;
}
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -833,7 +814,7 @@
return;
}
- d->addAttr(::new (S.Context) ConstructorAttr(priority));
+ d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -863,7 +844,7 @@
return;
}
- d->addAttr(::new (S.Context) DestructorAttr(priority));
+ d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -873,7 +854,7 @@
return;
}
- d->addAttr(::new (S.Context) DeprecatedAttr());
+ d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -883,7 +864,7 @@
return;
}
- d->addAttr(::new (S.Context) UnavailableAttr());
+ d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
}
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -904,22 +885,22 @@
}
llvm::StringRef TypeStr = Str->getString();
- VisibilityAttr::VisibilityTypes type;
+ VisibilityAttr::VisibilityType type;
if (TypeStr == "default")
- type = VisibilityAttr::DefaultVisibility;
+ type = VisibilityAttr::Default;
else if (TypeStr == "hidden")
- type = VisibilityAttr::HiddenVisibility;
+ type = VisibilityAttr::Hidden;
else if (TypeStr == "internal")
- type = VisibilityAttr::HiddenVisibility; // FIXME
+ type = VisibilityAttr::Hidden; // FIXME
else if (TypeStr == "protected")
- type = VisibilityAttr::ProtectedVisibility;
+ type = VisibilityAttr::Protected;
else {
S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
return;
}
- d->addAttr(::new (S.Context) VisibilityAttr(type, false));
+ d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
}
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -935,7 +916,7 @@
return;
}
- D->addAttr(::new (S.Context) ObjCExceptionAttr());
+ D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
}
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -951,7 +932,7 @@
return;
}
}
- D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+ D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
}
static void
@@ -966,7 +947,7 @@
return;
}
- D->addAttr(::new (S.Context) OverloadableAttr());
+ D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
}
static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -981,7 +962,7 @@
return;
}
- BlocksAttr::BlocksAttrTypes type;
+ BlocksAttr::BlockType type;
if (Attr.getParameterName()->isStr("byref"))
type = BlocksAttr::ByRef;
else {
@@ -990,7 +971,7 @@
return;
}
- d->addAttr(::new (S.Context) BlocksAttr(type));
+ d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
}
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1083,7 +1064,7 @@
<< Attr.getName() << 6 /*function, method or block */;
return;
}
- d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+ d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
}
static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1111,7 +1092,7 @@
return;
}
- D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+ D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1135,7 +1116,7 @@
return;
}
- D->addAttr(::new (S.Context) WeakAttr());
+ D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1171,7 +1152,7 @@
return;
}
- D->addAttr(::new (S.Context) WeakImportAttr());
+ D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
}
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -1194,7 +1175,8 @@
}
WGSize[i] = (unsigned) ArgNum.getZExtValue();
}
- D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+ D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+ WGSize[0], WGSize[1],
WGSize[2]));
}
@@ -1228,7 +1210,7 @@
return;
}
- D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+ D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
}
@@ -1239,7 +1221,7 @@
return;
}
- d->addAttr(::new (S.Context) NoThrowAttr());
+ d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
}
static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1249,7 +1231,7 @@
return;
}
- d->addAttr(::new (S.Context) ConstAttr());
+ d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
}
static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1259,7 +1241,7 @@
return;
}
- d->addAttr(::new (S.Context) PureAttr());
+ d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
}
static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1317,7 +1299,7 @@
return;
}
- d->addAttr(::new (S.Context) CleanupAttr(FD));
+ d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1380,7 +1362,7 @@
return;
}
- d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+ d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
}
enum FormatAttrKind {
@@ -1462,7 +1444,7 @@
Attr.setInvalid();
return;
}
- d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+ d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -1606,7 +1588,8 @@
return;
}
- d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+ d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+ Idx.getZExtValue(),
FirstArg.getZExtValue()));
}
@@ -1675,7 +1658,7 @@
}
}
- RD->addAttr(::new (S.Context) TransparentUnionAttr());
+ RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
}
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1693,7 +1676,7 @@
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
- d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+ d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
}
static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1708,9 +1691,7 @@
// weaker alignment, rather than being silently ignored.
if (Attr.getNumArgs() == 0) {
- // FIXME: This should be the target specific maximum alignment.
- // (For now we just use 128 bits which is the maximum on X86).
- D->addAttr(::new (S.Context) AlignedAttr(128));
+ D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
return;
}
@@ -1720,10 +1701,11 @@
void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
if (E->isTypeDependent() || E->isValueDependent()) {
// Save dependent expressions in the AST to be instantiated.
- D->addAttr(::new (Context) AlignedAttr(E));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
return;
}
+ // FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
if (!E->isIntegerConstantExpr(Alignment, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_not_int)
@@ -1736,7 +1718,14 @@
return;
}
- D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+ // FIXME: Cache the number on the Attr object if non-dependent?
+ // FIXME: Perform checking of type validity
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+ return;
}
/// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1923,7 +1912,7 @@
return;
}
- d->addAttr(::new (S.Context) NoDebugAttr());
+ d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1939,7 +1928,7 @@
return;
}
- d->addAttr(::new (S.Context) NoInlineAttr());
+ d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
@@ -1956,7 +1945,7 @@
return;
}
- d->addAttr(::new (S.Context) NoInstrumentFunctionAttr());
+ d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
}
static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1978,7 +1967,7 @@
return;
}
- d->addAttr(::new (S.Context) GNUInlineAttr());
+ d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1988,15 +1977,15 @@
switch (Attr.getKind()) {
case AttributeList::AT_fastcall:
- d->addAttr(::new (S.Context) FastCallAttr());
+ d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_stdcall:
- d->addAttr(::new (S.Context) StdCallAttr());
+ d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_thiscall:
- d->addAttr(::new (S.Context) ThisCallAttr());
+ d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
case AttributeList::AT_cdecl:
- d->addAttr(::new (S.Context) CDeclAttr());
+ d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
return;
default:
llvm_unreachable("unexpected attribute kind");
@@ -2038,7 +2027,8 @@
return;
}
- d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+ d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+ NumParams.getZExtValue()));
}
static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2064,7 +2054,7 @@
return;
}
- d->addAttr(::new (S.Context) FinalAttr());
+ d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -2090,7 +2080,7 @@
return;
}
- d->addAttr(::new (S.Context) BaseCheckAttr());
+ d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
}
static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2115,7 +2105,7 @@
return;
}
- d->addAttr(::new (S.Context) HidingAttr());
+ d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
}
static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2140,7 +2130,7 @@
return;
}
- d->addAttr(::new (S.Context) OverrideAttr());
+ d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -2176,16 +2166,16 @@
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_cf_returns_not_retained:
- d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_not_retained:
- d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
};
}
@@ -2369,8 +2359,9 @@
if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
IdentifierInfo *NDId = ND->getIdentifier();
NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
- NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
- NewD->addAttr(::new (Context) WeakAttr());
+ NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+ NDId->getName()));
+ NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
WeakTopLevelDecl.push_back(NewD);
// FIXME: "hideous" code from Sema::LazilyCreateBuiltin
// to insert Decl at TU scope, sorry.
@@ -2379,7 +2370,7 @@
PushOnScopeChains(NewD, S);
CurContext = SavedContext;
} else { // just add weak to existing
- ND->addAttr(::new (Context) WeakAttr());
+ ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
}
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 7791b68..fff37d9 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3292,7 +3292,7 @@
ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
- PushPragmaVisibility(attr->getVisibility());
+ PushPragmaVisibility(attr->getVisibility(), attr->getLocation());
if (II) {
// C++ [namespace.def]p2:
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8bcb616..0fd3d6e 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1454,13 +1454,14 @@
}
static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
// The 'ibaction' attribute is allowed on method definitions because of
// how the IBAction macro is used on both method declarations and definitions.
// If the method definitions contains any other attributes, return true.
- while (A && A->getKind() == AttributeList::AT_IBAction)
- A = A->getNext();
- return A != NULL;
+ for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+ if ((*i)->getKind() != attr::IBAction)
+ return true;
+ return false;
}
Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
@@ -1590,7 +1591,8 @@
}
InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
MethodType == tok::minus);
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
} else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1601,7 +1603,8 @@
PrevMethod = CatImpDecl->getClassMethod(Sel);
CatImpDecl->addClassMethod(ObjCMethod);
}
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
}
if (PrevMethod) {
@@ -1613,8 +1616,10 @@
// If the interface declared this method, and it was deprecated there,
// mark it deprecated here.
- if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
- ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+ if (InterfaceMD)
+ if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+ ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+ Context));
return DeclPtrTy::make(ObjCMethod);
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8599a14..2267e0c 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1259,7 +1259,7 @@
// FIXME: Do we need to check for default arguments here?
if (Func->getNumParams() == 1 && InitialParamType == Argument) {
if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
- Func->addAttr(::new (Context) MallocAttr());
+ Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
return;
}
}
@@ -1287,7 +1287,7 @@
Alloc->setImplicit();
if (AddMallocAttr)
- Alloc->addAttr(::new (Context) MallocAttr());
+ Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 24ecb47..5cfacf7 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -4031,7 +4031,7 @@
/// \brief Strips various properties off an implicit instantiation
/// that has just been explicitly specialized.
static void StripImplicitInstantiation(NamedDecl *D) {
- D->invalidateAttrs();
+ D->dropAttrs();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
FD->setInlineSpecified(false);
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 1cb5077..6fc9563 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -140,21 +140,30 @@
// FIXME: Is this still too simple?
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
Decl *Tmpl, Decl *New) {
- for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
- TmplAttr = TmplAttr->getNext()) {
+ for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+ i != e; ++i) {
+ const Attr *TmplAttr = *i;
// FIXME: This should be generalized to more than just the AlignedAttr.
if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
- if (Aligned->isDependent()) {
+ if (Aligned->isAlignmentDependent()) {
// The alignment expression is not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(*this,
Action::Unevaluated);
- OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
- TemplateArgs);
- if (!Result.isInvalid())
- // FIXME: Is this the correct source location?
- AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
- New, Result.takeAs<Expr>());
+ if (Aligned->isAlignmentExpr()) {
+ OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+ TemplateArgs);
+ if (!Result.isInvalid())
+ AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+ }
+ else {
+ TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+ TemplateArgs,
+ Aligned->getLocation(),
+ DeclarationName());
+ if (Result)
+ AddAlignedAttr(Aligned->getLocation(), New, Result);
+ }
continue;
}
}
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 4d9e486..dc08a73 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -51,8 +51,8 @@
return;
}
- d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
namespace {
@@ -97,7 +97,7 @@
return;
}
- D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+ D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +109,7 @@
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -146,7 +146,7 @@
return;
}
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +158,7 @@
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -177,7 +177,7 @@
return;
}
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
}
namespace {