summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-06-07 11:27:53 +0000
committerManuel Klimek <klimek@google.com>2013-06-07 11:27:53 +0000
commite29ec9680a6650b80cede7ecb68480283c41f1ff (patch)
tree6a71a7f2ee88a813e99702083129b0ab6357bd73 /clang/lib
parentf0ec19944860fb62cf02bfe816417802ad637e13 (diff)
downloadbcm5719-llvm-e29ec9680a6650b80cede7ecb68480283c41f1ff.tar.gz
bcm5719-llvm-e29ec9680a6650b80cede7ecb68480283c41f1ff.zip
Reverts r183466: "Perform dynamic alignment computations..."
This introduces bugs in TemplateSpecializationTypeLoc's angle bracket locations. Regression test follows in a subsequent commit. llvm-svn: 183513
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/TypeLoc.cpp34
-rw-r--r--clang/lib/Sema/CMakeLists.txt1
-rw-r--r--clang/lib/Sema/SemaLambda.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp17
-rw-r--r--clang/lib/Sema/TreeTransform.h2
-rw-r--r--clang/lib/Sema/TypeLocBuilder.cpp136
-rw-r--r--clang/lib/Sema/TypeLocBuilder.h86
7 files changed, 85 insertions, 197 deletions
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index c47bde8ddec..03d40309f53 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -41,30 +41,12 @@ 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.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/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 836d1259785..e92f7671342 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/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/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 3402f220625..d647be37616 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/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<ReferenceTypeLoc>(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<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, 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/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index cb6f4c19de0..3b8228016c5 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/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<PackExpansionTypeLoc>(Result);
+
+ TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
+ PackExpansionTypeLoc TL =
+ TSResult->getTypeLoc().castAs<PackExpansionTypeLoc>();
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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index fe49153d991..3fcd0375d08 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 = T.getUnqualifiedLoc().getSourceRange();
+ SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange();
SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant)
<< Result << R;
diff --git a/clang/lib/Sema/TypeLocBuilder.cpp b/clang/lib/Sema/TypeLocBuilder.cpp
deleted file mode 100644
index c7d43b70469..00000000000
--- a/clang/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<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);
-}
diff --git a/clang/lib/Sema/TypeLocBuilder.h b/clang/lib/Sema/TypeLocBuilder.h
index b1e909859b2..f36ec9f3e20 100644
--- a/clang/lib/Sema/TypeLocBuilder.h
+++ b/clang/lib/Sema/TypeLocBuilder.h
@@ -39,19 +39,14 @@ class TypeLocBuilder {
#endif
/// The inline buffer.
- enum { BufferMaxAlignment = llvm::AlignOf<void*>::Alignment };
- llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> 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<TypeSpecTypeLoc>();
+ return pushImpl(T, LocalSize).castAs<TypeSpecTypeLoc>();
}
/// 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 <class TyLocType> TyLocType push(QualType T) {
- TyLocType Loc = TypeLoc(T, 0).castAs<TyLocType>();
- size_t LocalSize = Loc.getLocalDataSize();
- unsigned LocalAlign = Loc.getLocalDataAlignment();
- return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
+ size_t LocalSize = TypeLoc(T, 0).castAs<TyLocType>().getLocalDataSize();
+ return pushImpl(T, LocalSize).castAs<TyLocType>();
}
/// 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.
///
OpenPOWER on IntegriCloud