diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | lib/AST/AttrImpl.cpp | 227 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 22 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 10 | ||||
-rw-r--r-- | lib/Checker/MallocChecker.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 34 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 80 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 225 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/TargetAttributesSema.cpp | 14 | ||||
-rw-r--r-- | lib/Serialization/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Serialization/PCHReaderDecl.cpp | 176 | ||||
-rw-r--r-- | lib/Serialization/PCHWriter.cpp | 170 |
20 files changed, 295 insertions, 800 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b549415a1b..f53a50e314 100644 --- a/lib/AST/ASTContext.cpp +++ b/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/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp index 994d45cf74..3ca7d4d01d 100644 --- a/lib/AST/AttrImpl.cpp +++ b/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/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index b340c0464c..82a81ec424 100644 --- a/lib/AST/CMakeLists.txt +++ b/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/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index e4ff679c04..74cc1c29b9 100644 --- a/lib/AST/DeclBase.cpp +++ b/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/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index ad15917b88..f42ba5a29f 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/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/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp index 0076e1e868..6e7faa7c07 100644 --- a/lib/Checker/MallocChecker.cpp +++ b/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/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index ffe8f22791..72ec584f6c 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/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/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 96793d5a40..66d31dda9f 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 @@ 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/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 9a484932b2..4e8c82fd7e 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index dfbc7e1559..f6d6e6b399 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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(TUSc |