diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 113 | ||||
-rw-r--r-- | lib/AST/ASTDiagnostic.cpp | 6 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 14 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 21 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 15 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 7 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 8 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 35 | ||||
-rw-r--r-- | lib/AST/NestedNameSpecifier.cpp | 1 | ||||
-rw-r--r-- | lib/AST/RecordLayout.cpp | 67 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 35 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 1 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 164 |
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); |