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.

llvm-svn: 336945
This commit is contained in:
Erich Keane 2018-07-12 21:09:05 +00:00
parent 0de57a676c
commit c480f30580
29 changed files with 1057 additions and 1376 deletions

View File

@ -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);
//===--------------------------------------------------------------------===//

View File

@ -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));
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) {
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));
}
};
class ParsedAttributesView {
using VecTy = llvm::TinyPtrVector<AttributeList *>;
using SizeType = decltype(std::declval<VecTy>().size());
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 addAtStart(AttributeList *newAttr) {
assert(newAttr);
AttrList.insert(AttrList.begin(), newAttr);
}
void addAtEnd(AttributeList *newAttr) {
assert(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 clearListOnly() { AttrList.clear(); }
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;
};
void addAll(iterator B, iterator E) {
AttrList.insert(AttrList.begin(), B.I, E.I);
}
void addAll(const_iterator B, const_iterator E) {
AttrList.insert(AttrList.begin(), B.I, E.I);
}
void addAllAtEnd(iterator B, iterator E) {
AttrList.insert(AttrList.end(), B.I, E.I);
}
void addAllAtEnd(const_iterator B, const_iterator E) {
AttrList.insert(AttrList.end(), B.I, E.I);
}
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 {
class ParsedAttributes : public ParsedAttributesView {
public:
ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
ParsedAttributes(const ParsedAttributes &) = delete;
AttributePool &getPool() const { return pool; }
bool empty() const { return list == nullptr; }
void add(AttributeList *newAttr) {
assert(newAttr);
assert(newAttr->getNext() == nullptr);
newAttr->setNext(list);
list = newAttr;
}
void addAll(AttributeList *newList) {
if (!newList) return;
AttributeList *lastInNewList = newList;
while (AttributeList *next = lastInNewList->getNext())
lastInNewList = next;
lastInNewList->setNext(list);
list = newList;
}
void addAllAtEnd(AttributeList *newList) {
if (!list) {
list = newList;
return;
}
AttributeList *lastInList = list;
while (AttributeList *next = lastInList->getNext())
lastInList = next;
lastInList->setNext(newList);
}
void set(AttributeList *newList) {
list = newList;
}
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

View File

@ -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; }

View File

@ -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);
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,
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,
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() {

View File

@ -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'!");

View File

@ -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();
llvm::SmallVector<AttributeList *, 1> ToBeMoved;
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;
}
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.

View File

@ -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());
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.
// 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();

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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)) {

View File

@ -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))) {

View File

@ -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 {

View File

@ -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

View File

@ -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;
void AttributeFactory::deallocate(AttributeList *Attr) {
size_t size = Attr->allocated_size();
size_t freeListIndex = getFreeListIndexForSize(size);
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);
// Expand FreeLists to the appropriate size, if required.
if (freeListIndex >= FreeLists.size())
FreeLists.resize(freeListIndex+1);
#if !NDEBUG
// In debug mode, zero out the attribute to help find memory overwriting.
memset(Attr, 0, size);
#endif
// Add 'cur' to the appropriate free-list.
cur->NextInPool = FreeLists[freeListIndex];
FreeLists[freeListIndex] = cur;
cur = next;
} while (cur);
// Add 'Attr' to the appropriate free-list.
FreeLists[freeListIndex].push_back(Attr);
}
void AttributePool::takePool(AttributeList *pool) {
assert(pool);
void AttributeFactory::reclaimPool(AttributePool &cur) {
for (AttributeList *AL : cur.Attrs)
deallocate(AL);
}
// Fast path: this pool is empty.
if (!Head) {
Head = pool;
return;
}
// 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"

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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())