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:
parent
0de57a676c
commit
c480f30580
|
@ -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);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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'!");
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in New Issue