summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp113
-rw-r--r--lib/AST/ASTDiagnostic.cpp6
-rw-r--r--lib/AST/ASTImporter.cpp14
-rw-r--r--lib/AST/CMakeLists.txt3
-rw-r--r--lib/AST/DeclBase.cpp21
-rw-r--r--lib/AST/DeclCXX.cpp15
-rw-r--r--lib/AST/DeclObjC.cpp7
-rw-r--r--lib/AST/DeclTemplate.cpp8
-rw-r--r--lib/AST/Expr.cpp35
-rw-r--r--lib/AST/NestedNameSpecifier.cpp1
-rw-r--r--lib/AST/RecordLayout.cpp67
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp35
-rw-r--r--lib/AST/Type.cpp1
-rw-r--r--lib/AST/TypePrinter.cpp164
14 files changed, 341 insertions, 149 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d8c1c84..26b10b5 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -78,21 +78,21 @@ ASTContext::~ASTContext() {
// Increment in loop to prevent using deallocated memory.
Deallocate(&*I++);
}
- }
- for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
- I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
- // Increment in loop to prevent using deallocated memory.
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
- }
+ for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
+ I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ R->Destroy(*this);
+ }
- for (llvm::DenseMap<const ObjCContainerDecl*,
- const ASTRecordLayout*>::iterator
- I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
- // Increment in loop to prevent using deallocated memory.
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
+ for (llvm::DenseMap<const ObjCContainerDecl*,
+ const ASTRecordLayout*>::iterator
+ I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ R->Destroy(*this);
+ }
}
// Destroy nested-name-specifiers.
@@ -888,6 +888,10 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::QualifiedName:
return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+ case Type::InjectedClassName:
+ return getTypeInfo(cast<InjectedClassNameType>(T)
+ ->getUnderlyingType().getTypePtr());
+
case Type::TemplateSpecialization:
assert(getCanonicalType(T) != T &&
"Cannot request the size of a dependent type");
@@ -1918,38 +1922,71 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
return QualType(FTP, 0);
}
+#ifndef NDEBUG
+static bool NeedsInjectedClassNameType(const RecordDecl *D) {
+ if (!isa<CXXRecordDecl>(D)) return false;
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+ if (isa<ClassTemplatePartialSpecializationDecl>(RD))
+ return true;
+ if (RD->getDescribedClassTemplate() &&
+ !isa<ClassTemplateSpecializationDecl>(RD))
+ return true;
+ return false;
+}
+#endif
+
+/// getInjectedClassNameType - Return the unique reference to the
+/// injected class name type for the specified templated declaration.
+QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,
+ QualType TST) {
+ assert(NeedsInjectedClassNameType(Decl));
+ if (Decl->TypeForDecl) {
+ assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+ } else if (CXXRecordDecl *PrevDecl
+ = cast_or_null<CXXRecordDecl>(Decl->getPreviousDeclaration())) {
+ assert(PrevDecl->TypeForDecl && "previous declaration has no type");
+ Decl->TypeForDecl = PrevDecl->TypeForDecl;
+ assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+ } else {
+ Decl->TypeForDecl = new (*this, TypeAlignment)
+ InjectedClassNameType(Decl, TST, TST->getCanonicalTypeInternal());
+ Types.push_back(Decl->TypeForDecl);
+ }
+ return QualType(Decl->TypeForDecl, 0);
+}
+
/// getTypeDeclType - Return the unique reference to the type for the
/// specified type declaration.
-QualType ASTContext::getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl* PrevDecl) {
+QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) {
assert(Decl && "Passed null for Decl param");
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+ assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
return getTypedefType(Typedef);
- else if (isa<TemplateTypeParmDecl>(Decl)) {
- assert(false && "Template type parameter types are always available.");
- } else if (const ObjCInterfaceDecl *ObjCInterface
+
+ if (const ObjCInterfaceDecl *ObjCInterface
= dyn_cast<ObjCInterfaceDecl>(Decl))
return getObjCInterfaceType(ObjCInterface);
+ assert(!isa<TemplateTypeParmDecl>(Decl) &&
+ "Template type parameter types are always available.");
+
if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
- if (PrevDecl)
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- else
- Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
+ assert(!Record->getPreviousDeclaration() &&
+ "struct/union has previous declaration");
+ assert(!NeedsInjectedClassNameType(Record));
+ Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
} else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
- if (PrevDecl)
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- else
- Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
+ assert(!Enum->getPreviousDeclaration() &&
+ "enum has previous declaration");
+ Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
} else if (const UnresolvedUsingTypenameDecl *Using =
dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
} else
- assert(false && "TypeDecl without a type?");
+ llvm_unreachable("TypeDecl without a type?");
- if (!PrevDecl) Types.push_back(Decl->TypeForDecl);
+ Types.push_back(Decl->TypeForDecl);
return QualType(Decl->TypeForDecl, 0);
}
@@ -2022,6 +2059,24 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
return QualType(TypeParm, 0);
}
+TypeSourceInfo *
+ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo &Args,
+ QualType CanonType) {
+ QualType TST = getTemplateSpecializationType(Name, Args, CanonType);
+
+ TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
+ TemplateSpecializationTypeLoc TL
+ = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+ TL.setTemplateNameLoc(NameLoc);
+ TL.setLAngleLoc(Args.getLAngleLoc());
+ TL.setRAngleLoc(Args.getRAngleLoc());
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+ TL.setArgLocInfo(i, Args[i].getLocInfo());
+ return DI;
+}
+
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgumentListInfo &Args,
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 7402b7d..866b7f7 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -56,6 +56,12 @@ static bool ShouldAKA(ASTContext &Context, QualType QT,
QT = cast<QualifiedNameType>(Ty)->desugar();
continue;
}
+
+ // ...or an injected class name...
+ if (isa<InjectedClassNameType>(Ty)) {
+ QT = cast<InjectedClassNameType>(Ty)->desugar();
+ continue;
+ }
// ...or a substituted template type parameter.
if (isa<SubstTemplateTypeParmType>(Ty)) {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 2bcf07e..d9c0d7b 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -610,6 +610,16 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
+ case Type::InjectedClassName: {
+ const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
+ const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
+ if (!IsStructurallyEquivalent(Context,
+ Inj1->getUnderlyingType(),
+ Inj2->getUnderlyingType()))
+ return false;
+ break;
+ }
+
case Type::Typename: {
const TypenameType *Typename1 = cast<TypenameType>(T1);
const TypenameType *Typename2 = cast<TypenameType>(T2);
@@ -2244,12 +2254,14 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
if (ResultTy.isNull())
return 0;
+ TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
+
ObjCMethodDecl *ToMethod
= ObjCMethodDecl::Create(Importer.getToContext(),
Loc,
Importer.Import(D->getLocEnd()),
Name.getObjCSelector(),
- ResultTy, DC,
+ ResultTy, ResultTInfo, DC,
D->isInstanceMethod(),
D->isVariadic(),
D->isSynthesized(),
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index e5bd9b7..2f1a6af 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -4,8 +4,8 @@ add_clang_library(clangAST
APValue.cpp
ASTConsumer.cpp
ASTContext.cpp
- ASTImporter.cpp
ASTDiagnostic.cpp
+ ASTImporter.cpp
AttrImpl.cpp
CXXInheritance.cpp
Decl.cpp
@@ -23,6 +23,7 @@ add_clang_library(clangAST
InheritViz.cpp
NestedNameSpecifier.cpp
ParentMap.cpp
+ RecordLayout.cpp
RecordLayoutBuilder.cpp
Stmt.cpp
StmtDumper.cpp
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 9db6ae1..a949534 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -574,11 +574,22 @@ DeclContext *DeclContext::getPrimaryContext() {
if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
// If this is a tag type that has a definition or is currently
// being defined, that definition is our primary context.
- if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAs<TagType>())
- if (TagT->isBeingDefined() ||
- (TagT->getDecl() && TagT->getDecl()->isDefinition()))
- return TagT->getDecl();
- return this;
+ TagDecl *Tag = cast<TagDecl>(this);
+ assert(isa<TagType>(Tag->TypeForDecl) ||
+ isa<InjectedClassNameType>(Tag->TypeForDecl));
+
+ if (TagDecl *Def = Tag->getDefinition())
+ return Def;
+
+ if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
+ const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
+ if (TagTy->isBeingDefined())
+ // FIXME: is it necessarily being defined in the decl
+ // that owns the type?
+ return TagTy->getDecl();
+ }
+
+ return Tag;
}
assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 9b693af..7f4ad34 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -636,11 +636,16 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
assert(isInstance() && "No 'this' for static methods!");
- QualType ClassTy;
- if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate())
- ClassTy = TD->getInjectedClassNameType(C);
- else
- ClassTy = C.getTagDeclType(getParent());
+ QualType ClassTy = C.getTypeDeclType(getParent());
+
+ // Aesthetically we prefer not to synthesize a type as the
+ // InjectedClassNameType of a template pattern: injected class names
+ // are printed without template arguments, which might
+ // surprise/confuse/distract our poor users if they didn't
+ // explicitly write one.
+ if (isa<InjectedClassNameType>(ClassTy))
+ ClassTy = cast<InjectedClassNameType>(ClassTy)->getUnderlyingType();
+
ClassTy = C.getQualifiedType(ClassTy,
Qualifiers::fromCVRMask(getTypeQualifiers()));
return C.getPointerType(ClassTy);
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 8decafa..67b71a0 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -304,15 +304,16 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
+ TypeSourceInfo *ResultTInfo,
DeclContext *contextDecl,
bool isInstance,
bool isVariadic,
bool isSynthesized,
ImplementationControl impControl) {
return new (C) ObjCMethodDecl(beginLoc, endLoc,
- SelInfo, T, contextDecl,
- isInstance,
- isVariadic, isSynthesized, impControl);
+ SelInfo, T, ResultTInfo, contextDecl,
+ isInstance,
+ isVariadic, isSynthesized, impControl);
}
void ObjCMethodDecl::Destroy(ASTContext &C) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index d80db45..b449398 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -193,7 +193,8 @@ ClassTemplateDecl::findPartialSpecialization(QualType T) {
return 0;
}
-QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
+QualType
+ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
if (!CommonPtr->InjectedClassNameType.isNull())
return CommonPtr->InjectedClassNameType;
@@ -393,6 +394,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
SpecializedTemplate->getIdentifier(),
PrevDecl),
SpecializedTemplate(SpecializedTemplate),
+ TypeAsWritten(0),
TemplateArgs(Context, Builder, /*TakeArgs=*/true),
SpecializationKind(TSK_Undeclared) {
}
@@ -453,6 +455,7 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
+ QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
unsigned N = ArgInfos.size();
TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
@@ -467,7 +470,8 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
ClonedArgs, N,
PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
- Context.getTypeDeclType(Result, PrevDecl);
+
+ Context.getInjectedClassNameType(Result, CanonInjectedType);
return Result;
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index a2914bc..efd0fd1 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -181,7 +181,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
}
PrintingPolicy Policy(Context.getLangOptions());
- Policy.SuppressTagKind = true;
std::string Proto = FD->getQualifiedNameAsString(Policy);
@@ -2115,12 +2114,12 @@ ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, Expr *receiver,
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
- Selector selInfo, QualType retType,
- ObjCMethodDecl *mproto,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
- MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
@@ -2134,12 +2133,14 @@ ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
// constructor for class messages.
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
- Selector selInfo, QualType retType,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType,
ObjCMethodDecl *mproto, SourceLocation LBrac,
SourceLocation RBrac, Expr **ArgExprs,
unsigned nargs)
-: Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
-MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto)
+{
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
@@ -2157,23 +2158,27 @@ ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
default:
assert(false && "Invalid ObjCMessageExpr.");
case IsInstMeth:
- return ClassInfo(0, 0);
+ return ClassInfo(0, 0, SourceLocation());
case IsClsMethDeclUnknown:
- return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
+ return ClassInfo(0, (IdentifierInfo*) (x & ~Flags), ClassNameLoc);
case IsClsMethDeclKnown: {
ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
- return ClassInfo(D, D->getIdentifier());
+ return ClassInfo(D, D->getIdentifier(), ClassNameLoc);
}
}
}
void ObjCMessageExpr::setClassInfo(const ObjCMessageExpr::ClassInfo &CI) {
- if (CI.first == 0 && CI.second == 0)
+ if (CI.Decl == 0 && CI.Name == 0) {
SubExprs[RECEIVER] = (Expr*)((uintptr_t)0 | IsInstMeth);
- else if (CI.first == 0)
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.second | IsClsMethDeclUnknown);
+ return;
+ }
+
+ if (CI.Decl == 0)
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Name | IsClsMethDeclUnknown);
else
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.first | IsClsMethDeclKnown);
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Decl | IsClsMethDeclKnown);
+ ClassNameLoc = CI.Loc;
}
void ObjCMessageExpr::DoDestroy(ASTContext &C) {
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index e26c0bb..45518e9 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -142,7 +142,6 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS,
Type *T = getAsType();
PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
InnerPolicy.SuppressScope = true;
// Nested-name-specifiers are intended to contain minimally-qualified
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
new file mode 100644
index 0000000..838753a
--- /dev/null
+++ b/lib/AST/RecordLayout.cpp
@@ -0,0 +1,67 @@
+//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+
+using namespace clang;
+
+void ASTRecordLayout::Destroy(ASTContext &Ctx) {
+ if (FieldOffsets)
+ Ctx.Deallocate(FieldOffsets);
+ if (CXXInfo)
+ Ctx.Deallocate(CXXInfo);
+ this->~ASTRecordLayout();
+ Ctx.Deallocate(this);
+}
+
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
+ unsigned datasize, const uint64_t *fieldoffsets,
+ unsigned fieldcount)
+ : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+ FieldCount(fieldcount), CXXInfo(0) {
+ if (FieldCount > 0) {
+ FieldOffsets = new (Ctx) uint64_t[FieldCount];
+ memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+ }
+}
+
+// Constructor for C++ records.
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
+ uint64_t size, unsigned alignment,
+ uint64_t datasize,
+ const uint64_t *fieldoffsets,
+ unsigned fieldcount,
+ uint64_t nonvirtualsize,
+ unsigned nonvirtualalign,
+ const PrimaryBaseInfo &PrimaryBase,
+ const std::pair<const CXXRecordDecl *, uint64_t> *bases,
+ unsigned numbases,
+ const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
+ unsigned numvbases)
+ : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+ FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
+{
+ if (FieldCount > 0) {
+ FieldOffsets = new (Ctx) uint64_t[FieldCount];
+ memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+ }
+
+ CXXInfo->PrimaryBase = PrimaryBase;
+ CXXInfo->NonVirtualSize = nonvirtualsize;
+ CXXInfo->NonVirtualAlign = nonvirtualalign;
+ for (unsigned i = 0; i != numbases; ++i)
+ CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
+ for (unsigned i = 0; i != numvbases; ++i)
+ CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
+}
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 10c5089..22285ca 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -675,9 +675,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D);
if (!isa<CXXRecordDecl>(D))
- return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ Builder.Size,
+ Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
// FIXME: This is not always correct. See the part about bitfields at
// http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
@@ -690,16 +691,16 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
- return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size(),
- NonVirtualSize,
- Builder.NonVirtualAlignment,
- Builder.PrimaryBase,
- Builder.Bases.data(),
- Builder.Bases.size(),
- Builder.VBases.data(),
- Builder.VBases.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ DataSize, Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size(),
+ NonVirtualSize,
+ Builder.NonVirtualAlignment,
+ Builder.PrimaryBase,
+ Builder.Bases.data(),
+ Builder.Bases.size(),
+ Builder.VBases.data(),
+ Builder.VBases.size());
}
const ASTRecordLayout *
@@ -710,10 +711,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D, Impl);
- return new ASTRecordLayout(Builder.Size, Builder.Alignment,
- Builder.DataSize,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ Builder.DataSize,
+ Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
}
const CXXMethodDecl *
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 76cc382..8a64f8e 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -650,6 +650,7 @@ bool Type::isPODType() const {
case Vector:
case ExtVector:
case ObjCObjectPointer:
+ case BlockPointer:
return true;
case Enum:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 5b621cf..037bc14 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -30,7 +30,8 @@ namespace {
explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
void Print(QualType T, std::string &S);
- void PrintTag(const TagType *T, std::string &S);
+ void AppendScope(DeclContext *DC, std::string &S);
+ void PrintTag(TagDecl *T, std::string &S);
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) \
void Print##CLASS(const CLASS##Type *T, std::string &S);
@@ -330,19 +331,21 @@ void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
Print(T->getResultType(), S);
}
-void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
- std::string &S) {
- IdentifierInfo *II = T->getDecl()->getIdentifier();
+static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
+ IdentifierInfo *II = D->getIdentifier();
if (S.empty())
S = II->getName().str();
else
S = II->getName().str() + ' ' + S;
}
+void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
+ std::string &S) {
+ PrintTypeSpec(T->getDecl(), S);
+}
+
void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
- if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- S = ' ' + S;
- S = T->getDecl()->getIdentifier()->getName().str() + S;
+ PrintTypeSpec(T->getDecl(), S);
}
void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
@@ -371,89 +374,106 @@ void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
S = "decltype(" + s.str() + ")" + S;
}
-void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
+/// Appends the given scope to the end of a string.
+void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
+ if (DC->isTranslationUnit()) return;
+ AppendScope(DC->getParent(), Buffer);
+
+ unsigned OldSize = Buffer.size();
+
+ if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+ if (NS->getIdentifier())
+ Buffer += NS->getNameAsString();
+ else
+ Buffer += "<anonymous>";
+ } else if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ std::string TemplateArgsStr
+ = TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size(),
+ Policy);
+ Buffer += Spec->getIdentifier()->getName();
+ Buffer += TemplateArgsStr;
+ } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+ if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+ Buffer += Typedef->getIdentifier()->getName();
+ else if (Tag->getIdentifier())
+ Buffer += Tag->getIdentifier()->getName();
+ }
+
+ if (Buffer.size() != OldSize)
+ Buffer += "::";
+}
+
+void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
if (Policy.SuppressTag)
return;
-
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
+
+ std::string Buffer;
+
+ // We don't print tags unless this is an elaborated type.
+ // In C, we just assume every RecordType is an elaborated type.
+ if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
+ Buffer += D->getKindName();
+ Buffer += ' ';
+ }
+
+ if (!Policy.SuppressScope)
+ // Compute the full nested-name-specifier for this type. In C,
+ // this will always be empty.
+ AppendScope(D->getDeclContext(), Buffer);
+
const char *ID;
- if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
+ if (const IdentifierInfo *II = D->getIdentifier())
ID = II->getNameStart();
- else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
- Kind = 0;
+ else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
assert(Typedef->getIdentifier() && "Typedef without identifier?");
ID = Typedef->getIdentifier()->getNameStart();
} else
ID = "<anonymous>";
-
+ Buffer += ID;
+
// If this is a class template specialization, print the template
// arguments.
if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- InnerString = TemplateArgsStr + InnerString;
- }
-
- if (!Policy.SuppressScope) {
- // Compute the full nested-name-specifier for this type. In C,
- // this will always be empty.
- std::string ContextStr;
- for (DeclContext *DC = T->getDecl()->getDeclContext();
- !DC->isTranslationUnit(); DC = DC->getParent()) {
- std::string MyPart;
- if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
- if (NS->getIdentifier())
- MyPart = NS->getNameAsString();
- } else if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
- } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
- if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
- MyPart = Typedef->getIdentifier()->getName();
- else if (Tag->getIdentifier())
- MyPart = Tag->getIdentifier()->getName();
- }
-
- if (!MyPart.empty())
- ContextStr = MyPart + "::" + ContextStr;
+ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ const TemplateArgument *Args;
+ unsigned NumArgs;
+ if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
+ const TemplateSpecializationType *TST =
+ cast<TemplateSpecializationType>(TAW->getType());
+ Args = TST->getArgs();
+ NumArgs = TST->getNumArgs();
+ } else {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ Args = TemplateArgs.getFlatArgumentList();
+ NumArgs = TemplateArgs.flat_size();
}
-
- if (Kind)
- InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
- else
- InnerString = ContextStr + ID + InnerString;
- } else
- InnerString = ID + InnerString;
+ Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+ NumArgs,
+ Policy);
+ }
+
+ if (!InnerString.empty()) {
+ Buffer += ' ';
+ Buffer += InnerString;
+ }
+
+ std::swap(Buffer, InnerString);
}
void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
- PrintTag(T, S);
+ PrintTag(T->getDecl(), S);
}
void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
- PrintTag(T, S);
+ PrintTag(T->getDecl(), S);
}
void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
- std::string TypeStr;
- PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
- TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
-
+ Print(T->getUnderlyingType(), S);
S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;
}
@@ -494,6 +514,11 @@ void TypePrinter::PrintTemplateSpecialization(
S = SpecString + ' ' + S;
}
+void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
+ std::string &S) {
+ PrintTemplateSpecialization(T->getUnderlyingTST(), S);
+}
+
void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
std::string &S) {
std::string MyString;
@@ -505,7 +530,6 @@ void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
std::string TypeStr;
PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
InnerPolicy.SuppressScope = true;
TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
OpenPOWER on IntegriCloud