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:
John McCall
2011-03-24 11:26:52 +00:00
parent 33f352ca62
commit 084e83dfe7
16 changed files with 572 additions and 329 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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