diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 3e2435197d29..f6478d9ea669 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -297,6 +297,7 @@ public: } bool hasAttrs() const { return HasAttrs; } + void initAttrs(Attr *attrs); void addAttr(Attr *attr); const Attr *getAttrs() const { if (!HasAttrs) return 0; // common case, no attributes. diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 8f6fdbc956f8..f1b78e40fc80 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -314,9 +314,20 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { return 0; } +void Decl::initAttrs(Attr *attrs) { + assert(!HasAttrs && "Decl already contains attrs."); + + Attr *&AttrBlank = getASTContext().getDeclAttrs(this); + assert(AttrBlank == 0 && "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; diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 7ccf14362f9d..cece1b659c5c 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -113,7 +113,7 @@ void PCHDeclReader::VisitDecl(Decl *D) { D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); D->setInvalidDecl(Record[Idx++]); if (Record[Idx++]) - D->addAttr(Reader.ReadAttributes()); + D->initAttrs(Reader.ReadAttributes()); D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); diff --git a/clang/test/PCH/attrs.h b/clang/test/PCH/attrs.h index 0d0156515c88..58f058970431 100644 --- a/clang/test/PCH/attrs.h +++ b/clang/test/PCH/attrs.h @@ -4,4 +4,4 @@ -int f(int) __attribute__((overloadable)); +int f(int) __attribute__((visibility("default"), overloadable));