diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AttributeList.cpp | 109 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 1 |
4 files changed, 84 insertions, 41 deletions
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index ae5ea673eb..792ab4ee8b 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -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*)); +} + +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::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) { +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) { diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 8cbf9d9fed..9bbeef7cb0 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -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(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 544d1ae1e7..a6c154338f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b3cdbb2725..53242294ac 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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, |