aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp12
-rw-r--r--lib/AST/AttrImpl.cpp227
-rw-r--r--lib/AST/CMakeLists.txt2
-rw-r--r--lib/AST/DeclBase.cpp22
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp10
-rw-r--r--lib/Checker/MallocChecker.cpp37
-rw-r--r--lib/CodeGen/CodeGenModule.cpp16
-rw-r--r--lib/Sema/SemaAttr.cpp34
-rw-r--r--lib/Sema/SemaChecking.cpp12
-rw-r--r--lib/Sema/SemaDecl.cpp80
-rw-r--r--lib/Sema/SemaDeclAttr.cpp225
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaDeclObjC.cpp21
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
-rw-r--r--lib/Sema/SemaTemplate.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp27
-rw-r--r--lib/Sema/TargetAttributesSema.cpp14
-rw-r--r--lib/Serialization/CMakeLists.txt2
-rw-r--r--lib/Serialization/PCHReaderDecl.cpp176
-rw-r--r--lib/Serialization/PCHWriter.cpp170
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