summaryrefslogtreecommitdiffstats
path: root/clang/include/clang/Sema/AttributeList.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Sema/AttributeList.h')
-rw-r--r--clang/include/clang/Sema/AttributeList.h284
1 files changed, 150 insertions, 134 deletions
diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h
index dd15b7a2f56..70a0306f41a 100644
--- a/clang/include/clang/Sema/AttributeList.h
+++ b/clang/include/clang/Sema/AttributeList.h
@@ -21,6 +21,7 @@
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/VersionTuple.h"
#include <cassert>
@@ -181,12 +182,6 @@ private:
const Expr *MessageExpr;
- /// The next attribute in the current position.
- AttributeList *NextInPosition = nullptr;
-
- /// The next attribute allocated in the current Pool.
- AttributeList *NextInPool = nullptr;
-
/// Arguments, if any, are stored immediately following the object.
ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
ArgsUnion const *getArgsBuffer() const {
@@ -433,9 +428,6 @@ public:
static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
Syntax SyntaxUsed);
- AttributeList *getNext() const { return NextInPosition; }
- void setNext(AttributeList *N) { NextInPosition = N; }
-
/// getNumArgs - Return the number of actual arguments to this attribute.
unsigned getNumArgs() const { return NumArgs; }
@@ -555,6 +547,7 @@ public:
unsigned getSemanticSpelling() const;
};
+class AttributePool;
/// A factory, from which one makes pools, from which one creates
/// individual attributes which are deallocated with the pool.
///
@@ -595,7 +588,8 @@ private:
/// Free lists. The index is determined by the following formula:
/// (size - sizeof(AttributeList)) / sizeof(void*)
- SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
+ SmallVector<SmallVector<AttributeList *, 8>, InlineFreeListsCapacity>
+ FreeLists;
// The following are the private interface used by AttributePool.
friend class AttributePool;
@@ -603,12 +597,14 @@ private:
/// Allocate an attribute of the given size.
void *allocate(size_t size);
+ void deallocate(AttributeList *AL);
+
/// Reclaim all the attributes in the given pool chain, which is
/// non-empty. Note that the current implementation is safe
/// against reclaiming things which were not actually allocated
/// with the allocator, although of course it's important to make
/// sure that their allocator lives at least as long as this one.
- void reclaimPool(AttributeList *head);
+ void reclaimPool(AttributePool &head);
public:
AttributeFactory();
@@ -616,21 +612,26 @@ public:
};
class AttributePool {
+ friend class AttributeFactory;
AttributeFactory &Factory;
- AttributeList *Head = nullptr;
+ llvm::TinyPtrVector<AttributeList *> Attrs;
void *allocate(size_t size) {
return Factory.allocate(size);
}
AttributeList *add(AttributeList *attr) {
- // We don't care about the order of the pool.
- attr->NextInPool = Head;
- Head = attr;
+ Attrs.push_back(attr);
return attr;
}
- void takePool(AttributeList *pool);
+ void remove(AttributeList *attr) {
+ assert(llvm::is_contained(Attrs, attr) &&
+ "Can't take attribute from a pool that doesn't own it!");
+ Attrs.erase(llvm::find(Attrs, attr));
+ }
+
+ void takePool(AttributePool &pool);
public:
/// Create a new pool for a factory.
@@ -638,30 +639,22 @@ public:
AttributePool(const AttributePool &) = delete;
- ~AttributePool() {
- if (Head) Factory.reclaimPool(Head);
- }
+ ~AttributePool() { Factory.reclaimPool(*this); }
/// Move the given pool's allocations to this pool.
- AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
- pool.Head = nullptr;
- }
+ AttributePool(AttributePool &&pool) = default;
AttributeFactory &getFactory() const { return Factory; }
void clear() {
- if (Head) {
- Factory.reclaimPool(Head);
- Head = nullptr;
- }
+ Factory.reclaimPool(*this);
+ Attrs.clear();
}
/// Take the given pool's allocations and add them to this pool.
void takeAllFrom(AttributePool &pool) {
- if (pool.Head) {
- takePool(pool.Head);
- pool.Head = nullptr;
- }
+ takePool(pool);
+ pool.Attrs.clear();
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -669,12 +662,11 @@ public:
ArgsUnion *args, unsigned numArgs,
AttributeList::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) {
- void *memory = allocate(sizeof(AttributeList)
- + numArgs * sizeof(ArgsUnion));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- args, numArgs, syntax,
- ellipsisLoc));
+ void *memory =
+ allocate(sizeof(AttributeList) + numArgs * sizeof(ArgsUnion));
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc, args,
+ numArgs, syntax, ellipsisLoc));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -683,133 +675,158 @@ public:
const AvailabilityChange &introduced,
const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted,
- SourceLocation unavailable,
- const Expr *MessageExpr,
- AttributeList::Syntax syntax,
- SourceLocation strict, const Expr *ReplacementExpr) {
+ SourceLocation unavailable, const Expr *MessageExpr,
+ AttributeList::Syntax syntax, SourceLocation strict,
+ const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr,
- syntax, strict, ReplacementExpr));
+ return add(new (memory) AttributeList(
+ attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
+ obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1,
- IdentifierLoc *Param2,
- IdentifierLoc *Param3,
- AttributeList::Syntax syntax) {
+ IdentifierLoc *Param1, IdentifierLoc *Param2,
+ IdentifierLoc *Param3, AttributeList::Syntax syntax) {
size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
void *memory = allocate(size);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param1, Param2, Param3,
- syntax));
- }
-
- AttributeList *createTypeTagForDatatype(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull,
- AttributeList::Syntax syntax) {
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc,
+ Param1, Param2, Param3, syntax));
+ }
+
+ AttributeList *
+ createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *argumentKind,
+ ParsedType matchingCType, bool layoutCompatible,
+ bool mustBeNull, AttributeList::Syntax syntax) {
void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- argumentKind, matchingCType,
- layoutCompatible, mustBeNull,
- syntax));
+ return add(new (memory) AttributeList(
+ attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
+ layoutCompatible, mustBeNull, syntax));
}
- AttributeList *createTypeAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ AttributeList *
+ createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- typeArg, syntaxUsed));
+ return add(new (memory) AttributeList(attrName, attrRange, scopeName,
+ scopeLoc, typeArg, syntaxUsed));
}
- AttributeList *createPropertyAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- AttributeList::Syntax syntaxUsed) {
+ AttributeList *
+ createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ AttributeList::Syntax syntaxUsed) {
void *memory = allocate(AttributeFactory::PropertyAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- getterId, setterId,
- syntaxUsed));
+ return add(new (memory)
+ AttributeList(attrName, attrRange, scopeName, scopeLoc,
+ getterId, setterId, syntaxUsed));
}
};
-/// ParsedAttributes - A collection of parsed attributes. Currently
-/// we don't differentiate between the various attribute syntaxes,
-/// which is basically silly.
-///
-/// Right now this is a very lightweight container, but the expectation
-/// is that this will become significantly more serious.
-class ParsedAttributes {
-public:
- ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
- ParsedAttributes(const ParsedAttributes &) = delete;
-
- AttributePool &getPool() const { return pool; }
+class ParsedAttributesView {
+ using VecTy = llvm::TinyPtrVector<AttributeList *>;
+ using SizeType = decltype(std::declval<VecTy>().size());
- bool empty() const { return list == nullptr; }
+public:
+ bool empty() const { return AttrList.empty(); }
+ SizeType size() const { return AttrList.size(); }
+ AttributeList &operator[](SizeType pos) { return *AttrList[pos]; }
+ const AttributeList &operator[](SizeType pos) const { return *AttrList[pos]; }
- void add(AttributeList *newAttr) {
+ void addAtStart(AttributeList *newAttr) {
+ assert(newAttr);
+ AttrList.insert(AttrList.begin(), newAttr);
+ }
+ void addAtEnd(AttributeList *newAttr) {
assert(newAttr);
- assert(newAttr->getNext() == nullptr);
- newAttr->setNext(list);
- list = newAttr;
+ AttrList.push_back(newAttr);
+ }
+
+ void remove(AttributeList *ToBeRemoved) {
+ assert(is_contained(AttrList, ToBeRemoved) &&
+ "Cannot remove attribute that isn't in the list");
+ AttrList.erase(llvm::find(AttrList, ToBeRemoved));
}
- void addAll(AttributeList *newList) {
- if (!newList) return;
+ void clearListOnly() { AttrList.clear(); }
- AttributeList *lastInNewList = newList;
- while (AttributeList *next = lastInNewList->getNext())
- lastInNewList = next;
+ struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
+ std::random_access_iterator_tag,
+ AttributeList> {
+ iterator() : iterator_adaptor_base(nullptr) {}
+ iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
+ reference operator*() { return **I; }
+ friend class ParsedAttributesView;
+ };
+ struct const_iterator
+ : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
+ std::random_access_iterator_tag,
+ AttributeList> {
+ const_iterator() : iterator_adaptor_base(nullptr) {}
+ const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
+
+ reference operator*() const { return **I; }
+ friend class ParsedAttributesView;
+ };
- lastInNewList->setNext(list);
- list = newList;
+ void addAll(iterator B, iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
}
- void addAllAtEnd(AttributeList *newList) {
- if (!list) {
- list = newList;
- return;
- }
+ void addAll(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
+ }
- AttributeList *lastInList = list;
- while (AttributeList *next = lastInList->getNext())
- lastInList = next;
+ void addAllAtEnd(iterator B, iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
+ }
- lastInList->setNext(newList);
+ void addAllAtEnd(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
}
- void set(AttributeList *newList) {
- list = newList;
+ iterator begin() { return iterator(AttrList.begin()); }
+ const_iterator begin() const { return const_iterator(AttrList.begin()); }
+ iterator end() { return iterator(AttrList.end()); }
+ const_iterator end() const { return const_iterator(AttrList.end()); }
+
+ bool hasAttribute(AttributeList::Kind K) const {
+ return llvm::any_of(
+ AttrList, [K](const AttributeList *AL) { return AL->getKind() == K; });
}
+private:
+ VecTy AttrList;
+};
+
+/// ParsedAttributes - A collection of parsed attributes. Currently
+/// we don't differentiate between the various attribute syntaxes,
+/// which is basically silly.
+///
+/// Right now this is a very lightweight container, but the expectation
+/// is that this will become significantly more serious.
+class ParsedAttributes : public ParsedAttributesView {
+public:
+ ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
+ ParsedAttributes(const ParsedAttributes &) = delete;
+
+ AttributePool &getPool() const { return pool; }
+
void takeAllFrom(ParsedAttributes &attrs) {
- addAll(attrs.list);
- attrs.list = nullptr;
+ addAll(attrs.begin(), attrs.end());
+ attrs.clearListOnly();
pool.takeAllFrom(attrs.pool);
}
- void clear() { list = nullptr; pool.clear(); }
- AttributeList *getList() const { return list; }
-
- void clearListOnly() { list = nullptr; }
-
- /// Returns a reference to the attribute list. Try not to introduce
- /// dependencies on this method, it may not be long-lived.
- AttributeList *&getListRef() { return list; }
+ void clear() {
+ clearListOnly();
+ pool.clear();
+ }
/// Add attribute with expression arguments.
AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
@@ -820,7 +837,7 @@ public:
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
syntax, ellipsisLoc);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -839,7 +856,7 @@ public:
pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
deprecated, obsoleted, unavailable, MessageExpr, syntax,
strict, ReplacementExpr);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -853,7 +870,7 @@ public:
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -869,7 +886,7 @@ public:
scopeName, scopeLoc,
argumentKind, matchingCType,
layoutCompatible, mustBeNull, syntax);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -881,7 +898,7 @@ public:
AttributeList *attr =
pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
typeArg, syntaxUsed);
- add(attr);
+ addAtStart(attr);
return attr;
}
@@ -894,13 +911,12 @@ public:
AttributeList *attr =
pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed);
- add(attr);
+ addAtStart(attr);
return attr;
}
private:
mutable AttributePool pool;
- AttributeList *list = nullptr;
};
/// These constants match the enumerated choices of
OpenPOWER on IntegriCloud