diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/AttrImpl.cpp | 227 | ||||
-rw-r--r-- | clang/lib/AST/CMakeLists.txt | 2 | ||||
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Checker/MallocChecker.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 80 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 225 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/TargetAttributesSema.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Serialization/CMakeLists.txt | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/PCHReaderDecl.cpp | 176 | ||||
-rw-r--r-- | clang/lib/Serialization/PCHWriter.cpp | 170 |
20 files changed, 295 insertions, 800 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b549415a1b4..f53a50e3145 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -497,8 +497,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) { unsigned Align = Target.getCharWidth(); - if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) - Align = std::max(Align, AA->getMaxAlignment()); + Align = std::max(Align, D->getMaxAlignment()); if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { QualType T = VD->getType(); @@ -760,12 +759,9 @@ ASTContext::getTypeInfo(const Type *T) { case Type::Typedef: { const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); - if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { - Align = std::max(Aligned->getMaxAlignment(), - getTypeAlign(Typedef->getUnderlyingType().getTypePtr())); - Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr()); - } else - return getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); + Align = std::max(Typedef->getMaxAlignment(), + getTypeAlign(Typedef->getUnderlyingType().getTypePtr())); + Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr()); break; } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index 994d45cf745..3ca7d4d01d1 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -13,231 +13,10 @@ #include "clang/AST/Attr.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "clang/AST/Expr.h" using namespace clang; Attr::~Attr() { } -AttrWithString::AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s) - : Attr(AK) { - assert(!s.empty()); - StrLen = s.size(); - Str = new (C) char[StrLen]; - memcpy(const_cast<char*>(Str), s.data(), StrLen); -} - -void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) { - if (newS.size() > StrLen) { - C.Deallocate(const_cast<char*>(Str)); - Str = new (C) char[newS.size()]; - } - StrLen = newS.size(); - memcpy(const_cast<char*>(Str), newS.data(), StrLen); -} - -void FormatAttr::setType(ASTContext &C, llvm::StringRef type) { - ReplaceString(C, type); -} - -NonNullAttr::NonNullAttr(ASTContext &C, unsigned* arg_nums, unsigned size) - : Attr(attr::NonNull), ArgNums(0), Size(0) { - if (size == 0) - return; - assert(arg_nums); - ArgNums = new (C) unsigned[size]; - Size = size; - memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size); -} - -OwnershipAttr::OwnershipAttr(attr::Kind AK, ASTContext &C, unsigned* arg_nums, - unsigned size, llvm::StringRef module) - : AttrWithString(AK, C, module), ArgNums(0), Size(0) { - if (size == 0) - return; - assert(arg_nums); - ArgNums = new (C) unsigned[size]; - Size = size; - memcpy(ArgNums, arg_nums, sizeof(*ArgNums) * size); -} - - -void OwnershipAttr::Destroy(ASTContext &C) { - if (ArgNums) - C.Deallocate(ArgNums); -} - -OwnershipTakesAttr::OwnershipTakesAttr(ASTContext &C, unsigned* arg_nums, - unsigned size, llvm::StringRef module) - : OwnershipAttr(attr::OwnershipTakes, C, arg_nums, size, module) { -} - -OwnershipHoldsAttr::OwnershipHoldsAttr(ASTContext &C, unsigned* arg_nums, - unsigned size, llvm::StringRef module) - : OwnershipAttr(attr::OwnershipHolds, C, arg_nums, size, module) { -} - -OwnershipReturnsAttr::OwnershipReturnsAttr(ASTContext &C, unsigned* arg_nums, - unsigned size, - llvm::StringRef module) - : OwnershipAttr(attr::OwnershipReturns, C, arg_nums, size, module) { -} - -#define DEF_SIMPLE_ATTR_CLONE(ATTR) \ - Attr *ATTR##Attr::clone(ASTContext &C) const { \ - return ::new (C) ATTR##Attr; \ - } - -// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for -// "non-simple" classes? - -DEF_SIMPLE_ATTR_CLONE(AlignMac68k) -DEF_SIMPLE_ATTR_CLONE(AlwaysInline) -DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn) -DEF_SIMPLE_ATTR_CLONE(BaseCheck) -DEF_SIMPLE_ATTR_CLONE(CDecl) -DEF_SIMPLE_ATTR_CLONE(CFReturnsNotRetained) -DEF_SIMPLE_ATTR_CLONE(CFReturnsRetained) -DEF_SIMPLE_ATTR_CLONE(Const) -DEF_SIMPLE_ATTR_CLONE(DLLExport) -DEF_SIMPLE_ATTR_CLONE(DLLImport) -DEF_SIMPLE_ATTR_CLONE(Deprecated) -DEF_SIMPLE_ATTR_CLONE(FastCall) -DEF_SIMPLE_ATTR_CLONE(Final) -DEF_SIMPLE_ATTR_CLONE(Hiding) -DEF_SIMPLE_ATTR_CLONE(Malloc) -DEF_SIMPLE_ATTR_CLONE(NSReturnsNotRetained) -DEF_SIMPLE_ATTR_CLONE(NSReturnsRetained) -DEF_SIMPLE_ATTR_CLONE(NoDebug) -DEF_SIMPLE_ATTR_CLONE(NoInline) -DEF_SIMPLE_ATTR_CLONE(NoInstrumentFunction) -DEF_SIMPLE_ATTR_CLONE(NoReturn) -DEF_SIMPLE_ATTR_CLONE(NoThrow) -DEF_SIMPLE_ATTR_CLONE(ObjCException) -DEF_SIMPLE_ATTR_CLONE(ObjCNSObject) -DEF_SIMPLE_ATTR_CLONE(Override) -DEF_SIMPLE_ATTR_CLONE(Packed) -DEF_SIMPLE_ATTR_CLONE(Pure) -DEF_SIMPLE_ATTR_CLONE(StdCall) -DEF_SIMPLE_ATTR_CLONE(ThisCall) -DEF_SIMPLE_ATTR_CLONE(TransparentUnion) -DEF_SIMPLE_ATTR_CLONE(Unavailable) -DEF_SIMPLE_ATTR_CLONE(Unused) -DEF_SIMPLE_ATTR_CLONE(Used) -DEF_SIMPLE_ATTR_CLONE(VecReturn) -DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult) -DEF_SIMPLE_ATTR_CLONE(Weak) -DEF_SIMPLE_ATTR_CLONE(WeakImport) - -DEF_SIMPLE_ATTR_CLONE(WeakRef) -DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer) - -Attr* MaxFieldAlignmentAttr::clone(ASTContext &C) const { - return ::new (C) MaxFieldAlignmentAttr(Alignment); -} - -Attr* AlignedAttr::clone(ASTContext &C) const { - return ::new (C) AlignedAttr(Alignment); -} - -Attr* AnnotateAttr::clone(ASTContext &C) const { - return ::new (C) AnnotateAttr(C, getAnnotation()); -} - -Attr *AsmLabelAttr::clone(ASTContext &C) const { - return ::new (C) AsmLabelAttr(C, getLabel()); -} - -Attr *AliasAttr::clone(ASTContext &C) const { - return ::new (C) AliasAttr(C, getAliasee()); -} - -Attr *ConstructorAttr::clone(ASTContext &C) const { - return ::new (C) ConstructorAttr(priority); -} - -Attr *DestructorAttr::clone(ASTContext &C) const { - return ::new (C) DestructorAttr(priority); -} - -Attr *IBOutletAttr::clone(ASTContext &C) const { - return ::new (C) IBOutletAttr; -} - -Attr *IBOutletCollectionAttr::clone(ASTContext &C) const { - return ::new (C) IBOutletCollectionAttr(QT); -} - -Attr *IBActionAttr::clone(ASTContext &C) const { - return ::new (C) IBActionAttr; -} - -Attr *GNUInlineAttr::clone(ASTContext &C) const { - return ::new (C) GNUInlineAttr; -} - -Attr *SectionAttr::clone(ASTContext &C) const { - return ::new (C) SectionAttr(C, getName()); -} - -Attr *NonNullAttr::clone(ASTContext &C) const { - return ::new (C) NonNullAttr(C, ArgNums, Size); -} - -Attr *OwnershipAttr::clone(ASTContext &C) const { - return ::new (C) OwnershipAttr(AKind, C, ArgNums, Size, getModule()); -} - -Attr *OwnershipReturnsAttr::clone(ASTContext &C) const { - return ::new (C) OwnershipReturnsAttr(C, ArgNums, Size, getModule()); -} - -Attr *OwnershipTakesAttr::clone(ASTContext &C) const { - return ::new (C) OwnershipTakesAttr(C, ArgNums, Size, getModule()); -} - -Attr *OwnershipHoldsAttr::clone(ASTContext &C) const { - return ::new (C) OwnershipHoldsAttr(C, ArgNums, Size, getModule()); -} - -Attr *FormatAttr::clone(ASTContext &C) const { - return ::new (C) FormatAttr(C, getType(), formatIdx, firstArg); -} - -Attr *FormatArgAttr::clone(ASTContext &C) const { - return ::new (C) FormatArgAttr(formatIdx); -} - -Attr *SentinelAttr::clone(ASTContext &C) const { - return ::new (C) SentinelAttr(sentinel, NullPos); -} - -Attr *VisibilityAttr::clone(ASTContext &C) const { - return ::new (C) VisibilityAttr(VisibilityType, FromPragma); -} - -Attr *OverloadableAttr::clone(ASTContext &C) const { - return ::new (C) OverloadableAttr; -} - -Attr *BlocksAttr::clone(ASTContext &C) const { - return ::new (C) BlocksAttr(BlocksAttrType); -} - -Attr *CleanupAttr::clone(ASTContext &C) const { - return ::new (C) CleanupAttr(FD); -} - -Attr *RegparmAttr::clone(ASTContext &C) const { - return ::new (C) RegparmAttr(NumParams); -} - -Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const { - return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z); -} - -Attr *InitPriorityAttr::clone(ASTContext &C) const { - return ::new (C) InitPriorityAttr(Priority); -} - -Attr *MSP430InterruptAttr::clone(ASTContext &C) const { - return ::new (C) MSP430InterruptAttr(Number); -} +#include "clang/AST/AttrImpl.inc" diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index b340c0464cc..82a81ec4241 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -43,4 +43,4 @@ add_clang_library(clangAST ) add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList - ClangDiagnosticAST ClangDeclNodes ClangStmtNodes) + ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes) diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index e4ff679c041..74cc1c29b98 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -312,35 +312,25 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { return 0; } -void Decl::initAttrs(Attr *attrs) { +void Decl::setAttrs(const AttrVec &attrs) { assert(!HasAttrs && "Decl already contains attrs."); - Attr *&AttrBlank = getASTContext().getDeclAttrs(this); - assert(AttrBlank == 0 && "HasAttrs was wrong?"); + AttrVec &AttrBlank = getASTContext().getDeclAttrs(this); + assert(AttrBlank.empty() && "HasAttrs was wrong?"); AttrBlank = attrs; HasAttrs = true; } -void Decl::addAttr(Attr *NewAttr) { - Attr *&ExistingAttr = getASTContext().getDeclAttrs(this); - - assert(NewAttr->getNext() == 0 && "Chain of attributes will be truncated!"); - NewAttr->setNext(ExistingAttr); - ExistingAttr = NewAttr; - - HasAttrs = true; -} - -void Decl::invalidateAttrs() { +void Decl::dropAttrs() { if (!HasAttrs) return; HasAttrs = false; getASTContext().eraseDeclAttrs(this); } -const Attr *Decl::getAttrsImpl() const { - assert(HasAttrs && "getAttrs() should verify this!"); +const AttrVec &Decl::getAttrs() const { + assert(HasAttrs && "No attrs to get!"); return getASTContext().getDeclAttrs(this); } diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index ad15917b88e..f42ba5a29fc 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1123,8 +1123,8 @@ void RecordLayoutBuilder::InitializeLayout(const Decl *D) { if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) MaxFieldAlignment = MFAA->getAlignment(); - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) - UpdateAlignment(AA->getMaxAlignment()); + if (unsigned MaxAlign = D->getMaxAlignment()) + UpdateAlignment(MaxAlign); } } @@ -1287,8 +1287,7 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { if (FieldPacked || !Context.Target.useBitFieldTypeAlignment()) FieldAlign = 1; - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) - FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); + FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); // The maximum field alignment overrides the aligned attribute. if (MaxFieldAlignment) @@ -1357,8 +1356,7 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) { if (FieldPacked) FieldAlign = 8; - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) - FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); + FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); // The maximum field alignment overrides the aligned attribute. if (MaxFieldAlignment) diff --git a/clang/lib/Checker/MallocChecker.cpp b/clang/lib/Checker/MallocChecker.cpp index 0076e1e8687..6e7faa7c071 100644 --- a/clang/lib/Checker/MallocChecker.cpp +++ b/clang/lib/Checker/MallocChecker.cpp @@ -176,19 +176,23 @@ bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { // There can be multiple of these attributes. bool rv = false; if (FD->hasAttrs()) { - for (const Attr *attr = FD->getAttrs(); attr; attr = attr->getNext()) { - switch (attr->getKind()) { - case attr::OwnershipReturns: - MallocMemReturnsAttr(C, CE, cast<OwnershipAttr>(attr)); + for (specific_attr_iterator<OwnershipAttr> + i = FD->specific_attr_begin<OwnershipAttr>(), + e = FD->specific_attr_end<OwnershipAttr>(); + i != e; ++i) { + switch ((*i)->getOwnKind()) { + case OwnershipAttr::Returns: { + MallocMemReturnsAttr(C, CE, *i); rv = true; break; - case attr::OwnershipTakes: - case attr::OwnershipHolds: - FreeMemAttr(C, CE, cast<OwnershipAttr>(attr)); + } + case OwnershipAttr::Takes: + case OwnershipAttr::Holds: { + FreeMemAttr(C, CE, *i); rv = true; break; + } default: - // Ignore non-ownership attributes. break; } } @@ -204,10 +208,10 @@ void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) { void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att) { - if (!Att->isModule("malloc")) + if (Att->getModule() != "malloc") return; - const unsigned *I = Att->begin(), *E = Att->end(); + OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); if (I != E) { const GRState *state = MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); @@ -258,14 +262,15 @@ void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) { void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE, const OwnershipAttr* Att) { - if (!Att->isModule("malloc")) + if (Att->getModule() != "malloc") return; - for (const unsigned *I = Att->begin(), *E = Att->end(); I != E; ++I) { - const GRState *state = - FreeMemAux(C, CE, C.getState(), *I, isa<OwnershipHoldsAttr>(Att)); - if (state) - C.addTransition(state); + for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); + I != E; ++I) { + const GRState *state = FreeMemAux(C, CE, C.getState(), *I, + Att->getOwnKind() == OwnershipAttr::Holds); + if (state) + C.addTransition(state); } } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ffe8f22791a..72ec584f6c8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -150,11 +150,11 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const { if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) { switch (attr->getVisibility()) { default: assert(0 && "Unknown visibility!"); - case VisibilityAttr::DefaultVisibility: + case VisibilityAttr::Default: return LangOptions::Default; - case VisibilityAttr::HiddenVisibility: + case VisibilityAttr::Hidden: return LangOptions::Hidden; - case VisibilityAttr::ProtectedVisibility: + case VisibilityAttr::Protected: return LangOptions::Protected; } } @@ -461,12 +461,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, else if (Features.getStackProtectorMode() == LangOptions::SSPReq) F->addFnAttr(llvm::Attribute::StackProtectReq); - if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) { - unsigned width = Context.Target.getCharWidth(); - F->setAlignment(AA->getAlignment() / width); - while ((AA = AA->getNext<AlignedAttr>())) - F->setAlignment(std::max(F->getAlignment(), AA->getAlignment() / width)); - } + unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); + if (alignment) + F->setAlignment(alignment); + // C++ ABI requires 2-byte alignment for member functions. if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D)) F->setAlignment(2); diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 96793d5a40a..66d31dda9f5 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/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 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { // 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 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers, 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 @@ void Sema::AddPushedVisibilityAttribute(Decl *D) { 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 @@ void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType, 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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9a484932b2e..4e8c82fd7e9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -347,9 +347,12 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { } } - 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 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, 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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index dfbc7e1559b..f6d6e6b3995 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -997,19 +997,32 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) { /// 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 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { /// \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 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { return New->setInvalidDecl(); } - MergeAttributes(New, Old, Context); + MergeDeclAttributes(New, Old, Context); // Merge the types QualType MergedT; @@ -1611,9 +1624,7 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } 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 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { // 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 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, 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 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { 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 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { 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 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // 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 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, 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/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 7125c36a130..1776d46bd76 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -211,7 +211,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { } 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 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 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 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { unsigned* start = &NonNullArgs[0]; unsigned size = NonNullArgs.size(); llvm::array_pod_sort(start, start + size); - d->addAttr(::new (S.Context) NonNullAttr(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 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 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 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { } --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 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { } // 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 @@ static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 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; - } - 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"); + + if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { + S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; + return; } + + d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, + start, size)); } static bool isStaticVarOrStaticFunciton(Decl *D) { @@ -622,10 +603,10 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { } // GCC will accept anything as the argument of weakref. Should we // check for an existing decl? - d->addAttr(::new (S.Context) AliasAttr(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 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { // FIXME: check if target symbol exists in current file - d->addAttr(::new (S.Context) AliasAttr(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 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 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 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 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 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 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 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { } 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 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 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 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { return; } } - D->addAttr(::new (S.Context) ObjCNSObjectAttr()); + D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); } static void @@ -966,7 +947,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - BlocksAttr::BlocksAttrTypes type; + BlocksAttr::BlockType type; if (Attr.getParameterName()->isStr("byref")) type = BlocksAttr::ByRef; else { @@ -990,7 +971,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { << 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 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) 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 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, } 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 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 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 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, } } - 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 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; return; } - d->addAttr(::new (S.Context) AnnotateAttr(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 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 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 @@ static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 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 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(::new (S.Context) FinalAttr()); + d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); } //===----------------------------------------------------------------------===// @@ -2090,7 +2080,7 @@ static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(::new (S.Context) OverrideAttr()); + d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); } //===----------------------------------------------------------------------===// @@ -2176,16 +2166,16 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 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 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 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 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7791b682e8d..fff37d98e08 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3292,7 +3292,7 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope, 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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 8bcb616285f..0fd3d6e9ccf 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1454,13 +1454,14 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) { } 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 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( } 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 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( 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 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( // 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/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8599a146c69..2267e0c7579 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1259,7 +1259,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, // 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 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, 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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 24ecb47110d..5cfacf78b57 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4031,7 +4031,7 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, /// \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/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1cb5077ade5..6fc95634ab7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -140,21 +140,30 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, // 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/clang/lib/Sema/TargetAttributesSema.cpp b/clang/lib/Sema/TargetAttributesSema.cpp index 4d9e4861e02..dc08a735a75 100644 --- a/clang/lib/Sema/TargetAttributesSema.cpp +++ b/clang/lib/Sema/TargetAttributesSema.cpp @@ -51,8 +51,8 @@ static void HandleMSP430InterruptAttr(Decl *d, 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 @@ static void HandleX86ForceAlignArgPointerAttr(Decl *D, 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 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 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 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(::new (S.Context) DLLExportAttr()); + D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context)); } namespace { diff --git a/clang/lib/Serialization/CMakeLists.txt b/clang/lib/Serialization/CMakeLists.txt index 551c0654d4a..bab2b53d410 100644 --- a/clang/lib/Serialization/CMakeLists.txt +++ b/clang/lib/Serialization/CMakeLists.txt @@ -13,6 +13,8 @@ add_clang_library(clangSerialization add_dependencies(clangSerialization ClangAttrClasses ClangAttrList + ClangAttrPCHRead + ClangAttrPCHWrite ClangDiagnosticFrontend ClangDiagnosticLex ClangDiagnosticSema diff --git a/clang/lib/Serialization/PCHReaderDecl.cpp b/clang/lib/Serialization/PCHReaderDecl.cpp index 91c71611b7e..201360ad1b5 100644 --- a/clang/lib/Serialization/PCHReaderDecl.cpp +++ b/clang/lib/Serialization/PCHReaderDecl.cpp @@ -148,8 +148,11 @@ void PCHDeclReader::VisitDecl(Decl *D) { cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); D->setInvalidDecl(Record[Idx++]); - if (Record[Idx++]) - D->initAttrs(Reader.ReadAttributes(Cursor)); + if (Record[Idx++]) { + AttrVec Attrs; + Reader.ReadAttributes(Cursor, Attrs); + D->setAttrs(Attrs); + } D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); @@ -1091,7 +1094,8 @@ void PCHDeclReader::VisitRedeclarable(Redeclarable<T> *D) { //===----------------------------------------------------------------------===// /// \brief Reads attributes from the current stream position. -Attr *PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor) { +void PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor, + AttrVec &Attrs) { unsigned Code = DeclsCursor.ReadCode(); assert(Code == llvm::bitc::UNABBREV_RECORD && "Expected unabbreviated record"); (void)Code; @@ -1102,174 +1106,18 @@ Attr *PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor) { assert(RecCode == pch::DECL_ATTR && "Expected attribute record"); (void)RecCode; -#define SIMPLE_ATTR(Name) \ - case attr::Name: \ - New = ::new (*Context) Name##Attr(); \ - break - -#define STRING_ATTR(Name) \ - case attr::Name: \ - New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx)); \ - break - -#define UNSIGNED_ATTR(Name) \ - case attr::Name: \ - New = ::new (*Context) Name##Attr(Record[Idx++]); \ - break - - Attr *Attrs = 0; while (Idx < Record.size()) { Attr *New = 0; attr::Kind Kind = (attr::Kind)Record[Idx++]; - bool IsInherited = Record[Idx++]; - - switch (Kind) { - default: - assert(0 && "Unknown attribute!"); - break; - STRING_ATTR(Alias); - SIMPLE_ATTR(AlignMac68k); - UNSIGNED_ATTR(Aligned); - SIMPLE_ATTR(AlwaysInline); - SIMPLE_ATTR(AnalyzerNoReturn); - STRING_ATTR(Annotate); - STRING_ATTR(AsmLabel); - SIMPLE_ATTR(BaseCheck); - - case attr::Blocks: - New = ::new (*Context) BlocksAttr( - (BlocksAttr::BlocksAttrTypes)Record[Idx++]); - break; - - SIMPLE_ATTR(CDecl); - - case attr::Cleanup: - New = ::new (*Context) CleanupAttr( - cast<FunctionDecl>(GetDecl(Record[Idx++]))); - break; - - SIMPLE_ATTR(Const); - UNSIGNED_ATTR(Constructor); - SIMPLE_ATTR(DLLExport); - SIMPLE_ATTR(DLLImport); - SIMPLE_ATTR(Deprecated); - UNSIGNED_ATTR(Destructor); - SIMPLE_ATTR(FastCall); - SIMPLE_ATTR(Final); - - case attr::Format: { - std::string Type = ReadString(Record, Idx); - unsigned FormatIdx = Record[Idx++]; - unsigned FirstArg = Record[Idx++]; - New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg); - break; - } - - case attr::FormatArg: { - unsigned FormatIdx = Record[Idx++]; - New = ::new (*Context) FormatArgAttr(FormatIdx); - break; - } - - case attr::Sentinel: { - int sentinel = Record[Idx++]; - int nullPos = Record[Idx++]; - New = ::new (*Context) SentinelAttr(sentinel, nullPos); - break; - } - - SIMPLE_ATTR(GNUInline); - SIMPLE_ATTR(Hiding); - - case attr::IBAction: - New = ::new (*Context) IBActionAttr(); - break; - - case attr::IBOutlet: - New = ::new (*Context) IBOutletAttr(); - break; - - case attr::IBOutletCollection: { - QualType QT = GetType(Record[Idx++]); - New = ::new (*Context) IBOutletCollectionAttr(QT); - break; - } - - SIMPLE_ATTR(Malloc); - SIMPLE_ATTR(NoDebug); - SIMPLE_ATTR(NoInline); - SIMPLE_ATTR(NoReturn); - SIMPLE_ATTR(NoThrow); - - case attr::NonNull: { - unsigned Size = Record[Idx++]; - llvm::SmallVector<unsigned, 16> ArgNums; - ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size); - Idx += Size; - New = ::new (*Context) NonNullAttr(*Context, ArgNums.data(), Size); - break; - } - - case attr::ReqdWorkGroupSize: { - unsigned X = Record[Idx++]; - unsigned Y = Record[Idx++]; - unsigned Z = Record[Idx++]; - New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z); - break; - } + SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[Idx++]); + bool isInherited = Record[Idx++]; - SIMPLE_ATTR(ObjCException); - SIMPLE_ATTR(ObjCNSObject); - SIMPLE_ATTR(CFReturnsNotRetained); - SIMPLE_ATTR(CFReturnsRetained); - SIMPLE_ATTR(NSReturnsNotRetained); - SIMPLE_ATTR(NSReturnsRetained); - SIMPLE_ATTR(Overloadable); - SIMPLE_ATTR(Override); - SIMPLE_ATTR(Packed); - UNSIGNED_ATTR(MaxFieldAlignment); - SIMPLE_ATTR(Pure); - UNSIGNED_ATTR(Regparm); - STRING_ATTR(Section); - SIMPLE_ATTR(StdCall); - SIMPLE_ATTR(ThisCall); - SIMPLE_ATTR(TransparentUnion); - SIMPLE_ATTR(Unavailable); - SIMPLE_ATTR(Unused); - SIMPLE_ATTR(Used); - - case attr::Visibility: - New = ::new (*Context) VisibilityAttr( - (VisibilityAttr::VisibilityTypes)Record[Idx++], - (bool)Record[Idx++]); - break; - - SIMPLE_ATTR(WarnUnusedResult); - SIMPLE_ATTR(Weak); - SIMPLE_ATTR(WeakRef); - SIMPLE_ATTR(WeakImport); - } +#include "clang/Serialization/AttrPCHRead.inc" assert(New && "Unable to decode attribute?"); - New->setInherited(IsInherited); - New->setNext(Attrs); - Attrs = New; + New->setInherited(isInherited); + Attrs.push_back(New); } -#undef UNSIGNED_ATTR -#undef STRING_ATTR -#undef SIMPLE_ATTR - - // The list of attributes was built backwards. Reverse the list - // before returning it. - Attr *PrevAttr = 0, *NextAttr = 0; - while (Attrs) { - NextAttr = Attrs->getNext(); - Attrs->setNext(PrevAttr); - PrevAttr = Attrs; - Attrs = NextAttr; - } - - return PrevAttr; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/PCHWriter.cpp b/clang/lib/Serialization/PCHWriter.cpp index 2cb2758e9a8..f78a8ba23bd 100644 --- a/clang/lib/Serialization/PCHWriter.cpp +++ b/clang/lib/Serialization/PCHWriter.cpp @@ -1949,172 +1949,16 @@ void PCHWriter::WriteIdentifierTable(Preprocessor &PP) { //===----------------------------------------------------------------------===// /// \brief Write a record containing the given attributes. -void PCHWriter::WriteAttributeRecord(const Attr *Attr) { +void PCHWriter::WriteAttributeRecord(const AttrVec &Attrs) { RecordData Record; - for (; Attr; Attr = Attr->getNext()) { - Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs - Record.push_back(Attr->isInherited()); - switch (Attr->getKind()) { - default: - assert(0 && "Does not support PCH writing for this attribute yet!"); - break; - case attr::Alias: - AddString(cast<AliasAttr>(Attr)->getAliasee(), Record); - break; - - case attr::AlignMac68k: - break; - - case attr::Aligned: - Record.push_back(cast<AlignedAttr>(Attr)->getAlignment()); - break; - - case attr::AlwaysInline: - break; - - case attr::AnalyzerNoReturn: - break; - - case attr::Annotate: - AddString(cast<AnnotateAttr>(Attr)->getAnnotation(), Record); - break; - - case attr::AsmLabel: - AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record); - break; - - case attr::BaseCheck: - break; - - case attr::Blocks: - Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable - break; - - case attr::CDecl: - break; - - case attr::Cleanup: - AddDeclRef(cast<CleanupAttr>(Attr)->getFunctionDecl(), Record); - break; - - case attr::Const: - break; - - case attr::Constructor: - Record.push_back(cast<ConstructorAttr>(Attr)->getPriority()); - break; - - case attr::DLLExport: - case attr::DLLImport: - case attr::Deprecated: - break; - - case attr::Destructor: - Record.push_back(cast<DestructorAttr>(Attr)->getPriority()); - break; - - case attr::FastCall: - case attr::Final: - break; - - case attr::Format: { - const FormatAttr *Format = cast<FormatAttr>(Attr); - AddString(Format->getType(), Record); - Record.push_back(Format->getFormatIdx()); - Record.push_back(Format->getFirstArg()); - break; - } - - case attr::FormatArg: { - const FormatArgAttr *Format = cast<FormatArgAttr>(Attr); - Record.push_back(Format->getFormatIdx()); - break; - } - - case attr::Sentinel : { - const SentinelAttr *Sentinel = cast<SentinelAttr>(Attr); - Record.push_back(Sentinel->getSentinel()); - Record.push_back(Sentinel->getNullPos()); - break; - } - - case attr::GNUInline: - case attr::Hiding: - case attr::IBAction: - case attr::IBOutlet: - case attr::Malloc: - case attr::NoDebug: - case attr::NoInline: - case attr::NoReturn: - case attr::NoThrow: - break; - - case attr::IBOutletCollection: { - const IBOutletCollectionAttr *ICA = cast<IBOutletCollectionAttr>(Attr); - AddTypeRef(ICA->getType(), Record); - break; - } - - case attr::NonNull: { - const NonNullAttr *NonNull = cast<NonNullAttr>(Attr); - Record.push_back(NonNull->size()); - Record.insert(Record.end(), NonNull->begin(), NonNull->end()); - break; - } - - case attr::CFReturnsNotRetained: - case attr::CFReturnsRetained: - case attr::NSReturnsNotRetained: - case attr::NSReturnsRetained: - case attr::ObjCException: - case attr::ObjCNSObject: - case attr::Overloadable: - case attr::Override: - break; + for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ + const Attr * A = *i; + Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs + AddSourceLocation(A->getLocation(), Record); + Record.push_back(A->isInherited()); - case attr::MaxFieldAlignment: - Record.push_back(cast<MaxFieldAlignmentAttr>(Attr)->getAlignment()); - break; - - case attr::Packed: - break; - - case attr::Pure: - break; - - case attr::Regparm: - Record.push_back(cast<RegparmAttr>(Attr)->getNumParams()); - break; - - case attr::ReqdWorkGroupSize: - Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim()); - Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim()); - Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim()); - break; +#include "clang/Serialization/AttrPCHWrite.inc" - case attr::Section: - AddString(cast<SectionAttr>(Attr)->getName(), Record); - break; - - case attr::StdCall: - case attr::TransparentUnion: - case attr::Unavailable: - case attr::Unused: - case attr::Used: - break; - - case attr::Visibility: - // FIXME: stable encoding - Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility()); - Record.push_back(cast<VisibilityAttr>(Attr)->isFromPragma()); - break; - - case attr::WarnUnusedResult: - case attr::Weak: - case attr::WeakRef: - case attr::WeakImport: - break; - } } Stream.EmitRecord(pch::DECL_ATTR, Record); |