summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2018-07-12 21:09:05 +0000
committerErich Keane <erich.keane@intel.com>2018-07-12 21:09:05 +0000
commit829882796ce575409bda1c0a9f026dbf82bc8086 (patch)
tree170110bb65b17b5e7a68a936c2e3d291a824829e
parent6e54f66e13baad6b3d3753c25492439ab1d06f08 (diff)
AttributeList de-listifying:
Basically, "AttributeList" loses all list-like mechanisms, ParsedAttributes is switched to use a TinyPtrVector (and a ParsedAttributesView is created to have a non-allocating attributes list). DeclaratorChunk gets the later kind, Declarator/DeclSpec keep ParsedAttributes. Iterators are added to the ParsedAttribute types so that for-loops work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336945 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Parse/Parser.h65
-rw-r--r--include/clang/Sema/AttributeList.h284
-rw-r--r--include/clang/Sema/DeclSpec.h81
-rw-r--r--include/clang/Sema/Sema.h261
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp10
-rw-r--r--lib/Parse/ParseDecl.cpp203
-rw-r--r--lib/Parse/ParseDeclCXX.cpp145
-rw-r--r--lib/Parse/ParseExpr.cpp50
-rw-r--r--lib/Parse/ParseExprCXX.cpp105
-rw-r--r--lib/Parse/ParseObjc.cpp99
-rw-r--r--lib/Parse/ParsePragma.cpp12
-rw-r--r--lib/Parse/ParseStmt.cpp14
-rw-r--r--lib/Parse/ParseTemplate.cpp58
-rw-r--r--lib/Parse/Parser.cpp22
-rw-r--r--lib/Sema/AttributeList.cpp67
-rw-r--r--lib/Sema/DeclSpec.cpp11
-rw-r--r--lib/Sema/SemaAttr.cpp7
-rw-r--r--lib/Sema/SemaCUDA.cpp9
-rw-r--r--lib/Sema/SemaDecl.cpp78
-rw-r--r--lib/Sema/SemaDeclAttr.cpp87
-rw-r--r--lib/Sema/SemaDeclCXX.cpp137
-rw-r--r--lib/Sema/SemaDeclObjC.cpp90
-rw-r--r--lib/Sema/SemaLambda.cpp4
-rw-r--r--lib/Sema/SemaStmt.cpp2
-rw-r--r--lib/Sema/SemaStmtAttr.cpp7
-rw-r--r--lib/Sema/SemaTemplate.cpp96
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp6
-rw-r--r--lib/Sema/SemaType.cpp429
29 files changed, 1061 insertions, 1380 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 416691ccc8..f4d9f0168f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1361,11 +1361,11 @@ private:
};
NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- AttributeList *AccessAttrs,
- ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers& VS,
- SourceLocation PureSpecLoc);
+ ParsedAttributes &AccessAttrs,
+ ParsingDeclarator &D,
+ const ParsedTemplateInfo &TemplateInfo,
+ const VirtSpecifiers &VS,
+ SourceLocation PureSpecLoc);
void ParseCXXNonStaticMemberInitializer(Decl *VarD);
void ParseLexedAttributes(ParsingClass &Class);
void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
@@ -1406,6 +1406,15 @@ private:
SourceRange Range;
};
+ struct ParsedAttributesViewWithRange : ParsedAttributesView {
+ ParsedAttributesViewWithRange() : ParsedAttributesView() {}
+ void clearListOnly() {
+ ParsedAttributesView::clearListOnly();
+ Range = SourceRange();
+ }
+
+ SourceRange Range;
+ };
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS = nullptr);
@@ -1921,7 +1930,8 @@ private:
void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
void ParseMicrosoftIfExistsExternalDeclaration();
void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- AccessSpecifier& CurAS);
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier &CurAS);
bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
bool &InitExprsOk);
bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
@@ -2310,14 +2320,23 @@ private:
DeclSpec &DS, Sema::TagUseKind TUK);
// FixItLoc = possible correct location for the attributes
- void ProhibitAttributes(ParsedAttributesWithRange &attrs,
+ void ProhibitAttributes(ParsedAttributesWithRange &Attrs,
SourceLocation FixItLoc = SourceLocation()) {
- if (!attrs.Range.isValid()) return;
- DiagnoseProhibitedAttributes(attrs, FixItLoc);
- attrs.clear();
+ if (Attrs.Range.isInvalid())
+ return;
+ DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ Attrs.clear();
}
- void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs,
- SourceLocation FixItLoc);
+
+ void ProhibitAttributes(ParsedAttributesViewWithRange &Attrs,
+ SourceLocation FixItLoc = SourceLocation()) {
+ if (Attrs.Range.isInvalid())
+ return;
+ DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ Attrs.clearListOnly();
+ }
+ void DiagnoseProhibitedAttributes(const SourceRange &Range,
+ SourceLocation FixItLoc);
// Forbid C++11 and C2x attributes that appear on certain syntactic locations
// which standard permits but we don't supported yet, for example, attributes
@@ -2694,7 +2713,7 @@ private:
void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
VirtSpecifiers &VS);
DeclGroupPtrTy ParseCXXClassMemberDeclaration(
- AccessSpecifier AS, AttributeList *Attr,
+ AccessSpecifier AS, ParsedAttributes &Attr,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas(
@@ -2851,20 +2870,17 @@ private:
// C++ 14.1: Template Parameters [temp.param]
Decl *ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none,
- AttributeList *AccessAttrs = nullptr);
+ SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier AS = AS_none);
Decl *ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs);
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier AS);
Decl *ParseSingleDeclarationAfterTemplate(
- DeclaratorContext Context,
- const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromParams,
- SourceLocation &DeclEnd,
- AccessSpecifier AS=AS_none,
- AttributeList *AccessAttrs = nullptr);
+ DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
+ ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
bool ParseTemplateParameters(unsigned Depth,
SmallVectorImpl<NamedDecl *> &TemplateParams,
SourceLocation &LAngleLoc,
@@ -2907,6 +2923,7 @@ private:
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
AccessSpecifier AS = AS_none);
//===--------------------------------------------------------------------===//
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index dd15b7a2f5..70a0306f41 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -21,6 +21,7 @@
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/VersionTuple.h"
#include <cassert>
@@ -181,12 +182,6 @@ private:
const Expr *MessageExpr;
- /// The next attribute in the current position.
- AttributeList *NextInPosition = nullptr;
-
- /// The next attribute allocated in the current Pool.
- AttributeList *NextInPool = nullptr;
-
/// Arguments, if any, are stored immediately following the object.
ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
ArgsUnion const *getArgsBuffer() const {
@@ -433,9 +428,6 @@ public:
static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
Syntax SyntaxUsed);
- AttributeList *getNext() const { return NextInPosition; }
- void setNext(AttributeList *N) { NextInPosition = N; }
-
/// getNumArgs - Return the number of actual arguments to this attribute.
unsigned getNumArgs() const { return NumArgs; }
@@ -555,6 +547,7 @@ public:
unsigned getSemanticSpelling() const;
};
+class AttributePool;
/// A factory, from which one makes pools, from which one creates
/// individual attributes which are deallocated with the pool.
///
@@ -595,7 +588,8 @@ private:
/// Free lists. The index is determined by the following formula:
/// (size - sizeof(AttributeList)) / sizeof(void*)
- SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
+ SmallVector<SmallVector<AttributeList *, 8>, InlineFreeListsCapacity>
+ FreeLists;
// The following are the private interface used by AttributePool.
friend class AttributePool;
@@ -603,12 +597,14 @@ private:
/// Allocate an attribute of the given size.
void *allocate(size_t size);
+ void deallocate(AttributeList *AL);
+
/// Reclaim all the attributes in the given pool chain, which is
/// non-empty. Note that the current implementation is safe
/// against reclaiming things which were not actually allocated
/// with the allocator, although of course it's important to make
/// sure that their allocator lives at least as long as this one.
- void reclaimPool(AttributeList *head);
+ void reclaimPool(AttributePool &head);
public:
AttributeFactory();
@@ -616,21 +612,26 @@ public:
};
class AttributePool {
+ friend class AttributeFactory;
AttributeFactory &Factory;
- AttributeList *Head = nullptr;
+ llvm::TinyPtrVector<AttributeList *> Attrs;
void *allocate(size_t size) {
return Factory.allocate(size);
}
AttributeList *add(AttributeList *attr) {
- // We don't care about the order of the pool.
- attr->NextInPool = Head;
- Head = attr;
+ Attrs.push_back(attr);
return attr;
}
- void takePool(AttributeList *pool);
+ void remove(AttributeList *attr) {
+ assert(llvm::is_contained(Attrs, attr) &&
+ "Can't take attribute from a pool that doesn't own it!");
+ Attrs.erase(llvm::find(Attrs, attr));
+ }
+
+ void takePool(AttributePool &pool);
public:
/// Create a new pool for a factory.
@@ -638,30 +639,22 @@ public:
AttributePool(const AttributePool &) = delete;
- ~AttributePool() {
- if (Head) Factory.reclaimPool(Head);
- }
+ ~AttributePool() { Factory.reclaimPool(*this); }
/// Move the given pool's allocations to this pool.
- AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
- pool.Head = nullptr;
- }
+ AttributePool(AttributePool &&pool) = default;
AttributeFactory &getFactory() const { return Factory; }
void clear() {
- if (Head) {
- Factory.reclaimPool(Head);
- Head = nullptr;
- }
+ Factory.reclaimPool(*this);
+ Attrs.clear();
}
/// Take the given pool's allocations and add them to this pool.
void takeAllFrom(AttributePool &pool) {
- if (pool.Head) {
- takePool(pool.Head);
- pool.Head = nullptr;
- }
+ takePool(pool);
+ pool.Attrs.clear();
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -669,12 +662,11 @@ public:
ArgsUnion *args, unsigned numArgs,
AttributeList::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) {
- void *memory = allocate(sizeof(AttributeList)
- + numArgs * sizeof(ArgsUnion));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- args, numArgs, syntax,
- ellipsisLoc));
+ void *memory =
+ allocate(sizeof(AttributeList) + numArgs * sizeof(ArgsUnion));
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc, args,
+ numArgs, syntax, ellipsisLoc));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -683,133 +675,158 @@ public:
const AvailabilityChange &introduced,
const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted,
- SourceLocation unavailable,
- const Expr *MessageExpr,
- AttributeList::Syntax syntax,
- SourceLocation strict, const Expr *ReplacementExpr) {
+ SourceLocation unavailable, const Expr *MessageExpr,
+ AttributeList::Syntax syntax, SourceLocation strict,
+ const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr,
- syntax, strict, ReplacementExpr));
+ return add(new (memory) AttributeList(
+ attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
+ obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1,
- IdentifierLoc *Param2,
- IdentifierLoc *Param3,
- AttributeList::Syntax syntax) {
+ IdentifierLoc *Param1, IdentifierLoc *Param2,
+ IdentifierLoc *Param3, AttributeList::Syntax syntax) {
size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
void *memory = allocate(size);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param1, Param2, Param3,
- syntax));
- }
-
- AttributeList *createTypeTagForDatatype(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull,
- AttributeList::Syntax syntax) {
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc,
+ Param1, Param2, Param3, syntax));
+ }
+
+ AttributeList *
+ createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *argumentKind,
+ ParsedType matchingCType, bool layoutCompatible,
+ bool mustBeNull, AttributeList::Syntax syntax) {
void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- argumentKind, matchingCType,
- layoutCompatible, mustBeNull,
- syntax));
+ return add(new (memory) AttributeList(
+ attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
+ layoutCompatible, mustBeNull, syntax));
}
- AttributeList *createTypeAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ AttributeList *
+ createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- typeArg, syntaxUsed));
+ return add(new (memory) AttributeList(attrName, attrRange, scopeName,
+ scopeLoc, typeArg, syntaxUsed));
}
- AttributeList *createPropertyAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- AttributeList::Syntax syntaxUsed) {
+ AttributeList *
+ createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ AttributeList::Syntax syntaxUsed) {
void *memory = allocate(AttributeFactory::PropertyAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- getterId, setterId,
- syntaxUsed));
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc,
+ getterId, setterId, syntaxUsed));
}
};
-/// ParsedAttributes - A collection of parsed attributes. Currently
-/// we don't differentiate between the various attribute syntaxes,
-/// which is basically silly.
-///
-/// Right now this is a very lightweight container, but the expectation
-/// is that this will become significantly more serious.
-class ParsedAttributes {
-public:
- ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
- ParsedAttributes(const ParsedAttributes &) = delete;
-
- AttributePool &getPool() const { return pool; }
+class ParsedAttributesView {
+ using VecTy = llvm::TinyPtrVector<AttributeList *>;
+ using SizeType = decltype(std::declval<VecTy>().size());
- bool empty() const { return list == nullptr; }
+public:
+ bool empty() const { return AttrList.empty(); }
+ SizeType size() const { return AttrList.size(); }
+ AttributeList &operator[](SizeType pos) { return *AttrList[pos]; }
+ const AttributeList &operator[](SizeType pos) const { return *AttrList[pos]; }
- void add(AttributeList *newAttr) {
+ void addAtStart(AttributeList *newAttr) {
+ assert(newAttr);
+ AttrList.insert(AttrList.begin(), newAttr);
+ }
+ void addAtEnd(AttributeList *newAttr) {
assert(newAttr);
- assert(newAttr->getNext() == nullptr);
- newAttr->setNext(list);
- list = newAttr;
+ AttrList.push_back(newAttr);
+ }
+
+ void remove(AttributeList *ToBeRemoved) {
+ assert(is_contained(AttrList, ToBeRemoved) &&
+ "Cannot remove attribute that isn't in the list");
+ AttrList.erase(llvm::find(AttrList, ToBeRemoved));
}
- void addAll(AttributeList *newList) {
- if (!newList) return;
+ void clearListOnly() { AttrList.clear(); }
- AttributeList *lastInNewList = newList;
- while (AttributeList *next = lastInNewList->getNext())
- lastInNewList = next;
+ struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
+ std::random_access_iterator_tag,
+ AttributeList> {
+ iterator() : iterator_adaptor_base(nullptr) {}
+ iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
+ reference operator*() { return **I; }
+ friend class ParsedAttributesView;
+ };
+ struct const_iterator
+ : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
+ std::random_access_iterator_tag,
+ AttributeList> {
+ const_iterator() : iterator_adaptor_base(nullptr) {}
+ const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
+
+ reference operator*() const { return **I; }
+ friend class ParsedAttributesView;
+ };
- lastInNewList->setNext(list);
- list = newList;
+ void addAll(iterator B, iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
}
- void addAllAtEnd(AttributeList *newList) {
- if (!list) {
- list = newList;
- return;
- }
+ void addAll(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
+ }
- AttributeList *lastInList = list;
- while (AttributeList *next = lastInList->getNext())
- lastInList = next;
+ void addAllAtEnd(iterator B, iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
+ }
- lastInList->setNext(newList);
+ void addAllAtEnd(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
}
- void set(AttributeList *newList) {
- list = newList;
+ iterator begin() { return iterator(AttrList.begin()); }
+ const_iterator begin() const { return const_iterator(AttrList.begin()); }
+ iterator end() { return iterator(AttrList.end()); }
+ const_iterator end() const { return const_iterator(AttrList.end()); }
+
+ bool hasAttribute(AttributeList::Kind K) const {
+ return llvm::any_of(
+ AttrList, [K](const AttributeList *AL) { return AL->getKind() == K; });
}
+private:
+ VecTy AttrList;
+};
+
+/// ParsedAttributes - A collection of parsed attributes. Currently
+/// we don't differentiate between the various attribute syntaxes,
+/// which is basically silly.
+///
+/// Right now this is a very lightweight container, but the expectation
+/// is that this will become significantly more serious.
+class ParsedAttributes : public ParsedAttributesView {
+public:
+ ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
+ ParsedAttributes(const ParsedAttributes &) = delete;
+
+ AttributePool &getPool() const { return pool; }
+
void takeAllFrom(ParsedAttributes &attrs) {
- addAll(attrs.list);
- attrs.list = nullptr;
+ addAll(attrs.begin(), attrs.end());
+ attrs.clearListOnly();
pool.takeAllFrom(attrs.pool);
}
- void clear() { list = nullptr; pool.clear(); }
- AttributeList *getList() const { return list; }
-
- void clearListOnly() { list = nullptr; }
-
- /// Returns a reference to the attribute list. Try not to introduce
- /// dependencies on this method, it may not be long-lived.
- AttributeList *&getListRef() { return list; }
+ void clear() {
+ clearListOnly();
+ pool.clear();
+ }
/// Add attribute with expression arguments.
AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
@@ -820,7 +837,7 @@ public:
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
syntax, ellipsisLoc);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -839,7 +856,7 @@ public:
pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
deprecated, obsoleted, unavailable, MessageExpr, syntax,
strict, ReplacementExpr);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -853,7 +870,7 @@ public:
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -869,7 +886,7 @@ public:
scopeName, scopeLoc,
argumentKind, matchingCType,
layoutCompatible, mustBeNull, syntax);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -881,7 +898,7 @@ public:
AttributeList *attr =
pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
typeArg, syntaxUsed);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -894,13 +911,12 @@ public:
AttributeList *attr =
pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed);
- add(attr);
+ addAtStart(attr);
return attr;
}
private:
mutable AttributePool pool;
- AttributeList *list = nullptr;
};
/// These constants match the enumerated choices of
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 9c72afb058..77e90a964f 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -739,8 +739,8 @@ public:
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
/// \endcode
///
- void addAttributes(AttributeList *AL) {
- Attrs.addAll(AL);
+ void addAttributes(ParsedAttributesView &AL) {
+ Attrs.addAll(AL.begin(), AL.end());
}
bool hasAttributes() const { return !Attrs.empty(); }
@@ -1147,11 +1147,9 @@ struct DeclaratorChunk {
return SourceRange(Loc, EndLoc);
}
- struct TypeInfoCommon {
- AttributeList *AttrList;
- };
+ ParsedAttributesView AttrList;
- struct PointerTypeInfo : TypeInfoCommon {
+ struct PointerTypeInfo {
/// The type qualifiers: const/volatile/restrict/unaligned/atomic.
unsigned TypeQuals : 5;
@@ -1174,7 +1172,7 @@ struct DeclaratorChunk {
}
};
- struct ReferenceTypeInfo : TypeInfoCommon {
+ struct ReferenceTypeInfo {
/// The type qualifier: restrict. [GNU] C++ extension
bool HasRestrict : 1;
/// True if this is an lvalue reference, false if it's an rvalue reference.
@@ -1183,7 +1181,7 @@ struct DeclaratorChunk {
}
};
- struct ArrayTypeInfo : TypeInfoCommon {
+ struct ArrayTypeInfo {
/// The type qualifiers for the array:
/// const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
@@ -1234,7 +1232,7 @@ struct DeclaratorChunk {
SourceRange Range;
};
- struct FunctionTypeInfo : TypeInfoCommon {
+ struct FunctionTypeInfo {
/// hasPrototype - This is true if the function had at least one typed
/// parameter. If the function is () or (a,b,c), then it has no prototype,
/// and is treated as a K&R-style function.
@@ -1463,7 +1461,7 @@ struct DeclaratorChunk {
ParsedType getTrailingReturnType() const { return TrailingReturnType; }
};
- struct BlockPointerTypeInfo : TypeInfoCommon {
+ struct BlockPointerTypeInfo {
/// For now, sema will catch these as invalid.
/// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
@@ -1472,7 +1470,7 @@ struct DeclaratorChunk {
}
};
- struct MemberPointerTypeInfo : TypeInfoCommon {
+ struct MemberPointerTypeInfo {
/// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
// CXXScopeSpec has a constructor, so it can't be a direct member.
@@ -1489,15 +1487,14 @@ struct DeclaratorChunk {
}
};
- struct PipeTypeInfo : TypeInfoCommon {
- /// The access writes.
- unsigned AccessWrites : 3;
+ struct PipeTypeInfo {
+ /// The access writes.
+ unsigned AccessWrites : 3;
- void destroy() {}
+ void destroy() {}
};
union {
- TypeInfoCommon Common;
PointerTypeInfo Ptr;
ReferenceTypeInfo Ref;
ArrayTypeInfo Arr;
@@ -1522,13 +1519,8 @@ struct DeclaratorChunk {
/// If there are attributes applied to this declaratorchunk, return
/// them.
- const AttributeList *getAttrs() const {
- return Common.AttrList;
- }
-
- AttributeList *&getAttrListRef() {
- return Common.AttrList;
- }
+ const ParsedAttributesView &getAttrs() const { return AttrList; }
+ ParsedAttributesView &getAttrs() { return AttrList; }
/// Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
@@ -1546,7 +1538,6 @@ struct DeclaratorChunk {
I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding();
I.Ptr.UnalignedQualLoc = UnalignedQualLoc.getRawEncoding();
- I.Ptr.AttrList = nullptr;
return I;
}
@@ -1558,7 +1549,6 @@ struct DeclaratorChunk {
I.Loc = Loc;
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
I.Ref.LValueRef = lvalue;
- I.Ref.AttrList = nullptr;
return I;
}
@@ -1570,7 +1560,6 @@ struct DeclaratorChunk {
I.Kind = Array;
I.Loc = LBLoc;
I.EndLoc = RBLoc;
- I.Arr.AttrList = nullptr;
I.Arr.TypeQuals = TypeQuals;
I.Arr.hasStatic = isStatic;
I.Arr.isStar = isStar;
@@ -1614,7 +1603,6 @@ struct DeclaratorChunk {
I.Kind = BlockPointer;
I.Loc = Loc;
I.Cls.TypeQuals = TypeQuals;
- I.Cls.AttrList = nullptr;
return I;
}
@@ -1625,7 +1613,6 @@ struct DeclaratorChunk {
I.Kind = Pipe;
I.Loc = Loc;
I.Cls.TypeQuals = TypeQuals;
- I.Cls.AttrList = nullptr;
return I;
}
@@ -1637,7 +1624,6 @@ struct DeclaratorChunk {
I.Loc = SS.getBeginLoc();
I.EndLoc = Loc;
I.Mem.TypeQuals = TypeQuals;
- I.Mem.AttrList = nullptr;
new (I.Mem.ScopeMem) CXXScopeSpec(SS);
return I;
}
@@ -1649,7 +1635,6 @@ struct DeclaratorChunk {
I.Kind = Paren;
I.Loc = LParenLoc;
I.EndLoc = RParenLoc;
- I.Common.AttrList = nullptr;
return I;
}
@@ -2144,17 +2129,27 @@ public:
/// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
/// EndLoc, which should be the last token of the chunk.
- void AddTypeInfo(const DeclaratorChunk &TI,
- ParsedAttributes &attrs,
+ /// This function takes attrs by R-Value reference because it takes ownership
+ /// of those attributes from the parameter.
+ void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs,
SourceLocation EndLoc) {
DeclTypeInfo.push_back(TI);
- DeclTypeInfo.back().getAttrListRef() = attrs.getList();
+ DeclTypeInfo.back().getAttrs().addAll(attrs.begin(), attrs.end());
getAttributePool().takeAllFrom(attrs.getPool());
if (!EndLoc.isInvalid())
SetRangeEnd(EndLoc);
}
+ /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
+ /// EndLoc, which should be the last token of the chunk.
+ void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) {
+ DeclTypeInfo.push_back(TI);
+
+ if (!EndLoc.isInvalid())
+ SetRangeEnd(EndLoc);
+ }
+
/// Add a new innermost chunk to this declarator.
void AddInnermostTypeInfo(const DeclaratorChunk &TI) {
DeclTypeInfo.insert(DeclTypeInfo.begin(), TI);
@@ -2395,16 +2390,15 @@ public:
SetRangeEnd(lastLoc);
}
- const AttributeList *getAttributes() const { return Attrs.getList(); }
- AttributeList *getAttributes() { return Attrs.getList(); }
-
- AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
+ const ParsedAttributes &getAttributes() const { return Attrs; }
+ ParsedAttributes &getAttributes() { return Attrs; }
/// hasAttributes - do we contain any attributes?
bool hasAttributes() const {
- if (getAttributes() || getDeclSpec().hasAttributes()) return true;
+ if (!getAttributes().empty() || getDeclSpec().hasAttributes())
+ return true;
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
- if (getTypeObject(i).getAttrs())
+ if (!getTypeObject(i).getAttrs().empty())
return true;
return false;
}
@@ -2412,12 +2406,9 @@ public:
/// Return a source range list of C++11 attributes associated
/// with the declarator.
void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
- AttributeList *AttrList = Attrs.getList();
- while (AttrList) {
- if (AttrList->isCXX11Attribute())
- Ranges.push_back(AttrList->getRange());
- AttrList = AttrList->getNext();
- }
+ for (const AttributeList &AL : Attrs)
+ if (AL.isCXX11Attribute())
+ Ranges.push_back(AL.getRange());
}
void setAsmLabel(Expr *E) { AsmLabel = E; }
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index c5f62bd400..12a38677e4 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2048,8 +2048,7 @@ public:
SourceLocation RParenLoc);
/// Handle a C++11 empty-declaration and attribute-declaration.
- Decl *ActOnEmptyDeclaration(Scope *S,
- AttributeList *AttrList,
+ Decl *ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList,
SourceLocation SemiLoc);
enum class ModuleDeclKind {
@@ -2187,7 +2186,7 @@ public:
Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr,
+ SourceLocation NameLoc, const ParsedAttributesView &Attr,
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl,
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
@@ -2197,9 +2196,9 @@ public:
Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const ParsedAttributesView &Attr,
MultiTemplateParamsArg TempParamLists);
TypeResult ActOnDependentTag(Scope *S,
@@ -2221,11 +2220,11 @@ public:
InClassInitStyle InitStyle,
AccessSpecifier AS);
MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD,
- SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
+ SourceLocation DeclStart, Declarator &D,
+ Expr *BitfieldWidth,
InClassInitStyle InitStyle,
AccessSpecifier AS,
- AttributeList *MSPropertyAttr);
+ const AttributeList &MSPropertyAttr);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
@@ -2258,10 +2257,9 @@ public:
tok::ObjCKeywordKind visibility);
// This is used for both record definitions and ObjC interface declarations.
- void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl,
- ArrayRef<Decl *> Fields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList);
+ void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl,
+ ArrayRef<Decl *> Fields, SourceLocation LBrac,
+ SourceLocation RBrac, const ParsedAttributesView &AttrList);
/// ActOnTagStartDefinition - Invoked when we have entered the
/// scope of a tag's definition (e.g., for an enumeration, class,
@@ -2326,12 +2324,11 @@ public:
Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
- AttributeList *Attrs, SourceLocation EqualLoc,
- Expr *Val);
+ const ParsedAttributesView &Attrs,
+ SourceLocation EqualLoc, Expr *Val);
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
- Decl *EnumDecl,
- ArrayRef<Decl *> Elements,
- Scope *S, AttributeList *Attr);
+ Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S,
+ const ParsedAttributesView &Attr);
DeclContext *getContainingDC(DeclContext *DC);
@@ -3322,11 +3319,13 @@ public:
// Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
// Helper for delayed processing of attributes.
- void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList);
- void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
+ void ProcessDeclAttributeDelayed(Decl *D,
+ const ParsedAttributesView &AttrList);
+ void ProcessDeclAttributeList(Scope *S, Decl *D,
+ const ParsedAttributesView &AL,
bool IncludeCXX11Attributes = true);
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
- const AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void checkUnusedDeclAttributes(Declarator &D);
@@ -3392,7 +3391,8 @@ public:
bool allowArrayTypes);
/// Stmt attributes - this routine is the top level dispatcher.
- StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
+ StmtResult ProcessStmtAttributes(Stmt *Stmt,
+ const ParsedAttributesView &Attrs,
SourceRange Range);
void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
@@ -4548,11 +4548,10 @@ public:
// Act on C++ namespaces
Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc,
SourceLocation NamespaceLoc,
- SourceLocation IdentLoc,
- IdentifierInfo *Ident,
+ SourceLocation IdentLoc, IdentifierInfo *Ident,
SourceLocation LBrace,
- AttributeList *AttrList,
- UsingDirectiveDecl * &UsingDecl);
+ const ParsedAttributesView &AttrList,
+ UsingDirectiveDecl *&UsingDecl);
void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
NamespaceDecl *getStdNamespace() const;
@@ -4593,13 +4592,11 @@ public:
/// defined in [dcl.init.list]p2.
bool isInitListConstructor(const FunctionDecl *Ctor);
- Decl *ActOnUsingDirective(Scope *CurScope,
- SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- CXXScopeSpec &SS,
+ Decl *ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc,
+ SourceLocation NamespcLoc, CXXScopeSpec &SS,
SourceLocation IdentLoc,
IdentifierInfo *NamespcName,
- AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
@@ -4630,15 +4627,11 @@ public:
const DeclarationNameInfo &NameInfo,
SourceLocation NameLoc);
- NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
- SourceLocation UsingLoc,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
- DeclarationNameInfo NameInfo,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList,
- bool IsInstantiation);
+ NamedDecl *BuildUsingDeclaration(
+ Scope *S, AccessSpecifier AS, SourceLocation UsingLoc,
+ bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS,
+ DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc,
+ const ParsedAttributesView &AttrList, bool IsInstantiation);
NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> Expansions);
@@ -4651,22 +4644,16 @@ public:
findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor,
ConstructorUsingShadowDecl *DerivedShadow);
- Decl *ActOnUsingDeclaration(Scope *CurScope,
- AccessSpecifier AS,
+ Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS,
SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList);
- Decl *ActOnAliasDeclaration(Scope *CurScope,
- AccessSpecifier AS,
+ SourceLocation TypenameLoc, CXXScopeSpec &SS,
+ UnqualifiedId &Name, SourceLocation EllipsisLoc,
+ const ParsedAttributesView &AttrList);
+ Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParams,
- SourceLocation UsingLoc,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- TypeResult Type,
- Decl *DeclFromDeclSpec);
+ SourceLocation UsingLoc, UnqualifiedId &Name,
+ const ParsedAttributesView &AttrList,
+ TypeResult Type, Decl *DeclFromDeclSpec);
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
@@ -5727,10 +5714,9 @@ public:
const CXXScopeSpec *SS = nullptr);
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
- bool ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc,
+ bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc,
SourceLocation ColonLoc,
- AttributeList *Attrs = nullptr);
+ const ParsedAttributesView &Attrs);
NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
@@ -5869,11 +5855,10 @@ public:
/// conditions that are needed for the attribute to have an effect.
void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD);
- void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- Decl *TagDecl,
- SourceLocation LBrac,
+ void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc,
+ Decl *TagDecl, SourceLocation LBrac,
SourceLocation RBrac,
- AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void ActOnFinishCXXMemberDecls();
void ActOnFinishCXXNonNestedClass(Decl *D);
@@ -6207,17 +6192,14 @@ public:
ArrayRef<TemplateParameterList *> ParamLists,
bool IsFriend, bool &IsMemberSpecialization, bool &Invalid);
- DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- TemplateParameterList *TemplateParams,
- AccessSpecifier AS,
- SourceLocation ModulePrivateLoc,
- SourceLocation FriendLoc,
- unsigned NumOuterTemplateParamLists,
- TemplateParameterList **OuterTemplateParamLists,
- SkipBodyInfo *SkipBody = nullptr);
+ DeclResult CheckClassTemplate(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
+ AccessSpecifier AS, SourceLocation ModulePrivateLoc,
+ SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
+ TemplateParameterList **OuterTemplateParamLists,
+ SkipBodyInfo *SkipBody = nullptr);
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType,
@@ -6291,14 +6273,12 @@ public:
const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext,
TemplateTy &Template, bool AllowInjectedClassName = false);
- DeclResult
- ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc,
- SourceLocation ModulePrivateLoc,
- TemplateIdAnnotation &TemplateId,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists,
- SkipBodyInfo *SkipBody = nullptr);
+ DeclResult ActOnClassTemplateSpecialization(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId,
+ const ParsedAttributesView &Attr,
+ MultiTemplateParamsArg TemplateParameterLists,
+ SkipBodyInfo *SkipBody = nullptr);
bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc,
TemplateDecl *PrimaryTemplate,
@@ -6331,30 +6311,19 @@ public:
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
- DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- AttributeList *Attr);
+ DeclResult ActOnExplicitInstantiation(
+ Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc,
+ unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS,
+ TemplateTy Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation RAngleLoc, const ParsedAttributesView &Attr);
- DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr);
+ DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ unsigned TagSpec, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const ParsedAttributesView &Attr);
DeclResult ActOnExplicitInstantiation(Scope *S,
SourceLocation ExternLoc,
@@ -7939,20 +7908,14 @@ public:
SourceLocation rAngleLoc);
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList);
- Decl *ActOnStartClassInterface(Scope *S,
- SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- ArrayRef<ParsedType> SuperTypeArgs,
- SourceRange SuperTypeArgsRange,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
+ Decl *ActOnStartClassInterface(
+ Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList);
void ActOnSuperClassOfClassInterface(Scope *S,
SourceLocation AtInterfaceLoc,
@@ -7980,24 +7943,18 @@ public:
const ObjCList<ObjCProtocolDecl> &PList);
Decl *ActOnStartProtocolInterface(
- SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
- Decl * const *ProtoRefNames, unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
+ SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName,
+ SourceLocation ProtocolLoc, Decl *const *ProtoRefNames,
+ unsigned NumProtoRefs, const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList);
+
+ Decl *ActOnStartCategoryInterface(
+ SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList);
Decl *ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
@@ -8020,9 +7977,10 @@ public:
ArrayRef<ObjCTypeParamList *> TypeParamLists,
unsigned NumElts);
- DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
- ArrayRef<IdentifierLocPair> IdentList,
- AttributeList *attrList);
+ DeclGroupPtrTy
+ ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
+ ArrayRef<IdentifierLocPair> IdentList,
+ const ParsedAttributesView &attrList);
void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
ArrayRef<IdentifierLocPair> ProtocolId,
@@ -8157,22 +8115,21 @@ public:
ObjCDeclSpec DeclSpec;
/// ArgAttrs - Attribute list for this argument.
- AttributeList *ArgAttrs;
+ ParsedAttributesView ArgAttrs;
};
Decl *ActOnMethodDeclaration(
- Scope *S,
- SourceLocation BeginLoc, // location of the + or -.
- SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType,
- ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
- ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
- // optional arguments. The number of types/arguments is obtained
- // from the Sel.getNumArgs().
- ObjCArgInfo *ArgInfo,
- DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
- AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
- bool isVariadic, bool MethodDefinition);
+ Scope *S,
+ SourceLocation BeginLoc, // location of the + or -.
+ SourceLocation EndLoc, // location of the ; or {.
+ tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
+ ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
+ // optional arguments. The number of types/arguments is obtained
+ // from the Sel.getNumArgs().
+ ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
+ unsigned CNumArgs, // c-style args
+ const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
+ bool isVariadic, bool MethodDefinition);
ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
const ObjCObjectPointerType *OPT,
@@ -10093,7 +10050,7 @@ public:
/// will get it wrong. Returns CFT_Host if D is null.
CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D,
bool IgnoreImplicitHDAttr = false);
- CUDAFunctionTarget IdentifyCUDATarget(const AttributeList *Attr);
+ CUDAFunctionTarget IdentifyCUDATarget(const ParsedAttributesView &Attrs);
/// Gets the CUDA target for the current context.
CUDAFunctionTarget CurrentCUDATarget() {
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 77f2dccfed..27d48be0e3 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -22,12 +22,10 @@ using namespace clang;
/// ParseCXXInlineMethodDef - We parsed and verified that the specified
/// Declarator is a well formed C++ inline method definition. Now lex its body
/// and store its tokens for parsing after the C++ class is complete.
-NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
- AttributeList *AccessAttrs,
- ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers& VS,
- SourceLocation PureSpecLoc) {
+NamedDecl *Parser::ParseCXXInlineMethodDef(
+ AccessSpecifier AS, ParsedAttributes &AccessAttrs, ParsingDeclarator &D,
+ const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers &VS,
+ SourceLocation PureSpecLoc) {
assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&
"Current token not a '{', ':', '=', or 'try'!");
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c580d1777d..4b6b2b3336 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -53,7 +53,7 @@ TypeResult Parser::ParseTypeName(SourceRange *Range,
// Parse the common declaration-specifiers piece.
DeclSpec DS(AttrFactory);
if (Attrs)
- DS.addAttributes(Attrs->getList());
+ DS.addAttributes(*Attrs);
ParseSpecifierQualifierList(DS, AS, DSC);
if (OwnedType)
*OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr;
@@ -422,7 +422,7 @@ unsigned Parser::ParseClangAttributeArgs(
ScopeName, ScopeLoc, Syntax);
break;
}
- return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0;
+ return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0;
}
bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
@@ -560,8 +560,7 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
// If this attribute's args were parsed, and it was expected to have
// arguments but none were provided, emit a diagnostic.
- const AttributeList *Attr = Attrs.getList();
- if (Attr && Attr->getMaxArgs() && !NumArgs) {
+ if (!Attrs.empty() && Attrs.begin()->getMaxArgs() && !NumArgs) {
Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
return false;
}
@@ -1437,9 +1436,8 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
}
- const AttributeList *AL = Attrs.getList();
- if (OnDefinition && AL && !AL->isCXX11Attribute() &&
- AL->isKnownToGCC())
+ if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
+ Attrs.begin()->isKnownToGCC())
Diag(Tok, diag::warn_attribute_on_function_definition)
<< &LA.AttrName;
@@ -1570,29 +1568,27 @@ void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
<< FixItHint::CreateRemoval(AttrRange);
}
-void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs,
- const SourceLocation CorrectLocation) {
+void Parser::DiagnoseProhibitedAttributes(
+ const SourceRange &Range, const SourceLocation CorrectLocation) {
if (CorrectLocation.isValid()) {
- CharSourceRange AttrRange(attrs.Range, true);
+ CharSourceRange AttrRange(Range, true);
Diag(CorrectLocation, diag::err_attributes_misplaced)
<< FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
<< FixItHint::CreateRemoval(AttrRange);
} else
- Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << attrs.Range;
+ Diag(Range.getBegin(), diag::err_attributes_not_allowed) << Range;
}
void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
unsigned DiagID) {
- for (AttributeList *Attr = Attrs.getList(); Attr; Attr = Attr->getNext()) {
- if (!Attr->isCXX11Attribute() && !Attr->isC2xAttribute())
+ for (const AttributeList &AL : Attrs) {
+ if (!AL.isCXX11Attribute() && !AL.isC2xAttribute())
continue;
- if (Attr->getKind() == AttributeList::UnknownAttribute)
- Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored)
- << Attr->getName();
+ if (AL.getKind() == AttributeList::UnknownAttribute)
+ Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName();
else {
- Diag(Attr->getLoc(), DiagID)
- << Attr->getName();
- Attr->setInvalid();
+ Diag(AL.getLoc(), DiagID) << AL.getName();
+ AL.setInvalid();
}
}
}
@@ -1610,47 +1606,19 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
if (TUK == Sema::TUK_Reference)
return;
- ParsedAttributes &PA = DS.getAttributes();
- AttributeList *AL = PA.getList();
- AttributeList *Prev = nullptr;
- AttributeList *TypeAttrHead = nullptr;
- AttributeList *TypeAttrTail = nullptr;
- while (AL) {
- AttributeList *Next = AL->getNext();
-
- if ((AL->getKind() == AttributeList::AT_Aligned &&
- AL->isDeclspecAttribute()) ||
- AL->isMicrosoftAttribute()) {
- // Stitch the attribute into the tag's attribute list.
- if (TypeAttrTail)
- TypeAttrTail->setNext(AL);
- else
- TypeAttrHead = AL;
- TypeAttrTail = AL;
- TypeAttrTail->setNext(nullptr);
-
- // Remove the attribute from the variable's attribute list.
- if (Prev) {
- // Set the last variable attribute's next attribute to be the attribute
- // after the current one.
- Prev->setNext(Next);
- } else {
- // Removing the head of the list requires us to reset the head to the
- // next attribute.
- PA.set(Next);
- }
- } else {
- Prev = AL;
- }
+ llvm::SmallVector<AttributeList *, 1> ToBeMoved;
- AL = Next;
+ for (AttributeList &AL : DS.getAttributes()) {
+ if ((AL.getKind() == AttributeList::AT_Aligned &&
+ AL.isDeclspecAttribute()) ||
+ AL.isMicrosoftAttribute())
+ ToBeMoved.push_back(&AL);
}
- // Find end of type attributes Attrs and add NewTypeAttributes in the same
- // order they were in originally. (Remember, in AttributeList things earlier
- // in source order are later in the list, since new attributes are added to
- // the front of the list.)
- Attrs.addAllAtEnd(TypeAttrHead);
+ for (AttributeList *AL : ToBeMoved) {
+ DS.getAttributes().remove(AL);
+ Attrs.addAtEnd(AL);
+ }
}
/// ParseDeclaration - Parse a full 'declaration', which consists of
@@ -1682,7 +1650,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
case tok::kw_template:
case tok::kw_export:
ProhibitAttributes(attrs);
- SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
+ SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd, attrs);
break;
case tok::kw_inline:
// Could be the start of an inline namespace. Allowed as an ext in C++03.
@@ -4075,10 +4043,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
// If attributes exist after struct contents, parse them.
MaybeParseGNUAttributes(attrs);
- Actions.ActOnFields(getCurScope(),
- RecordLoc, TagDecl, FieldDecls,
- T.getOpenLocation(), T.getCloseLocation(),
- attrs.getList());
+ Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,
+ T.getOpenLocation(), T.getCloseLocation(), attrs);
StructScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
}
@@ -4389,8 +4355,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
unsigned DiagID;
Decl *TagDecl = Actions.ActOnTag(
getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc,
- attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned,
- IsDependent, ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
+ attrs, AS, DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+ ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
@@ -4531,8 +4497,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
// Install the enumerator constant into EnumDecl.
Decl *EnumConstDecl = Actions.ActOnEnumConstant(
- getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident,
- attrs.getList(), EqualLoc, AssignedVal.get());
+ getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
+ EqualLoc, AssignedVal.get());
EnumAvailabilityDiags.back().done();
EnumConstantDecls.push_back(EnumConstDecl);
@@ -4584,10 +4550,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
- Actions.ActOnEnumBody(StartLoc, T.getRange(),
- EnumDecl, EnumConstantDecls,
- getCurScope(),
- attrs.getList());
+ Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
+ getCurScope(), attrs);
// Now handle enum constant availability diagnostics.
assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
@@ -5382,10 +5346,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Sema will have to catch (syntactically invalid) pointers into global
// scope. It has to catch pointers into namespace scope anyway.
- D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
- DS.getLocEnd()),
- DS.getAttributes(),
- /* Don't replace range end. */SourceLocation());
+ D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
+ SS, DS.getTypeQualifiers(), DS.getLocEnd()),
+ std::move(DS.getAttributes()),
+ /* Don't replace range end. */ SourceLocation());
return;
}
}
@@ -5398,7 +5362,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
D.AddTypeInfo(
DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()),
- DS.getAttributes(), SourceLocation());
+ std::move(DS.getAttributes()), SourceLocation());
}
// Not a pointer, C++ reference, or block.
@@ -5430,20 +5394,16 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
ParseDeclaratorInternal(D, DirectDeclParser);
if (Kind == tok::star)
// Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
- DS.getConstSpecLoc(),
- DS.getVolatileSpecLoc(),
- DS.getRestrictSpecLoc(),
- DS.getAtomicSpecLoc(),
- DS.getUnalignedSpecLoc()),
- DS.getAttributes(),
- SourceLocation());
+ D.AddTypeInfo(DeclaratorChunk::getPointer(
+ DS.getTypeQualifiers(), Loc, DS.getConstSpecLoc(),
+ DS.getVolatileSpecLoc(), DS.getRestrictSpecLoc(),
+ DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()),
+ std::move(DS.getAttributes()), SourceLocation());
else
// Remember that we parsed a Block type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
- Loc),
- DS.getAttributes(),
- SourceLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), Loc),
+ std::move(DS.getAttributes()), SourceLocation());
} else {
// Is a reference
DeclSpec DS(AttrFactory);
@@ -5498,8 +5458,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Remember that we parsed a reference type.
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Kind == tok::amp),
- DS.getAttributes(),
- SourceLocation());
+ std::move(DS.getAttributes()), SourceLocation());
}
}
@@ -6007,9 +5966,9 @@ void Parser::ParseParenDeclarator(Declarator &D) {
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
// Match the ')'.
T.consumeClose();
- D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
- T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getParen(T.getOpenLocation(), T.getCloseLocation()),
+ std::move(attrs), T.getCloseLocation());
D.setGroupingParens(hadGroupingParens);
@@ -6239,28 +6198,19 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
}
// Remember that we parsed a function type, and remember the attributes.
- D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
- IsAmbiguous,
- LParenLoc,
- ParamInfo.data(), ParamInfo.size(),
- EllipsisLoc, RParenLoc,
- DS.getTypeQualifiers(),
- RefQualifierIsLValueRef,
- RefQualifierLoc, ConstQualifierLoc,
- VolatileQualifierLoc,
- RestrictQualifierLoc,
- /*MutableLoc=*/SourceLocation(),
- ESpecType, ESpecRange,
- DynamicExceptions.data(),
- DynamicExceptionRanges.data(),
- DynamicExceptions.size(),
- NoexceptExpr.isUsable() ?
- NoexceptExpr.get() : nullptr,
- ExceptionSpecTokens,
- DeclsInPrototype,
- StartLoc, LocalEndLoc, D,
- TrailingReturnType),
- FnAttrs, EndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
+ ParamInfo.size(), EllipsisLoc, RParenLoc,
+ DS.getTypeQualifiers(), RefQualifierIsLValueRef,
+ RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc,
+ RestrictQualifierLoc,
+ /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange,
+ DynamicExceptions.data(), DynamicExceptionRanges.data(),
+ DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
+ ExceptionSpecTokens, DeclsInPrototype, StartLoc,
+ LocalEndLoc, D, TrailingReturnType),
+ std::move(FnAttrs), EndLoc);
}
/// ParseRefQualifier - Parses a member function ref-qualifier. Returns
@@ -6582,7 +6532,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, nullptr,
T.getOpenLocation(),
T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ std::move(attrs), T.getCloseLocation());
return;
} else if (Tok.getKind() == tok::numeric_constant &&
GetLookAheadToken(1).is(tok::r_square)) {
@@ -6595,11 +6545,10 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
MaybeParseCXX11Attributes(attrs);
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
- ExprRes.get(),
+ D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, ExprRes.get(),
T.getOpenLocation(),
T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ std::move(attrs), T.getCloseLocation());
return;
} else if (Tok.getKind() == tok::code_completion) {
Actions.CodeCompleteBracketDeclarator(getCurScope());
@@ -6672,12 +6621,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
MaybeParseCXX11Attributes(DS.getAttributes());
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
- StaticLoc.isValid(), isStar,
- NumElements.get(),
- T.getOpenLocation(),
- T.getCloseLocation()),
- DS.getAttributes(), T.getCloseLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getArray(DS.getTypeQualifiers(), StaticLoc.isValid(),
+ isStar, NumElements.get(), T.getOpenLocation(),
+ T.getCloseLocation()),
+ std::move(DS.getAttributes()), T.getCloseLocation());
}
/// Diagnose brackets before an identifier.
@@ -6729,18 +6677,15 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
if (NeedParens) {
// Create a DeclaratorChunk for the inserted parens.
- ParsedAttributes attrs(AttrFactory);
SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
- D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), attrs,
+ D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc),
SourceLocation());
}
// Adding back the bracket info to the end of the Declarator.
for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
- ParsedAttributes attrs(AttrFactory);
- attrs.set(Chunk.Common.AttrList);
- D.AddTypeInfo(Chunk, attrs, SourceLocation());
+ D.AddTypeInfo(Chunk, SourceLocation());
}
// The missing identifier would have been diagnosed in ParseDirectDeclarator.
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index a969a0f849..166f7a8d23 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -183,10 +183,9 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
ParseScope NamespaceScope(this, Scope::DeclScope);
UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
- Decl *NamespcDecl =
- Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
- IdentLoc, Ident, T.getOpenLocation(),
- attrs.getList(), ImplicitUsingDirectiveDecl);
+ Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+ getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
+ T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl);
PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl,
NamespaceLoc, "parsing namespace");
@@ -233,11 +232,10 @@ void Parser::ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
// desugaring it here.
ParseScope NamespaceScope(this, Scope::DeclScope);
UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
- Decl *NamespcDecl =
- Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
- NamespaceLoc[index], IdentLoc[index],
- Ident[index], Tracker.getOpenLocation(),
- attrs.getList(), ImplicitUsingDirectiveDecl);
+ Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+ getCurScope(), SourceLocation(), NamespaceLoc[index], IdentLoc[index],
+ Ident[index], Tracker.getOpenLocation(), attrs,
+ ImplicitUsingDirectiveDecl);
assert(!ImplicitUsingDirectiveDecl &&
"nested namespace definition cannot define anonymous namespace");
@@ -543,7 +541,7 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
SkipUntil(tok::semi);
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
- IdentLoc, NamespcName, attrs.getList());
+ IdentLoc, NamespcName, attrs);
}
/// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
@@ -711,7 +709,7 @@ Parser::ParseUsingDeclaration(DeclaratorContext Context,
Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,
D.TypenameLoc, D.SS, D.Name,
- D.EllipsisLoc, Attrs.getList());
+ D.EllipsisLoc, Attrs);
if (UD)
DeclsInGroup.push_back(UD);
}
@@ -813,8 +811,8 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
TemplateParams ? TemplateParams->data() : nullptr,
TemplateParams ? TemplateParams->size() : 0);
return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
- UsingLoc, D.Name, Attrs.getList(),
- TypeAlias, DeclFromDeclSpec);
+ UsingLoc, D.Name, Attrs, TypeAlias,
+ DeclFromDeclSpec);
}
/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
@@ -1752,24 +1750,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// This is an explicit instantiation of a class template.
ProhibitAttributes(attrs);
- TagOrTempResult
- = Actions.ActOnExplicitInstantiation(getCurScope(),
- TemplateInfo.ExternLoc,
- TemplateInfo.TemplateLoc,
- TagType,
- StartLoc,
- SS,
- TemplateId->Template,
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->RAngleLoc,
- attrs.getList());
-
- // Friend template-ids are treated as references unless
- // they have template headers, in which case they're ill-formed
- // (FIXME: "template <class T> friend class A<T>::B<int>;").
- // We diagnose this error in ActOnClassTemplateSpecialization.
+ TagOrTempResult = Actions.ActOnExplicitInstantiation(
+ getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+ TagType, StartLoc, SS, TemplateId->Template,
+ TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
+ TemplateId->RAngleLoc, attrs);
+
+ // Friend template-ids are treated as references unless
+ // they have template headers, in which case they're ill-formed
+ // (FIXME: "template <class T> friend class A<T>::B<int>;").
+ // We diagnose this error in ActOnClassTemplateSpecialization.
} else if (TUK == Sema::TUK_Reference ||
(TUK == Sema::TUK_Friend &&
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
@@ -1825,7 +1815,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Build the class template specialization.
TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
- *TemplateId, attrs.getList(),
+ *TemplateId, attrs,
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
: nullptr,
TemplateParams ? TemplateParams->size() : 0),
@@ -1840,24 +1830,18 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
//
ProhibitAttributes(attrs);
- TagOrTempResult
- = Actions.ActOnExplicitInstantiation(getCurScope(),
- TemplateInfo.ExternLoc,
- TemplateInfo.TemplateLoc,
- TagType, StartLoc, SS, Name,
- NameLoc, attrs.getList());
+ TagOrTempResult = Actions.ActOnExplicitInstantiation(
+ getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+ TagType, StartLoc, SS, Name, NameLoc, attrs);
} else if (TUK == Sema::TUK_Friend &&
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
ProhibitAttributes(attrs);
- TagOrTempResult =
- Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
- TagType, StartLoc, SS,
- Name, NameLoc, attrs.getList(),
- MultiTemplateParamsArg(
- TemplateParams? &(*TemplateParams)[0]
- : nullptr,
- TemplateParams? TemplateParams->size() : 0));
+ TagOrTempResult = Actions.ActOnTemplatedFriendTag(
+ getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,
+ NameLoc, attrs,
+ MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
+ TemplateParams ? TemplateParams->size() : 0));
} else {
if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
ProhibitAttributes(attrs);
@@ -1885,9 +1869,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Declaration or definition of a class type
TagOrTempResult = Actions.ActOnTag(
- getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc,
- attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned,
- IsDependent, SourceLocation(), false, clang::TypeResult(),
+ getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,
+ DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+ SourceLocation(), false, clang::TypeResult(),
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
@@ -1929,7 +1913,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
if (!TagOrTempResult.isInvalid())
// Delayed processing of attributes.
- Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList());
+ Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs);
const char *PrevSpec = nullptr;
unsigned DiagID;
@@ -2300,12 +2284,10 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
if (!VS.isUnset()) {
// If we saw any GNU-style attributes that are known to GCC followed by a
// virt-specifier, issue a GCC-compat warning.
- const AttributeList *Attr = DeclaratorInfo.getAttributes();
- while (Attr) {
- if (Attr->isKnownToGCC() && !Attr->isCXX11Attribute())
- Diag(Attr->getLoc(), diag::warn_gcc_attribute_location);
- Attr = Attr->getNext();
- }
+ for (const AttributeList &AL : DeclaratorInfo.getAttributes())
+ if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
+ Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
+
MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
}
}
@@ -2424,7 +2406,7 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
///
Parser::DeclGroupPtrTy
Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
- AttributeList *AccessAttrs,
+ ParsedAttributes &AccessAttrs,
const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject *TemplateDiags) {
if (Tok.is(tok::at)) {
@@ -2492,7 +2474,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
getCurScope(), AS, /*UsingLoc*/ SourceLocation(),
/*TypenameLoc*/ SourceLocation(), SS, Name,
- /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr)));
+ /*EllipsisLoc*/ SourceLocation(),
+ /*AttrList*/ ParsedAttributesView())));
}
}
@@ -2512,7 +2495,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
SourceLocation DeclEnd;
return DeclGroupPtrTy::make(
DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
- DeclaratorContext::MemberContext, DeclEnd, AS, AccessAttrs)));
+ DeclaratorContext::MemberContext, DeclEnd, AccessAttrs, AS)));
}
// Handle: member-declaration ::= '__extension__' member-declaration
@@ -2525,12 +2508,12 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
ParsedAttributesWithRange attrs(AttrFactory);
- ParsedAttributesWithRange FnAttrs(AttrFactory);
+ ParsedAttributesViewWithRange FnAttrs;
// Optional C++11 attribute-specifier
MaybeParseCXX11Attributes(attrs);
// We need to keep these attributes for future diagnostic
// before they are taken over by declaration specifier.
- FnAttrs.addAll(attrs.getList());
+ FnAttrs.addAll(attrs.begin(), attrs.end());
FnAttrs.Range = attrs.Range;
MaybeParseMicrosoftAttributes(attrs);
@@ -2777,7 +2760,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// initialize it.
ThisDecl = VT->getTemplatedDecl();
- if (ThisDecl && AccessAttrs)
+ if (ThisDecl)
Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
}
@@ -3014,7 +2997,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
switch (Tok.getKind()) {
case tok::kw___if_exists:
case tok::kw___if_not_exists:
- ParseMicrosoftIfExistsClassDeclaration(TagType, AS);
+ ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);
return nullptr;
case tok::semi:
@@ -3080,8 +3063,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
}
- if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc,
- AccessAttrs.getList())) {
+ if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) {
// found another attribute than only annotations
AccessAttrs.clear();
}
@@ -3094,7 +3076,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
TagDecl);
default:
- return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
+ return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
}
}
@@ -3282,9 +3264,8 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
if (TagDecl)
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
- T.getOpenLocation(),
- T.getCloseLocation(),
- attrs.getList());
+ T.getOpenLocation(),
+ T.getCloseLocation(), attrs);
// C++11 [class.mem]p2:
// Within the class member-specification, the class is regarded as complete
@@ -3893,25 +3874,26 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
- const AttributeList *Attr = Attrs.getList();
- if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+ if (!Attrs.empty() &&
+ IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+ AttributeList &Attr = *Attrs.begin();
// If the attribute is a standard or built-in attribute and we are
// parsing an argument list, we need to determine whether this attribute
// was allowed to have an argument list (such as [[deprecated]]), and how
// many arguments were parsed (so we can diagnose on [[deprecated()]]).
- if (Attr->getMaxArgs() && !NumArgs) {
+ if (Attr.getMaxArgs() && !NumArgs) {
// The attribute was allowed to have arguments, but none were provided
// even though the attribute parsed successfully. This is an error.
Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
- Attr->setInvalid(true);
- } else if (!Attr->getMaxArgs()) {
+ Attr.setInvalid(true);
+ } else if (!Attr.getMaxArgs()) {
// The attribute parsed successfully, but was not allowed to have any
// arguments. It doesn't matter whether any were provided -- the
// presence of the argument list (even if empty) is diagnosed.
Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
<< AttrName
<< FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
- Attr->setInvalid(true);
+ Attr.setInvalid(true);
}
}
return true;
@@ -4221,8 +4203,9 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
} while (Tok.is(tok::l_square));
}
-void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- AccessSpecifier& CurAS) {
+void Parser::ParseMicrosoftIfExistsClassDeclaration(
+ DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,
+ AccessSpecifier &CurAS) {
IfExistsCondition Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;
@@ -4252,7 +4235,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// __if_exists, __if_not_exists can nest.
if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
- ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
+ ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType,
+ AccessAttrs, CurAS);
continue;
}
@@ -4269,7 +4253,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
SourceLocation ASLoc = Tok.getLocation();
ConsumeToken();
if (Tok.is(tok::colon))
- Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+ Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(),
+ ParsedAttributesView{});
else
Diag(Tok, diag::err_expected) << tok::colon;
ConsumeToken();
@@ -4277,7 +4262,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
}
// Parse all the comma separated declarators.
- ParseCXXClassMemberDeclaration(CurAS, nullptr);
+ ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
}
Braces.consumeClose();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 619fd222fd..d96dc5b362 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2948,33 +2948,31 @@ ExprResult Parser::ParseBlockLiteralExpression() {
ParseBlockId(CaretLoc);
} else {
// Otherwise, pretend we saw (void).
- ParsedAttributes attrs(AttrFactory);
SourceLocation NoLoc;
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true,
- /*IsAmbiguous=*/false,
- /*RParenLoc=*/NoLoc,
- /*ArgInfo=*/nullptr,
- /*NumArgs=*/0,
- /*EllipsisLoc=*/NoLoc,
- /*RParenLoc=*/NoLoc,
- /*TypeQuals=*/0,
- /*RefQualifierIsLvalueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- /*MutableLoc=*/NoLoc,
- EST_None,
- /*ESpecRange=*/SourceRange(),
- /*Exceptions=*/nullptr,
- /*ExceptionRanges=*/nullptr,
- /*NumExceptions=*/0,
- /*NoexceptExpr=*/nullptr,
- /*ExceptionSpecTokens=*/nullptr,
- /*DeclsInPrototype=*/None,
- CaretLoc, CaretLoc,
- ParamInfo),
- attrs, CaretLoc);
+ ParamInfo.AddTypeInfo(
+ DeclaratorChunk::getFunction(/*HasProto=*/true,
+ /*IsAmbiguous=*/false,
+ /*RParenLoc=*/NoLoc,
+ /*ArgInfo=*/nullptr,
+ /*NumArgs=*/0,
+ /*EllipsisLoc=*/NoLoc,
+ /*RParenLoc=*/NoLoc,
+ /*TypeQuals=*/0,
+ /*RefQualifierIsLvalueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc,
+ /*MutableLoc=*/NoLoc, EST_None,
+ /*ESpecRange=*/SourceRange(),
+ /*Exceptions=*/nullptr,
+ /*ExceptionRanges=*/nullptr,
+ /*NumExceptions=*/0,
+ /*NoexceptExpr=*/nullptr,
+ /*ExceptionSpecTokens=*/nullptr,
+ /*DeclsInPrototype=*/None, CaretLoc,
+ CaretLoc, ParamInfo),
+ CaretLoc);
MaybeParseGNUAttributes(ParamInfo);
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 77f758b159..e23581d203 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1109,12 +1109,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// after '(...)'. nvcc doesn't accept this.
auto WarnIfHasCUDATargetAttr = [&] {
if (getLangOpts().CUDA)
- for (auto *A = Attr.getList(); A != nullptr; A = A->getNext())
- if (A->getKind() == AttributeList::AT_CUDADevice ||
- A->getKind() == AttributeList::AT_CUDAHost ||
- A->getKind() == AttributeList::AT_CUDAGlobal)
- Diag(A->getLoc(), diag::warn_cuda_attr_lambda_position)
- << A->getName()->getName();
+ for (const AttributeList &A : Attr)
+ if (A.getKind() == AttributeList::AT_CUDADevice ||
+ A.getKind() == AttributeList::AT_CUDAHost ||
+ A.getKind() == AttributeList::AT_CUDAGlobal)
+ Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
+ << A.getName()->getName();
};
TypeResult TrailingReturnType;
@@ -1197,29 +1197,23 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
WarnIfHasCUDATargetAttr();
SourceLocation NoLoc;
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
- /*isAmbiguous=*/false,
- LParenLoc,
- ParamInfo.data(), ParamInfo.size(),
- EllipsisLoc, RParenLoc,
- DS.getTypeQualifiers(),
- /*RefQualifierIsLValueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- MutableLoc,
- ESpecType, ESpecRange,
- DynamicExceptions.data(),
- DynamicExceptionRanges.data(),
- DynamicExceptions.size(),
- NoexceptExpr.isUsable() ?
- NoexceptExpr.get() : nullptr,
- /*ExceptionSpecTokens*/nullptr,
- /*DeclsInPrototype=*/None,
- LParenLoc, FunLocalRangeEnd, D,
- TrailingReturnType),
- Attr, DeclEndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ /*hasProto=*/true,
+ /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(),
+ ParamInfo.size(), EllipsisLoc, RParenLoc,
+ DS.getTypeQualifiers(),
+ /*RefQualifierIsLValueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType,
+ ESpecRange, DynamicExceptions.data(),
+ DynamicExceptionRanges.data(), DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
+ /*ExceptionSpecTokens*/ nullptr,
+ /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D,
+ TrailingReturnType),
+ std::move(Attr), DeclEndLoc);
} else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,
tok::kw_constexpr) ||
(Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
@@ -1266,31 +1260,29 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
WarnIfHasCUDATargetAttr();
SourceLocation NoLoc;
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
- /*isAmbiguous=*/false,
- /*LParenLoc=*/NoLoc,
- /*Params=*/nullptr,
- /*NumParams=*/0,
- /*EllipsisLoc=*/NoLoc,
- /*RParenLoc=*/NoLoc,
- /*TypeQuals=*/0,
- /*RefQualifierIsLValueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- MutableLoc,
- EST_None,
- /*ESpecRange=*/SourceRange(),
- /*Exceptions=*/nullptr,
- /*ExceptionRanges=*/nullptr,
- /*NumExceptions=*/0,
- /*NoexceptExpr=*/nullptr,
- /*ExceptionSpecTokens=*/nullptr,
- /*DeclsInPrototype=*/None,
- DeclLoc, DeclEndLoc, D,
- TrailingReturnType),
- Attr, DeclEndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ /*hasProto=*/true,
+ /*isAmbiguous=*/false,
+ /*LParenLoc=*/NoLoc,
+ /*Params=*/nullptr,
+ /*NumParams=*/0,
+ /*EllipsisLoc=*/NoLoc,
+ /*RParenLoc=*/NoLoc,
+ /*TypeQuals=*/0,
+ /*RefQualifierIsLValueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None,
+ /*ESpecRange=*/SourceRange(),
+ /*Exceptions=*/nullptr,
+ /*ExceptionRanges=*/nullptr,
+ /*NumExceptions=*/0,
+ /*NoexceptExpr=*/nullptr,
+ /*ExceptionSpecTokens=*/nullptr,
+ /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D,
+ TrailingReturnType),
+ std::move(Attr), DeclEndLoc);
}
// FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
@@ -2889,10 +2881,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
D.AddTypeInfo(DeclaratorChunk::getArray(0,
/*static=*/false, /*star=*/false,
- Size.get(),
- T.getOpenLocation(),
+ Size.get(), T.getOpenLocation(),
T.getCloseLocation()),
- Attrs, T.getCloseLocation());
+ std::move(Attrs), T.getCloseLocation());
if (T.getCloseLocation().isInvalid())
return;
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 81b930a228..447eb9610b 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -287,7 +287,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
Decl *CategoryType = Actions.ActOnStartCategoryInterface(
AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
- EndProtoLoc, attrs.getList());
+ EndProtoLoc, attrs);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
@@ -353,17 +353,12 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
if (Tok.isNot(tok::less))
Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
superClassId, superClassLoc);
-
- Decl *ClsType =
- Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc,
- typeParameterList, superClassId,
- superClassLoc,
- typeArgs,
- SourceRange(typeArgsLAngleLoc,
- typeArgsRAngleLoc),
- protocols.data(), protocols.size(),
- protocolLocs.data(),
- EndProtoLoc, attrs.getList());
+
+ Decl *ClsType = Actions.ActOnStartClassInterface(
+ getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
+ superClassLoc, typeArgs,
+ SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
+ protocols.size(), protocolLocs.data(), EndProtoLoc, attrs);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
@@ -389,15 +384,13 @@ static void addContextSensitiveTypeNullability(Parser &P,
if (D.getNumTypeObjects() > 0) {
// Add the attribute to the declarator chunk nearest the declarator.
- auto nullabilityAttr = getNullabilityAttr(D.getAttributePool());
- DeclaratorChunk &chunk = D.getTypeObject(0);
- nullabilityAttr->setNext(chunk.getAttrListRef());
- chunk.getAttrListRef() = nullabilityAttr;
+ D.getTypeObject(0).getAttrs().addAtStart(
+ getNullabilityAttr(D.getAttributePool()));
} else if (!addedToDeclSpec) {
// Otherwise, just put it on the declaration specifiers (if one
// isn't there already).
- D.getMutableDeclSpec().addAttributes(
- getNullabilityAttr(D.getDeclSpec().getAttributePool()));
+ D.getMutableDeclSpec().getAttributes().addAtStart(
+ getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool()));
addedToDeclSpec = true;
}
}
@@ -1200,18 +1193,12 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
/// Take all the decl attributes out of the given list and add
/// them to the given attribute set.
-static void takeDeclAttributes(ParsedAttributes &attrs,
- AttributeList *list) {
- while (list) {
- AttributeList *cur = list;
- list = cur->getNext();
-
- if (!cur->isUsedAsTypeAttr()) {
- // Clear out the next pointer. We're really completely
- // destroying the internal invariants of the declarator here,
- // but it doesn't matter because we're done with it.
- cur->setNext(nullptr);
- attrs.add(cur);
+static void takeDeclAttributes(ParsedAttributesView &attrs,
+ ParsedAttributesView &from) {
+ for (auto &AL : llvm::reverse(from)) {
+ if (!AL.isUsedAsTypeAttr()) {
+ from.remove(&AL);
+ attrs.addAtStart(&AL);
}
}
}
@@ -1225,11 +1212,10 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
// Now actually move the attributes over.
- takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList());
+ takeDeclAttributes(attrs, D.getMutableDeclSpec().getAttributes());
takeDeclAttributes(attrs, D.getAttributes());
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
- takeDeclAttributes(attrs,
- const_cast<AttributeList*>(D.getTypeObject(i).getAttrs()));
+ takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs());
}
/// objc-type-name:
@@ -1384,13 +1370,10 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
MaybeParseCXX11Attributes(methodAttrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
- Decl *Result
- = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
- selLoc, Sel, nullptr,
- CParamInfo.data(), CParamInfo.size(),
- methodAttrs.getList(), MethodImplKind,
- false, MethodDefinition);
+ Decl *Result = Actions.ActOnMethodDeclaration(
+ getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
+ selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
+ MethodImplKind, false, MethodDefinition);
PD.complete(Result);
return Result;
}
@@ -1421,7 +1404,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(paramAttrs);
MaybeParseCXX11Attributes(paramAttrs);
- ArgInfo.ArgAttrs = paramAttrs.getList();
+ ArgInfo.ArgAttrs = paramAttrs;
// Code completion for the next piece of the selector.
if (Tok.is(tok::code_completion)) {
@@ -1511,14 +1494,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
&KeyIdents[0]);
- Decl *Result
- = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
- KeyLocs, Sel, &ArgInfos[0],
- CParamInfo.data(), CParamInfo.size(),
- methodAttrs.getList(),
- MethodImplKind, isVariadic, MethodDefinition);
-
+ Decl *Result = Actions.ActOnMethodDeclaration(
+ getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
+ Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
+ MethodImplKind, isVariadic, MethodDefinition);
+
PD.complete(Result);
return Result;
}
@@ -1883,9 +1863,9 @@ void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocatio
Actions.ActOnObjCContainerFinishDefinition();
// Call ActOnFields() even if we don't have any decls. This is useful
// for code rewriting tools that need to be aware of the empty list.
- Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
- AllIvarDecls,
- T.getOpenLocation(), T.getCloseLocation(), nullptr);
+ Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
+ T.getOpenLocation(), T.getCloseLocation(),
+ ParsedAttributesView());
}
/// objc-class-instance-variables:
@@ -2035,8 +2015,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
- return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo,
- attrs.getList());
+ return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
}
CheckNestedObjCContexts(AtLoc);
@@ -2063,8 +2042,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
return nullptr;
- return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs,
- attrs.getList());
+ return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
}
// Last, and definitely not least, parse a protocol declaration.
@@ -2078,12 +2056,9 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
/*consumeLastToken=*/true))
return nullptr;
- Decl *ProtoType =
- Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
- ProtocolRefs.data(),
- ProtocolRefs.size(),
- ProtocolLocs.data(),
- EndProtoLoc, attrs.getList());
+ Decl *ProtoType = Actions.ActOnStartProtocolInterface(
+ AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
+ ProtocolLocs.data(), EndProtoLoc, attrs);
ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
return Actions.ConvertDeclToDeclGroup(ProtoType);
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index afd99b23a8..553b490f48 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1410,26 +1410,26 @@ void Parser::HandlePragmaAttribute() {
return;
}
- if (!Attrs.getList() || Attrs.getList()->isInvalid()) {
+ if (Attrs.empty() || Attrs.begin()->isInvalid()) {
SkipToEnd();
return;
}
// Ensure that we don't have more than one attribute.
- if (Attrs.getList()->getNext()) {
- SourceLocation Loc = Attrs.getList()->getNext()->getLoc();
+ if (Attrs.size() > 1) {
+ SourceLocation Loc = Attrs[1].getLoc();
Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
SkipToEnd();
return;
}
- if (!Attrs.getList()->isSupportedByPragmaAttribute()) {
+ AttributeList &Attribute = *Attrs.begin();
+ if (!Attribute.isSupportedByPragmaAttribute()) {
Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
- << Attrs.getList()->getName();
+ << Attribute.getName();
SkipToEnd();
return;
}
- AttributeList &Attribute = *Attrs.getList();
// Parse the subject-list.
if (!TryConsumeToken(tok::comma)) {
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 8dba6386d0..1127158a05 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -116,7 +116,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
if (Attrs.empty() || Res.isInvalid())
return Res;
- return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
+ return Actions.ProcessStmtAttributes(Res.get(), Attrs, Attrs.Range);
}
namespace {
@@ -610,8 +610,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
Stmts, /*Allowed=*/ACK_StatementsOpenMPNonStandalone, nullptr,
TempAttrs);
if (!TempAttrs.empty() && !SubStmt.isInvalid())
- SubStmt = Actions.ProcessStmtAttributes(
- SubStmt.get(), TempAttrs.getList(), TempAttrs.Range);
+ SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs,
+ TempAttrs.Range);
} else {
Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi;
}
@@ -627,10 +627,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
IdentTok.getLocation());
- if (AttributeList *Attrs = attrs.getList()) {
- Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
- attrs.clear();
- }
+ Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
+ attrs.clear();
return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
SubStmt.get());
@@ -2269,7 +2267,7 @@ bool Parser::ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) {
if (Attrs.empty())
return true;
- if (Attrs.getList()->getKind() != AttributeList::AT_OpenCLUnrollHint)
+ if (Attrs.begin()->getKind() != AttributeList::AT_OpenCLUnrollHint)
return true;
if (!(Tok.is(tok::kw_for) || Tok.is(tok::kw_while) || Tok.is(tok::kw_do))) {
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index f701f4639c..f7a69c482e 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -23,24 +23,19 @@ using namespace clang;
/// Parse a template declaration, explicit instantiation, or
/// explicit specialization.
-Decl *
-Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseDeclarationStartingWithTemplate(
+ DeclaratorContext Context, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
ObjCDeclContextSwitch ObjCDC(*this);
if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
- return ParseExplicitInstantiation(Context,
- SourceLocation(), ConsumeToken(),
- DeclEnd, AS);
+ return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(),
+ DeclEnd, AccessAttrs, AS);
}
- return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS,
- AccessAttrs);
+ return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
+ AS);
}
-
-
/// Parse a template declaration or an explicit specialization.
///
/// Template declarations include one or more template parameter lists
@@ -56,11 +51,9 @@ Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
///
/// explicit-specialization: [ C++ temp.expl.spec]
/// 'template' '<' '>' declaration
-Decl *
-Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseTemplateDeclarationOrSpecialization(
+ DeclaratorContext Context, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&
"Token does not start a template declaration.");
@@ -149,12 +142,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
// Parse the actual template declaration.
- return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(&ParamLists,
- isSpecialization,
- LastParamListWasEmpty),
- ParsingTemplateParams,
- DeclEnd, AS, AccessAttrs);
+ return ParseSingleDeclarationAfterTemplate(
+ Context,
+ ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
+ ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}
/// Parse a single declaration that declares a template,
@@ -167,14 +158,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
/// declaration. Will be AS_none for namespace-scope declarations.
///
/// \returns the new declaration.
-Decl *
-Parser::ParseSingleDeclarationAfterTemplate(
- DeclaratorContext Context,
- const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromTParams,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseSingleDeclarationAfterTemplate(
+ DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
+ ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
"Template information required");
@@ -1342,16 +1329,15 @@ Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
AccessSpecifier AS) {
// This isn't really required here.
ParsingDeclRAIIObject
ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);
- return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(ExternLoc,
- TemplateLoc),
- ParsingTemplateParams,
- DeclEnd, AS);
+ return ParseSingleDeclarationAfterTemplate(
+ Context, ParsedTemplateInfo(ExternLoc, TemplateLoc),
+ ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}
SourceRange Parser::ParsedTemplateInfo::getSourceRange() const {
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index d1c35352ae..7bda21b551 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -698,9 +698,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
return nullptr;
case tok::semi:
// Either a C++11 empty-declaration or attribute-declaration.
- SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
- attrs.getList(),
- Tok.getLocation());
+ SingleDecl =
+ Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation());
ConsumeExtraSemi(OutsideFunction);
break;
case tok::r_brace:
@@ -829,8 +828,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
return Actions.ConvertDeclToDeclGroup(
- ParseExplicitInstantiation(DeclaratorContext::FileContext,
- ExternLoc, TemplateLoc, DeclEnd));
+ ParseExplicitInstantiation(DeclaratorContext::FileContext, ExternLoc,
+ TemplateLoc, DeclEnd, attrs));
}
goto dont_know;
@@ -1090,15 +1089,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Check to make sure that any normal attributes are allowed to be on
// a definition. Late parsed attributes are checked at the end.
if (Tok.isNot(tok::equal)) {
- AttributeList *DtorAttrs = D.getAttributes();
- while (DtorAttrs) {
- if (DtorAttrs->isKnownToGCC() &&
- !DtorAttrs->isCXX11Attribute()) {
- Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition)
- << DtorAttrs->getName();
- }
- DtorAttrs = DtorAttrs->getNext();
- }
+ for (const AttributeList &AL : D.getAttributes())
+ if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
+ Diag(AL.getLoc(), diag::warn_attribute_on_function_definition)
+ << AL.getName();
}
// In delayed template parsing mode, for function template we consume the
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 4cd32b361d..6d5c6a26ef 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -60,56 +60,41 @@ static size_t getFreeListIndexForSize(size_t size) {
void *AttributeFactory::allocate(size_t size) {
// Check for a previously reclaimed attribute.
size_t index = getFreeListIndexForSize(size);
- if (index < FreeLists.size()) {
- if (AttributeList *attr = FreeLists[index]) {
- FreeLists[index] = attr->NextInPool;
- return attr;
- }
+ if (index < FreeLists.size() && !FreeLists[index].empty()) {
+ AttributeList *attr = FreeLists[index].back();
+ FreeLists[index].pop_back();
+ return attr;
}
// Otherwise, allocate something new.
return Alloc.Allocate(size, alignof(AttributeFactory));
}
-void AttributeFactory::reclaimPool(AttributeList *cur) {
- assert(cur && "reclaiming empty pool!");
- do {
- // Read this here, because we're going to overwrite NextInPool
- // when we toss 'cur' into the appropriate queue.
- AttributeList *next = cur->NextInPool;
-
- size_t size = cur->allocated_size();
- size_t freeListIndex = getFreeListIndexForSize(size);
-
- // Expand FreeLists to the appropriate size, if required.
- if (freeListIndex >= FreeLists.size())
- FreeLists.resize(freeListIndex+1);
-
- // Add 'cur' to the appropriate free-list.
- cur->NextInPool = FreeLists[freeListIndex];
- FreeLists[freeListIndex] = cur;
-
- cur = next;
- } while (cur);
-}
+void AttributeFactory::deallocate(AttributeList *Attr) {
+ size_t size = Attr->allocated_size();
+ size_t freeListIndex = getFreeListIndexForSize(size);
-void AttributePool::takePool(AttributeList *pool) {
- assert(pool);
+ // Expand FreeLists to the appropriate size, if required.
+ if (freeListIndex >= FreeLists.size())
+ FreeLists.resize(freeListIndex + 1);
- // Fast path: this pool is empty.
- if (!Head) {
- Head = pool;
- return;
- }
+#if !NDEBUG
+ // In debug mode, zero out the attribute to help find memory overwriting.
+ memset(Attr, 0, size);
+#endif
+
+ // Add 'Attr' to the appropriate free-list.
+ FreeLists[freeListIndex].push_back(Attr);
+}
+
+void AttributeFactory::reclaimPool(AttributePool &cur) {
+ for (AttributeList *AL : cur.Attrs)
+ deallocate(AL);
+}
- // Reverse the pool onto the current head. This optimizes for the
- // pattern of pulling a lot of pools into a single pool.
- do {
- AttributeList *next = pool->NextInPool;
- pool->NextInPool = Head;
- Head = pool;
- pool = next;
- } while (pool);
+void AttributePool::takePool(AttributePool &pool) {
+ Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
+ pool.Attrs.clear();
}
#include "clang/Sema/AttrParsedAttrKinds.inc"
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index fe111a5dde..01c9bad16f 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -186,7 +186,6 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
I.Kind = Function;
I.Loc = LocalRangeBegin;
I.EndLoc = LocalRangeEnd;
- I.Fun.AttrList = nullptr;
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = EllipsisLoc.isValid();
I.Fun.isAmbiguous = isAmbiguous;
@@ -995,15 +994,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
writtenBS.Width = getTypeSpecWidth();
writtenBS.Type = getTypeSpecType();
// Search the list of attributes for the presence of a mode attribute.
- writtenBS.ModeAttr = false;
- AttributeList* attrs = getAttributes().getList();
- while (attrs) {
- if (attrs->getKind() == AttributeList::AT_Mode) {
- writtenBS.ModeAttr = true;
- break;
- }
- attrs = attrs->getNext();
- }
+ writtenBS.ModeAttr = getAttributes().hasAttribute(AttributeList::AT_Mode);
}
/// Finish - This does final analysis of the declspec, rejecting things like
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 64f12f3f5e..cc155b7ff6 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -645,7 +645,7 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
if (PragmaAttributeStack.empty())
return;
for (auto &Entry : PragmaAttributeStack) {
- const AttributeList *Attribute = Entry.Attribute;
+ AttributeList *Attribute = Entry.Attribute;
assert(Attribute && "Expected an attribute");
// Ensure that the attribute can be applied to the given declaration.
@@ -659,9 +659,10 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
if (!Applies)
continue;
Entry.IsUsed = true;
- assert(!Attribute->getNext() && "Expected just one attribute");
PragmaAttributeCurrentTargetDecl = D;
- ProcessDeclAttributeList(S, D, Attribute);
+ ParsedAttributesView Attrs;
+ Attrs.addAtStart(Attribute);
+ ProcessDeclAttributeList(S, D, Attrs);
PragmaAttributeCurrentTargetDecl = nullptr;
}
}
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp
index a44eeb47c1..5b81eb3a43 100644
--- a/lib/Sema/SemaCUDA.cpp
+++ b/lib/Sema/SemaCUDA.cpp
@@ -55,13 +55,14 @@ ExprResult Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
/*IsExecConfig=*/true);
}
-Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const AttributeList *Attr) {
+Sema::CUDAFunctionTarget
+Sema::IdentifyCUDATarget(const ParsedAttributesView &Attrs) {
bool HasHostAttr = false;
bool HasDeviceAttr = false;
bool HasGlobalAttr = false;
bool HasInvalidTargetAttr = false;
- while (Attr) {
- switch(Attr->getKind()){
+ for (const AttributeList &AL : Attrs) {
+ switch (AL.getKind()) {
case AttributeList::AT_CUDAGlobal:
HasGlobalAttr = true;
break;
@@ -77,8 +78,8 @@ Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const AttributeList *Attr) {
default:
break;
}
- Attr = Attr->getNext();
}
+
if (HasInvalidTargetAttr)
return CFT_InvalidTarget;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 13ef46b541..1e63fd3bfe 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4447,10 +4447,9 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS,
TypeSpecType == DeclSpec::TST_interface ||
TypeSpecType == DeclSpec::TST_union ||
TypeSpecType == DeclSpec::TST_enum) {
- for (AttributeList* attrs = DS.getAttributes().getList(); attrs;
- attrs = attrs->getNext())
- Diag(attrs->getLoc(), diag::warn_declspec_attribute_ignored)
- << attrs->getName() << GetDiagnosticTypeSpecifierID(TypeSpecType);
+ for (const AttributeList &AL : DS.getAttributes())
+ Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
+ << AL.getName() << GetDiagnosticTypeSpecifierID(TypeSpecType);
}
}
@@ -6204,29 +6203,21 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) {
llvm_unreachable("Unexpected context");
}
-static bool hasParsedAttr(Scope *S, const AttributeList *AttrList,
- AttributeList::Kind Kind) {
- for (const AttributeList *L = AttrList; L; L = L->getNext())
- if (L->getKind() == Kind)
- return true;
- return false;
-}
-
static bool hasParsedAttr(Scope *S, const Declarator &PD,
AttributeList::Kind Kind) {
// Check decl attributes on the DeclSpec.
- if (hasParsedAttr(S, PD.getDeclSpec().getAttributes().getList(), Kind))
+ if (PD.getDeclSpec().getAttributes().hasAttribute(Kind))
return true;
// Walk the declarator structure, checking decl attributes that were in a type
// position to the decl itself.
for (unsigned I = 0, E = PD.getNumTypeObjects(); I != E; ++I) {
- if (hasParsedAttr(S, PD.getTypeObject(I).getAttrs(), Kind))
+ if (PD.getTypeObject(I).getAttrs().hasAttribute(Kind))
return true;
}
// Finally, check attributes on the decl itself.
- return hasParsedAttr(S, PD.getAttributes(), Kind);
+ return PD.getAttributes().hasAttribute(Kind);
}
/// Adjust the \c DeclContext for a function or variable that might be a
@@ -11340,8 +11331,8 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
D.takeAttributes(Attrs, AttrEnd);
ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
- D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false),
- EmptyAttrs, IdentLoc);
+ D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false),
+ IdentLoc);
Decl *Var = ActOnDeclarator(S, D);
cast<VarDecl>(Var)->setCXXForRangeDecl(true);
FinalizeDeclaration(Var);
@@ -12944,7 +12935,7 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,
// Always attach attributes to the underlying decl.
if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
D = TD->getTemplatedDecl();
- ProcessDeclAttributeList(S, D, Attrs.getList());
+ ProcessDeclAttributeList(S, D, Attrs);
if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D))
if (Method->isStatic())
@@ -13046,18 +13037,16 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
/*ConstQualifierLoc=*/NoLoc,
/*VolatileQualifierLoc=*/NoLoc,
/*RestrictQualifierLoc=*/NoLoc,
- /*MutableLoc=*/NoLoc,
- EST_None,
+ /*MutableLoc=*/NoLoc, EST_None,
/*ESpecRange=*/SourceRange(),
/*Exceptions=*/nullptr,
/*ExceptionRanges=*/nullptr,
/*NumExceptions=*/0,
/*NoexceptExpr=*/nullptr,
/*ExceptionSpecTokens=*/nullptr,
- /*DeclsInPrototype=*/None,
- Loc, Loc, D),
- DS.getAttributes(),
- SourceLocation());
+ /*DeclsInPrototype=*/None, Loc,
+ Loc, D),
+ std::move(DS.getAttributes()), SourceLocation());
D.SetIdentifier(&II, Loc);
// Insert this function into the enclosing block scope.
@@ -13529,13 +13518,12 @@ static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC,
Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr, AccessSpecifier AS,
+ const ParsedAttributesView &Attrs, AccessSpecifier AS,
SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists,
bool &OwnedDecl, bool &IsDependent,
SourceLocation ScopedEnumKWLoc,
- bool ScopedEnumUsesClassTag,
- TypeResult UnderlyingType,
+ bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
SkipBodyInfo *SkipBody) {
// If this is not a definition, it must have a name.
@@ -13574,14 +13562,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
return nullptr;
OwnedDecl = false;
- DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
- SS, Name, NameLoc, Attr,
- TemplateParams, AS,
- ModulePrivateLoc,
- /*FriendLoc*/SourceLocation(),
- TemplateParameterLists.size()-1,
- TemplateParameterLists.data(),
- SkipBody);
+ DeclResult Result = CheckClassTemplate(
+ S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attrs, TemplateParams,
+ AS, ModulePrivateLoc,
+ /*FriendLoc*/ SourceLocation(), TemplateParameterLists.size() - 1,
+ TemplateParameterLists.data(), SkipBody);
return Result.get();
} else {
// The "template<>" header is extraneous.
@@ -14047,7 +14032,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// If this is a use, just return the declaration we found, unless
// we have attributes.
if (TUK == TUK_Reference || TUK == TUK_Friend) {
- if (Attr) {
+ if (!Attrs.empty()) {
// FIXME: Diagnose these attributes. For now, we create a new
// declaration to hold them.
} else if (TUK == TUK_Reference &&
@@ -14407,8 +14392,7 @@ CreateNewDecl:
if (TUK == TUK_Definition)
New->startDefinition();
- if (Attr)
- ProcessDeclAttributeList(S, New, Attr);
+ ProcessDeclAttributeList(S, New, Attrs);
AddPragmaAttributes(S, New);
// If this has an identifier, add it to the scope stack.
@@ -15227,7 +15211,8 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
ArrayRef<Decl *> Fields, SourceLocation LBrac,
- SourceLocation RBrac, AttributeList *Attr) {
+ SourceLocation RBrac,
+ const ParsedAttributesView &Attrs) {
assert(EnclosingDecl && "missing record or interface decl");
// If this is an Objective-C @implementation or category and we have
@@ -15545,8 +15530,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Record->completeDefinition();
// Handle attributes before checking the layout.
- if (Attr)
- ProcessDeclAttributeList(S, Record, Attr);
+ ProcessDeclAttributeList(S, Record, Attrs);
// We may have deferred checking for a deleted destructor. Check now.
if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) {
@@ -15924,7 +15908,7 @@ Sema::SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,
Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
- AttributeList *Attr,
+ const ParsedAttributesView &Attrs,
SourceLocation EqualLoc, Expr *Val) {
EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);
EnumConstantDecl *LastEnumConst =
@@ -15975,7 +15959,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
}
// Process attributes.
- if (Attr) ProcessDeclAttributeList(S, New, Attr);
+ ProcessDeclAttributeList(S, New, Attrs);
AddPragmaAttributes(S, New);
// Register this decl in the current scope stack.
@@ -16167,14 +16151,12 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
}
void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
- Decl *EnumDeclX,
- ArrayRef<Decl *> Elements,
- Scope *S, AttributeList *Attr) {
+ Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S,
+ const ParsedAttributesView &Attrs) {
EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
QualType EnumType = Context.getTypeDeclType(Enum);
- if (Attr)
- ProcessDeclAttributeList(S, Enum, Attr);
+ ProcessDeclAttributeList(S, Enum, Attrs);
if (Enum->isDependentType()) {
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 022d9fe8b8..d352015a51 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5820,8 +5820,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
if (AL.getKind() == AttributeList::UnknownAttribute ||
!AL.existsInTarget(S.Context.getTargetInfo())) {
S.Diag(AL.getLoc(), AL.isDeclspecAttribute()
- ? diag::warn_unhandled_ms_attribute_ignored
- : diag::warn_unknown_attribute_ignored)
+ ? diag::warn_unhandled_ms_attribute_ignored
+ : diag::warn_unknown_attribute_ignored)
<< AL.getName();
return;
}
@@ -5992,8 +5992,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
AL);
break;
case AttributeList::AT_CUDAHost:
- handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D,
- AL);
+ handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D, AL);
break;
case AttributeList::AT_GNUInline:
handleGNUInlineAttr(S, D, AL);
@@ -6095,8 +6094,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleObjCRuntimeName(S, D, AL);
break;
case AttributeList::AT_ObjCRuntimeVisible:
- handleSimpleAttribute<ObjCRuntimeVisibleAttr>(S, D, AL);
- break;
+ handleSimpleAttribute<ObjCRuntimeVisibleAttr>(S, D, AL);
+ break;
case AttributeList::AT_ObjCBoxable:
handleObjCBoxable(S, D, AL);
break;
@@ -6177,12 +6176,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSimpleAttribute<ReturnsTwiceAttr>(S, D, AL);
break;
case AttributeList::AT_NotTailCalled:
- handleSimpleAttributeWithExclusions<NotTailCalledAttr,
- AlwaysInlineAttr>(S, D, AL);
+ handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>(
+ S, D, AL);
break;
case AttributeList::AT_DisableTailCalls:
- handleSimpleAttributeWithExclusions<DisableTailCallsAttr,
- NakedAttr>(S, D, AL);
+ handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D,
+ AL);
break;
case AttributeList::AT_Used:
handleSimpleAttribute<UsedAttr>(S, D, AL);
@@ -6458,18 +6457,21 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
/// attribute list to the specified decl, ignoring any type attributes.
void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
- const AttributeList *AttrList,
+ const ParsedAttributesView &AttrList,
bool IncludeCXX11Attributes) {
- for (const AttributeList* l = AttrList; l; l = l->getNext())
- ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes);
+ if (AttrList.empty())
+ return;
+
+ for (const AttributeList &AL : AttrList)
+ ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes);
// FIXME: We should be able to handle these cases in TableGen.
// GCC accepts
// static int a9 __attribute__((weakref));
// but that looks really pointless. We reject it.
if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
- Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias)
- << cast<NamedDecl>(D);
+ Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
+ << cast<NamedDecl>(D);
D->dropAttr<WeakRefAttr>();
return;
}
@@ -6517,44 +6519,46 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
}
// Helper for delayed processing TransparentUnion attribute.
-void Sema::ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList) {
- for (const AttributeList *AL = AttrList; AL; AL = AL->getNext())
- if (AL->getKind() == AttributeList::AT_TransparentUnion) {
- handleTransparentUnionAttr(*this, D, *AL);
+void Sema::ProcessDeclAttributeDelayed(Decl *D,
+ const ParsedAttributesView &AttrList) {
+ for (const AttributeList &AL : AttrList)
+ if (AL.getKind() == AttributeList::AT_TransparentUnion) {
+ handleTransparentUnionAttr(*this, D, AL);
break;
}
}
// Annotation attributes are the only attributes allowed after an access
// specifier.
-bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
- const AttributeList *AttrList) {
- for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- if (l->getKind() == AttributeList::AT_Annotate) {
- ProcessDeclAttribute(*this, nullptr, ASDecl, *l, l->isCXX11Attribute());
+bool Sema::ProcessAccessDeclAttributeList(
+ AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
+ for (const AttributeList &AL : AttrList) {
+ if (AL.getKind() == AttributeList::AT_Annotate) {
+ ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute());
} else {
- Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
+ Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
return true;
}
}
-
return false;
}
/// checkUnusedDeclAttributes - Check a list of attributes to see if it
/// contains any decl attributes that we should warn about.
-static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
- for ( ; A; A = A->getNext()) {
+static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {
+ for (const AttributeList &AL : A) {
// Only warn if the attribute is an unignored, non-type attribute.
- if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
- if (A->getKind() == AttributeList::IgnoredAttribute) continue;
+ if (AL.isUsedAsTypeAttr() || AL.isInvalid())
+ continue;
+ if (AL.getKind() == AttributeList::IgnoredAttribute)
+ continue;
- if (A->getKind() == AttributeList::UnknownAttribute) {
- S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
- << A->getName() << A->getRange();
+ if (AL.getKind() == AttributeList::UnknownAttribute) {
+ S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
+ << AL.getName() << AL.getRange();
} else {
- S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
- << A->getName() << A->getRange();
+ S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl)
+ << AL.getName() << AL.getRange();
}
}
}
@@ -6563,7 +6567,7 @@ static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
/// used to build a declaration, complain about any decl attributes
/// which might be lying around on it.
void Sema::checkUnusedDeclAttributes(Declarator &D) {
- ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
+ ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes());
::checkUnusedDeclAttributes(*this, D.getAttributes());
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
@@ -6670,20 +6674,19 @@ void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
/// specified in many different places, and we need to find and apply them all.
void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
// Apply decl attributes from the DeclSpec if present.
- if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
- ProcessDeclAttributeList(S, D, Attrs);
+ if (!PD.getDeclSpec().getAttributes().empty())
+ ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes());
// Walk the declarator structure, applying decl attributes that were in a type
// position to the decl itself. This handles cases like:
// int *__attr__(x)** D;
// when X is a decl attribute.
for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
- if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
- ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false);
+ ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(),
+ /*IncludeCXX11Attributes=*/false);
// Finally, apply any attributes on the decl itself.
- if (const AttributeList *Attrs = PD.getAttributes())
- ProcessDeclAttributeList(S, D, Attrs);
+ ProcessDeclAttributeList(S, D, PD.getAttributes());
// Apply additional attributes specified by '#pragma clang attribute'.
AddPragmaAttributes(S, D);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 822d5ef254..6f411ca26d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2300,18 +2300,13 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
// We do not support any C++11 attributes on base-specifiers yet.
// Diagnose any attributes we see.
- if (!Attributes.empty()) {
- for (AttributeList *Attr = Attributes.getList(); Attr;
- Attr = Attr->getNext()) {
- if (Attr->isInvalid() ||
- Attr->getKind() == AttributeList::IgnoredAttribute)
- continue;
- Diag(Attr->getLoc(),
- Attr->getKind() == AttributeList::UnknownAttribute
- ? diag::warn_unknown_attribute_ignored
- : diag::err_base_specifier_attribute)
- << Attr->getName();
- }
+ for (const AttributeList &AL : Attributes) {
+ if (AL.isInvalid() || AL.getKind() == AttributeList::IgnoredAttribute)
+ continue;
+ Diag(AL.getLoc(), AL.getKind() == AttributeList::UnknownAttribute
+ ? diag::warn_unknown_attribute_ignored
+ : diag::err_base_specifier_attribute)
+ << AL.getName();
}
TypeSourceInfo *TInfo = nullptr;
@@ -2691,10 +2686,9 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
//===----------------------------------------------------------------------===//
/// ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
-bool Sema::ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc,
+bool Sema::ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc,
SourceLocation ColonLoc,
- AttributeList *Attrs) {
+ const ParsedAttributesView &Attrs) {
assert(Access != AS_none && "Invalid kind for syntactic access specifier!");
AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
ASLoc, ColonLoc);
@@ -2822,10 +2816,14 @@ static bool InitializationHasSideEffects(const FieldDecl &FD) {
return false;
}
-static AttributeList *getMSPropertyAttr(AttributeList *list) {
- for (AttributeList *it = list; it != nullptr; it = it->getNext())
- if (it->isDeclspecPropertyAttribute())
- return it;
+static const AttributeList *
+getMSPropertyAttr(const ParsedAttributesView &list) {
+ ParsedAttributesView::const_iterator Itr =
+ llvm::find_if(list, [](const AttributeList &AL) {
+ return AL.isDeclspecPropertyAttribute();
+ });
+ if (Itr != list.end())
+ return &*Itr;
return nullptr;
}
@@ -2904,8 +2902,8 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
assert(!DS.isFriendSpecified());
bool isFunc = D.isDeclarationOfFunction();
- AttributeList *MSPropertyAttr =
- getMSPropertyAttr(D.getDeclSpec().getAttributes().getList());
+ const AttributeList *MSPropertyAttr =
+ getMSPropertyAttr(D.getDeclSpec().getAttributes());
if (cast<CXXRecordDecl>(CurContext)->isInterface()) {
// The Microsoft extension __interface only permits public member functions
@@ -3073,7 +3071,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
if (MSPropertyAttr) {
Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D,
- BitWidth, InitStyle, AS, MSPropertyAttr);
+ BitWidth, InitStyle, AS, *MSPropertyAttr);
if (!Member)
return nullptr;
isInstField = false;
@@ -7809,22 +7807,20 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
}
}
-void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- Decl *TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac,
- AttributeList *AttrList) {
+void Sema::ActOnFinishCXXMemberSpecification(
+ Scope *S, SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac,
+ SourceLocation RBrac, const ParsedAttributesView &AttrList) {
if (!TagDecl)
return;
AdjustDeclIfTemplate(TagDecl);
- for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- if (l->getKind() != AttributeList::AT_Visibility)
+ for (const AttributeList &AL : AttrList) {
+ if (AL.getKind() != AttributeList::AT_Visibility)
continue;
- l->setInvalid();
- Diag(l->getLoc(), diag::warn_attribute_after_definition_ignored) <<
- l->getName();
+ AL.setInvalid();
+ Diag(AL.getLoc(), diag::warn_attribute_after_definition_ignored)
+ << AL.getName();
}
ActOnFields(S, RLoc, TagDecl, llvm::makeArrayRef(
@@ -8751,14 +8747,10 @@ static void DiagnoseNamespaceInlineMismatch(Sema &S, SourceLocation KeywordLoc,
/// ActOnStartNamespaceDef - This is called at the start of a namespace
/// definition.
-Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
- SourceLocation InlineLoc,
- SourceLocation NamespaceLoc,
- SourceLocation IdentLoc,
- IdentifierInfo *II,
- SourceLocation LBrace,
- AttributeList *AttrList,
- UsingDirectiveDecl *&UD) {
+Decl *Sema::ActOnStartNamespaceDef(
+ Scope *NamespcScope, SourceLocation InlineLoc, SourceLocation NamespaceLoc,
+ SourceLocation IdentLoc, IdentifierInfo *II, SourceLocation LBrace,
+ const ParsedAttributesView &AttrList, UsingDirectiveDecl *&UD) {
SourceLocation StartLoc = InlineLoc.isValid() ? InlineLoc : NamespaceLoc;
// For anonymous namespace, take the location of the left brace.
SourceLocation Loc = II ? IdentLoc : LBrace;
@@ -9273,13 +9265,11 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc,
return false;
}
-Decl *Sema::ActOnUsingDirective(Scope *S,
- SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *NamespcName,
- AttributeList *AttrList) {
+Decl *Sema::ActOnUsingDirective(Scope *S, SourceLocation UsingLoc,
+ SourceLocation NamespcLoc, CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ IdentifierInfo *NamespcName,
+ const ParsedAttributesView &AttrList) {
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
assert(NamespcName && "Invalid NamespcName.");
assert(IdentLoc.isValid() && "Invalid NamespceName location.");
@@ -9371,15 +9361,12 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
S->PushUsingDirective(UDir);
}
-
-Decl *Sema::ActOnUsingDeclaration(Scope *S,
- AccessSpecifier AS,
+Decl *Sema::ActOnUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
+ SourceLocation TypenameLoc, CXXScopeSpec &SS,
UnqualifiedId &Name,
SourceLocation EllipsisLoc,
- AttributeList *AttrList) {
+ const ParsedAttributesView &AttrList) {
assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
if (SS.isEmpty()) {
@@ -9836,15 +9823,11 @@ private:
/// \param IsInstantiation - Whether this call arises from an
/// instantiation of an unresolved using declaration. We treat
/// the lookup differently for these declarations.
-NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
- SourceLocation UsingLoc,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
- DeclarationNameInfo NameInfo,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList,
- bool IsInstantiation) {
+NamedDecl *Sema::BuildUsingDeclaration(
+ Scope *S, AccessSpecifier AS, SourceLocation UsingLoc,
+ bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS,
+ DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc,
+ const ParsedAttributesView &AttrList, bool IsInstantiation) {
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
SourceLocation IdentLoc = NameInfo.getLoc();
assert(IdentLoc.isValid() && "Invalid TargetName location.");
@@ -10410,14 +10393,11 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
return true;
}
-Decl *Sema::ActOnAliasDeclaration(Scope *S,
- AccessSpecifier AS,
+Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParamLists,
- SourceLocation UsingLoc,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- TypeResult Type,
- Decl *DeclFromDeclSpec) {
+ SourceLocation UsingLoc, UnqualifiedId &Name,
+ const ParsedAttributesView &AttrList,
+ TypeResult Type, Decl *DeclFromDeclSpec) {
// Skip up to the relevant declaration scope.
while (S->isTemplateParamScope())
S = S->getParent();
@@ -13575,13 +13555,12 @@ Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
}
Decl *Sema::ActOnEmptyDeclaration(Scope *S,
- AttributeList *AttrList,
+ const ParsedAttributesView &AttrList,
SourceLocation SemiLoc) {
Decl *ED = EmptyDecl::Create(Context, CurContext, SemiLoc);
// Attribute declarations appertain to empty declaration so we handle
// them here.
- if (AttrList)
- ProcessDeclAttributeList(S, ED, AttrList);
+ ProcessDeclAttributeList(S, ED, AttrList);
CurContext->addDecl(ED);
return ED;
@@ -13920,10 +13899,9 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart,
/// templated.
Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
SourceLocation NameLoc,
- AttributeList *Attr,
+ const ParsedAttributesView &Attr,
MultiTemplateParamsArg TempParamLists) {
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
@@ -14036,7 +14014,6 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
return Friend;
}
-
/// Handle a friend type declaration. This works in tandem with
/// ActOnTag.
///
@@ -15407,11 +15384,11 @@ void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
/// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class.
///
MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
- SourceLocation DeclStart,
- Declarator &D, Expr *BitWidth,
+ SourceLocation DeclStart, Declarator &D,
+ Expr *BitWidth,
InClassInitStyle InitStyle,
AccessSpecifier AS,
- AttributeList *MSPropertyAttr) {
+ const AttributeList &MSPropertyAttr) {
IdentifierInfo *II = D.getIdentifier();
if (!II) {
Diag(DeclStart, diag::err_anonymous_property);
@@ -15474,7 +15451,7 @@ MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
PrevDecl = nullptr;
SourceLocation TSSL = D.getLocStart();
- const AttributeList::PropertyData &Data = MSPropertyAttr->getPropertyData();
+ const AttributeList::PropertyData &Data = MSPropertyAttr.getPropertyData();
MSPropertyDecl *NewPD = MSPropertyDecl::Create(
Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId);
ProcessDeclAttributes(TUScope, NewPD, D);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8c621dfa40..e1b033ea82 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -948,16 +948,14 @@ static bool checkTypeParamListConsistency(Sema &S,
return false;
}
-Decl *Sema::
-ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *SuperName, SourceLocation SuperLoc,
- ArrayRef<ParsedType> SuperTypeArgs,
- SourceRange SuperTypeArgsRange,
- Decl * const *ProtoRefs, unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc, AttributeList *AttrList) {
+Decl *Sema::ActOnStartClassInterface(
+ Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList) {
assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name.
@@ -1042,9 +1040,8 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
IDecl->setInvalidDecl();
}
}
-
- if (AttrList)
- ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+
+ ProcessDeclAttributeList(TUScope, IDecl, AttrList);
AddPragmaAttributes(TUScope, IDecl);
PushOnScopeChains(IDecl, TUScope);
@@ -1183,15 +1180,11 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency(
return res;
}
-Decl *
-Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName,
- SourceLocation ProtocolLoc,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
+Decl *Sema::ActOnStartProtocolInterface(
+ SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName,
+ SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList) {
bool err = false;
// FIXME: Deal with AttrList.
assert(ProtocolName && "Missing protocol identifier");
@@ -1234,9 +1227,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
PushOnScopeChains(PDecl, TUScope);
PDecl->startDefinition();
}
-
- if (AttrList)
- ProcessDeclAttributeList(TUScope, PDecl, AttrList);
+
+ ProcessDeclAttributeList(TUScope, PDecl, AttrList);
AddPragmaAttributes(TUScope, PDecl);
// Merge attributes from previous declarations.
@@ -1567,14 +1559,12 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers(
// add the '*'.
if (type->getAs<ObjCInterfaceType>()) {
SourceLocation starLoc = getLocForEndOfToken(loc);
- ParsedAttributes parsedAttrs(attrFactory);
D.AddTypeInfo(DeclaratorChunk::getPointer(/*typeQuals=*/0, starLoc,
SourceLocation(),
SourceLocation(),
SourceLocation(),
SourceLocation(),
SourceLocation()),
- parsedAttrs,
starLoc);
// Diagnose the missing '*'.
@@ -1752,7 +1742,7 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
Sema::DeclGroupPtrTy
Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
ArrayRef<IdentifierLocPair> IdentList,
- AttributeList *attrList) {
+ const ParsedAttributesView &attrList) {
SmallVector<Decl *, 8> DeclsInGroup;
for (const IdentifierLocPair &IdentPair : IdentList) {
IdentifierInfo *Ident = IdentPair.first;
@@ -1765,9 +1755,8 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
PushOnScopeChains(PDecl, TUScope);
CheckObjCDeclScope(PDecl);
-
- if (attrList)
- ProcessDeclAttributeList(TUScope, PDecl, attrList);
+
+ ProcessDeclAttributeList(TUScope, PDecl, attrList);
AddPragmaAttributes(TUScope, PDecl);
if (PrevDecl)
@@ -1779,17 +1768,13 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
return BuildDeclaratorGroup(DeclsInGroup);
}
-Decl *Sema::
-ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
+Decl *Sema::ActOnStartCategoryInterface(
+ SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList) {
ObjCCategoryDecl *CDecl;
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
@@ -1858,8 +1843,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
// Process the attributes before looking at protocols to ensure that the
// availability attribute is attached to the category to provide availability
// checking for protocol uses.
- if (AttrList)
- ProcessDeclAttributeList(TUScope, CDecl, AttrList);
+ ProcessDeclAttributeList(TUScope, CDecl, AttrList);
AddPragmaAttributes(TUScope, CDecl);
if (NumProtoRefs) {
@@ -4516,17 +4500,14 @@ static void checkObjCMethodX86VectorTypes(Sema &SemaRef,
}
Decl *Sema::ActOnMethodDeclaration(
- Scope *S,
- SourceLocation MethodLoc, SourceLocation EndLoc,
- tok::TokenKind MethodType,
- ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
- ArrayRef<SourceLocation> SelectorLocs,
- Selector Sel,
+ Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc,
+ tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
+ ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
- ObjCArgInfo *ArgInfo,
- DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
- AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
+ ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
+ unsigned CNumArgs, // c-style args
+ const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind,
bool isVariadic, bool MethodDefinition) {
// Make sure we can establish a context for the method.
if (!CurContext->isObjCContainer()) {
@@ -4634,8 +4615,7 @@ Decl *Sema::ActOnMethodDeclaration(
ObjCMethod->setObjCDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
- if (AttrList)
- ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+ ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
AddPragmaAttributes(TUScope, ObjCMethod);
// Add the method now.
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 5e69feceda..9e53beb449 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1170,7 +1170,7 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
Class->setInvalidDecl();
SmallVector<Decl*, 4> Fields(Class->fields());
ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
- SourceLocation(), nullptr);
+ SourceLocation(), ParsedAttributesView());
CheckCompletedCXXClass(Class);
PopFunctionScopeInfo();
@@ -1608,7 +1608,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
// Finalize the lambda class.
SmallVector<Decl*, 4> Fields(Class->fields());
ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
- SourceLocation(), nullptr);
+ SourceLocation(), ParsedAttributesView());
CheckCompletedCXXClass(Class);
}
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index ccf25ee9eb..058a2cd4f2 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -4283,7 +4283,7 @@ void Sema::ActOnCapturedRegionError() {
SmallVector<Decl*, 4> Fields(Record->fields());
ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields,
- SourceLocation(), SourceLocation(), /*AttributeList=*/nullptr);
+ SourceLocation(), SourceLocation(), ParsedAttributesView());
PopDeclContext();
PopFunctionScopeInfo();
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index e55e20c282..dbd967cc93 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -313,11 +313,12 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
}
}
-StmtResult Sema::ProcessStmtAttributes(Stmt *S, AttributeList *AttrList,
+StmtResult Sema::ProcessStmtAttributes(Stmt *S,
+ const ParsedAttributesView &AttrList,
SourceRange Range) {
SmallVector<const Attr*, 8> Attrs;
- for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- if (Attr *a = ProcessStmtAttribute(*this, S, *l, Range))
+ for (const AttributeList &AL : AttrList) {
+ if (Attr *a = ProcessStmtAttribute(*this, S, AL, Range))
Attrs.push_back(a);
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 68a5196f6b..276a617d1a 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1263,17 +1263,13 @@ static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext()));
}
-DeclResult
-Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- TemplateParameterList *TemplateParams,
- AccessSpecifier AS, SourceLocation ModulePrivateLoc,
- SourceLocation FriendLoc,
- unsigned NumOuterTemplateParamLists,
- TemplateParameterList** OuterTemplateParamLists,
- SkipBodyInfo *SkipBody) {
+DeclResult Sema::CheckClassTemplate(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
+ AccessSpecifier AS, SourceLocation ModulePrivateLoc,
+ SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
+ TemplateParameterList **OuterTemplateParamLists, SkipBodyInfo *SkipBody) {
assert(TemplateParams && TemplateParams->size() > 0 &&
"No template parameters");
assert(TUK != TUK_Reference && "Can only declare or define class templates");
@@ -1613,8 +1609,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (TUK == TUK_Definition)
NewClass->startDefinition();
- if (Attr)
- ProcessDeclAttributeList(S, NewClass, Attr);
+ ProcessDeclAttributeList(S, NewClass, Attr);
if (PrevClassTemplate)
mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
@@ -7401,16 +7396,11 @@ bool Sema::CheckTemplatePartialSpecializationArgs(
return false;
}
-DeclResult
-Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
- TagUseKind TUK,
- SourceLocation KWLoc,
- SourceLocation ModulePrivateLoc,
- TemplateIdAnnotation &TemplateId,
- AttributeList *Attr,
- MultiTemplateParamsArg
- TemplateParameterLists,
- SkipBodyInfo *SkipBody) {
+DeclResult Sema::ActOnClassTemplateSpecialization(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId,
+ const ParsedAttributesView &Attr,
+ MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody) {
assert(TUK != TUK_Reference && "References are not specializations");
CXXScopeSpec &SS = TemplateId.SS;
@@ -7711,8 +7701,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
}
}
- if (Attr)
- ProcessDeclAttributeList(S, Specialization, Attr);
+ ProcessDeclAttributeList(S, Specialization, Attr);
// Add alignment attributes if necessary; these attributes are checked when
// the ASTContext lays out the structure.
@@ -8564,19 +8553,12 @@ static void dllExportImportClassTemplateSpecialization(
}
// Explicit instantiation of a class template specialization
-DeclResult
-Sema::ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy TemplateD,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation RAngleLoc,
- AttributeList *Attr) {
+DeclResult Sema::ActOnExplicitInstantiation(
+ Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc,
+ unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS,
+ TemplateTy TemplateD, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation RAngleLoc, const ParsedAttributesView &Attr) {
// Find the class template we're specializing
TemplateName Name = TemplateD.get();
TemplateDecl *TD = Name.getAsTemplateDecl();
@@ -8617,11 +8599,11 @@ Sema::ActOnExplicitInstantiation(Scope *S,
if (TSK == TSK_ExplicitInstantiationDeclaration) {
// Check for dllexport class template instantiation declarations.
- for (AttributeList *A = Attr; A; A = A->getNext()) {
- if (A->getKind() == AttributeList::AT_DLLExport) {
+ for (const AttributeList &AL : Attr) {
+ if (AL.getKind() == AttributeList::AT_DLLExport) {
Diag(ExternLoc,
diag::warn_attribute_dllexport_explicit_instantiation_decl);
- Diag(A->getLoc(), diag::note_attribute);
+ Diag(AL.getLoc(), diag::note_attribute);
break;
}
}
@@ -8641,10 +8623,10 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Check for dllimport class template instantiation definitions.
bool DLLImport =
ClassTemplate->getTemplatedDecl()->getAttr<DLLImportAttr>();
- for (AttributeList *A = Attr; A; A = A->getNext()) {
- if (A->getKind() == AttributeList::AT_DLLImport)
+ for (const AttributeList &AL : Attr) {
+ if (AL.getKind() == AttributeList::AT_DLLImport)
DLLImport = true;
- if (A->getKind() == AttributeList::AT_DLLExport) {
+ if (AL.getKind() == AttributeList::AT_DLLExport) {
// dllexport trumps dllimport here.
DLLImport = false;
break;
@@ -8754,8 +8736,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
Specialization->setBraceRange(SourceRange());
bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
- if (Attr)
- ProcessDeclAttributeList(S, Specialization, Attr);
+ ProcessDeclAttributeList(S, Specialization, Attr);
// Add the explicit instantiation into its lexical context. However,
// since explicit instantiations are never found by name lookup, we
@@ -8853,15 +8834,11 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Explicit instantiation of a member class of a class template.
DeclResult
-Sema::ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr) {
+Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
+ SourceLocation TemplateLoc, unsigned TagSpec,
+ SourceLocation KWLoc, CXXScopeSpec &SS,
+ IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attr) {
bool Owned = false;
bool IsDependent = false;
@@ -9163,8 +9140,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (PrevTemplate) {
// Merge attributes.
- if (AttributeList *Attr = D.getDeclSpec().getAttributes().getList())
- ProcessDeclAttributeList(S, Prev, Attr);
+ ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes());
}
if (TSK == TSK_ExplicitInstantiationDefinition)
InstantiateVariableDefinition(D.getIdentifierLoc(), Prev);
@@ -9200,7 +9176,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// template.
UnresolvedSet<8> TemplateMatches;
FunctionDecl *NonTemplateMatch = nullptr;
- AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc());
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
P != PEnd; ++P) {
@@ -9248,7 +9223,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
if (LangOpts.CUDA &&
IdentifyCUDATarget(Specialization,
/* IgnoreImplicitHDAttributes = */ true) !=
- IdentifyCUDATarget(Attr)) {
+ IdentifyCUDATarget(D.getDeclSpec().getAttributes())) {
FailedCandidates.addCandidate().set(
P.getPair(), FunTmpl->getTemplatedDecl(),
MakeDeductionFailureInfo(Context, TDK_CUDATargetMismatch, Info));
@@ -9327,8 +9302,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return (Decl*) nullptr;
}
- if (Attr)
- ProcessDeclAttributeList(S, Specialization, Attr);
+ ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes());
// In MSVC mode, dllimported explicit instantiation definitions are treated as
// instantiation declarations.
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 2218bdd958..5a4a6bd033 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2125,7 +2125,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Finish checking fields.
ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
- SourceLocation(), SourceLocation(), nullptr);
+ SourceLocation(), SourceLocation(), ParsedAttributesView());
CheckCompletedCXXClass(Instantiation);
// Default arguments are parsed, if not instantiated. We can go instantiate
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 68857d972b..5109dc8290 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1118,8 +1118,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition(
}
SemaRef.ActOnEnumBody(Enum->getLocation(), Enum->getBraceRange(), Enum,
- Enumerators,
- nullptr, nullptr);
+ Enumerators, nullptr, ParsedAttributesView());
}
Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
@@ -2648,7 +2647,8 @@ Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
NamedDecl *UD = SemaRef.BuildUsingDeclaration(
/*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(),
- /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, nullptr,
+ /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc,
+ ParsedAttributesView(),
/*IsInstantiation*/ true);
if (UD)
SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index c7e251d35b..18c5ce75d1 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -195,10 +195,10 @@ namespace {
chunkIndex = idx;
}
- AttributeList *&getCurrentAttrListRef() const {
+ ParsedAttributesView &getCurrentAttributes() const {
if (isProcessingDeclSpec())
- return getMutableDeclSpec().getAttributes().getListRef();
- return declarator.getTypeObject(chunkIndex).getAttrListRef();
+ return getMutableDeclSpec().getAttributes();
+ return declarator.getTypeObject(chunkIndex).getAttrs();
}
/// Save the current set of attributes on the DeclSpec.
@@ -207,9 +207,8 @@ namespace {
if (hasSavedAttrs) return;
DeclSpec &spec = getMutableDeclSpec();
- for (AttributeList *attr = spec.getAttributes().getList(); attr;
- attr = attr->getNext())
- savedAttrs.push_back(attr);
+ for (AttributeList &AL : spec.getAttributes())
+ savedAttrs.push_back(&AL);
trivial &= savedAttrs.empty();
hasSavedAttrs = true;
}
@@ -241,46 +240,18 @@ namespace {
void restoreDeclSpecAttrs() {
assert(hasSavedAttrs);
- if (savedAttrs.empty()) {
- getMutableDeclSpec().getAttributes().set(nullptr);
- return;
- }
-
- getMutableDeclSpec().getAttributes().set(savedAttrs[0]);
- for (unsigned i = 0, e = savedAttrs.size() - 1; i != e; ++i)
- savedAttrs[i]->setNext(savedAttrs[i+1]);
- savedAttrs.back()->setNext(nullptr);
+ getMutableDeclSpec().getAttributes().clearListOnly();
+ for (AttributeList *AL : savedAttrs)
+ getMutableDeclSpec().getAttributes().addAtStart(AL);
}
};
} // end anonymous namespace
-static void spliceAttrIntoList(AttributeList &attr, AttributeList *&head) {
- attr.setNext(head);
- head = &attr;
-}
-
-static void spliceAttrOutOfList(AttributeList &attr, AttributeList *&head) {
- if (head == &attr) {
- head = attr.getNext();
- return;
- }
-
- AttributeList *cur = head;
- while (true) {
- assert(cur && cur->getNext() && "ran out of attrs?");
- if (cur->getNext() == &attr) {
- cur->setNext(attr.getNext());
- return;
- }
- cur = cur->getNext();
- }
-}
-
static void moveAttrFromListToList(AttributeList &attr,
- AttributeList *&fromList,
- AttributeList *&toList) {
- spliceAttrOutOfList(attr, fromList);
- spliceAttrIntoList(attr, toList);
+ ParsedAttributesView &fromList,
+ ParsedAttributesView &toList) {
+ fromList.remove(&attr);
+ toList.addAtStart(&attr);
}
/// The location of a type attribute.
@@ -293,9 +264,8 @@ enum TypeAttrLocation {
TAL_DeclName
};
-static void processTypeAttrs(TypeProcessingState &state,
- QualType &type, TypeAttrLocation TAL,
- AttributeList *attrs);
+static void processTypeAttrs(TypeProcessingState &state, QualType &type,
+ TypeAttrLocation TAL, ParsedAttributesView &attrs);
static bool handleFunctionTypeAttr(TypeProcessingState &state,
AttributeList &attr,
@@ -416,8 +386,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
/*onlyBlockPointers=*/true);
if (!destChunk) destChunk = &chunk;
- moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
- destChunk->getAttrListRef());
+ moveAttrFromListToList(attr, state.getCurrentAttributes(),
+ destChunk->getAttrs());
return;
}
@@ -432,8 +402,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
if (DeclaratorChunk *dest = maybeMovePastReturnType(
declarator, i,
/*onlyBlockPointers=*/true)) {
- moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
- dest->getAttrListRef());
+ moveAttrFromListToList(attr, state.getCurrentAttributes(),
+ dest->getAttrs());
return;
}
}
@@ -493,8 +463,8 @@ distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state,
// attribute from being applied multiple times and gives
// the source-location-filler something to work with.
state.saveDeclSpecAttrs();
- moveAttrFromListToList(attr, declarator.getAttrListRef(),
- declarator.getMutableDeclSpec().getAttributes().getListRef());
+ moveAttrFromListToList(attr, declarator.getAttributes(),
+ declarator.getMutableDeclSpec().getAttributes());
return;
}
}
@@ -502,13 +472,13 @@ distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state,
// Otherwise, if we found an appropriate chunk, splice the attribute
// into it.
if (innermost != -1U) {
- moveAttrFromListToList(attr, declarator.getAttrListRef(),
- declarator.getTypeObject(innermost).getAttrListRef());
+ moveAttrFromListToList(attr, declarator.getAttributes(),
+ declarator.getTypeObject(innermost).getAttrs());
return;
}
// Otherwise, diagnose when we're done building the type.
- spliceAttrOutOfList(attr, declarator.getAttrListRef());
+ declarator.getAttributes().remove(&attr);
state.addIgnoredTypeAttr(attr);
}
@@ -527,8 +497,8 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state,
DeclaratorChunk &chunk = declarator.getTypeObject(i-1);
switch (chunk.Kind) {
case DeclaratorChunk::Function:
- moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
- chunk.getAttrListRef());
+ moveAttrFromListToList(attr, state.getCurrentAttributes(),
+ chunk.getAttrs());
return;
case DeclaratorChunk::Paren:
@@ -548,11 +518,9 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state,
/// Try to distribute a function type attribute to the innermost
/// function chunk or type. Returns true if the attribute was
/// distributed, false if no location was found.
-static bool
-distributeFunctionTypeAttrToInnermost(TypeProcessingState &state,
- AttributeList &attr,
- AttributeList *&attrList,
- QualType &declSpecType) {
+static bool distributeFunctionTypeAttrToInnermost(
+ TypeProcessingState &state, AttributeList &attr,
+ ParsedAttributesView &attrList, QualType &declSpecType) {
Declarator &declarator = state.getDeclarator();
// Put it on the innermost function chunk, if there is one.
@@ -560,7 +528,7 @@ distributeFunctionTypeAttrToInnermost(TypeProcessingState &state,
DeclaratorChunk &chunk = declarator.getTypeObject(i);
if (chunk.Kind != DeclaratorChunk::Function) continue;
- moveAttrFromListToList(attr, attrList, chunk.getAttrListRef());
+ moveAttrFromListToList(attr, attrList, chunk.getAttrs());
return true;
}
@@ -579,15 +547,14 @@ distributeFunctionTypeAttrFromDeclSpec(TypeProcessingState &state,
// the declarators. Move them straight there. We don't support the
// 'put them wherever you like' semantics we allow for GNU attributes.
if (attr.isCXX11Attribute()) {
- moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
- state.getDeclarator().getAttrListRef());
+ moveAttrFromListToList(attr, state.getCurrentAttributes(),
+ state.getDeclarator().getAttributes());
return;
}
// Try to distribute to the innermost.
- if (distributeFunctionTypeAttrToInnermost(state, attr,
- state.getCurrentAttrListRef(),
- declSpecType))
+ if (distributeFunctionTypeAttrToInnermost(
+ state, attr, state.getCurrentAttributes(), declSpecType))
return;
// If that failed, diagnose the bad attribute when the declarator is
@@ -604,14 +571,13 @@ distributeFunctionTypeAttrFromDeclarator(TypeProcessingState &state,
Declarator &declarator = state.getDeclarator();
// Try to distribute to the innermost.
- if (distributeFunctionTypeAttrToInnermost(state, attr,
- declarator.getAttrListRef(),
- declSpecType))
+ if (distributeFunctionTypeAttrToInnermost(
+ state, attr, declarator.getAttributes(), declSpecType))
return;
// If that failed, diagnose the bad attribute when the declarator is
// fully built.
- spliceAttrOutOfList(attr, declarator.getAttrListRef());
+ declarator.getAttributes().remove(&attr);
state.addIgnoredTypeAttr(attr);
}
@@ -627,24 +593,25 @@ distributeFunctionTypeAttrFromDeclarator(TypeProcessingState &state,
static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
QualType &declSpecType) {
// Collect all the type attributes from the declarator itself.
- assert(state.getDeclarator().getAttributes() && "declarator has no attrs!");
- AttributeList *attr = state.getDeclarator().getAttributes();
- AttributeList *next;
- do {
- next = attr->getNext();
-
+ assert(!state.getDeclarator().getAttributes().empty() &&
+ "declarator has no attrs!");
+ // The called functions in this loop actually remove things from the current
+ // list, so iterating over the existing list isn't possible. Instead, make a
+ // non-owning copy and iterate over that.
+ ParsedAttributesView AttrsCopy{state.getDeclarator().getAttributes()};
+ for (AttributeList &attr : AttrsCopy) {
// Do not distribute C++11 attributes. They have strict rules for what
// they appertain to.
- if (attr->isCXX11Attribute())
+ if (attr.isCXX11Attribute())
continue;
- switch (attr->getKind()) {
+ switch (attr.getKind()) {
OBJC_POINTER_TYPE_ATTRS_CASELIST:
- distributeObjCPointerTypeAttrFromDeclarator(state, *attr, declSpecType);
+ distributeObjCPointerTypeAttrFromDeclarator(state, attr, declSpecType);
break;
FUNCTION_TYPE_ATTRS_CASELIST:
- distributeFunctionTypeAttrFromDeclarator(state, *attr, declSpecType);
+ distributeFunctionTypeAttrFromDeclarator(state, attr, declSpecType);
break;
MS_TYPE_ATTRS_CASELIST:
@@ -661,7 +628,7 @@ static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
default:
break;
}
- } while ((attr = next));
+ }
}
/// Add a synthetic '()' to a block-literal declarator if it is
@@ -761,28 +728,18 @@ static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator,
return false;
// Warn if we see type attributes for omitted return type on a block literal.
- AttributeList *&attrs =
- declarator.getMutableDeclSpec().getAttributes().getListRef();
- AttributeList *prev = nullptr;
- for (AttributeList *cur = attrs; cur; cur = cur->getNext()) {
- AttributeList &attr = *cur;
- // Skip attributes that were marked to be invalid or non-type
- // attributes.
- if (attr.isInvalid() || !attr.isTypeAttr()) {
- prev = cur;
+ SmallVector<AttributeList *, 2> ToBeRemoved;
+ for (AttributeList &AL : declarator.getMutableDeclSpec().getAttributes()) {
+ if (AL.isInvalid() || !AL.isTypeAttr())
continue;
- }
- S.Diag(attr.getLoc(),
+ S.Diag(AL.getLoc(),
diag::warn_block_literal_attributes_on_omitted_return_type)
- << attr.getName();
- // Remove cur from the list.
- if (prev) {
- prev->setNext(cur->getNext());
- prev = cur;
- } else {
- attrs = cur->getNext();
- }
+ << AL.getName();
+ ToBeRemoved.push_back(&AL);
}
+ // Remove bad attributes from the list.
+ for (AttributeList *AL : ToBeRemoved)
+ declarator.getMutableDeclSpec().getAttributes().remove(AL);
// Warn if we see type qualifiers for omitted return type on a block literal.
const DeclSpec &DS = declarator.getDeclSpec();
@@ -1210,18 +1167,11 @@ TypeResult Sema::actOnObjCTypeArgsAndProtocolQualifiers(
return CreateParsedType(Result, ResultTInfo);
}
-static OpenCLAccessAttr::Spelling getImageAccess(const AttributeList *Attrs) {
- if (Attrs) {
- const AttributeList *Next = Attrs;
- do {
- const AttributeList &Attr = *Next;
- Next = Attr.getNext();
- if (Attr.getKind() == AttributeList::AT_OpenCLAccess) {
- return static_cast<OpenCLAccessAttr::Spelling>(
- Attr.getSemanticSpelling());
- }
- } while (Next);
- }
+static OpenCLAccessAttr::Spelling
+getImageAccess(const ParsedAttributesView &Attrs) {
+ for (const AttributeList &AL : Attrs)
+ if (AL.getKind() == AttributeList::AT_OpenCLAccess)
+ return static_cast<OpenCLAccessAttr::Spelling>(AL.getSemanticSpelling());
return OpenCLAccessAttr::Keyword_read_only;
}
@@ -1237,7 +1187,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
Sema &S = state.getSema();
Declarator &declarator = state.getDeclarator();
- const DeclSpec &DS = declarator.getDeclSpec();
+ DeclSpec &DS = declarator.getMutableDeclSpec();
SourceLocation DeclLoc = declarator.getIdentifierLoc();
if (DeclLoc.isInvalid())
DeclLoc = DS.getLocStart();
@@ -1582,16 +1532,19 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
}
break;
-#define GENERIC_IMAGE_TYPE(ImgType, Id) \
- case DeclSpec::TST_##ImgType##_t: \
- switch (getImageAccess(DS.getAttributes().getList())) { \
- case OpenCLAccessAttr::Keyword_write_only: \
- Result = Context.Id##WOTy; break; \
- case OpenCLAccessAttr::Keyword_read_write: \
- Result = Context.Id##RWTy; break; \
- case OpenCLAccessAttr::Keyword_read_only: \
- Result = Context.Id##ROTy; break; \
- } \
+#define GENERIC_IMAGE_TYPE(ImgType, Id) \
+ case DeclSpec::TST_##ImgType##_t: \
+ switch (getImageAccess(DS.getAttributes())) { \
+ case OpenCLAccessAttr::Keyword_write_only: \
+ Result = Context.Id##WOTy; \
+ break; \
+ case OpenCLAccessAttr::Keyword_read_write: \
+ Result = Context.Id##RWTy; \
+ break; \
+ case OpenCLAccessAttr::Keyword_read_only: \
+ Result = Context.Id##ROTy; \
+ break; \
+ } \
break;
#include "clang/Basic/OpenCLImageTypes.def"
@@ -1644,7 +1597,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
// attributes are pushed around.
// pipe attributes will be handled later ( at GetFullTypeForDeclarator )
if (!DS.isTypeSpecPipe())
- processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes().getList());
+ processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes());
// Apply const/volatile/restrict qualifiers to T.
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
@@ -2646,9 +2599,8 @@ static void inferARCWriteback(TypeProcessingState &state,
if (chunk.Kind != DeclaratorChunk::Pointer &&
chunk.Kind != DeclaratorChunk::BlockPointer)
return;
- for (const AttributeList *attr = chunk.getAttrs(); attr;
- attr = attr->getNext())
- if (attr->getKind() == AttributeList::AT_ObjCOwnership)
+ for (const AttributeList &AL : chunk.getAttrs())
+ if (AL.getKind() == AttributeList::AT_ObjCOwnership)
return;
transferARCOwnershipToDeclaratorChunk(state, Qualifiers::OCL_Autoreleasing,
@@ -2813,7 +2765,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
// "void" instead.
T = SemaRef.Context.VoidTy;
processTypeAttrs(state, T, TAL_DeclSpec,
- D.getDeclSpec().getAttributes().getList());
+ D.getMutableDeclSpec().getAttributes());
break;
case UnqualifiedIdKind::IK_DeductionGuideName:
@@ -2830,7 +2782,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
break;
}
- if (D.getAttributes())
+ if (!D.getAttributes().empty())
distributeTypeAttrsFromDeclarator(state, T);
// C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
@@ -3314,21 +3266,20 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) {
/// this is the outermost chunk, then we can determine the CC from the
/// declarator context. If not, then this could be either a member function
/// type or normal function type.
-static CallingConv
-getCCForDeclaratorChunk(Sema &S, Declarator &D,
- const DeclaratorChunk::FunctionTypeInfo &FTI,
- unsigned ChunkIndex) {
+static CallingConv getCCForDeclaratorChunk(
+ Sema &S, Declarator &D, const ParsedAttributesView &AttrList,
+ const DeclaratorChunk::FunctionTypeInfo &FTI, unsigned ChunkIndex) {
assert(D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function);
// Check for an explicit CC attribute.
- for (auto Attr = FTI.AttrList; Attr; Attr = Attr->getNext()) {
- switch (Attr->getKind()) {
- CALLING_CONV_ATTRS_CASELIST: {
+ for (const AttributeList &AL : AttrList) {
+ switch (AL.getKind()) {
+ CALLING_CONV_ATTRS_CASELIST : {
// Ignore attributes that don't validate or can't apply to the
// function type. We'll diagnose the failure to apply them in
// handleFunctionTypeAttr.
CallingConv CC;
- if (!S.CheckCallingConvAttr(*Attr, CC) &&
+ if (!S.CheckCallingConvAttr(AL, CC) &&
(!FTI.isVariadic || supportsVariadicCall(CC))) {
return CC;
}
@@ -3384,9 +3335,8 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D,
// convention attribute. This is the simplest place to infer
// calling convention for OpenCL kernels.
if (S.getLangOpts().OpenCL) {
- for (const AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
- Attr; Attr = Attr->getNext()) {
- if (Attr->getKind() == AttributeList::AT_OpenCLKernel) {
+ for (const AttributeList &AL : D.getDeclSpec().getAttributes()) {
+ if (AL.getKind() == AttributeList::AT_OpenCLKernel) {
CC = CC_OpenCLKernel;
break;
}
@@ -3437,12 +3387,11 @@ IdentifierInfo *Sema::getNSErrorIdent() {
/// Check whether there is a nullability attribute of any kind in the given
/// attribute list.
-static bool hasNullabilityAttr(const AttributeList *attrs) {
- for (const AttributeList *attr = attrs; attr;
- attr = attr->getNext()) {
- if (attr->getKind() == AttributeList::AT_TypeNonNull ||
- attr->getKind() == AttributeList::AT_TypeNullable ||
- attr->getKind() == AttributeList::AT_TypeNullUnspecified)
+static bool hasNullabilityAttr(const ParsedAttributesView &attrs) {
+ for (const AttributeList &AL : attrs) {
+ if (AL.getKind() == AttributeList::AT_TypeNonNull ||
+ AL.getKind() == AttributeList::AT_TypeNullable ||
+ AL.getKind() == AttributeList::AT_TypeNullUnspecified)
return true;
}
@@ -4044,19 +3993,16 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// On pointer-to-pointer parameters marked cf_returns_retained or
// cf_returns_not_retained, if the outer pointer is explicit then
// infer the inner pointer as _Nullable.
- auto hasCFReturnsAttr = [](const AttributeList *NextAttr) -> bool {
- while (NextAttr) {
- if (NextAttr->getKind() == AttributeList::AT_CFReturnsRetained ||
- NextAttr->getKind() == AttributeList::AT_CFReturnsNotRetained)
- return true;
- NextAttr = NextAttr->getNext();
- }
- return false;
+ auto hasCFReturnsAttr =
+ [](const ParsedAttributesView &AttrList) -> bool {
+ return AttrList.hasAttribute(AttributeList::AT_CFReturnsRetained) ||
+ AttrList.hasAttribute(
+ AttributeList::AT_CFReturnsNotRetained);
};
if (const auto *InnermostChunk = D.getInnermostNonParenChunk()) {
if (hasCFReturnsAttr(D.getAttributes()) ||
hasCFReturnsAttr(InnermostChunk->getAttrs()) ||
- hasCFReturnsAttr(D.getDeclSpec().getAttributes().getList())) {
+ hasCFReturnsAttr(D.getDeclSpec().getAttributes())) {
inferNullability = NullabilityKind::Nullable;
inferNullabilityInnerOnly = true;
}
@@ -4112,10 +4058,10 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Local function that checks the nullability for a given pointer declarator.
// Returns true if _Nonnull was inferred.
- auto inferPointerNullability = [&](SimplePointerKind pointerKind,
- SourceLocation pointerLoc,
- SourceLocation pointerEndLoc,
- AttributeList *&attrs) -> AttributeList * {
+ auto inferPointerNullability =
+ [&](SimplePointerKind pointerKind, SourceLocation pointerLoc,
+ SourceLocation pointerEndLoc,
+ ParsedAttributesView &attrs) -> AttributeList * {
// We've seen a pointer.
if (NumPointersRemaining > 0)
--NumPointersRemaining;
@@ -4137,7 +4083,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
nullptr, SourceLocation(),
nullptr, 0, syntax);
- spliceAttrIntoList(*nullabilityAttr, attrs);
+ attrs.addAtStart(nullabilityAttr);
if (inferNullabilityCS) {
state.getDeclarator().getMutableDeclSpec().getObjCQualifiers()
@@ -4192,9 +4138,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
pointerKind = SimplePointerKind::MemberPointer;
if (auto *attr = inferPointerNullability(
- pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
- D.getDeclSpec().getLocEnd(),
- D.getMutableDeclSpec().getAttributes().getListRef())) {
+ pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
+ D.getDeclSpec().getLocEnd(),
+ D.getMutableDeclSpec().getAttributes())) {
T = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*inferNullability),T,T);
attr->setUsedAsTypeAttr();
@@ -4232,7 +4178,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability.
inferPointerNullability(SimplePointerKind::BlockPointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrListRef());
+ DeclType.EndLoc, DeclType.getAttrs());
T = S.BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
if (DeclType.Cls.TypeQuals || LangOpts.OpenCL) {
@@ -4254,7 +4200,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability
inferPointerNullability(SimplePointerKind::Pointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrListRef());
+ DeclType.EndLoc, DeclType.getAttrs());
if (LangOpts.ObjC1 && T->getAs<ObjCObjectType>()) {
T = Context.getObjCObjectPointerType(T);
@@ -4528,20 +4474,17 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
SourceLocation AttrLoc;
if (chunkIndex + 1 < D.getNumTypeObjects()) {
DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1);
- for (const AttributeList *Attr = ReturnTypeChunk.getAttrs();
- Attr; Attr = Attr->getNext()) {
- if (Attr->getKind() == AttributeList::AT_ObjCOwnership) {
- AttrLoc = Attr->getLoc();
+ for (const AttributeList &AL : ReturnTypeChunk.getAttrs()) {
+ if (AL.getKind() == AttributeList::AT_ObjCOwnership) {
+ AttrLoc = AL.getLoc();
break;
}
}
}
if (AttrLoc.isInvalid()) {
- for (const AttributeList *Attr
- = D.getDeclSpec().getAttributes().getList();
- Attr; Attr = Attr->getNext()) {
- if (Attr->getKind() == AttributeList::AT_ObjCOwnership) {
- AttrLoc = Attr->getLoc();
+ for (const AttributeList &AL : D.getDeclSpec().getAttributes()) {
+ if (AL.getKind() == AttributeList::AT_ObjCOwnership) {
+ AttrLoc = AL.getLoc();
break;
}
}
@@ -4581,7 +4524,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (FTI.isAmbiguous)
warnAboutAmbiguousFunction(S, D, DeclType, T);
- FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex));
+ FunctionType::ExtInfo EI(
+ getCCForDeclaratorChunk(S, D, DeclType.getAttrs(), FTI, chunkIndex));
if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus
&& !LangOpts.OpenCL) {
@@ -4591,19 +4535,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// We allow a zero-parameter variadic function in C if the
// function is marked with the "overloadable" attribute. Scan
// for this attribute now.
- if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus) {
- bool Overloadable = false;
- for (const AttributeList *Attrs = D.getAttributes();
- Attrs; Attrs = Attrs->getNext()) {
- if (Attrs->getKind() == AttributeList::AT_Overloadable) {
- Overloadable = true;
- break;
- }
- }
-
- if (!Overloadable)
+ if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus)
+ if (!D.getAttributes().hasAttribute(AttributeList::AT_Overloadable))
S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param);
- }
if (FTI.NumParams && FTI.Params[0].Param == nullptr) {
// C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
@@ -4758,7 +4692,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability.
inferPointerNullability(SimplePointerKind::MemberPointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrListRef());
+ DeclType.EndLoc, DeclType.getAttrs());
if (SS.isInvalid()) {
// Avoid emitting extra errors if we already errored on the scope.
@@ -4814,7 +4748,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
case DeclaratorChunk::Pipe: {
T = S.BuildReadPipeType(T, DeclType.Loc);
processTypeAttrs(state, T, TAL_DeclSpec,
- D.getDeclSpec().getAttributes().getList());
+ D.getMutableDeclSpec().getAttributes());
break;
}
}
@@ -4825,8 +4759,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
// See if there are any attributes on this declarator chunk.
- processTypeAttrs(state, T, TAL_DeclChunk,
- const_cast<AttributeList *>(DeclType.getAttrs()));
+ processTypeAttrs(state, T, TAL_DeclChunk, DeclType.getAttrs());
}
// GNU warning -Wstrict-prototypes
@@ -5091,10 +5024,8 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
// Look for an explicit lifetime attribute.
DeclaratorChunk &chunk = D.getTypeObject(chunkIndex);
- for (const AttributeList *attr = chunk.getAttrs(); attr;
- attr = attr->getNext())
- if (attr->getKind() == AttributeList::AT_ObjCOwnership)
- return;
+ if (chunk.getAttrs().hasAttribute(AttributeList::AT_ObjCOwnership))
+ return;
const char *attrStr = nullptr;
switch (ownership) {
@@ -5117,8 +5048,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
.create(&S.Context.Idents.get("objc_ownership"), SourceLocation(),
/*scope*/ nullptr, SourceLocation(),
/*args*/ &Args, 1, AttributeList::AS_GNU);
- spliceAttrIntoList(*attr, chunk.getAttrListRef());
-
+ chunk.getAttrs().addAtStart(attr);
// TODO: mark whether we did this inference?
}
@@ -5262,39 +5192,19 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
llvm_unreachable("unexpected attribute kind!");
}
-static void fillAttributedTypeLoc(AttributedTypeLoc TL,
- const AttributeList *attrs,
- const AttributeList *DeclAttrs = nullptr) {
- // DeclAttrs and attrs cannot be both empty.
- assert((attrs || DeclAttrs) &&
- "no type attributes in the expected location!");
-
- AttributeList::Kind parsedKind = getAttrListKind(TL.getAttrKind());
- // Try to search for an attribute of matching kind in attrs list.
- while (attrs && attrs->getKind() != parsedKind)
- attrs = attrs->getNext();
- if (!attrs) {
- // No matching type attribute in attrs list found.
- // Try searching through C++11 attributes in the declarator attribute list.
- while (DeclAttrs && (!DeclAttrs->isCXX11Attribute() ||
- DeclAttrs->getKind() != parsedKind))
- DeclAttrs = DeclAttrs->getNext();
- attrs = DeclAttrs;
- }
-
- assert(attrs && "no matching type attribute in expected location!");
-
- TL.setAttrNameLoc(attrs->getLoc());
+static void setAttributedTypeLoc(AttributedTypeLoc TL,
+ const AttributeList &attr) {
+ TL.setAttrNameLoc(attr.getLoc());
if (TL.hasAttrExprOperand()) {
- assert(attrs->isArgExpr(0) && "mismatched attribute operand kind");
- TL.setAttrExprOperand(attrs->getArgAsExpr(0));
+ assert(attr.isArgExpr(0) && "mismatched attribute operand kind");
+ TL.setAttrExprOperand(attr.getArgAsExpr(0));
} else if (TL.hasAttrEnumOperand()) {
- assert((attrs->isArgIdent(0) || attrs->isArgExpr(0)) &&
+ assert((attr.isArgIdent(0) || attr.isArgExpr(0)) &&
"unexpected attribute operand kind");
- if (attrs->isArgIdent(0))
- TL.setAttrEnumOperandLoc(attrs->getArgAsIdent(0)->Loc);
+ if (attr.isArgIdent(0))
+ TL.setAttrEnumOperandLoc(attr.getArgAsIdent(0)->Loc);
else
- TL.setAttrEnumOperandLoc(attrs->getArgAsExpr(0)->getExprLoc());
+ TL.setAttrEnumOperandLoc(attr.getArgAsExpr(0)->getExprLoc());
}
// FIXME: preserve this information to here.
@@ -5302,6 +5212,25 @@ static void fillAttributedTypeLoc(AttributedTypeLoc TL,
TL.setAttrOperandParensRange(SourceRange());
}
+static void fillAttributedTypeLoc(AttributedTypeLoc TL,
+ const ParsedAttributesView &Attrs,
+ const ParsedAttributesView &DeclAttrs) {
+ // DeclAttrs and Attrs cannot be both empty.
+ assert((!Attrs.empty() || !DeclAttrs.empty()) &&
+ "no type attributes in the expected location!");
+
+ AttributeList::Kind parsedKind = getAttrListKind(TL.getAttrKind());
+ // Try to search for an attribute of matching kind in Attrs list.
+ for (const AttributeList &AL : Attrs)
+ if (AL.getKind() == parsedKind)
+ return setAttributedTypeLoc(TL, AL);
+
+ for (const AttributeList &AL : DeclAttrs)
+ if (AL.isCXX11Attribute() || AL.getKind() == parsedKind)
+ return setAttributedTypeLoc(TL, AL);
+ llvm_unreachable("no matching type attribute in expected location!");
+}
+
namespace {
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
ASTContext &Context;
@@ -5312,7 +5241,7 @@ namespace {
: Context(Context), DS(DS) {}
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
- fillAttributedTypeLoc(TL, DS.getAttributes().getList());
+ fillAttributedTypeLoc(TL, DS.getAttributes(), ParsedAttributesView{});
Visit(TL.getModifiedLoc());
}
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
@@ -5484,7 +5413,7 @@ namespace {
}
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
- fillAttributedTypeLoc(TL, Chunk.getAttrs());
+ fillAttributedTypeLoc(TL, Chunk.getAttrs(), ParsedAttributesView{});
}
void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
// nothing
@@ -5617,16 +5546,20 @@ static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
ATL.setParensRange(SourceRange());
}
-static void fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
- const AttributeList *Attrs) {
- while (Attrs && Attrs->getKind() != AttributeList::AT_AddressSpace)
- Attrs = Attrs->getNext();
+static void
+fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
+ const ParsedAttributesView &Attrs) {
+ for (const AttributeList &AL : Attrs) {
+ if (AL.getKind() == AttributeList::AT_AddressSpace) {
+ DASTL.setAttrNameLoc(AL.getLoc());
+ DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
+ DASTL.setAttrOperandParensRange(SourceRange());
+ return;
+ }
+ }
- assert(Attrs && "no address_space attribute found at the expected location!");
-
- DASTL.setAttrNameLoc(Attrs->getLoc());
- DASTL.setAttrExprOperand(Attrs->getArgAsExpr(0));
- DASTL.setAttrOperandParensRange(SourceRange());
+ llvm_unreachable(
+ "no address_space attribute found at the expected location!");
}
/// Create and instantiate a TypeSourceInfo with type source information.
@@ -5642,7 +5575,6 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
TypeSourceInfo *ReturnTypeInfo) {
TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);
UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
- const AttributeList *DeclAttrs = D.getAttributes();
// Handle parameter packs whose type is a pack expansion.
if (isa<PackExpansionType>(T)) {
@@ -5666,7 +5598,8 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
}
while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
- fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(), DeclAttrs);
+ fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(),
+ D.getAttributes());
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
}
@@ -6558,7 +6491,7 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
auto moveToChunk = [&](DeclaratorChunk &chunk, bool inFunction) -> bool {
// If there is already a nullability attribute there, don't add
// one.
- if (hasNullabilityAttr(chunk.getAttrListRef()))
+ if (hasNullabilityAttr(chunk.getAttrs()))
return false;
// Complain about the nullability qualifier being in the wrong
@@ -6591,8 +6524,8 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
" " + attr.getName()->getName().str() + " ");
}
- moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
- chunk.getAttrListRef());
+ moveAttrFromListToList(attr, state.getCurrentAttributes(),
+ chunk.getAttrs());
return true;
};
@@ -7239,16 +7172,18 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
}
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
- TypeAttrLocation TAL, AttributeList *attrs) {
+ TypeAttrLocation TAL,
+ ParsedAttributesView &attrs) {
// Scan through and apply attributes to this type where it makes sense. Some
// attributes (such as __address_space__, __vector_size__, etc) apply to the
// type, but others can be present in the type specifiers even though they
// apply to the decl. Here we apply type attributes and ignore the rest.
- while (attrs) {
- AttributeList &attr = *attrs;
- attrs = attr.getNext(); // reset to the next here due to early loop continue
- // stmts
+ // This loop modifies the list pretty frequently, but we still need to make
+ // sure we visit every element once. Copy the attributes list, and iterate
+ // over that.
+ ParsedAttributesView AttrsCopy{attrs};
+ for (AttributeList &attr : AttrsCopy) {
// Skip attributes that were marked to be invalid.
if (attr.isInvalid())