From: Manuel Klimek Date: Fri, 7 Jun 2013 11:27:53 +0000 (+0000) Subject: Reverts r183466: "Perform dynamic alignment computations..." X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20387efff0870da2c8b30bb62ae661239a903021;p=clang Reverts r183466: "Perform dynamic alignment computations..." This introduces bugs in TemplateSpecializationTypeLoc's angle bracket locations. Regression test follows in a subsequent commit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183513 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index f7083d5216..9e2d3bffb9 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -95,10 +95,6 @@ public: /// \brief Returns the size of type source info data block for the given type. static unsigned getFullDataSizeForType(QualType Ty); - /// \brief Returns the alignment of type source info data block for - /// the given type. - static unsigned getLocalAlignmentForType(QualType Ty); - /// \brief Get the type for which this source info wrapper provides /// information. QualType getType() const { @@ -233,11 +229,7 @@ public: } UnqualTypeLoc getUnqualifiedLoc() const { - unsigned align = - TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); - uintptr_t dataInt = reinterpret_cast(Data); - dataInt = llvm::RoundUpToAlignment(dataInt, align); - return UnqualTypeLoc(getTypePtr(), reinterpret_cast(dataInt)); + return UnqualTypeLoc(getTypePtr(), Data); } /// Initializes the local data of this type source info block to @@ -258,11 +250,10 @@ public: return 0; } - /// \brief Returns the alignment of the type source info data block that is - /// specific to this type. - unsigned getLocalDataAlignment() const { - // We don't preserve any location information. - return 1; + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + + getFullDataSizeForType(getType().getLocalUnqualifiedType()); } private: @@ -289,6 +280,9 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { /// \tparam LocalData the structure type of local location data for /// this type /// +/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or +/// else the world will end. +/// /// TypeLocs with non-constant amounts of local data should override /// getExtraLocalDataSize(); getExtraLocalData() will then point to /// this extra memory. @@ -323,16 +317,12 @@ class ConcreteTypeLoc : public Base { } public: - unsigned getLocalDataAlignment() const { - return std::max(llvm::alignOf(), - asDerived()->getExtraLocalDataAlignment()); - } unsigned getLocalDataSize() const { - unsigned size = sizeof(LocalData); - unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); - size += asDerived()->getExtraLocalDataSize(); - return size; + return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); + } + // Give a default implementation that's useful for leaf types. + unsigned getFullDataSize() const { + return asDerived()->getLocalDataSize() + getInnerTypeSize(); } TypeLoc getNextTypeLoc() const { @@ -348,10 +338,6 @@ protected: return 0; } - unsigned getExtraLocalDataAlignment() const { - return 1; - } - LocalData *getLocalData() const { return static_cast(Base::Data); } @@ -360,17 +346,11 @@ protected: /// local data that can't be captured in the Info (e.g. because it's /// of variable size). void *getExtraLocalData() const { - unsigned size = sizeof(LocalData); - unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); - return reinterpret_cast(Base::Data) + size; + return getLocalData() + 1; } void *getNonLocalData() const { - uintptr_t data = reinterpret_cast(Base::Data); - data += asDerived()->getLocalDataSize(); - data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); - return reinterpret_cast(data); + return static_cast(Base::Data) + asDerived()->getLocalDataSize(); } struct HasNoInnerType {}; @@ -393,18 +373,6 @@ private: return getInnerTypeLoc().getFullDataSize(); } - unsigned getNextTypeAlign() const { - return getNextTypeAlign(asDerived()->getInnerType()); - } - - unsigned getNextTypeAlign(HasNoInnerType _) const { - return 1; - } - - unsigned getNextTypeAlign(QualType T) const { - return TypeLoc::getLocalAlignmentForType(T); - } - TypeLoc getNextTypeLoc(HasNoInnerType _) const { return TypeLoc(); } @@ -449,8 +417,7 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc { public: - enum { LocalDataSize = sizeof(TypeSpecLocInfo), - LocalDataAlignment = llvm::AlignOf::Alignment }; + enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; @@ -481,6 +448,8 @@ class BuiltinTypeLoc : public ConcreteTypeLoc { public: + enum { LocalDataSize = sizeof(BuiltinLocInfo) }; + SourceLocation getBuiltinLoc() const { return getLocalData()->BuiltinLoc; } @@ -509,10 +478,6 @@ public: return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; } - unsigned getExtraLocalDataAlignment() const { - return needsExtraLocalData() ? llvm::alignOf() : 1; - } - SourceRange getLocalSourceRange() const { return SourceRange(getBuiltinLoc(), getBuiltinLoc()); } @@ -875,10 +840,6 @@ public: return this->getNumProtocols() * sizeof(SourceLocation); } - unsigned getExtraLocalDataAlignment() const { - return llvm::alignOf(); - } - QualType getInnerType() const { return getTypePtr()->getBaseType(); } @@ -1205,10 +1166,6 @@ public: return getNumArgs() * sizeof(ParmVarDecl*); } - unsigned getExtraLocalDataAlignment() const { - return llvm::alignOf(); - } - QualType getInnerType() const { return getTypePtr()->getResultType(); } }; @@ -1400,10 +1357,6 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } - unsigned getExtraLocalDataAlignment() const { - return llvm::alignOf(); - } - private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast(getExtraLocalData()); @@ -1808,10 +1761,6 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } - unsigned getExtraLocalDataAlignment() const { - return llvm::alignOf(); - } - private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast(getExtraLocalData()); diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index c47bde8dde..03d40309f5 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -40,31 +40,13 @@ SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) { return TypeLocRanger().Visit(TL); } -namespace { - class TypeAligner : public TypeLocVisitor { - public: -#define ABSTRACT_TYPELOC(CLASS, PARENT) -#define TYPELOC(CLASS, PARENT) \ - unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ - return TyLoc.getLocalDataAlignment(); \ - } -#include "clang/AST/TypeLocNodes.def" - }; -} - -/// \brief Returns the alignment of the type source info data block. -unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) { - if (Ty.isNull()) return 1; - return TypeAligner().Visit(TypeLoc(Ty, 0)); -} - namespace { class TypeSizer : public TypeLocVisitor { public: #define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ - return TyLoc.getLocalDataSize(); \ + return TyLoc.getFullDataSize(); \ } #include "clang/AST/TypeLocNodes.def" }; @@ -72,18 +54,8 @@ namespace { /// \brief Returns the size of the type source info data block. unsigned TypeLoc::getFullDataSizeForType(QualType Ty) { - unsigned Total = 0; - TypeLoc TyLoc(Ty, 0); - unsigned MaxAlign = 1; - while (!TyLoc.isNull()) { - unsigned Align = getLocalAlignmentForType(TyLoc.getType()); - MaxAlign = std::max(Align, MaxAlign); - Total = llvm::RoundUpToAlignment(Total, Align); - Total += TypeSizer().Visit(TyLoc); - TyLoc = TyLoc.getNextTypeLoc(); - } - Total = llvm::RoundUpToAlignment(Total, MaxAlign); - return Total; + if (Ty.isNull()) return 0; + return TypeSizer().Visit(TypeLoc(Ty, 0)); } namespace { diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 836d125978..e92f767134 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -51,7 +51,6 @@ add_clang_library(clangSema SemaTemplateVariadic.cpp SemaType.cpp TargetAttributesSema.cpp - TypeLocBuilder.cpp ) add_dependencies(clangSema diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 3402f22062..d647be3761 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -445,7 +445,6 @@ FieldDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef, assert(!DeductType.isNull() && "can't build reference to auto"); TLB.push(DeductType).setSigilLoc(Loc); } - TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType); InitializationKind InitKind = InitializationKind::CreateDefault(Loc); Expr *Init = InitExpr; @@ -477,7 +476,8 @@ FieldDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef, else InitKind = InitializationKind::CreateCopy(Loc, Loc); QualType DeducedType; - if (DeduceAutoType(TSI, Init, DeducedType) == DAR_Failed) { + if (DeduceAutoType(TLB.getTemporaryTypeLoc(DeductType), + Init, DeducedType) == DAR_Failed) { if (isa(Init)) Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list) << Id << Init->getSourceRange(); @@ -492,7 +492,7 @@ FieldDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef, // the closure type. This member is not a bit-field and not mutable. // Core issue: the member is (probably...) public. FieldDecl *NewFD = CheckFieldDecl( - Id, DeducedType, TSI, LSI->Lambda, + Id, DeducedType, TLB.getTypeSourceInfo(Context, DeductType), LSI->Lambda, Loc, /*Mutable*/ false, /*BitWidth*/ 0, ICIS_NoInit, Loc, AS_public, /*PrevDecl*/ 0, /*Declarator*/ 0); LSI->Lambda->addDecl(NewFD); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index cb6f4c19de..3b8228016c 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -18,7 +18,6 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" -#include "TypeLocBuilder.h" using namespace clang; @@ -464,13 +463,17 @@ Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, EllipsisLoc, NumExpansions); if (Result.isNull()) return 0; - - TypeLocBuilder TLB; - TLB.pushFullCopy(Pattern->getTypeLoc()); - PackExpansionTypeLoc TL = TLB.push(Result); + + TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result); + PackExpansionTypeLoc TL = + TSResult->getTypeLoc().castAs(); TL.setEllipsisLoc(EllipsisLoc); - - return TLB.getTypeSourceInfo(Context, Result); + + // Copy over the source-location information from the type. + memcpy(TL.getNextTypeLoc().getOpaqueData(), + Pattern->getTypeLoc().getOpaqueData(), + Pattern->getTypeLoc().getFullDataSize()); + return TSResult; } QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index fe49153d99..3fcd0375d0 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3427,7 +3427,7 @@ TreeTransform::TransformQualifiedType(TypeLocBuilder &TLB, } else { // Otherwise, complain about the addition of a qualifier to an // already-qualified type. - SourceRange R = T.getUnqualifiedLoc().getSourceRange(); + SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange(); SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant) << Result << R; diff --git a/lib/Sema/TypeLocBuilder.cpp b/lib/Sema/TypeLocBuilder.cpp deleted file mode 100644 index c7d43b7046..0000000000 --- a/lib/Sema/TypeLocBuilder.cpp +++ /dev/null @@ -1,136 +0,0 @@ -//===--- TypeLocBuilder.cpp - Type Source Info collector ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This files defines TypeLocBuilder, a class for building TypeLocs -// bottom-up. -// -//===----------------------------------------------------------------------===// - -#include "TypeLocBuilder.h" - -using namespace clang; - -void TypeLocBuilder::pushFullCopy(TypeLoc L) { - size_t Size = L.getFullDataSize(); - reserve(Size); - - SmallVector TypeLocs; - TypeLoc CurTL = L; - while (CurTL) { - TypeLocs.push_back(CurTL); - CurTL = CurTL.getNextTypeLoc(); - } - - for (unsigned i = 0, e = TypeLocs.size(); i < e; ++i) { - TypeLoc CurTL = TypeLocs[e-i-1]; - switch (CurTL.getTypeLocClass()) { -#define ABSTRACT_TYPELOC(CLASS, PARENT) -#define TYPELOC(CLASS, PARENT) \ - case TypeLoc::CLASS: { \ - CLASS##TypeLoc NewTL = push(CurTL.getType()); \ - memcpy(NewTL.getOpaqueData(), CurTL.getOpaqueData(), NewTL.getLocalDataSize()); \ - break; \ - } -#include "clang/AST/TypeLocNodes.def" - } - } -} - -void TypeLocBuilder::grow(size_t NewCapacity) { - assert(NewCapacity > Capacity); - - // Allocate the new buffer and copy the old data into it. - char *NewBuffer = new char[NewCapacity]; - unsigned NewIndex = Index + NewCapacity - Capacity; - memcpy(&NewBuffer[NewIndex], - &Buffer[Index], - Capacity - Index); - - if (Buffer != InlineBuffer.buffer) - delete[] Buffer; - - Buffer = NewBuffer; - Capacity = NewCapacity; - Index = NewIndex; -} - -TypeLoc TypeLocBuilder::pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment) { -#ifndef NDEBUG - QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType(); - assert(TLast == LastTy && - "mismatch between last type and new type's inner type"); - LastTy = T; -#endif - - assert(LocalAlignment <= BufferMaxAlignment && "Unexpected alignment"); - - // If we need to grow, grow by a factor of 2. - if (LocalSize > Index) { - size_t RequiredCapacity = Capacity + (LocalSize - Index); - size_t NewCapacity = Capacity * 2; - while (RequiredCapacity > NewCapacity) - NewCapacity *= 2; - grow(NewCapacity); - } - - // Because we're adding elements to the TypeLoc backwards, we have to - // do some extra work to keep everything aligned appropriately. - // FIXME: This algorithm is a absolute mess because every TypeLoc returned - // needs to be valid. Partial TypeLocs are a terrible idea. - // FIXME: 4 and 8 are sufficient at the moment, but it's pretty ugly to - // hardcode them. - if (LocalAlignment == 4) { - if (NumBytesAtAlign8 == 0) { - NumBytesAtAlign4 += LocalSize; - } else { - unsigned Padding = NumBytesAtAlign4 % 8; - if (Padding == 0) { - if (LocalSize % 8 == 0) { - // Everything is set: there's no padding and we don't need to add - // any. - } else { - assert(LocalSize % 8 == 4); - // No existing padding; add in 4 bytes padding - memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); - Index -= 4; - } - } else { - assert(Padding == 4); - if (LocalSize % 8 == 0) { - // Everything is set: there's 4 bytes padding and we don't need - // to add any. - } else { - assert(LocalSize % 8 == 4); - // There are 4 bytes padding, but we don't need any; remove it. - memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4); - Index += 4; - } - } - NumBytesAtAlign4 += LocalSize; - } - } else if (LocalAlignment == 8) { - if (!NumBytesAtAlign8 && NumBytesAtAlign4 % 8 != 0) { - // No existing padding and misaligned members; add in 4 bytes padding - memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); - Index -= 4; - } - // Forget about any padding. - NumBytesAtAlign4 = 0; - NumBytesAtAlign8 += LocalSize; - } else { - assert(LocalSize == 0); - } - - Index -= LocalSize; - - assert(Capacity - Index == TypeLoc::getFullDataSizeForType(T) && - "incorrect data size provided to CreateTypeSourceInfo!"); - - return getTemporaryTypeLoc(T); -} diff --git a/lib/Sema/TypeLocBuilder.h b/lib/Sema/TypeLocBuilder.h index b1e909859b..f36ec9f3e2 100644 --- a/lib/Sema/TypeLocBuilder.h +++ b/lib/Sema/TypeLocBuilder.h @@ -39,19 +39,14 @@ class TypeLocBuilder { #endif /// The inline buffer. - enum { BufferMaxAlignment = llvm::AlignOf::Alignment }; - llvm::AlignedCharArray InlineBuffer; - unsigned NumBytesAtAlign4, NumBytesAtAlign8; + char InlineBuffer[InlineCapacity]; public: TypeLocBuilder() - : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity), - Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0) - { - } + : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity) {} ~TypeLocBuilder() { - if (Buffer != InlineBuffer.buffer) + if (Buffer != InlineBuffer) delete[] Buffer; } @@ -64,14 +59,23 @@ class TypeLocBuilder { /// Pushes a copy of the given TypeLoc onto this builder. The builder /// must be empty for this to work. - void pushFullCopy(TypeLoc L); + void pushFullCopy(TypeLoc L) { + size_t Size = L.getFullDataSize(); + TypeLoc Copy = pushFullUninitializedImpl(L.getType(), Size); + memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size); + } + + /// Pushes uninitialized space for the given type. The builder must + /// be empty. + TypeLoc pushFullUninitialized(QualType T) { + return pushFullUninitializedImpl(T, TypeLoc::getFullDataSizeForType(T)); + } /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs /// previously retrieved from this builder. TypeSpecTypeLoc pushTypeSpec(QualType T) { size_t LocalSize = TypeSpecTypeLoc::LocalDataSize; - unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment; - return pushImpl(T, LocalSize, LocalAlign).castAs(); + return pushImpl(T, LocalSize).castAs(); } /// Resets this builder to the newly-initialized state. @@ -80,7 +84,6 @@ class TypeLocBuilder { LastTy = QualType(); #endif Index = Capacity; - NumBytesAtAlign4 = NumBytesAtAlign8 = 0; } /// \brief Tell the TypeLocBuilder that the type it is storing has been @@ -94,10 +97,8 @@ class TypeLocBuilder { /// Pushes space for a new TypeLoc of the given type. Invalidates /// any TypeLocs previously retrieved from this builder. template TyLocType push(QualType T) { - TyLocType Loc = TypeLoc(T, 0).castAs(); - size_t LocalSize = Loc.getLocalDataSize(); - unsigned LocalAlign = Loc.getLocalDataAlignment(); - return pushImpl(T, LocalSize, LocalAlign).castAs(); + size_t LocalSize = TypeLoc(T, 0).castAs().getLocalDataSize(); + return pushImpl(T, LocalSize).castAs(); } /// Creates a TypeSourceInfo for the given type. @@ -126,12 +127,61 @@ class TypeLocBuilder { } private: + TypeLoc pushImpl(QualType T, size_t LocalSize) { +#ifndef NDEBUG + QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType(); + assert(TLast == LastTy && + "mismatch between last type and new type's inner type"); + LastTy = T; +#endif + + // If we need to grow, grow by a factor of 2. + if (LocalSize > Index) { + size_t RequiredCapacity = Capacity + (LocalSize - Index); + size_t NewCapacity = Capacity * 2; + while (RequiredCapacity > NewCapacity) + NewCapacity *= 2; + grow(NewCapacity); + } - TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment); + Index -= LocalSize; + + return getTemporaryTypeLoc(T); + } /// Grow to the given capacity. - void grow(size_t NewCapacity); + void grow(size_t NewCapacity) { + assert(NewCapacity > Capacity); + + // Allocate the new buffer and copy the old data into it. + char *NewBuffer = new char[NewCapacity]; + unsigned NewIndex = Index + NewCapacity - Capacity; + memcpy(&NewBuffer[NewIndex], + &Buffer[Index], + Capacity - Index); + + if (Buffer != InlineBuffer) + delete[] Buffer; + + Buffer = NewBuffer; + Capacity = NewCapacity; + Index = NewIndex; + } + + TypeLoc pushFullUninitializedImpl(QualType T, size_t Size) { +#ifndef NDEBUG + assert(LastTy.isNull() && "pushing full on non-empty TypeLocBuilder"); + LastTy = T; +#endif + assert(Index == Capacity && "pushing full on non-empty TypeLocBuilder"); + + reserve(Size); + Index -= Size; + + return getTemporaryTypeLoc(T); + } +public: /// \brief Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder /// object. ///