diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2013-06-07 20:31:48 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2013-06-07 20:31:48 +0000 |
| commit | 7152fbe57ef2ba15bf90f9a27f5d273e0e92ef42 (patch) | |
| tree | 03284a8f1dcd9694833e62b26fa65644b272206c /clang/lib | |
| parent | 1b0a9494823e57bec2374bd9f7e040a7356cc2ae (diff) | |
| download | bcm5719-llvm-7152fbe57ef2ba15bf90f9a27f5d273e0e92ef42.tar.gz bcm5719-llvm-7152fbe57ef2ba15bf90f9a27f5d273e0e92ef42.zip | |
Re-commit r183466 with a fix to make the TypeLoc casting machinery work
correctly in the presence of qualified types.
(I had to change the unittest because it was trying to cast a
QualifiedTypeLoc to TemplateSpecializationTypeLoc.)
llvm-svn: 183563
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/Sema/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/TypeLocBuilder.h | 86 |
7 files changed, 65 insertions, 87 deletions
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 03d40309f53..c47bde8ddec 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -41,12 +41,30 @@ SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) { } 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 { diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index e92f7671342..836d1259785 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -51,6 +51,7 @@ add_clang_library(clangSema SemaTemplateVariadic.cpp SemaType.cpp TargetAttributesSema.cpp + TypeLocBuilder.cpp ) add_dependencies(clangSema diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index d647be37616..3402f220625 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -445,6 +445,7 @@ FieldDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef, 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(SourceLocation Loc, bool ByRef, 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(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, 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); diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 3b8228016c5..cb6f4c19de0 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -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 *Pattern, SourceLocation EllipsisLoc, 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, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 39664d0491e..e27d627d3ff 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3418,9 +3418,11 @@ namespace { TemplateSpecializationTypeLoc NamedTL = ElabTL.getNamedTypeLoc() .castAs<TemplateSpecializationTypeLoc>(); TL.copy(NamedTL); - } - else + } else { TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>()); + assert(TL.getRAngleLoc() == OldTL.castAs<TemplateSpecializationTypeLoc>().getRAngleLoc()); + } + } void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3fcd0375d08..fe49153d991 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3427,7 +3427,7 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, } 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; diff --git a/clang/lib/Sema/TypeLocBuilder.h b/clang/lib/Sema/TypeLocBuilder.h index f36ec9f3e20..b1e909859b2 100644 --- a/clang/lib/Sema/TypeLocBuilder.h +++ b/clang/lib/Sema/TypeLocBuilder.h @@ -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. /// |

