From 967eb20ebe8b399a83ac7c24da7808bd8f9011b0 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Tue, 29 Dec 2015 22:13:13 +0000 Subject: [PATCH] [TrailingObjects] Convert Decl* classes. Also remove now-redundant explicit alignment specification on some of the classes converted prior to TrailingObjects automatically ensuring proper alignment. llvm-svn: 256585 --- clang/include/clang/AST/DeclCXX.h | 13 +++++++----- clang/include/clang/AST/DeclFriend.h | 24 ++++++++++------------- clang/include/clang/AST/DeclGroup.h | 15 +++++++------- clang/include/clang/AST/DeclObjC.h | 8 +++++--- clang/include/clang/AST/DeclOpenMP.h | 13 ++++++------ clang/include/clang/AST/DeclTemplate.h | 7 +++---- clang/lib/AST/DeclCXX.cpp | 7 +++---- clang/lib/AST/DeclFriend.cpp | 7 +++++-- clang/lib/AST/DeclGroup.cpp | 7 +++---- clang/lib/AST/DeclObjC.cpp | 14 ++++++------- clang/lib/AST/DeclOpenMP.cpp | 10 +++++----- clang/lib/Serialization/ASTReaderDecl.cpp | 15 ++++++++------ 12 files changed, 72 insertions(+), 68 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 1c54e1bb62db..c24823f7f17d 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1888,7 +1888,8 @@ public: /// B(A& a) : A(a), f(3.14159) { } /// }; /// \endcode -class CXXCtorInitializer { +class CXXCtorInitializer final + : private llvm::TrailingObjects { /// \brief Either the base class name/delegating constructor type (stored as /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field /// (IndirectFieldDecl*) being initialized. @@ -2104,24 +2105,26 @@ public: /// describe an array member initialization. VarDecl *getArrayIndex(unsigned I) { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - return reinterpret_cast(this + 1)[I]; + return getTrailingObjects()[I]; } const VarDecl *getArrayIndex(unsigned I) const { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - return reinterpret_cast(this + 1)[I]; + return getTrailingObjects()[I]; } void setArrayIndex(unsigned I, VarDecl *Index) { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - reinterpret_cast(this + 1)[I] = Index; + getTrailingObjects()[I] = Index; } ArrayRef getArrayIndexes() { assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); - return llvm::makeArrayRef(reinterpret_cast(this + 1), + return llvm::makeArrayRef(getTrailingObjects(), getNumArrayIndices()); } /// \brief Get the initializer. Expr *getInit() const { return static_cast(Init); } + + friend TrailingObjects; }; /// \brief Represents a C++ constructor within a class. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index 12b93b408a70..27b0388007a1 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -37,7 +37,9 @@ namespace clang { /// @endcode /// /// The semantic context of a friend decl is its declaring class. -class FriendDecl : public Decl { +class FriendDecl final + : public Decl, + private llvm::TrailingObjects { virtual void anchor(); public: typedef llvm::PointerUnion FriendUnion; @@ -62,14 +64,6 @@ private: // template friend class A::B; unsigned NumTPLists : 31; - // The tail-allocated friend type template parameter lists (if any). - TemplateParameterList* const *getTPLists() const { - return reinterpret_cast(this + 1); - } - TemplateParameterList **getTPLists() { - return reinterpret_cast(this + 1); - } - friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; @@ -83,7 +77,7 @@ private: UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) { for (unsigned i = 0; i < NumTPLists; ++i) - getTPLists()[i] = FriendTypeTPLists[i]; + getTrailingObjects()[i] = FriendTypeTPLists[i]; } FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) @@ -118,7 +112,7 @@ public: } TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { assert(N < NumTPLists); - return getTPLists()[N]; + return getTrailingObjects()[N]; } /// If this friend declaration doesn't name a type, return the inner @@ -148,9 +142,10 @@ public: return SourceRange(getFriendLoc(), ND->getLocEnd()); } else if (TypeSourceInfo *TInfo = getFriendType()) { - SourceLocation StartL = (NumTPLists == 0) - ? getFriendLoc() - : getTPLists()[0]->getTemplateLoc(); + SourceLocation StartL = + (NumTPLists == 0) ? getFriendLoc() + : getTrailingObjects()[0] + ->getTemplateLoc(); return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc()); } else @@ -171,6 +166,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// An iterator over the friend declarations of a class. diff --git a/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h index bd3dbd8fa787..c84bb5e60481 100644 --- a/clang/include/clang/AST/DeclGroup.h +++ b/clang/include/clang/AST/DeclGroup.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLGROUP_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/TrailingObjects.h" #include namespace clang { @@ -24,13 +25,9 @@ class Decl; class DeclGroup; class DeclGroupIterator; -class DeclGroup { +class DeclGroup final : private llvm::TrailingObjects { // FIXME: Include a TypeSpecifier object. - union { - unsigned NumDecls; - - Decl *Aligner; - }; + unsigned NumDecls; private: DeclGroup() : NumDecls(0) {} @@ -43,13 +40,15 @@ public: Decl*& operator[](unsigned i) { assert (i < NumDecls && "Out-of-bounds access."); - return ((Decl**) (this+1))[i]; + return getTrailingObjects()[i]; } Decl* const& operator[](unsigned i) const { assert (i < NumDecls && "Out-of-bounds access."); - return ((Decl* const*) (this+1))[i]; + return getTrailingObjects()[i]; } + + friend TrailingObjects; }; class DeclGroupRef { diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index f1e48a1296e9..f46078f28a7d 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -612,7 +612,8 @@ public: /// @interface NSArray // stores the /// @end /// \endcode -class ObjCTypeParamList { +class ObjCTypeParamList final + : private llvm::TrailingObjects { /// Stores the components of a SourceRange as a POD. struct PODSourceRange { unsigned Begin; @@ -644,7 +645,7 @@ public: /// Iterate through the type parameters in the list. typedef ObjCTypeParamDecl **iterator; - iterator begin() { return reinterpret_cast(this + 1); } + iterator begin() { return getTrailingObjects(); } iterator end() { return begin() + size(); } @@ -655,7 +656,7 @@ public: typedef ObjCTypeParamDecl * const *const_iterator; const_iterator begin() const { - return reinterpret_cast(this + 1); + return getTrailingObjects(); } const_iterator end() const { @@ -685,6 +686,7 @@ public: /// Gather the default set of type arguments to be substituted for /// these type parameters when dealing with an unspecialized type. void gatherDefaultTypeArgs(SmallVectorImpl &typeArgs) const; + friend TrailingObjects; }; /// ObjCContainerDecl - Represents a container for method declarations. diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index 7f0616f1e603..598f418f7e35 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -33,8 +33,12 @@ class Expr; /// }; /// \endcode /// -class OMPThreadPrivateDecl : public Decl { +class OMPThreadPrivateDecl final + : public Decl, + private llvm::TrailingObjects { friend class ASTDeclReader; + friend TrailingObjects; + unsigned NumVars; virtual void anchor(); @@ -43,14 +47,11 @@ class OMPThreadPrivateDecl : public Decl { Decl(DK, DC, L), NumVars(0) { } ArrayRef getVars() const { - return llvm::makeArrayRef(reinterpret_cast(this + 1), - NumVars); + return llvm::makeArrayRef(getTrailingObjects(), NumVars); } MutableArrayRef getVars() { - return MutableArrayRef( - reinterpret_cast(this + 1), - NumVars); + return MutableArrayRef(getTrailingObjects(), NumVars); } void setVars(ArrayRef VL); diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 8657baeb9211..a9109ef11426 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -45,7 +45,7 @@ typedef llvm::PointerUnion3 { /// The location of the 'template' keyword. @@ -169,7 +169,7 @@ public: }; /// \brief A template argument list. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateArgumentList final +class TemplateArgumentList final : private llvm::TrailingObjects { /// \brief The template argument list. const TemplateArgument *Arguments; @@ -553,8 +553,7 @@ public: /// friend void foo<>(T); /// }; /// \endcode -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) - DependentFunctionTemplateSpecializationInfo final +class DependentFunctionTemplateSpecializationInfo final : private llvm::TrailingObjects { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 32e64b6e4eca..71bc247a007f 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1675,8 +1675,8 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices) { - VarDecl **MyIndices = reinterpret_cast (this + 1); - memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *)); + std::uninitialized_copy(Indices, Indices + NumIndices, + getTrailingObjects()); } CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context, @@ -1686,8 +1686,7 @@ 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(NumIndices), llvm::alignOf()); return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R, Indices, NumIndices); diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index a996cab093af..121403b07e57 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -46,7 +46,9 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, } #endif - std::size_t Extra = FriendTypeTPLists.size() * sizeof(TemplateParameterList*); + std::size_t Extra = + FriendDecl::additionalSizeToAlloc( + FriendTypeTPLists.size()); FriendDecl *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL, FriendTypeTPLists); cast(DC)->pushFriendDecl(FD); @@ -55,7 +57,8 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned FriendTypeNumTPLists) { - std::size_t Extra = FriendTypeNumTPLists * sizeof(TemplateParameterList*); + std::size_t Extra = + additionalSizeToAlloc(FriendTypeNumTPLists); return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists); } diff --git a/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp index 512837fdf3f4..f162e6d40c48 100644 --- a/clang/lib/AST/DeclGroup.cpp +++ b/clang/lib/AST/DeclGroup.cpp @@ -18,10 +18,8 @@ using namespace clang; DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { - static_assert(sizeof(DeclGroup) % llvm::AlignOf::Alignment == 0, - "Trailing data is unaligned!"); assert(NumDecls > 1 && "Invalid DeclGroup"); - unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls; + unsigned Size = totalSizeToAlloc(NumDecls); void* Mem = C.Allocate(Size, llvm::AlignOf::Alignment); new (Mem) DeclGroup(NumDecls, Decls); return static_cast(Mem); @@ -30,5 +28,6 @@ DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { 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()); } diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index b5dc9e122c30..050a0f53f1e5 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -772,6 +772,10 @@ void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C, if (Params.empty() && SelLocs.empty()) return; + static_assert(llvm::AlignOf::Alignment >= + llvm::AlignOf::Alignment, + "Alignment not sufficient for SourceLocation"); + unsigned Size = sizeof(ParmVarDecl *) * NumParams + sizeof(SourceLocation) * SelLocs.size(); ParamsAndSelLocs = C.Allocate(Size); @@ -1326,13 +1330,9 @@ ObjCTypeParamList *ObjCTypeParamList::create( SourceLocation lAngleLoc, ArrayRef typeParams, SourceLocation rAngleLoc) { - unsigned size = sizeof(ObjCTypeParamList) - + sizeof(ObjCTypeParamDecl *) * typeParams.size(); - static_assert(llvm::AlignOf::Alignment >= - llvm::AlignOf::Alignment, - "type parameter list needs greater alignment"); - unsigned align = llvm::alignOf(); - void *mem = ctx.Allocate(size, align); + void *mem = + ctx.Allocate(totalSizeToAlloc(typeParams.size()), + llvm::alignOf()); return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc); } diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 5f8b42b3f964..493e2cd41226 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -29,8 +29,9 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL) { - OMPThreadPrivateDecl *D = new (C, DC, VL.size() * sizeof(Expr *)) - OMPThreadPrivateDecl(OMPThreadPrivate, DC, L); + OMPThreadPrivateDecl *D = + new (C, DC, additionalSizeToAlloc(VL.size())) + OMPThreadPrivateDecl(OMPThreadPrivate, DC, L); D->NumVars = VL.size(); D->setVars(VL); return D; @@ -39,7 +40,7 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned N) { - OMPThreadPrivateDecl *D = new (C, ID, N * sizeof(Expr *)) + OMPThreadPrivateDecl *D = new (C, ID, additionalSizeToAlloc(N)) OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation()); D->NumVars = N; return D; @@ -48,7 +49,6 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, void OMPThreadPrivateDecl::setVars(ArrayRef VL) { assert(VL.size() == NumVars && "Number of variables is not the same as the preallocated buffer"); - Expr **Vars = reinterpret_cast(this + 1); - std::copy(VL.begin(), VL.end(), Vars); + std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects()); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 2c868cbb9fca..8fb110e4551d 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1731,7 +1731,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) { VisitDecl(D); D->ImportedAndComplete.setPointer(readModule(Record, Idx)); D->ImportedAndComplete.setInt(Record[Idx++]); - SourceLocation *StoredLocs = reinterpret_cast(D + 1); + SourceLocation *StoredLocs = D->getTrailingObjects(); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = ReadSourceLocation(Record, Idx); ++Idx; // The number of stored source locations. @@ -1749,7 +1749,8 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { else D->Friend = GetTypeSourceInfo(Record, Idx); for (unsigned i = 0; i != D->NumTPLists; ++i) - D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx); + D->getTrailingObjects()[i] = + Reader.ReadTemplateParameterList(F, Record, Idx); D->NextFriend = ReadDeclID(Record, Idx); D->UnsupportedFriend = (Record[Idx++] != 0); D->FriendLoc = ReadSourceLocation(Record, Idx); @@ -2098,10 +2099,11 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); if (D->isExpandedParameterPack()) { - void **Data = reinterpret_cast(D + 1); + auto TypesAndInfos = + D->getTrailingObjects>(); 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. @@ -2117,7 +2119,8 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); if (D->isExpandedParameterPack()) { - void **Data = reinterpret_cast(D + 1); + TemplateParameterList **Data = + D->getTrailingObjects(); for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); I != N; ++I) Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);