/// B(A& a) : A(a), f(3.14159) { }
/// };
/// \endcode
-class CXXCtorInitializer {
+class CXXCtorInitializer final
+ : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
/// \brief Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
/// (IndirectFieldDecl*) being initialized.
/// describe an array member initialization.
VarDecl *getArrayIndex(unsigned I) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return reinterpret_cast<VarDecl **>(this + 1)[I];
+ return getTrailingObjects<VarDecl *>()[I];
}
const VarDecl *getArrayIndex(unsigned I) const {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
+ return getTrailingObjects<VarDecl *>()[I];
}
void setArrayIndex(unsigned I, VarDecl *Index) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
- reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
+ getTrailingObjects<VarDecl *>()[I] = Index;
}
ArrayRef<VarDecl *> getArrayIndexes() {
assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
- return llvm::makeArrayRef(reinterpret_cast<VarDecl **>(this + 1),
+ return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
getNumArrayIndices());
}
/// \brief Get the initializer.
Expr *getInit() const { return static_cast<Expr*>(Init); }
+
+ friend TrailingObjects;
};
/// \brief Represents a C++ constructor within a class.
/// @endcode
///
/// The semantic context of a friend decl is its declaring class.
-class FriendDecl : public Decl {
+class FriendDecl final
+ : public Decl,
+ private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
virtual void anchor();
public:
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
// template <class T> friend class A<T>::B;
unsigned NumTPLists : 31;
- // The tail-allocated friend type template parameter lists (if any).
- TemplateParameterList* const *getTPLists() const {
- return reinterpret_cast<TemplateParameterList* const *>(this + 1);
- }
- TemplateParameterList **getTPLists() {
- return reinterpret_cast<TemplateParameterList**>(this + 1);
- }
-
friend class CXXRecordDecl::friend_iterator;
friend class CXXRecordDecl;
UnsupportedFriend(false),
NumTPLists(FriendTypeTPLists.size()) {
for (unsigned i = 0; i < NumTPLists; ++i)
- getTPLists()[i] = FriendTypeTPLists[i];
+ getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
}
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
}
TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
assert(N < NumTPLists);
- return getTPLists()[N];
+ return getTrailingObjects<TemplateParameterList *>()[N];
}
/// If this friend declaration doesn't name a type, return the inner
return SourceRange(getFriendLoc(), ND->getLocEnd());
}
else if (TypeSourceInfo *TInfo = getFriendType()) {
- SourceLocation StartL = (NumTPLists == 0)
- ? getFriendLoc()
- : getTPLists()[0]->getTemplateLoc();
+ SourceLocation StartL =
+ (NumTPLists == 0) ? getFriendLoc()
+ : getTrailingObjects<TemplateParameterList *>()[0]
+ ->getTemplateLoc();
return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
}
else
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend TrailingObjects;
};
/// An iterator over the friend declarations of a class.
#define LLVM_CLANG_AST_DECLGROUP_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/TrailingObjects.h"
#include <cassert>
namespace clang {
class DeclGroup;
class DeclGroupIterator;
-class DeclGroup {
+class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
// FIXME: Include a TypeSpecifier object.
- union {
- unsigned NumDecls;
-
- Decl *Aligner;
- };
+ unsigned NumDecls;
private:
DeclGroup() : NumDecls(0) {}
Decl*& operator[](unsigned i) {
assert (i < NumDecls && "Out-of-bounds access.");
- return ((Decl**) (this+1))[i];
+ return getTrailingObjects<Decl *>()[i];
}
Decl* const& operator[](unsigned i) const {
assert (i < NumDecls && "Out-of-bounds access.");
- return ((Decl* const*) (this+1))[i];
+ return getTrailingObjects<Decl *>()[i];
}
+
+ friend TrailingObjects;
};
class DeclGroupRef {
/// @interface NSArray<T> // stores the <T>
/// @end
/// \endcode
-class ObjCTypeParamList {
+class ObjCTypeParamList final
+ : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
/// Stores the components of a SourceRange as a POD.
struct PODSourceRange {
unsigned Begin;
/// Iterate through the type parameters in the list.
typedef ObjCTypeParamDecl **iterator;
- iterator begin() { return reinterpret_cast<ObjCTypeParamDecl **>(this + 1); }
+ iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
iterator end() { return begin() + size(); }
typedef ObjCTypeParamDecl * const *const_iterator;
const_iterator begin() const {
- return reinterpret_cast<ObjCTypeParamDecl * const *>(this + 1);
+ return getTrailingObjects<ObjCTypeParamDecl *>();
}
const_iterator end() const {
/// Gather the default set of type arguments to be substituted for
/// these type parameters when dealing with an unspecialized type.
void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
+ friend TrailingObjects;
};
/// ObjCContainerDecl - Represents a container for method declarations.
/// };
/// \endcode
///
-class OMPThreadPrivateDecl : public Decl {
+class OMPThreadPrivateDecl final
+ : public Decl,
+ private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
friend class ASTDeclReader;
+ friend TrailingObjects;
+
unsigned NumVars;
virtual void anchor();
Decl(DK, DC, L), NumVars(0) { }
ArrayRef<const Expr *> getVars() const {
- return llvm::makeArrayRef(reinterpret_cast<const Expr * const *>(this + 1),
- NumVars);
+ return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
}
MutableArrayRef<Expr *> getVars() {
- return MutableArrayRef<Expr *>(
- reinterpret_cast<Expr **>(this + 1),
- NumVars);
+ return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
}
void setVars(ArrayRef<Expr *> VL);
/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes.
-class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList final
+class TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
/// The location of the 'template' keyword.
};
/// \brief A template argument list.
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateArgumentList final
+class TemplateArgumentList final
: private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
/// \brief The template argument list.
const TemplateArgument *Arguments;
/// friend void foo<>(T);
/// };
/// \endcode
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8)
- DependentFunctionTemplateSpecializationInfo final
+class DependentFunctionTemplateSpecializationInfo final
: private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
TemplateArgumentLoc,
FunctionTemplateDecl *> {
LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
{
- VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
- memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
+ std::uninitialized_copy(Indices, Indices + NumIndices,
+ getTrailingObjects<VarDecl *>());
}
CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
SourceLocation R,
VarDecl **Indices,
unsigned NumIndices) {
- void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +
- sizeof(VarDecl *) * NumIndices,
+ void *Mem = Context.Allocate(totalSizeToAlloc<VarDecl *>(NumIndices),
llvm::alignOf<CXXCtorInitializer>());
return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
Indices, NumIndices);
}
#endif
- std::size_t Extra = FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
+ std::size_t Extra =
+ FriendDecl::additionalSizeToAlloc<TemplateParameterList *>(
+ FriendTypeTPLists.size());
FriendDecl *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL,
FriendTypeTPLists);
cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists) {
- std::size_t Extra = FriendTypeNumTPLists * sizeof(TemplateParameterList*);
+ std::size_t Extra =
+ additionalSizeToAlloc<TemplateParameterList *>(FriendTypeNumTPLists);
return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
}
using namespace clang;
DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
- static_assert(sizeof(DeclGroup) % llvm::AlignOf<void *>::Alignment == 0,
- "Trailing data is unaligned!");
assert(NumDecls > 1 && "Invalid DeclGroup");
- unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
+ unsigned Size = totalSizeToAlloc<Decl *>(NumDecls);
void* Mem = C.Allocate(Size, llvm::AlignOf<DeclGroup>::Alignment);
new (Mem) DeclGroup(NumDecls, Decls);
return static_cast<DeclGroup*>(Mem);
DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) : NumDecls(numdecls) {
assert(numdecls > 0);
assert(decls);
- memcpy(this+1, decls, numdecls * sizeof(*decls));
+ std::uninitialized_copy(decls, decls + numdecls,
+ getTrailingObjects<Decl *>());
}
if (Params.empty() && SelLocs.empty())
return;
+ static_assert(llvm::AlignOf<ParmVarDecl *>::Alignment >=
+ llvm::AlignOf<SourceLocation>::Alignment,
+ "Alignment not sufficient for SourceLocation");
+
unsigned Size = sizeof(ParmVarDecl *) * NumParams +
sizeof(SourceLocation) * SelLocs.size();
ParamsAndSelLocs = C.Allocate(Size);
SourceLocation lAngleLoc,
ArrayRef<ObjCTypeParamDecl *> typeParams,
SourceLocation rAngleLoc) {
- unsigned size = sizeof(ObjCTypeParamList)
- + sizeof(ObjCTypeParamDecl *) * typeParams.size();
- static_assert(llvm::AlignOf<ObjCTypeParamList>::Alignment >=
- llvm::AlignOf<ObjCTypeParamDecl *>::Alignment,
- "type parameter list needs greater alignment");
- unsigned align = llvm::alignOf<ObjCTypeParamList>();
- void *mem = ctx.Allocate(size, align);
+ void *mem =
+ ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
+ llvm::alignOf<ObjCTypeParamList>());
return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
}
DeclContext *DC,
SourceLocation L,
ArrayRef<Expr *> VL) {
- OMPThreadPrivateDecl *D = new (C, DC, VL.size() * sizeof(Expr *))
- OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
+ OMPThreadPrivateDecl *D =
+ new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
+ OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
D->NumVars = VL.size();
D->setVars(VL);
return D;
OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
unsigned ID,
unsigned N) {
- OMPThreadPrivateDecl *D = new (C, ID, N * sizeof(Expr *))
+ OMPThreadPrivateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation());
D->NumVars = N;
return D;
void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
assert(VL.size() == NumVars &&
"Number of variables is not the same as the preallocated buffer");
- Expr **Vars = reinterpret_cast<Expr **>(this + 1);
- std::copy(VL.begin(), VL.end(), Vars);
+ std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
}
VisitDecl(D);
D->ImportedAndComplete.setPointer(readModule(Record, Idx));
D->ImportedAndComplete.setInt(Record[Idx++]);
- SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1);
+ SourceLocation *StoredLocs = D->getTrailingObjects<SourceLocation>();
for (unsigned I = 0, N = Record.back(); I != N; ++I)
StoredLocs[I] = ReadSourceLocation(Record, Idx);
++Idx; // The number of stored source locations.
else
D->Friend = GetTypeSourceInfo(Record, Idx);
for (unsigned i = 0; i != D->NumTPLists; ++i)
- D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
+ D->getTrailingObjects<TemplateParameterList *>()[i] =
+ Reader.ReadTemplateParameterList(F, Record, Idx);
D->NextFriend = ReadDeclID(Record, Idx);
D->UnsupportedFriend = (Record[Idx++] != 0);
D->FriendLoc = ReadSourceLocation(Record, Idx);
D->setDepth(Record[Idx++]);
D->setPosition(Record[Idx++]);
if (D->isExpandedParameterPack()) {
- void **Data = reinterpret_cast<void **>(D + 1);
+ auto TypesAndInfos =
+ D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
- Data[2*I] = Reader.readType(F, Record, Idx).getAsOpaquePtr();
- Data[2*I + 1] = GetTypeSourceInfo(Record, Idx);
+ new (&TypesAndInfos[I].first) QualType(Reader.readType(F, Record, Idx));
+ TypesAndInfos[I].second = GetTypeSourceInfo(Record, Idx);
}
} else {
// Rest of NonTypeTemplateParmDecl.
D->setDepth(Record[Idx++]);
D->setPosition(Record[Idx++]);
if (D->isExpandedParameterPack()) {
- void **Data = reinterpret_cast<void **>(D + 1);
+ TemplateParameterList **Data =
+ D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
I != N; ++I)
Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);