r183466 - Perform dynamic alignment computations so that the data in TypeLocs is
Manuel Klimek
klimek at google.com
Fri Jun 7 02:09:38 PDT 2013
More specifically, we get a TemplateSpecializationTypeLoc for which:
getLAngleLoc().isValid() is false, while
getRAngleLoc().isValid() && getLocStart().isValid() &&
getLocEnd().isValid() is true.
On Fri, Jun 7, 2013 at 10:46 AM, Manuel Klimek <klimek at google.com> wrote:
> FYI: this test leads to invalid type source locations in some cases. I
> don't have a good enough repro yet (internal refactoring tests found this),
> but the general idea is this:
> Given a TypeLoc for a templated type A<B> of a function parameter (like
> void f(const A<B>&), trying to getAs<clang::TemplateSpecializationTypeLoc>
> would previously return a valid type loc, and now returns an invalid type
> loc... Is that intentional?
>
> Thanks,
> /Manuel
>
>
>
> On Fri, Jun 7, 2013 at 2:04 AM, Eli Friedman <eli.friedman at gmail.com>wrote:
>
>> Author: efriedma
>> Date: Thu Jun 6 19:04:31 2013
>> New Revision: 183466
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=183466&view=rev
>> Log:
>> Perform dynamic alignment computations so that the data in TypeLocs is
>> correctly aligned. Not performing such computations led to misaligned
>> loads,
>> which crash on some platforms and are generally bad on other platforms.
>>
>> The implementation of TypeLocBuilder::pushImpl is rather messy; code using
>> TypeLocBuilder accidentally assumes that partial TypeLocs are
>> laid out like a complete TypeLoc. As a followup, I intend to work on
>> fixing the TypeLocBuilder API to avoid exposing partial TypeLocs; this
>> should
>> substantially simplify the implemementation.
>>
>> Fixes PR16144.
>>
>>
>> Added:
>> cfe/trunk/lib/Sema/TypeLocBuilder.cpp
>> Modified:
>> cfe/trunk/include/clang/AST/TypeLoc.h
>> cfe/trunk/lib/AST/TypeLoc.cpp
>> cfe/trunk/lib/Sema/CMakeLists.txt
>> cfe/trunk/lib/Sema/SemaLambda.cpp
>> cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>> cfe/trunk/lib/Sema/TreeTransform.h
>> cfe/trunk/lib/Sema/TypeLocBuilder.h
>>
>> Modified: cfe/trunk/include/clang/AST/TypeLoc.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
>> +++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Jun 6 19:04:31 2013
>> @@ -95,6 +95,10 @@ 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 {
>> @@ -229,7 +233,11 @@ public:
>> }
>>
>> UnqualTypeLoc getUnqualifiedLoc() const {
>> - return UnqualTypeLoc(getTypePtr(), Data);
>> + unsigned align =
>> + TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
>> + uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
>> + dataInt = llvm::RoundUpToAlignment(dataInt, align);
>> + return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
>> }
>>
>> /// Initializes the local data of this type source info block to
>> @@ -250,10 +258,11 @@ public:
>> return 0;
>> }
>>
>> - /// \brief Returns the size of the type source info data block.
>> - unsigned getFullDataSize() const {
>> - return getLocalDataSize() +
>> - getFullDataSizeForType(getType().getLocalUnqualifiedType());
>> + /// \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;
>> }
>>
>> private:
>> @@ -280,9 +289,6 @@ inline UnqualTypeLoc TypeLoc::getUnquali
>> /// \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.
>> @@ -317,12 +323,16 @@ class ConcreteTypeLoc : public Base {
>> }
>>
>> public:
>> - unsigned getLocalDataSize() const {
>> - return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
>> + unsigned getLocalDataAlignment() const {
>> + return std::max(llvm::alignOf<LocalData>(),
>> + asDerived()->getExtraLocalDataAlignment());
>> }
>> - // Give a default implementation that's useful for leaf types.
>> - unsigned getFullDataSize() const {
>> - return asDerived()->getLocalDataSize() + getInnerTypeSize();
>> + unsigned getLocalDataSize() const {
>> + unsigned size = sizeof(LocalData);
>> + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
>> + size = llvm::RoundUpToAlignment(size, extraAlign);
>> + size += asDerived()->getExtraLocalDataSize();
>> + return size;
>> }
>>
>> TypeLoc getNextTypeLoc() const {
>> @@ -338,6 +348,10 @@ protected:
>> return 0;
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return 1;
>> + }
>> +
>> LocalData *getLocalData() const {
>> return static_cast<LocalData*>(Base::Data);
>> }
>> @@ -346,11 +360,17 @@ protected:
>> /// local data that can't be captured in the Info (e.g. because it's
>> /// of variable size).
>> void *getExtraLocalData() const {
>> - return getLocalData() + 1;
>> + unsigned size = sizeof(LocalData);
>> + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
>> + size = llvm::RoundUpToAlignment(size, extraAlign);
>> + return reinterpret_cast<char*>(Base::Data) + size;
>> }
>>
>> void *getNonLocalData() const {
>> - return static_cast<char*>(Base::Data) +
>> asDerived()->getLocalDataSize();
>> + uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
>> + data += asDerived()->getLocalDataSize();
>> + data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
>> + return reinterpret_cast<void*>(data);
>> }
>>
>> struct HasNoInnerType {};
>> @@ -373,6 +393,18 @@ 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();
>> }
>> @@ -417,7 +449,8 @@ class TypeSpecTypeLoc : public ConcreteT
>> Type,
>> TypeSpecLocInfo> {
>> public:
>> - enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
>> + enum { LocalDataSize = sizeof(TypeSpecLocInfo),
>> + LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment
>> };
>>
>> SourceLocation getNameLoc() const {
>> return this->getLocalData()->NameLoc;
>> @@ -448,8 +481,6 @@ class BuiltinTypeLoc : public ConcreteTy
>> BuiltinType,
>> BuiltinLocInfo> {
>> public:
>> - enum { LocalDataSize = sizeof(BuiltinLocInfo) };
>> -
>> SourceLocation getBuiltinLoc() const {
>> return getLocalData()->BuiltinLoc;
>> }
>> @@ -478,6 +509,10 @@ public:
>> return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>()
>> : 1;
>> + }
>> +
>> SourceRange getLocalSourceRange() const {
>> return SourceRange(getBuiltinLoc(), getBuiltinLoc());
>> }
>> @@ -840,6 +875,10 @@ public:
>> return this->getNumProtocols() * sizeof(SourceLocation);
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return llvm::alignOf<SourceLocation>();
>> + }
>> +
>> QualType getInnerType() const {
>> return getTypePtr()->getBaseType();
>> }
>> @@ -1166,6 +1205,10 @@ public:
>> return getNumArgs() * sizeof(ParmVarDecl*);
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return llvm::alignOf<ParmVarDecl*>();
>> + }
>> +
>> QualType getInnerType() const { return getTypePtr()->getResultType(); }
>> };
>>
>> @@ -1357,6 +1400,10 @@ public:
>> return getNumArgs() * sizeof(TemplateArgumentLocInfo);
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return llvm::alignOf<TemplateArgumentLocInfo>();
>> + }
>> +
>> private:
>> TemplateArgumentLocInfo *getArgInfos() const {
>> return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
>> @@ -1761,6 +1808,10 @@ public:
>> return getNumArgs() * sizeof(TemplateArgumentLocInfo);
>> }
>>
>> + unsigned getExtraLocalDataAlignment() const {
>> + return llvm::alignOf<TemplateArgumentLocInfo>();
>> + }
>> +
>> private:
>> TemplateArgumentLocInfo *getArgInfos() const {
>> return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
>>
>> Modified: cfe/trunk/lib/AST/TypeLoc.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/TypeLoc.cpp (original)
>> +++ cfe/trunk/lib/AST/TypeLoc.cpp Thu Jun 6 19:04:31 2013
>> @@ -41,12 +41,30 @@ SourceRange TypeLoc::getLocalSourceRange
>> }
>>
>> namespace {
>> + class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
>> + 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<TypeSizer, unsigned> {
>> public:
>> #define ABSTRACT_TYPELOC(CLASS, PARENT)
>> #define TYPELOC(CLASS, PARENT) \
>> unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
>> - return TyLoc.getFullDataSize(); \
>> + return TyLoc.getLocalDataSize(); \
>> }
>> #include "clang/AST/TypeLocNodes.def"
>> };
>> @@ -54,8 +72,18 @@ namespace {
>>
>> /// \brief Returns the size of the type source info data block.
>> unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
>> - if (Ty.isNull()) return 0;
>> - return TypeSizer().Visit(TypeLoc(Ty, 0));
>> + 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;
>> }
>>
>> namespace {
>>
>> Modified: cfe/trunk/lib/Sema/CMakeLists.txt
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CMakeLists.txt?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/CMakeLists.txt (original)
>> +++ cfe/trunk/lib/Sema/CMakeLists.txt Thu Jun 6 19:04:31 2013
>> @@ -51,6 +51,7 @@ add_clang_library(clangSema
>> SemaTemplateVariadic.cpp
>> SemaType.cpp
>> TargetAttributesSema.cpp
>> + TypeLocBuilder.cpp
>> )
>>
>> add_dependencies(clangSema
>>
>> Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Jun 6 19:04:31 2013
>> @@ -445,6 +445,7 @@ FieldDecl *Sema::checkInitCapture(Source
>> assert(!DeductType.isNull() && "can't build reference to auto");
>> TLB.push<ReferenceTypeLoc>(DeductType).setSigilLoc(Loc);
>> }
>> + TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
>>
>> InitializationKind InitKind = InitializationKind::CreateDefault(Loc);
>> Expr *Init = InitExpr;
>> @@ -476,8 +477,7 @@ FieldDecl *Sema::checkInitCapture(Source
>> else
>> InitKind = InitializationKind::CreateCopy(Loc, Loc);
>> QualType DeducedType;
>> - if (DeduceAutoType(TLB.getTemporaryTypeLoc(DeductType),
>> - Init, DeducedType) == DAR_Failed) {
>> + if (DeduceAutoType(TSI, Init, DeducedType) == DAR_Failed) {
>> if (isa<InitListExpr>(Init))
>> Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list)
>> << Id << Init->getSourceRange();
>> @@ -492,7 +492,7 @@ FieldDecl *Sema::checkInitCapture(Source
>> // 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, TLB.getTypeSourceInfo(Context, DeductType),
>> LSI->Lambda,
>> + Id, DeducedType, TSI, LSI->Lambda,
>> Loc, /*Mutable*/ false, /*BitWidth*/ 0, ICIS_NoInit,
>> Loc, AS_public, /*PrevDecl*/ 0, /*Declarator*/ 0);
>> LSI->Lambda->addDecl(NewFD);
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Thu Jun 6 19:04:31 2013
>> @@ -18,6 +18,7 @@
>> #include "clang/Sema/ScopeInfo.h"
>> #include "clang/Sema/SemaInternal.h"
>> #include "clang/Sema/Template.h"
>> +#include "TypeLocBuilder.h"
>>
>> using namespace clang;
>>
>> @@ -463,17 +464,13 @@ Sema::CheckPackExpansion(TypeSourceInfo
>> EllipsisLoc, NumExpansions);
>> if (Result.isNull())
>> return 0;
>> -
>> - TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
>> - PackExpansionTypeLoc TL =
>> - TSResult->getTypeLoc().castAs<PackExpansionTypeLoc>();
>> +
>> + TypeLocBuilder TLB;
>> + TLB.pushFullCopy(Pattern->getTypeLoc());
>> + PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
>> TL.setEllipsisLoc(EllipsisLoc);
>> -
>> - // Copy over the source-location information from the type.
>> - memcpy(TL.getNextTypeLoc().getOpaqueData(),
>> - Pattern->getTypeLoc().getOpaqueData(),
>> - Pattern->getTypeLoc().getFullDataSize());
>> - return TSResult;
>> +
>> + return TLB.getTypeSourceInfo(Context, Result);
>> }
>>
>> QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange
>> PatternRange,
>>
>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>> +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 6 19:04:31 2013
>> @@ -3427,7 +3427,7 @@ TreeTransform<Derived>::TransformQualifi
>> } else {
>> // Otherwise, complain about the addition of a qualifier to an
>> // already-qualified type.
>> - SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange();
>> + SourceRange R = T.getUnqualifiedLoc().getSourceRange();
>> SemaRef.Diag(R.getBegin(),
>> diag::err_attr_objc_ownership_redundant)
>> << Result << R;
>>
>>
>> Added: cfe/trunk/lib/Sema/TypeLocBuilder.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TypeLocBuilder.cpp?rev=183466&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/TypeLocBuilder.cpp (added)
>> +++ cfe/trunk/lib/Sema/TypeLocBuilder.cpp Thu Jun 6 19:04:31 2013
>> @@ -0,0 +1,136 @@
>> +//===--- 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<TypeLoc, 4> 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<class
>> CLASS##TypeLoc>(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);
>> +}
>>
>> Modified: cfe/trunk/lib/Sema/TypeLocBuilder.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TypeLocBuilder.h?rev=183466&r1=183465&r2=183466&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/TypeLocBuilder.h (original)
>> +++ cfe/trunk/lib/Sema/TypeLocBuilder.h Thu Jun 6 19:04:31 2013
>> @@ -39,14 +39,19 @@ class TypeLocBuilder {
>> #endif
>>
>> /// The inline buffer.
>> - char InlineBuffer[InlineCapacity];
>> + enum { BufferMaxAlignment = llvm::AlignOf<void*>::Alignment };
>> + llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity>
>> InlineBuffer;
>> + unsigned NumBytesAtAlign4, NumBytesAtAlign8;
>>
>> public:
>> TypeLocBuilder()
>> - : Buffer(InlineBuffer), Capacity(InlineCapacity),
>> Index(InlineCapacity) {}
>> + : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity),
>> + Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0)
>> + {
>> + }
>>
>> ~TypeLocBuilder() {
>> - if (Buffer != InlineBuffer)
>> + if (Buffer != InlineBuffer.buffer)
>> delete[] Buffer;
>> }
>>
>> @@ -59,23 +64,14 @@ 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) {
>> - 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));
>> - }
>> + void pushFullCopy(TypeLoc L);
>>
>> /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
>> /// previously retrieved from this builder.
>> TypeSpecTypeLoc pushTypeSpec(QualType T) {
>> size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
>> - return pushImpl(T, LocalSize).castAs<TypeSpecTypeLoc>();
>> + unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment;
>> + return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>();
>> }
>>
>> /// Resets this builder to the newly-initialized state.
>> @@ -84,6 +80,7 @@ class TypeLocBuilder {
>> LastTy = QualType();
>> #endif
>> Index = Capacity;
>> + NumBytesAtAlign4 = NumBytesAtAlign8 = 0;
>> }
>>
>> /// \brief Tell the TypeLocBuilder that the type it is storing has been
>> @@ -97,8 +94,10 @@ class TypeLocBuilder {
>> /// Pushes space for a new TypeLoc of the given type. Invalidates
>> /// any TypeLocs previously retrieved from this builder.
>> template <class TyLocType> TyLocType push(QualType T) {
>> - size_t LocalSize = TypeLoc(T,
>> 0).castAs<TyLocType>().getLocalDataSize();
>> - return pushImpl(T, LocalSize).castAs<TyLocType>();
>> + TyLocType Loc = TypeLoc(T, 0).castAs<TyLocType>();
>> + size_t LocalSize = Loc.getLocalDataSize();
>> + unsigned LocalAlign = Loc.getLocalDataAlignment();
>> + return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
>> }
>>
>> /// Creates a TypeSourceInfo for the given type.
>> @@ -127,61 +126,12 @@ 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);
>> - }
>>
>> - Index -= LocalSize;
>> -
>> - return getTemporaryTypeLoc(T);
>> - }
>> + TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned
>> LocalAlignment);
>>
>> /// Grow to the given capacity.
>> - 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);
>> - }
>> + void grow(size_t NewCapacity);
>>
>> -public:
>> /// \brief Retrieve a temporary TypeLoc that refers into this \c
>> TypeLocBuilder
>> /// object.
>> ///
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130607/a392d0a9/attachment.html>
More information about the cfe-commits
mailing list