diff options
| author | James Y Knight <jyknight@google.com> | 2015-08-05 22:57:34 +0000 |
|---|---|---|
| committer | James Y Knight <jyknight@google.com> | 2015-08-05 22:57:34 +0000 |
| commit | aa365b2fcd975064234b0859d0881702789b6c40 (patch) | |
| tree | 01a584b4b8d4c1e1f12de8da4c542d402d0c1e82 /llvm/lib | |
| parent | d41611cfdf7a858d31c68d038eb70c7a73ed2c3c (diff) | |
| download | bcm5719-llvm-aa365b2fcd975064234b0859d0881702789b6c40.tar.gz bcm5719-llvm-aa365b2fcd975064234b0859d0881702789b6c40.zip | |
Add a TrailingObjects template class.
This is intended to help support the idiom of a class that has some
other objects (or multiple arrays of different types of objects)
appended on the end, which is used quite heavily in clang.
Differential Revision: http://reviews.llvm.org/D11272
llvm-svn: 244164
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/IR/AttributeImpl.h | 37 | ||||
| -rw-r--r-- | llvm/lib/IR/Attributes.cpp | 13 |
2 files changed, 24 insertions, 26 deletions
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index 6f338ae835f..d5456580a67 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -18,6 +18,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/IR/Attributes.h" +#include "llvm/Support/TrailingObjects.h" #include <string> namespace llvm { @@ -141,13 +142,16 @@ public: /// \class /// \brief This class represents a group of attributes that apply to one /// element: function, return type, or parameter. -class AttributeSetNode : public FoldingSetNode { +class AttributeSetNode final + : public FoldingSetNode, + private TrailingObjects<AttributeSetNode, Attribute> { + friend TrailingObjects; + unsigned NumAttrs; ///< Number of attributes in this node. AttributeSetNode(ArrayRef<Attribute> Attrs) : NumAttrs(Attrs.size()) { // There's memory after the node where we can store the entries in. - std::copy(Attrs.begin(), Attrs.end(), - reinterpret_cast<Attribute *>(this + 1)); + std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>()); } // AttributesSetNode is uniqued, these should not be publicly available. @@ -170,7 +174,7 @@ public: std::string getAsString(bool InAttrGrp) const; typedef const Attribute *iterator; - iterator begin() const { return reinterpret_cast<iterator>(this + 1); } + iterator begin() const { return getTrailingObjects<Attribute>(); } iterator end() const { return begin() + NumAttrs; } void Profile(FoldingSetNodeID &ID) const { @@ -181,27 +185,29 @@ public: AttrList[I].Profile(ID); } }; -static_assert( - AlignOf<AttributeSetNode>::Alignment >= AlignOf<Attribute>::Alignment, - "Alignment is insufficient for objects appended to AttributeSetNode"); //===----------------------------------------------------------------------===// /// \class /// \brief This class represents a set of attributes that apply to the function, /// return type, and parameters. -class AttributeSetImpl : public FoldingSetNode { - friend class AttributeSet; +typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair; -public: - typedef std::pair<unsigned, AttributeSetNode*> IndexAttrPair; +class AttributeSetImpl final + : public FoldingSetNode, + private TrailingObjects<AttributeSetImpl, IndexAttrPair> { + friend class AttributeSet; + friend TrailingObjects; private: LLVMContext &Context; unsigned NumAttrs; ///< Number of entries in this set. + // Helper fn for TrailingObjects class. + size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumAttrs; } + /// \brief Return a pointer to the IndexAttrPair for the specified slot. const IndexAttrPair *getNode(unsigned Slot) const { - return reinterpret_cast<const IndexAttrPair *>(this + 1) + Slot; + return getTrailingObjects<IndexAttrPair>() + Slot; } // AttributesSet is uniqued, these should not be publicly available. @@ -222,8 +228,7 @@ public: } #endif // There's memory after the node where we can store the entries in. - std::copy(Attrs.begin(), Attrs.end(), - reinterpret_cast<IndexAttrPair *>(this + 1)); + std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<IndexAttrPair>()); } /// \brief Get the context that created this AttributeSetImpl. @@ -273,10 +278,6 @@ public: void dump() const; }; -static_assert( - AlignOf<AttributeSetImpl>::Alignment >= - AlignOf<AttributeSetImpl::IndexAttrPair>::Alignment, - "Alignment is insufficient for objects appended to AttributeSetImpl"); } // end llvm namespace diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 0d89d127ed8..d909f7b880c 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -484,8 +484,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, // new one and insert it. if (!PA) { // Coallocate entries after the AttributeSetNode itself. - void *Mem = ::operator new(sizeof(AttributeSetNode) + - sizeof(Attribute) * SortedAttrs.size()); + void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size())); PA = new (Mem) AttributeSetNode(SortedAttrs); pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); } @@ -617,9 +616,8 @@ AttributeSet::getImpl(LLVMContext &C, // create a new one and insert it. if (!PA) { // Coallocate entries after the AttributeSetImpl itself. - void *Mem = ::operator new(sizeof(AttributeSetImpl) + - sizeof(std::pair<unsigned, AttributeSetNode *>) * - Attrs.size()); + void *Mem = ::operator new( + AttributeSetImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size())); PA = new (Mem) AttributeSetImpl(C, Attrs); pImpl->AttrsLists.InsertNode(PA, InsertPoint); } @@ -736,9 +734,8 @@ AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) { if (!AS) continue; SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator ANVI = AttrNodeVec.begin(), ANVE; - for (const AttributeSetImpl::IndexAttrPair - *AI = AS->getNode(0), - *AE = AS->getNode(AS->getNumAttributes()); + for (const IndexAttrPair *AI = AS->getNode(0), + *AE = AS->getNode(AS->getNumAttributes()); AI != AE; ++AI) { ANVE = AttrNodeVec.end(); while (ANVI != ANVE && ANVI->first <= AI->first) |

