mirror of
https://github.com/intel/llvm.git
synced 2026-02-02 18:18:09 +08:00
Insomniac refactoring: change how the parser allocates attributes so that
AttributeLists do not accumulate over the lifetime of parsing, but are instead reused. Also make the arguments array not require a separate allocation, and make availability attributes store their stuff in augmented memory, too. llvm-svn: 128209
This commit is contained in:
@@ -157,7 +157,7 @@ class Parser : public CodeCompletionHandler {
|
||||
unsigned TemplateParameterDepth;
|
||||
|
||||
/// Factory object for creating AttributeList objects.
|
||||
AttributeList::Factory AttrFactory;
|
||||
AttributeFactory AttrFactory;
|
||||
|
||||
public:
|
||||
Parser(Preprocessor &PP, Sema &Actions);
|
||||
@@ -801,10 +801,9 @@ private:
|
||||
ParsingDeclRAIIObject ParsingRAII;
|
||||
|
||||
public:
|
||||
ParsingDeclSpec(Parser &P) : ParsingRAII(P) {}
|
||||
ParsingDeclSpec(ParsingDeclRAIIObject &RAII) : ParsingRAII(RAII) {}
|
||||
ParsingDeclSpec(Parser &P) : DeclSpec(P.AttrFactory), ParsingRAII(P) {}
|
||||
ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
|
||||
: ParsingRAII(P, RAII) {}
|
||||
: DeclSpec(P.AttrFactory), ParsingRAII(P, RAII) {}
|
||||
|
||||
void complete(Decl *D) {
|
||||
ParsingRAII.complete(D);
|
||||
@@ -943,6 +942,9 @@ private:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C99 6.9: External Definitions.
|
||||
struct ParsedAttributesWithRange : ParsedAttributes {
|
||||
ParsedAttributesWithRange(AttributeFactory &factory)
|
||||
: ParsedAttributes(factory) {}
|
||||
|
||||
SourceRange Range;
|
||||
};
|
||||
|
||||
@@ -1506,10 +1508,10 @@ private:
|
||||
|
||||
void MaybeParseGNUAttributes(Declarator &D) {
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
SourceLocation endLoc;
|
||||
ParseGNUAttributes(attrs, &endLoc);
|
||||
D.addAttributes(attrs.getList(), endLoc);
|
||||
D.takeAttributes(attrs, endLoc);
|
||||
}
|
||||
}
|
||||
void MaybeParseGNUAttributes(ParsedAttributes &attrs,
|
||||
@@ -1522,18 +1524,18 @@ private:
|
||||
|
||||
void MaybeParseCXX0XAttributes(Declarator &D) {
|
||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
SourceLocation endLoc;
|
||||
ParseCXX0XAttributes(attrs, &endLoc);
|
||||
D.addAttributes(attrs.getList(), endLoc);
|
||||
D.takeAttributes(attrs, endLoc);
|
||||
}
|
||||
}
|
||||
void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
|
||||
SourceLocation *endLoc = 0) {
|
||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||
ParsedAttributesWithRange attrsWithRange;
|
||||
ParsedAttributesWithRange attrsWithRange(AttrFactory);
|
||||
ParseCXX0XAttributes(attrsWithRange, endLoc);
|
||||
attrs.append(attrsWithRange.getList());
|
||||
attrs.takeAllFrom(attrsWithRange);
|
||||
}
|
||||
}
|
||||
void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#define LLVM_CLANG_SEMA_ATTRLIST_H
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "clang/Sema/Ownership.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class IdentifierInfo;
|
||||
class Expr;
|
||||
|
||||
@@ -51,87 +51,96 @@ struct AvailabilityChange {
|
||||
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
|
||||
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
|
||||
///
|
||||
class AttributeList {
|
||||
public:
|
||||
class Factory;
|
||||
class AttributeList { // TODO: This should really be called ParsedAttribute
|
||||
private:
|
||||
IdentifierInfo *AttrName;
|
||||
SourceLocation AttrLoc;
|
||||
IdentifierInfo *ScopeName;
|
||||
SourceLocation ScopeLoc;
|
||||
IdentifierInfo *ParmName;
|
||||
SourceLocation AttrLoc;
|
||||
SourceLocation ScopeLoc;
|
||||
SourceLocation ParmLoc;
|
||||
Expr **Args;
|
||||
unsigned NumArgs;
|
||||
AttributeList *Next;
|
||||
bool DeclspecAttribute, CXX0XAttribute;
|
||||
|
||||
// For the 'availability' attribute.
|
||||
AvailabilityChange AvailabilityIntroduced;
|
||||
AvailabilityChange AvailabilityDeprecated;
|
||||
AvailabilityChange AvailabilityObsoleted;
|
||||
/// The number of expression arguments this attribute has.
|
||||
/// The expressions themselves are stored after the object.
|
||||
unsigned NumArgs;
|
||||
|
||||
/// True if Microsoft style: declspec(foo).
|
||||
bool DeclspecAttribute;
|
||||
|
||||
/// True if C++0x-style: [[foo]].
|
||||
bool CXX0XAttribute;
|
||||
|
||||
/// True if already diagnosed as invalid.
|
||||
mutable bool Invalid;
|
||||
|
||||
/// True if this has the extra information associated with an
|
||||
/// availability attribute.
|
||||
bool IsAvailability;
|
||||
|
||||
/// The next attribute in the current position.
|
||||
AttributeList *NextInPosition;
|
||||
|
||||
/// The next attribute allocated in the current Pool.
|
||||
AttributeList *NextInPool;
|
||||
|
||||
Expr **getArgsBuffer() {
|
||||
return reinterpret_cast<Expr**>(this+1);
|
||||
}
|
||||
Expr * const *getArgsBuffer() const {
|
||||
return reinterpret_cast<Expr* const *>(this+1);
|
||||
}
|
||||
|
||||
enum AvailabilitySlot {
|
||||
IntroducedSlot, DeprecatedSlot, ObsoletedSlot
|
||||
};
|
||||
|
||||
AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
|
||||
return reinterpret_cast<AvailabilityChange*>(this+1)[index];
|
||||
}
|
||||
const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
|
||||
return reinterpret_cast<const AvailabilityChange*>(this+1)[index];
|
||||
}
|
||||
|
||||
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
|
||||
void operator=(const AttributeList &); // DO NOT IMPLEMENT
|
||||
void operator delete(void *); // DO NOT IMPLEMENT
|
||||
~AttributeList(); // DO NOT IMPLEMENT
|
||||
AttributeList(llvm::BumpPtrAllocator &Alloc,
|
||||
IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||
Expr **args, unsigned numargs,
|
||||
bool declspec, bool cxx0x);
|
||||
|
||||
AttributeList(llvm::BumpPtrAllocator &Alloc,
|
||||
IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||
const AvailabilityChange &Introduced,
|
||||
const AvailabilityChange &Deprecated,
|
||||
const AvailabilityChange &Obsoleted,
|
||||
bool declspec, bool cxx0x);
|
||||
size_t allocated_size() const;
|
||||
|
||||
AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
Expr **args, unsigned numArgs,
|
||||
bool declspec, bool cxx0x)
|
||||
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
|
||||
AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
|
||||
NumArgs(numArgs),
|
||||
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false),
|
||||
IsAvailability(false), NextInPosition(0), NextInPool(0) {
|
||||
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
|
||||
}
|
||||
|
||||
AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
const AvailabilityChange &introduced,
|
||||
const AvailabilityChange &deprecated,
|
||||
const AvailabilityChange &obsoleted,
|
||||
bool declspec, bool cxx0x)
|
||||
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
|
||||
AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
|
||||
NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
|
||||
Invalid(false), IsAvailability(true), NextInPosition(0), NextInPool(0) {
|
||||
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
|
||||
new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
|
||||
new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
|
||||
}
|
||||
|
||||
friend class AttributePool;
|
||||
friend class AttributeFactory;
|
||||
|
||||
public:
|
||||
class Factory {
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
public:
|
||||
Factory() {}
|
||||
~Factory() {}
|
||||
AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||
Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) {
|
||||
AttributeList *Mem = Alloc.Allocate<AttributeList>();
|
||||
new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
|
||||
ParmName, ParmLoc, args, numargs,
|
||||
declspec, cxx0x);
|
||||
return Mem;
|
||||
}
|
||||
|
||||
AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||
const AvailabilityChange &Introduced,
|
||||
const AvailabilityChange &Deprecated,
|
||||
const AvailabilityChange &Obsoleted,
|
||||
bool declspec = false, bool cxx0x = false) {
|
||||
AttributeList *Mem = Alloc.Allocate<AttributeList>();
|
||||
new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
|
||||
ParmName, ParmLoc, Introduced, Deprecated,
|
||||
Obsoleted, declspec, cxx0x);
|
||||
return Mem;
|
||||
}
|
||||
|
||||
AttributeList* CreateIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
|
||||
SourceLocation TokLoc, int Arg) {
|
||||
Expr* IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t)Arg),
|
||||
C.IntTy, TokLoc);
|
||||
return Create( Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
|
||||
}
|
||||
};
|
||||
|
||||
enum Kind { // Please keep this list alphabetized.
|
||||
AT_IBAction, // Clang-specific.
|
||||
AT_IBOutlet, // Clang-specific.
|
||||
@@ -242,8 +251,8 @@ public:
|
||||
Kind getKind() const { return getKind(getName()); }
|
||||
static Kind getKind(const IdentifierInfo *Name);
|
||||
|
||||
AttributeList *getNext() const { return Next; }
|
||||
void setNext(AttributeList *N) { Next = N; }
|
||||
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; }
|
||||
@@ -251,14 +260,14 @@ public:
|
||||
/// getArg - Return the specified argument.
|
||||
Expr *getArg(unsigned Arg) const {
|
||||
assert(Arg < NumArgs && "Arg access out of range!");
|
||||
return Args[Arg];
|
||||
return getArgsBuffer()[Arg];
|
||||
}
|
||||
|
||||
class arg_iterator {
|
||||
Expr** X;
|
||||
Expr * const *X;
|
||||
unsigned Idx;
|
||||
public:
|
||||
arg_iterator(Expr** x, unsigned idx) : X(x), Idx(idx) {}
|
||||
arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {}
|
||||
|
||||
arg_iterator& operator++() {
|
||||
++Idx;
|
||||
@@ -285,29 +294,160 @@ public:
|
||||
};
|
||||
|
||||
arg_iterator arg_begin() const {
|
||||
return arg_iterator(Args, 0);
|
||||
return arg_iterator(getArgsBuffer(), 0);
|
||||
}
|
||||
|
||||
arg_iterator arg_end() const {
|
||||
return arg_iterator(Args, NumArgs);
|
||||
return arg_iterator(getArgsBuffer(), NumArgs);
|
||||
}
|
||||
|
||||
const AvailabilityChange &getAvailabilityIntroduced() const {
|
||||
assert(getKind() == AT_availability && "Not an availability attribute");
|
||||
return AvailabilityIntroduced;
|
||||
return getAvailabilitySlot(IntroducedSlot);
|
||||
}
|
||||
|
||||
const AvailabilityChange &getAvailabilityDeprecated() const {
|
||||
assert(getKind() == AT_availability && "Not an availability attribute");
|
||||
return AvailabilityDeprecated;
|
||||
return getAvailabilitySlot(DeprecatedSlot);
|
||||
}
|
||||
|
||||
const AvailabilityChange &getAvailabilityObsoleted() const {
|
||||
assert(getKind() == AT_availability && "Not an availability attribute");
|
||||
return AvailabilityObsoleted;
|
||||
return getAvailabilitySlot(ObsoletedSlot);
|
||||
}
|
||||
};
|
||||
|
||||
/// A factory, from which one makes pools, from which one creates
|
||||
/// individual attributes which are deallocated with the pool.
|
||||
///
|
||||
/// Note that it's tolerably cheap to create and destroy one of
|
||||
/// these as long as you don't actually allocate anything in it.
|
||||
class AttributeFactory {
|
||||
public:
|
||||
enum {
|
||||
/// The required allocation size of an availability attribute,
|
||||
/// which we want to ensure is a multiple of sizeof(void*).
|
||||
AvailabilityAllocSize =
|
||||
sizeof(AttributeList)
|
||||
+ ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1)
|
||||
/ sizeof(void*) * sizeof(void*))
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
/// The number of free lists we want to be sure to support
|
||||
/// inline. This is just enough that availability attributes
|
||||
/// don't surpass it. It's actually very unlikely we'll see an
|
||||
/// attribute that needs more than that; on x86-64 you'd need 10
|
||||
/// expression arguments, and on i386 you'd need 19.
|
||||
InlineFreeListsCapacity =
|
||||
1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
|
||||
};
|
||||
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
|
||||
/// Free lists. The index is determined by the following formula:
|
||||
/// (size - sizeof(AttributeList)) / sizeof(void*)
|
||||
llvm::SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
|
||||
|
||||
// The following are the private interface used by AttributePool.
|
||||
friend class AttributePool;
|
||||
|
||||
/// Allocate an attribute of the given size.
|
||||
void *allocate(size_t size);
|
||||
|
||||
/// 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);
|
||||
|
||||
public:
|
||||
AttributeFactory();
|
||||
~AttributeFactory();
|
||||
};
|
||||
|
||||
class AttributePool {
|
||||
AttributeFactory &Factory;
|
||||
AttributeList *Head;
|
||||
|
||||
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;
|
||||
return attr;
|
||||
}
|
||||
|
||||
void takePool(AttributeList *pool);
|
||||
|
||||
public:
|
||||
/// Create a new pool for a factory.
|
||||
AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {}
|
||||
|
||||
/// Move the given pool's allocations to this pool.
|
||||
AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
|
||||
pool.Head = 0;
|
||||
}
|
||||
|
||||
AttributeFactory &getFactory() const { return Factory; }
|
||||
|
||||
void clear() {
|
||||
if (Head) {
|
||||
Factory.reclaimPool(Head);
|
||||
Head = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Take the given pool's allocations and add them to this pool.
|
||||
void takeAllFrom(AttributePool &pool) {
|
||||
if (pool.Head) {
|
||||
takePool(pool.Head);
|
||||
pool.Head = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~AttributePool() {
|
||||
if (Head) Factory.reclaimPool(Head);
|
||||
}
|
||||
|
||||
AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
Expr **args, unsigned numArgs,
|
||||
bool declspec = false, bool cxx0x = false) {
|
||||
void *memory = allocate(sizeof(AttributeList)
|
||||
+ numArgs * sizeof(Expr*));
|
||||
return add(new (memory) AttributeList(attrName, attrLoc,
|
||||
scopeName, scopeLoc,
|
||||
parmName, parmLoc,
|
||||
args, numArgs,
|
||||
declspec, cxx0x));
|
||||
}
|
||||
|
||||
AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
const AvailabilityChange &introduced,
|
||||
const AvailabilityChange &deprecated,
|
||||
const AvailabilityChange &obsoleted,
|
||||
bool declspec = false, bool cxx0x = false) {
|
||||
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
|
||||
return add(new (memory) AttributeList(attrName, attrLoc,
|
||||
scopeName, scopeLoc,
|
||||
parmName, parmLoc,
|
||||
introduced, deprecated, obsoleted,
|
||||
declspec, cxx0x));
|
||||
}
|
||||
|
||||
AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
|
||||
SourceLocation TokLoc, int Arg);
|
||||
};
|
||||
|
||||
/// addAttributeLists - Add two AttributeLists together
|
||||
/// The right-hand list is appended to the left-hand list, if any
|
||||
/// A pointer to the joined list is returned.
|
||||
@@ -350,7 +490,16 @@ struct CXX0XAttributeList {
|
||||
/// is that this will become significantly more serious.
|
||||
class ParsedAttributes {
|
||||
public:
|
||||
ParsedAttributes() : list(0) {}
|
||||
ParsedAttributes(AttributeFactory &factory)
|
||||
: pool(factory), list(0) {
|
||||
}
|
||||
|
||||
ParsedAttributes(ParsedAttributes &attrs)
|
||||
: pool(attrs.pool), list(attrs.list) {
|
||||
attrs.list = 0;
|
||||
}
|
||||
|
||||
AttributePool &getPool() const { return pool; }
|
||||
|
||||
bool empty() const { return list == 0; }
|
||||
|
||||
@@ -361,7 +510,7 @@ public:
|
||||
list = newAttr;
|
||||
}
|
||||
|
||||
void append(AttributeList *newList) {
|
||||
void addAll(AttributeList *newList) {
|
||||
if (!newList) return;
|
||||
|
||||
AttributeList *lastInNewList = newList;
|
||||
@@ -376,14 +525,57 @@ public:
|
||||
list = newList;
|
||||
}
|
||||
|
||||
void clear() { list = 0; }
|
||||
void takeAllFrom(ParsedAttributes &attrs) {
|
||||
addAll(attrs.list);
|
||||
attrs.list = 0;
|
||||
pool.takeAllFrom(attrs.pool);
|
||||
}
|
||||
|
||||
void clear() { list = 0; pool.clear(); }
|
||||
AttributeList *getList() const { return list; }
|
||||
|
||||
/// 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; }
|
||||
|
||||
|
||||
AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
Expr **args, unsigned numArgs,
|
||||
bool declspec = false, bool cxx0x = false) {
|
||||
AttributeList *attr =
|
||||
pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc,
|
||||
args, numArgs, declspec, cxx0x);
|
||||
add(attr);
|
||||
return attr;
|
||||
}
|
||||
|
||||
AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc,
|
||||
IdentifierInfo *scopeName, SourceLocation scopeLoc,
|
||||
IdentifierInfo *parmName, SourceLocation parmLoc,
|
||||
const AvailabilityChange &introduced,
|
||||
const AvailabilityChange &deprecated,
|
||||
const AvailabilityChange &obsoleted,
|
||||
bool declspec = false, bool cxx0x = false) {
|
||||
AttributeList *attr =
|
||||
pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc,
|
||||
introduced, deprecated, obsoleted, declspec, cxx0x);
|
||||
add(attr);
|
||||
return attr;
|
||||
}
|
||||
|
||||
AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
|
||||
SourceLocation loc, int arg) {
|
||||
AttributeList *attr =
|
||||
pool.createIntegerAttribute(C, name, loc, arg);
|
||||
add(attr);
|
||||
return attr;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
mutable AttributePool pool;
|
||||
AttributeList *list;
|
||||
};
|
||||
|
||||
|
||||
@@ -271,7 +271,6 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// storage-class-specifier
|
||||
/*SCS*/unsigned StorageClassSpec : 3;
|
||||
unsigned SCS_thread_specified : 1;
|
||||
@@ -358,7 +357,7 @@ private:
|
||||
void operator=(const DeclSpec&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
|
||||
DeclSpec()
|
||||
DeclSpec(AttributeFactory &attrFactory)
|
||||
: StorageClassSpec(SCS_unspecified),
|
||||
SCS_thread_specified(false),
|
||||
SCS_extern_in_linkage_spec(false),
|
||||
@@ -377,6 +376,7 @@ public:
|
||||
Friend_specified(false),
|
||||
Constexpr_specified(false),
|
||||
StorageClassSpecAsWritten(SCS_unspecified),
|
||||
Attrs(attrFactory),
|
||||
ProtocolQualifiers(0),
|
||||
NumProtocolQualifiers(0),
|
||||
ProtocolLocs(0),
|
||||
@@ -581,6 +581,10 @@ public:
|
||||
bool isConstexprSpecified() const { return Constexpr_specified; }
|
||||
SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
|
||||
|
||||
AttributePool &getAttributePool() const {
|
||||
return Attrs.getPool();
|
||||
}
|
||||
|
||||
/// AddAttributes - contatenates two attribute lists.
|
||||
/// The GCC attribute syntax allows for the following:
|
||||
///
|
||||
@@ -594,9 +598,9 @@ public:
|
||||
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
|
||||
///
|
||||
void addAttributes(AttributeList *AL) {
|
||||
Attrs.append(AL);
|
||||
Attrs.addAll(AL);
|
||||
}
|
||||
void aetAttributes(AttributeList *AL) {
|
||||
void setAttributes(AttributeList *AL) {
|
||||
Attrs.set(AL);
|
||||
}
|
||||
|
||||
@@ -608,14 +612,12 @@ public:
|
||||
/// TakeAttributes - Return the current attribute list and remove them from
|
||||
/// the DeclSpec so that it doesn't own them.
|
||||
ParsedAttributes takeAttributes() {
|
||||
ParsedAttributes saved = Attrs;
|
||||
Attrs.clear();
|
||||
return saved;
|
||||
// The non-const "copy" constructor clears the operand automatically.
|
||||
return Attrs;
|
||||
}
|
||||
|
||||
void takeAttributesFrom(ParsedAttributes &attrs) {
|
||||
Attrs.append(attrs.getList());
|
||||
attrs.clear();
|
||||
Attrs.takeAllFrom(attrs);
|
||||
}
|
||||
|
||||
typedef Decl * const *ProtocolQualifierListTy;
|
||||
@@ -1197,8 +1199,7 @@ struct DeclaratorChunk {
|
||||
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
|
||||
SourceLocation ConstQualLoc,
|
||||
SourceLocation VolatileQualLoc,
|
||||
SourceLocation RestrictQualLoc,
|
||||
const ParsedAttributes &attrs) {
|
||||
SourceLocation RestrictQualLoc) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = Pointer;
|
||||
I.Loc = Loc;
|
||||
@@ -1206,35 +1207,33 @@ struct DeclaratorChunk {
|
||||
I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding();
|
||||
I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
|
||||
I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
|
||||
I.Ptr.AttrList = attrs.getList();
|
||||
I.Ptr.AttrList = 0;
|
||||
return I;
|
||||
}
|
||||
|
||||
/// getReference - Return a DeclaratorChunk for a reference.
|
||||
///
|
||||
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
|
||||
const ParsedAttributes &attrs,
|
||||
bool lvalue) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = Reference;
|
||||
I.Loc = Loc;
|
||||
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
|
||||
I.Ref.LValueRef = lvalue;
|
||||
I.Ref.AttrList = attrs.getList();
|
||||
I.Ref.AttrList = 0;
|
||||
return I;
|
||||
}
|
||||
|
||||
/// getArray - Return a DeclaratorChunk for an array.
|
||||
///
|
||||
static DeclaratorChunk getArray(unsigned TypeQuals,
|
||||
const ParsedAttributes &attrs,
|
||||
bool isStatic, bool isStar, Expr *NumElts,
|
||||
SourceLocation LBLoc, SourceLocation RBLoc) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = Array;
|
||||
I.Loc = LBLoc;
|
||||
I.EndLoc = RBLoc;
|
||||
I.Arr.AttrList = attrs.getList();
|
||||
I.Arr.AttrList = 0;
|
||||
I.Arr.TypeQuals = TypeQuals;
|
||||
I.Arr.hasStatic = isStatic;
|
||||
I.Arr.isStar = isStar;
|
||||
@@ -1244,8 +1243,7 @@ struct DeclaratorChunk {
|
||||
|
||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||
/// "TheDeclarator" is the declarator that this will be added to.
|
||||
static DeclaratorChunk getFunction(const ParsedAttributes &attrs,
|
||||
bool hasProto, bool isVariadic,
|
||||
static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
|
||||
SourceLocation EllipsisLoc,
|
||||
ParamInfo *ArgInfo, unsigned NumArgs,
|
||||
unsigned TypeQuals,
|
||||
@@ -1265,25 +1263,24 @@ struct DeclaratorChunk {
|
||||
|
||||
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
||||
///
|
||||
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
|
||||
const ParsedAttributes &attrs) {
|
||||
static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
|
||||
SourceLocation Loc) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = BlockPointer;
|
||||
I.Loc = Loc;
|
||||
I.Cls.TypeQuals = TypeQuals;
|
||||
I.Cls.AttrList = attrs.getList();
|
||||
I.Cls.AttrList = 0;
|
||||
return I;
|
||||
}
|
||||
|
||||
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
|
||||
unsigned TypeQuals,
|
||||
SourceLocation Loc,
|
||||
const ParsedAttributes &attrs) {
|
||||
SourceLocation Loc) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = MemberPointer;
|
||||
I.Loc = Loc;
|
||||
I.Mem.TypeQuals = TypeQuals;
|
||||
I.Mem.AttrList = attrs.getList();
|
||||
I.Mem.AttrList = 0;
|
||||
new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
|
||||
return I;
|
||||
}
|
||||
@@ -1352,8 +1349,8 @@ private:
|
||||
/// GroupingParens - Set by Parser::ParseParenDeclarator().
|
||||
bool GroupingParens : 1;
|
||||
|
||||
/// AttrList - Attributes.
|
||||
AttributeList *AttrList;
|
||||
/// Attrs - Attributes.
|
||||
ParsedAttributes Attrs;
|
||||
|
||||
/// AsmLabel - The asm label, if specified.
|
||||
Expr *AsmLabel;
|
||||
@@ -1377,8 +1374,8 @@ public:
|
||||
Declarator(const DeclSpec &ds, TheContext C)
|
||||
: DS(ds), Range(ds.getSourceRange()), Context(C),
|
||||
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
|
||||
GroupingParens(false), AttrList(0), AsmLabel(0),
|
||||
InlineParamsUsed(false), Extension(false) {
|
||||
GroupingParens(false), Attrs(ds.getAttributePool().getFactory()),
|
||||
AsmLabel(0), InlineParamsUsed(false), Extension(false) {
|
||||
}
|
||||
|
||||
~Declarator() {
|
||||
@@ -1396,6 +1393,10 @@ public:
|
||||
/// be shared or when in error recovery etc.
|
||||
DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
|
||||
|
||||
AttributePool &getAttributePool() const {
|
||||
return Attrs.getPool();
|
||||
}
|
||||
|
||||
/// getCXXScopeSpec - Return the C++ scope specifier (global scope or
|
||||
/// nested-name-specifier) that is part of the declarator-id.
|
||||
const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
|
||||
@@ -1445,7 +1446,7 @@ public:
|
||||
for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
|
||||
DeclTypeInfo[i].destroy();
|
||||
DeclTypeInfo.clear();
|
||||
AttrList = 0;
|
||||
Attrs.clear();
|
||||
AsmLabel = 0;
|
||||
InlineParamsUsed = false;
|
||||
}
|
||||
@@ -1552,8 +1553,13 @@ 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, SourceLocation EndLoc) {
|
||||
void AddTypeInfo(const DeclaratorChunk &TI,
|
||||
ParsedAttributes &attrs,
|
||||
SourceLocation EndLoc) {
|
||||
DeclTypeInfo.push_back(TI);
|
||||
DeclTypeInfo.back().getAttrListRef() = attrs.getList();
|
||||
getAttributePool().takeAllFrom(attrs.getPool());
|
||||
|
||||
if (!EndLoc.isInvalid())
|
||||
SetRangeEnd(EndLoc);
|
||||
}
|
||||
@@ -1633,28 +1639,26 @@ public:
|
||||
return const_cast<Declarator*>(this)->getFunctionTypeInfo();
|
||||
}
|
||||
|
||||
/// AddAttributes - simply adds the attribute list to the Declarator.
|
||||
/// takeAttributes - Takes attributes from the given parsed-attributes
|
||||
/// set and add them to this declarator.
|
||||
///
|
||||
/// These examples both add 3 attributes to "var":
|
||||
/// short int var __attribute__((aligned(16),common,deprecated));
|
||||
/// short int x, __attribute__((aligned(16)) var
|
||||
/// __attribute__((common,deprecated));
|
||||
///
|
||||
/// Also extends the range of the declarator.
|
||||
void addAttributes(AttributeList *alist, SourceLocation LastLoc) {
|
||||
AttrList = addAttributeLists(AttrList, alist);
|
||||
void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
|
||||
Attrs.takeAllFrom(attrs);
|
||||
|
||||
if (!LastLoc.isInvalid())
|
||||
SetRangeEnd(LastLoc);
|
||||
if (!lastLoc.isInvalid())
|
||||
SetRangeEnd(lastLoc);
|
||||
}
|
||||
|
||||
void addAttributes(const ParsedAttributes &attrs) {
|
||||
addAttributes(attrs.getList(), SourceLocation());
|
||||
}
|
||||
const AttributeList *getAttributes() const { return Attrs.getList(); }
|
||||
AttributeList *getAttributes() { return Attrs.getList(); }
|
||||
|
||||
const AttributeList *getAttributes() const { return AttrList; }
|
||||
AttributeList *getAttributes() { return AttrList; }
|
||||
|
||||
AttributeList *&getAttrListRef() { return AttrList; }
|
||||
AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
|
||||
|
||||
/// hasAttributes - do we contain any attributes?
|
||||
bool hasAttributes() const {
|
||||
|
||||
@@ -33,7 +33,7 @@ using namespace clang;
|
||||
TypeResult Parser::ParseTypeName(SourceRange *Range,
|
||||
Declarator::TheContext Context) {
|
||||
// Parse the common declaration-specifiers piece.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseSpecifierQualifierList(DS);
|
||||
|
||||
// Parse the abstract-declarator, if present.
|
||||
@@ -126,8 +126,8 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||
if (Tok.is(tok::r_paren)) {
|
||||
// __attribute__(( mode(byte) ))
|
||||
ConsumeParen(); // ignore the right paren loc for now
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
ParmName, ParmLoc, 0, 0));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
ParmName, ParmLoc, 0, 0);
|
||||
} else if (Tok.is(tok::comma)) {
|
||||
ConsumeToken();
|
||||
// __attribute__(( format(printf, 1, 2) ))
|
||||
@@ -150,9 +150,8 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||
}
|
||||
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
||||
ConsumeParen(); // ignore the right paren loc for now
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
||||
AttrNameLoc, ParmName, ParmLoc,
|
||||
ArgExprs.take(), ArgExprs.size()));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size());
|
||||
}
|
||||
}
|
||||
} else { // not an identifier
|
||||
@@ -161,8 +160,8 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||
// parse a possibly empty comma separated list of expressions
|
||||
// __attribute__(( nonnull() ))
|
||||
ConsumeParen(); // ignore the right paren loc for now
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0);
|
||||
break;
|
||||
case tok::kw_char:
|
||||
case tok::kw_wchar_t:
|
||||
@@ -179,9 +178,8 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||
case tok::kw_void:
|
||||
case tok::kw_typeof: {
|
||||
AttributeList *attr
|
||||
= AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0);
|
||||
attrs.add(attr);
|
||||
= attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0);
|
||||
if (attr->getKind() == AttributeList::AT_IBOutletCollection)
|
||||
Diag(Tok, diag::err_iboutletcollection_builtintype);
|
||||
// If it's a builtin type name, eat it and expect a rparen
|
||||
@@ -213,16 +211,16 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||
// Match the ')'.
|
||||
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
||||
ConsumeParen(); // ignore the right paren loc for now
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
||||
AttrNameLoc, 0, SourceLocation(),
|
||||
ArgExprs.take(), ArgExprs.size()));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0,
|
||||
AttrNameLoc, 0, SourceLocation(),
|
||||
ArgExprs.take(), ArgExprs.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0);
|
||||
}
|
||||
}
|
||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||
@@ -264,14 +262,14 @@ void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) {
|
||||
ExprResult ArgExpr(ParseAssignmentExpression());
|
||||
if (!ArgExpr.isInvalid()) {
|
||||
Expr *ExprList = ArgExpr.take();
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), &ExprList, 1, true));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), &ExprList, 1, true);
|
||||
}
|
||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||
SkipUntil(tok::r_paren, false);
|
||||
} else {
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0, true));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||
0, SourceLocation(), 0, 0, true);
|
||||
}
|
||||
}
|
||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||
@@ -290,8 +288,8 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
|
||||
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
|
||||
// FIXME: Support these properly!
|
||||
continue;
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, true));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,8 +298,8 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
|
||||
while (Tok.is(tok::kw___pascal)) {
|
||||
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
||||
SourceLocation AttrNameLoc = ConsumeToken();
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, true));
|
||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,9 +307,9 @@ void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
|
||||
// Treat these like attributes
|
||||
while (Tok.is(tok::kw___kernel)) {
|
||||
SourceLocation AttrNameLoc = ConsumeToken();
|
||||
attrs.add(AttrFactory.Create(PP.getIdentifierInfo("opencl_kernel_function"),
|
||||
AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, false));
|
||||
attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
|
||||
AttrNameLoc, 0, AttrNameLoc, 0,
|
||||
SourceLocation(), 0, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,45 +319,45 @@ void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
|
||||
// OpenCL qualifiers:
|
||||
case tok::kw___private:
|
||||
case tok::kw_private:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("address_space"), Loc, 0));
|
||||
PP.getIdentifierInfo("address_space"), Loc, 0);
|
||||
break;
|
||||
|
||||
case tok::kw___global:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global));
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
|
||||
break;
|
||||
|
||||
case tok::kw___local:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local));
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
|
||||
break;
|
||||
|
||||
case tok::kw___constant:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant));
|
||||
PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
|
||||
break;
|
||||
|
||||
case tok::kw___read_only:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only));
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
|
||||
break;
|
||||
|
||||
case tok::kw___write_only:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only));
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
|
||||
break;
|
||||
|
||||
case tok::kw___read_write:
|
||||
DS.addAttributes(AttrFactory.CreateIntegerAttribute(
|
||||
DS.getAttributes().addNewInteger(
|
||||
Actions.getASTContext(),
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write));
|
||||
PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@@ -592,12 +590,12 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
|
||||
*endLoc = RParenLoc;
|
||||
|
||||
// Record this attribute
|
||||
attrs.add(AttrFactory.Create(&Availability, AvailabilityLoc,
|
||||
0, SourceLocation(),
|
||||
Platform, PlatformLoc,
|
||||
Changes[Introduced],
|
||||
Changes[Deprecated],
|
||||
Changes[Obsoleted], false, false));
|
||||
attrs.addNew(&Availability, AvailabilityLoc,
|
||||
0, SourceLocation(),
|
||||
Platform, PlatformLoc,
|
||||
Changes[Introduced],
|
||||
Changes[Deprecated],
|
||||
Changes[Obsoleted], false, false);
|
||||
}
|
||||
|
||||
void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
|
||||
@@ -2175,7 +2173,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||
}
|
||||
|
||||
// Parse all the comma separated declarators.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
|
||||
if (!Tok.is(tok::at)) {
|
||||
struct CFieldCallback : FieldCallback {
|
||||
@@ -2236,7 +2234,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||
|
||||
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
||||
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
// If attributes exist after struct contents, parse them.
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
@@ -2286,7 +2284,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||
}
|
||||
|
||||
// If attributes exist after tag, parse them.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
CXXScopeSpec &SS = DS.getTypeSpecScope();
|
||||
@@ -2526,7 +2524,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
||||
SourceLocation IdentLoc = ConsumeToken();
|
||||
|
||||
// If attributes exist after the enumerator, parse them.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
SourceLocation EqualLoc;
|
||||
@@ -2570,7 +2568,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
||||
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
||||
|
||||
// If attributes exist after the identifier list, parse them.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
|
||||
@@ -2918,7 +2916,7 @@ bool Parser::isConstructorDeclarator() {
|
||||
DeclScopeObj.EnterDeclaratorScope();
|
||||
|
||||
// Optionally skip Microsoft attributes.
|
||||
ParsedAttributes Attrs;
|
||||
ParsedAttributes Attrs(AttrFactory);
|
||||
MaybeParseMicrosoftAttributes(Attrs);
|
||||
|
||||
// Check whether the next token(s) are part of a declaration
|
||||
@@ -2946,7 +2944,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
||||
bool CXX0XAttributesAllowed) {
|
||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
ParseCXX0XAttributes(attrs);
|
||||
if (CXX0XAttributesAllowed)
|
||||
DS.takeAttributesFrom(attrs);
|
||||
@@ -3092,7 +3090,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||
|
||||
SourceLocation Loc = ConsumeToken();
|
||||
D.SetRangeEnd(Loc);
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseTypeQualifierListOpt(DS);
|
||||
D.ExtendWithDeclSpec(DS);
|
||||
|
||||
@@ -3102,7 +3100,8 @@ 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(),
|
||||
Loc, DS.takeAttributes()),
|
||||
Loc),
|
||||
DS.getAttributes(),
|
||||
/* Don't replace range end. */SourceLocation());
|
||||
return;
|
||||
}
|
||||
@@ -3126,7 +3125,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||
|
||||
if (Kind == tok::star || Kind == tok::caret) {
|
||||
// Is a pointer.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
|
||||
ParseTypeQualifierListOpt(DS);
|
||||
D.ExtendWithDeclSpec(DS);
|
||||
@@ -3138,17 +3137,18 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||
D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
|
||||
DS.getConstSpecLoc(),
|
||||
DS.getVolatileSpecLoc(),
|
||||
DS.getRestrictSpecLoc(),
|
||||
DS.takeAttributes()),
|
||||
DS.getRestrictSpecLoc()),
|
||||
DS.getAttributes(),
|
||||
SourceLocation());
|
||||
else
|
||||
// Remember that we parsed a Block type, and remember the type-quals.
|
||||
D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
|
||||
Loc, DS.takeAttributes()),
|
||||
Loc),
|
||||
DS.getAttributes(),
|
||||
SourceLocation());
|
||||
} else {
|
||||
// Is a reference
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
|
||||
// Complain about rvalue references in C++03, but then go on and build
|
||||
// the declarator.
|
||||
@@ -3196,8 +3196,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||
|
||||
// Remember that we parsed a reference type. It doesn't have type-quals.
|
||||
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
|
||||
DS.takeAttributes(),
|
||||
Kind == tok::amp),
|
||||
DS.getAttributes(),
|
||||
SourceLocation());
|
||||
}
|
||||
}
|
||||
@@ -3362,7 +3362,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||
if (!isCXXFunctionDeclarator(warnIfAmbiguous))
|
||||
break;
|
||||
}
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
ParseFunctionDeclarator(ConsumeParen(), D, attrs);
|
||||
} else if (Tok.is(tok::l_square)) {
|
||||
ParseBracketDeclarator(D);
|
||||
@@ -3399,7 +3399,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||
// In either case, we need to eat any attributes to be able to determine what
|
||||
// sort of paren this is.
|
||||
//
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
bool RequiresArg = false;
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
ParseGNUAttributes(attrs);
|
||||
@@ -3445,13 +3445,12 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||
if (isGrouping) {
|
||||
bool hadGroupingParens = D.hasGroupingParens();
|
||||
D.setGroupingParens(true);
|
||||
if (!attrs.empty())
|
||||
D.addAttributes(attrs.getList(), SourceLocation());
|
||||
|
||||
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
|
||||
// Match the ')'.
|
||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, StartLoc);
|
||||
D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc), EndLoc);
|
||||
D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc),
|
||||
attrs, EndLoc);
|
||||
|
||||
D.setGroupingParens(hadGroupingParens);
|
||||
return;
|
||||
@@ -3518,7 +3517,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
SourceLocation EndLoc = ConsumeParen(); // Eat the closing ')'.
|
||||
|
||||
// cv-qualifier-seq[opt].
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
SourceLocation RefQualifierLoc;
|
||||
bool RefQualifierIsLValueRef = true;
|
||||
ExceptionSpecificationType ESpecType = EST_None;
|
||||
@@ -3559,8 +3558,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
|
||||
// Remember that we parsed a function type, and remember the attributes.
|
||||
// int() -> no prototype, no '...'.
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
|
||||
/*prototype*/getLang().CPlusPlus,
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
|
||||
/*variadic*/ false,
|
||||
SourceLocation(),
|
||||
/*arglist*/ 0, 0,
|
||||
@@ -3575,7 +3573,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
NoexceptExpr.get() : 0,
|
||||
LParenLoc, EndLoc, D,
|
||||
TrailingReturnType),
|
||||
EndLoc);
|
||||
attrs, EndLoc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3639,7 +3637,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
|
||||
// Parse the declaration-specifiers.
|
||||
// Just use the ParsingDeclaration "scope" of the declarator.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
|
||||
// Skip any Microsoft attributes before a param.
|
||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
||||
@@ -3765,7 +3763,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
// If we have the closing ')', eat it.
|
||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
SourceLocation RefQualifierLoc;
|
||||
bool RefQualifierIsLValueRef = true;
|
||||
ExceptionSpecificationType ESpecType = EST_None;
|
||||
@@ -3814,8 +3812,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
PrototypeScope.Exit();
|
||||
|
||||
// Remember that we parsed a function type, and remember the attributes.
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
|
||||
/*proto*/true, IsVariadic,
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
|
||||
EllipsisLoc,
|
||||
ParamInfo.data(), ParamInfo.size(),
|
||||
DS.getTypeQualifiers(),
|
||||
@@ -3829,7 +3826,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||
NoexceptExpr.get() : 0,
|
||||
LParenLoc, EndLoc, D,
|
||||
TrailingReturnType),
|
||||
EndLoc);
|
||||
attrs, EndLoc);
|
||||
}
|
||||
|
||||
/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
|
||||
@@ -3898,15 +3895,15 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
||||
// Remember that we parsed a function type, and remember the attributes. This
|
||||
// function type is always a K&R style function type, which is not varargs and
|
||||
// has no prototype.
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||
/*proto*/false, /*varargs*/false,
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
|
||||
SourceLocation(),
|
||||
&ParamInfo[0], ParamInfo.size(),
|
||||
/*TypeQuals*/0,
|
||||
true, SourceLocation(),
|
||||
EST_None, SourceLocation(), 0, 0,
|
||||
0, 0, LParenLoc, RLoc, D),
|
||||
RLoc);
|
||||
attrs, RLoc);
|
||||
}
|
||||
|
||||
/// [C90] direct-declarator '[' constant-expression[opt] ']'
|
||||
@@ -3921,14 +3918,14 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||
// This code does a fast path to handle some of the most obvious cases.
|
||||
if (Tok.getKind() == tok::r_square) {
|
||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
// Remember that we parsed the empty array type.
|
||||
ExprResult NumElements;
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
|
||||
StartLoc, EndLoc),
|
||||
EndLoc);
|
||||
attrs, EndLoc);
|
||||
return;
|
||||
} else if (Tok.getKind() == tok::numeric_constant &&
|
||||
GetLookAheadToken(1).is(tok::r_square)) {
|
||||
@@ -3937,14 +3934,14 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||
ConsumeToken();
|
||||
|
||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
// Remember that we parsed a array type, and remember its features.
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
|
||||
ExprRes.release(),
|
||||
StartLoc, EndLoc),
|
||||
EndLoc);
|
||||
attrs, EndLoc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3955,7 +3952,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||
|
||||
// If there is a type-qualifier-list, read it now.
|
||||
// Type qualifiers in an array subscript are a C99 feature.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||
|
||||
// If we haven't already read 'static', check to see if there is one after the
|
||||
@@ -4003,15 +4000,15 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||
|
||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
// Remember that we parsed a array type, and remember its features.
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
|
||||
StaticLoc.isValid(), isStar,
|
||||
NumElements.release(),
|
||||
StartLoc, EndLoc),
|
||||
EndLoc);
|
||||
attrs, EndLoc);
|
||||
}
|
||||
|
||||
/// [GNU] typeof-specifier:
|
||||
|
||||
@@ -69,11 +69,9 @@ Decl *Parser::ParseNamespace(unsigned Context,
|
||||
}
|
||||
|
||||
// Read label attributes, if present.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
attrTok = Tok;
|
||||
|
||||
// FIXME: save these somewhere.
|
||||
ParseGNUAttributes(attrs);
|
||||
}
|
||||
|
||||
@@ -118,7 +116,7 @@ Decl *Parser::ParseNamespace(unsigned Context,
|
||||
"parsing namespace");
|
||||
|
||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
ParseExternalDeclaration(attrs);
|
||||
@@ -138,9 +136,9 @@ Decl *Parser::ParseNamespace(unsigned Context,
|
||||
/// alias definition.
|
||||
///
|
||||
Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
|
||||
SourceLocation AliasLoc,
|
||||
IdentifierInfo *Alias,
|
||||
SourceLocation &DeclEnd) {
|
||||
SourceLocation AliasLoc,
|
||||
IdentifierInfo *Alias,
|
||||
SourceLocation &DeclEnd) {
|
||||
assert(Tok.is(tok::equal) && "Not equal token");
|
||||
|
||||
ConsumeToken(); // eat the '='.
|
||||
@@ -199,7 +197,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
|
||||
Tok.is(tok::l_brace) ? Tok.getLocation()
|
||||
: SourceLocation());
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
|
||||
@@ -216,7 +214,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
|
||||
|
||||
SourceLocation LBrace = ConsumeBrace();
|
||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
ParseExternalDeclaration(attrs);
|
||||
@@ -380,7 +378,7 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
|
||||
}
|
||||
|
||||
// Parse (optional) attributes (most likely GNU strong-using extension).
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
// Eat ';'.
|
||||
@@ -590,7 +588,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
|
||||
EndLocation = IdLoc;
|
||||
|
||||
// Fake up a Declarator to use with ActOnTypeName.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
DS.SetRangeStart(IdLoc);
|
||||
DS.SetRangeEnd(EndLocation);
|
||||
DS.getTypeSpecScope() = SS;
|
||||
@@ -677,7 +675,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||
SuppressingAccessChecks = true;
|
||||
}
|
||||
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
// If attributes exist after tag, parse them.
|
||||
if (Tok.is(tok::kw___attribute))
|
||||
ParseGNUAttributes(attrs);
|
||||
@@ -1488,7 +1486,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||
// is a bitfield.
|
||||
ColonProtectionRAIIObject X(*this);
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
// Optional C++0x attribute-specifier
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
@@ -1837,7 +1835,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||
}
|
||||
|
||||
// If attributes exist after class contents, parse them.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
if (TagDecl)
|
||||
@@ -2309,8 +2307,8 @@ void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||
break;
|
||||
}
|
||||
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
|
||||
SourceLocation(), 0, 0, false, true));
|
||||
attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
|
||||
SourceLocation(), 0, 0, false, true);
|
||||
AttrParsed = true;
|
||||
break;
|
||||
}
|
||||
@@ -2330,9 +2328,9 @@ void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||
|
||||
ExprVector ArgExprs(Actions);
|
||||
ArgExprs.push_back(ArgExpr.release());
|
||||
attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
|
||||
0, ParamLoc, ArgExprs.take(), 1,
|
||||
false, true));
|
||||
attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
|
||||
0, ParamLoc, ArgExprs.take(), 1,
|
||||
false, true);
|
||||
|
||||
AttrParsed = true;
|
||||
break;
|
||||
|
||||
@@ -683,7 +683,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
||||
if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
|
||||
if (Typ.get()->isObjCObjectOrInterfaceType()) {
|
||||
// Fake up a Declarator to use with ActOnTypeName.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
DS.SetRangeStart(ILoc);
|
||||
DS.SetRangeEnd(ILoc);
|
||||
const char *PrevSpec = 0;
|
||||
@@ -826,7 +826,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
||||
ParsedType Type = getTypeAnnotation(Tok);
|
||||
|
||||
// Fake up a Declarator to use with ActOnTypeName.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
DS.SetRangeStart(Tok.getLocation());
|
||||
DS.SetRangeEnd(Tok.getLastLoc());
|
||||
|
||||
@@ -876,7 +876,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
||||
|
||||
// postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
|
||||
//
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseCXXSimpleTypeSpecifier(DS);
|
||||
if (Tok.isNot(tok::l_paren))
|
||||
return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
|
||||
@@ -1634,7 +1634,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
||||
|
||||
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
||||
Diag(Tok, diag::ext_gnu_statement_expr);
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
StmtResult Stmt(ParseCompoundStatement(attrs, true));
|
||||
ExprType = CompoundStmt;
|
||||
|
||||
@@ -1850,7 +1850,7 @@ void Parser::ParseBlockId() {
|
||||
}
|
||||
|
||||
// Parse the specifier-qualifier-list piece.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseSpecifierQualifierList(DS);
|
||||
|
||||
// Parse the block-declarator.
|
||||
@@ -1858,7 +1858,7 @@ void Parser::ParseBlockId() {
|
||||
ParseDeclarator(DeclaratorInfo);
|
||||
|
||||
// We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
|
||||
DeclaratorInfo.addAttributes(DS.takeAttributes());
|
||||
DeclaratorInfo.takeAttributes(DS.getAttributes(), SourceLocation());
|
||||
|
||||
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||
|
||||
@@ -1894,7 +1894,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||
Actions.ActOnBlockStart(CaretLoc, getCurScope());
|
||||
|
||||
// Parse the return type if present.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
|
||||
// FIXME: Since the return type isn't actually parsed, it can't be used to
|
||||
// fill ParamInfo with an initial valid range, so do it manually.
|
||||
@@ -1926,8 +1926,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||
ParseBlockId();
|
||||
} else {
|
||||
// Otherwise, pretend we saw (void).
|
||||
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||
true, false,
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
|
||||
SourceLocation(),
|
||||
0, 0, 0,
|
||||
true, SourceLocation(),
|
||||
@@ -1936,7 +1936,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||
0, 0, 0, 0,
|
||||
CaretLoc, CaretLoc,
|
||||
ParamInfo),
|
||||
CaretLoc);
|
||||
attrs, CaretLoc);
|
||||
|
||||
MaybeParseGNUAttributes(ParamInfo);
|
||||
|
||||
|
||||
@@ -800,7 +800,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
|
||||
}
|
||||
|
||||
// type-specifier-seq
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseSpecifierQualifierList(DS);
|
||||
|
||||
// declarator
|
||||
@@ -1391,7 +1391,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
|
||||
// ptr-operator conversion-declarator[opt]
|
||||
|
||||
// Parse the type-specifier-seq.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
|
||||
return true;
|
||||
|
||||
@@ -1644,7 +1644,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
|
||||
SourceLocation PlacementLParen, PlacementRParen;
|
||||
|
||||
SourceRange TypeIdParens;
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
// If it turns out to be a placement, we change the type location.
|
||||
@@ -1746,10 +1746,12 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
|
||||
first = false;
|
||||
|
||||
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
|
||||
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
D.AddTypeInfo(DeclaratorChunk::getArray(0,
|
||||
/*static=*/false, /*star=*/false,
|
||||
Size.release(), LLoc, RLoc),
|
||||
RLoc);
|
||||
attrs, RLoc);
|
||||
|
||||
if (RLoc.isInvalid())
|
||||
return;
|
||||
|
||||
@@ -41,11 +41,11 @@ Decl *Parser::ParseObjCAtDirectives() {
|
||||
case tok::objc_class:
|
||||
return ParseObjCAtClassDeclaration(AtLoc);
|
||||
case tok::objc_interface: {
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
|
||||
}
|
||||
case tok::objc_protocol: {
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
|
||||
}
|
||||
case tok::objc_implementation:
|
||||
@@ -371,7 +371,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
|
||||
|
||||
// FIXME: as the name implies, this rule allows function definitions.
|
||||
// We could pass a flag or check for functions during semantic analysis.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
|
||||
continue;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
|
||||
OCDS, AtLoc, MethodImplKind);
|
||||
|
||||
// Parse all the comma separated declarators.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseStructDeclaration(DS, Callback);
|
||||
|
||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
|
||||
@@ -843,9 +843,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
ReturnType = ParseObjCTypeName(DSRet, OTN_ResultType);
|
||||
|
||||
// If attributes exist before the method, parse them.
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes methodAttrs(AttrFactory);
|
||||
if (getLang().ObjC2)
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
MaybeParseGNUAttributes(methodAttrs);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||
@@ -870,7 +870,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
// If attributes exist after the method, parse them.
|
||||
if (getLang().ObjC2)
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
MaybeParseGNUAttributes(methodAttrs);
|
||||
|
||||
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
|
||||
Decl *Result
|
||||
@@ -878,8 +878,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
mType, IDecl, DSRet, ReturnType, Sel,
|
||||
0,
|
||||
CParamInfo.data(), CParamInfo.size(),
|
||||
attrs.getList(), MethodImplKind, false,
|
||||
MethodDefinition);
|
||||
methodAttrs.getList(), MethodImplKind,
|
||||
false, MethodDefinition);
|
||||
PD.complete(Result);
|
||||
return Result;
|
||||
}
|
||||
@@ -888,8 +888,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
|
||||
ParseScope PrototypeScope(this,
|
||||
Scope::FunctionPrototypeScope|Scope::DeclScope);
|
||||
|
||||
AttributePool allParamAttrs(AttrFactory);
|
||||
|
||||
while (1) {
|
||||
ParsedAttributes paramAttrs(AttrFactory);
|
||||
Sema::ObjCArgInfo ArgInfo;
|
||||
|
||||
// Each iteration parses a single keyword argument.
|
||||
@@ -906,9 +909,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
// If attributes exist before the argument name, parse them.
|
||||
ArgInfo.ArgAttrs = 0;
|
||||
if (getLang().ObjC2) {
|
||||
ParsedAttributes attrs;
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
ArgInfo.ArgAttrs = attrs.getList();
|
||||
MaybeParseGNUAttributes(paramAttrs);
|
||||
ArgInfo.ArgAttrs = paramAttrs.getList();
|
||||
}
|
||||
|
||||
// Code completion for the next piece of the selector.
|
||||
@@ -937,6 +939,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
ArgInfos.push_back(ArgInfo);
|
||||
KeyIdents.push_back(SelIdent);
|
||||
|
||||
// Make sure the attributes persist.
|
||||
allParamAttrs.takeAllFrom(paramAttrs.getPool());
|
||||
|
||||
// Code completion for the next piece of the selector.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
ConsumeCodeCompletionToken();
|
||||
@@ -967,7 +972,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
ConsumeToken();
|
||||
break;
|
||||
}
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
// Parse the declarator.
|
||||
Declarator ParmDecl(DS, Declarator::PrototypeContext);
|
||||
@@ -984,7 +989,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
// FIXME: Add support for optional parameter list...
|
||||
// If attributes exist after the method, parse them.
|
||||
if (getLang().ObjC2)
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
MaybeParseGNUAttributes(methodAttrs);
|
||||
|
||||
if (KeyIdents.size() == 0) {
|
||||
// Leave prototype scope.
|
||||
@@ -999,7 +1004,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||
mType, IDecl, DSRet, ReturnType, Sel,
|
||||
&ArgInfos[0],
|
||||
CParamInfo.data(), CParamInfo.size(),
|
||||
attrs.getList(),
|
||||
methodAttrs.getList(),
|
||||
MethodImplKind, isVariadic, MethodDefinition);
|
||||
// Leave prototype scope.
|
||||
PrototypeScope.Exit();
|
||||
@@ -1172,7 +1177,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||
} Callback(*this, interfaceDecl, visibility, AllIvarDecls);
|
||||
|
||||
// Parse all the comma separated declarators.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseStructDeclaration(DS, Callback);
|
||||
|
||||
if (Tok.is(tok::semi)) {
|
||||
@@ -1616,7 +1621,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||
ConsumeParen();
|
||||
ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
|
||||
if (Tok.isNot(tok::ellipsis)) {
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
// For some odd reason, the name of the exception variable is
|
||||
// optional. As a result, we need to use "PrototypeContext", because
|
||||
@@ -1848,7 +1853,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
|
||||
// typename-specifier
|
||||
// simple-type-specifier
|
||||
// expression (that starts with one of the above)
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseCXXSimpleTypeSpecifier(DS);
|
||||
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
|
||||
@@ -81,7 +81,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
// Cases in this switch statement should fall through if the parser expects
|
||||
@@ -500,7 +500,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
|
||||
DeclsInGroup.data(), DeclsInGroup.size());
|
||||
StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
|
||||
@@ -528,7 +528,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||
while (Tok.is(tok::kw___extension__))
|
||||
ConsumeToken();
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
// If this is the start of a declaration, parse it as such.
|
||||
@@ -1049,7 +1049,7 @@ StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) {
|
||||
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
|
||||
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
|
||||
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
||||
@@ -1359,7 +1359,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
|
||||
msAsm = true;
|
||||
return FuzzyParseMicrosoftAsmStatement(AsmLoc);
|
||||
}
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
ParseTypeQualifierListOpt(DS, true, false);
|
||||
|
||||
@@ -1643,7 +1643,7 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
|
||||
if (Tok.isNot(tok::l_brace))
|
||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
StmtResult TryBlock(ParseCompoundStatement(attrs));
|
||||
if (TryBlock.isInvalid())
|
||||
return move(TryBlock);
|
||||
@@ -1696,7 +1696,7 @@ StmtResult Parser::ParseCXXCatchBlock() {
|
||||
// without default arguments.
|
||||
Decl *ExceptionDecl = 0;
|
||||
if (Tok.isNot(tok::ellipsis)) {
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
if (ParseCXXTypeSpecifierSeq(DS))
|
||||
return StmtError();
|
||||
Declarator ExDecl(DS, Declarator::CXXCatchContext);
|
||||
@@ -1712,7 +1712,7 @@ StmtResult Parser::ParseCXXCatchBlock() {
|
||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||
|
||||
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
StmtResult Block(ParseCompoundStatement(attrs));
|
||||
if (Block.isInvalid())
|
||||
return move(Block);
|
||||
|
||||
@@ -196,7 +196,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
|
||||
return 0;
|
||||
}
|
||||
|
||||
ParsedAttributesWithRange prefixAttrs;
|
||||
ParsedAttributesWithRange prefixAttrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(prefixAttrs);
|
||||
|
||||
if (Tok.is(tok::kw_using))
|
||||
@@ -205,7 +205,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
|
||||
|
||||
// Parse the declaration specifiers, stealing the accumulated
|
||||
// diagnostics from the template parameters.
|
||||
ParsingDeclSpec DS(DiagsFromTParams);
|
||||
ParsingDeclSpec DS(*this, &DiagsFromTParams);
|
||||
|
||||
DS.takeAttributesFrom(prefixAttrs);
|
||||
|
||||
@@ -598,7 +598,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
|
||||
// Parse the declaration-specifiers (i.e., the type).
|
||||
// FIXME: The type should probably be restricted in some way... Not all
|
||||
// declarators (parts of declarators?) are accepted for parameters.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
|
||||
// Parse this as a typename.
|
||||
|
||||
@@ -1151,7 +1151,7 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
|
||||
return TPResult::True(); // '...' is a sign of a function declarator.
|
||||
}
|
||||
|
||||
ParsedAttributes attrs;
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
|
||||
// decl-specifier-seq
|
||||
|
||||
@@ -441,7 +441,7 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ParsedAttributesWithRange attrs;
|
||||
ParsedAttributesWithRange attrs(AttrFactory);
|
||||
MaybeParseCXX0XAttributes(attrs);
|
||||
MaybeParseMicrosoftAttributes(attrs);
|
||||
|
||||
@@ -839,7 +839,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
|
||||
SourceLocation DSStart = Tok.getLocation();
|
||||
|
||||
// Parse the common declaration-specifiers piece.
|
||||
DeclSpec DS;
|
||||
DeclSpec DS(AttrFactory);
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
|
||||
// C99 6.9.1p6: 'each declaration in the declaration list shall have at
|
||||
|
||||
@@ -12,46 +12,89 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Sema/AttributeList.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
using namespace clang;
|
||||
|
||||
AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
|
||||
IdentifierInfo *aName, SourceLocation aLoc,
|
||||
IdentifierInfo *sName, SourceLocation sLoc,
|
||||
IdentifierInfo *pName, SourceLocation pLoc,
|
||||
Expr **ExprList, unsigned numArgs,
|
||||
bool declspec, bool cxx0x)
|
||||
: AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
|
||||
ScopeLoc(sLoc),
|
||||
ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
|
||||
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
|
||||
|
||||
if (numArgs == 0)
|
||||
Args = 0;
|
||||
else {
|
||||
// Allocate the Args array using the BumpPtrAllocator.
|
||||
Args = Alloc.Allocate<Expr*>(numArgs);
|
||||
memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
|
||||
}
|
||||
size_t AttributeList::allocated_size() const {
|
||||
if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
|
||||
return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
|
||||
}
|
||||
|
||||
AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
|
||||
IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||
const AvailabilityChange &Introduced,
|
||||
const AvailabilityChange &Deprecated,
|
||||
const AvailabilityChange &Obsoleted,
|
||||
bool declspec, bool cxx0x)
|
||||
: AttrName(AttrName), AttrLoc(AttrLoc), ScopeName(ScopeName),
|
||||
ScopeLoc(ScopeLoc), ParmName(ParmName), ParmLoc(ParmLoc),
|
||||
Args(0), NumArgs(0), Next(0),
|
||||
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
|
||||
AvailabilityIntroduced(Introduced),
|
||||
AvailabilityDeprecated(Deprecated),
|
||||
AvailabilityObsoleted(Obsoleted),
|
||||
Invalid(false) {
|
||||
AttributeFactory::AttributeFactory() {
|
||||
// Go ahead and configure all the inline capacity. This is just a memset.
|
||||
FreeLists.resize(InlineFreeListsCapacity);
|
||||
}
|
||||
AttributeFactory::~AttributeFactory() {}
|
||||
|
||||
static size_t getFreeListIndexForSize(size_t size) {
|
||||
assert(size >= sizeof(AttributeList));
|
||||
assert((size % sizeof(void*)) == 0);
|
||||
return ((size - sizeof(AttributeList)) / sizeof(void*));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, allocate something new.
|
||||
return Alloc.Allocate(size, llvm::AlignOf<AttributeFactory>::Alignment);
|
||||
}
|
||||
|
||||
void AttributeFactory::reclaimPool(AttributeList *cur) {
|
||||
assert(cur && "reclaiming empty pool!");
|
||||
do {
|
||||
// Read this here, because we're going to overwrite NextInPool
|
||||
// when we toss 'cur' into the appropriate queue.
|
||||
AttributeList *next = cur->NextInPool;
|
||||
|
||||
size_t size = cur->allocated_size();
|
||||
size_t freeListIndex = getFreeListIndexForSize(size);
|
||||
|
||||
// Expand FreeLists to the appropriate size, if required.
|
||||
if (freeListIndex >= FreeLists.size())
|
||||
FreeLists.resize(freeListIndex+1);
|
||||
|
||||
// Add 'cur' to the appropriate free-list.
|
||||
cur->NextInPool = FreeLists[freeListIndex];
|
||||
FreeLists[freeListIndex] = cur;
|
||||
|
||||
cur = next;
|
||||
} while (cur);
|
||||
}
|
||||
|
||||
void AttributePool::takePool(AttributeList *pool) {
|
||||
assert(pool);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
AttributeList *
|
||||
AttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
|
||||
SourceLocation TokLoc, int Arg) {
|
||||
Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
|
||||
C.IntTy, TokLoc);
|
||||
return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
|
||||
}
|
||||
|
||||
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
||||
|
||||
@@ -134,8 +134,7 @@ CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
|
||||
|
||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||
/// "TheDeclarator" is the declarator that this will be added to.
|
||||
DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
|
||||
bool hasProto, bool isVariadic,
|
||||
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||
SourceLocation EllipsisLoc,
|
||||
ParamInfo *ArgInfo,
|
||||
unsigned NumArgs,
|
||||
@@ -157,7 +156,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
|
||||
I.Kind = Function;
|
||||
I.Loc = LocalRangeBegin;
|
||||
I.EndLoc = LocalRangeEnd;
|
||||
I.Fun.AttrList = attrs.getList();
|
||||
I.Fun.AttrList = 0;
|
||||
I.Fun.hasPrototype = hasProto;
|
||||
I.Fun.isVariadic = isVariadic;
|
||||
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
||||
|
||||
@@ -5502,7 +5502,8 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
|
||||
|
||||
// Implicitly declare the argument as type 'int' for lack of a better
|
||||
// type.
|
||||
DeclSpec DS;
|
||||
AttributeFactory attrs;
|
||||
DeclSpec DS(attrs);
|
||||
const char* PrevSpec; // unused
|
||||
unsigned DiagID; // unused
|
||||
DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
|
||||
@@ -5838,17 +5839,18 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
||||
|
||||
// Set a Declarator for the implicit definition: int foo();
|
||||
const char *Dummy;
|
||||
DeclSpec DS;
|
||||
AttributeFactory attrFactory;
|
||||
DeclSpec DS(attrFactory);
|
||||
unsigned DiagID;
|
||||
bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
|
||||
(void)Error; // Silence warning.
|
||||
assert(!Error && "Error setting up implicit decl!");
|
||||
Declarator D(DS, Declarator::BlockContext);
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||
false, false, SourceLocation(), 0,
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
|
||||
0, 0, true, SourceLocation(),
|
||||
EST_None, SourceLocation(),
|
||||
0, 0, 0, 0, Loc, Loc, D),
|
||||
DS.getAttributes(),
|
||||
SourceLocation());
|
||||
D.SetIdentifier(&II, Loc);
|
||||
|
||||
|
||||
@@ -536,7 +536,6 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
|
||||
|
||||
// ...and *prepend* it to the declarator.
|
||||
declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction(
|
||||
ParsedAttributes(),
|
||||
/*proto*/ true,
|
||||
/*variadic*/ false, SourceLocation(),
|
||||
/*args*/ 0, 0,
|
||||
|
||||
Reference in New Issue
Block a user