diff options
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 31 | ||||
-rw-r--r-- | include/clang/Frontend/PCHReader.h | 6 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 28 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 93 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 104 |
5 files changed, 238 insertions, 24 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 74c579b602..cf42fa03fa 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -272,6 +272,16 @@ public: protected: NamedDecl *TemplatedDecl; TemplateParameterList* TemplateParams; + +public: + /// \brief Initialize the underlying templated declaration and + /// template parameters. + void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { + assert(TemplatedDecl == 0 && "TemplatedDecl already set!"); + assert(TemplateParams == 0 && "TemplateParams already set!"); + TemplatedDecl = templatedDecl; + TemplateParams = templateParams; + } }; /// \brief Provides information about a function template specialization, @@ -716,6 +726,13 @@ public: DefaultArgument = 0; InheritedDefault = false; } + + /// \brief Set whether this template type parameter was declared with + /// the 'typename' or 'class' keyword. + void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; } + + /// \brief Set whether this is a parameter pack. + void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; } /// \brief Retrieve the depth of the template parameter. unsigned getDepth() const; @@ -1292,10 +1309,9 @@ protected: Common *CommonPtr; ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl, - ClassTemplateDecl *PrevDecl, Common *CommonPtr) + TemplateParameterList *Params, NamedDecl *Decl) : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl), - PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { } + PreviousDeclaration(0), CommonPtr(0) { } ~ClassTemplateDecl(); @@ -1310,6 +1326,10 @@ public: return PreviousDeclaration; } + /// \brief Initialize the previous declaration. Only valid to call on a + /// ClassTemplateDecl that is created using ClassTemplateDecl::CreateEmpty. + void initPreviousDeclaration(ASTContext &C, ClassTemplateDecl *PrevDecl); + virtual ClassTemplateDecl *getCanonicalDecl(); /// Create a class template node. @@ -1320,6 +1340,11 @@ public: NamedDecl *Decl, ClassTemplateDecl *PrevDecl); + /// \brief Create an empty class template node. Mainly used for PCH reading. + static ClassTemplateDecl *CreateEmpty(ASTContext &C) { + return new (C) ClassTemplateDecl(0,SourceLocation(),DeclarationName(),0,0); + } + /// \brief Retrieve the set of specializations of this class template. llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() { return CommonPtr->Specializations; diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index b6881edce9..8139066c4b 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -693,6 +693,12 @@ public: NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx); + /// \brief Read a template name. + TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx); + + /// \brief Read a template argument. + TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx); + /// \brief Read a source location. SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) { return SourceLocation::getFromRawEncoding(Record[Idx++]); diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 85b7960075..1fcf92309b 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -155,23 +155,31 @@ ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() { return Template; } -ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, - DeclContext *DC, - SourceLocation L, - DeclarationName Name, - TemplateParameterList *Params, - NamedDecl *Decl, - ClassTemplateDecl *PrevDecl) { - Common *CommonPtr; +void ClassTemplateDecl::initPreviousDeclaration(ASTContext &C, + ClassTemplateDecl *PrevDecl) { + assert(PreviousDeclaration == 0 && "PreviousDeclaration already set!"); + assert(CommonPtr == 0 && "initPreviousDeclaration already called!"); + + PreviousDeclaration = PrevDecl; + if (PrevDecl) CommonPtr = PrevDecl->CommonPtr; else { CommonPtr = new (C) Common; C.AddDeallocation(DeallocateCommon, CommonPtr); } +} - return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, - CommonPtr); +ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, + DeclContext *DC, + SourceLocation L, + DeclarationName Name, + TemplateParameterList *Params, + NamedDecl *Decl, + ClassTemplateDecl *PrevDecl) { + ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); + New->initPreviousDeclaration(C, PrevDecl); + return New; } ClassTemplateDecl::~ClassTemplateDecl() { diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 99c28d4f03..c8663bc702 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2208,13 +2208,26 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context->getInjectedClassNameType(D, TST); } - case pch::TYPE_TEMPLATE_TYPE_PARM: - assert(false && "can't read template type parm types yet"); - break; + case pch::TYPE_TEMPLATE_TYPE_PARM: { + unsigned Idx = 0; + unsigned Depth = Record[Idx++]; + unsigned Index = Record[Idx++]; + bool Pack = Record[Idx++]; + IdentifierInfo *Name = GetIdentifierInfo(Record, Idx); + return Context->getTemplateTypeParmType(Depth, Index, Pack, Name); + } - case pch::TYPE_TEMPLATE_SPECIALIZATION: - assert(false && "can't read template specialization types yet"); - break; + case pch::TYPE_TEMPLATE_SPECIALIZATION: { + unsigned Idx = 0; + TemplateName Name = ReadTemplateName(Record, Idx); + unsigned NumArgs = Record[Idx++]; + llvm::SmallVector<TemplateArgument, 8> Args; + Args.reserve(NumArgs); + while (NumArgs--) + Args.push_back(ReadTemplateArgument(Record, Idx)); + return Context->getTemplateSpecializationType(Name, Args.data(),Args.size(), + QualType()); + } } // Suppress a GCC warning return QualType(); @@ -2932,6 +2945,74 @@ PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) { return DeclarationName(); } +TemplateName +PCHReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) { + TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; + switch (Kind) { + case TemplateName::Template: + return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++]))); + + case TemplateName::OverloadedTemplate: { + unsigned size = Record[Idx++]; + UnresolvedSet<8> Decls; + while (size--) + Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++]))); + + return Context->getOverloadedTemplateName(Decls.begin(), Decls.end()); + } + + case TemplateName::QualifiedTemplate: { + NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); + bool hasTemplKeyword = Record[Idx++]; + TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++])); + return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template); + } + + case TemplateName::DependentTemplate: { + NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); + if (Record[Idx++]) // isIdentifier + return Context->getDependentTemplateName(NNS, + GetIdentifierInfo(Record, Idx)); + return Context->getDependentTemplateName(NNS, + (OverloadedOperatorKind)Record[Idx++]); + } + } + + assert(0 && "Unhandled template name kind!"); + return TemplateName(); +} + +TemplateArgument +PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) { + switch ((TemplateArgument::ArgKind)Record[Idx++]) { + case TemplateArgument::Null: + return TemplateArgument(); + case TemplateArgument::Type: + return TemplateArgument(GetType(Record[Idx++])); + case TemplateArgument::Declaration: + return TemplateArgument(GetDecl(Record[Idx++])); + case TemplateArgument::Integral: + return TemplateArgument(ReadAPSInt(Record, Idx), GetType(Record[Idx++])); + case TemplateArgument::Template: + return TemplateArgument(ReadTemplateName(Record, Idx)); + case TemplateArgument::Expression: + return TemplateArgument(ReadDeclExpr()); + case TemplateArgument::Pack: { + unsigned NumArgs = Record[Idx++]; + llvm::SmallVector<TemplateArgument, 8> Args; + Args.reserve(NumArgs); + while (NumArgs--) + Args.push_back(ReadTemplateArgument(Record, Idx)); + TemplateArgument TemplArg; + TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true); + return TemplArg; + } + } + + assert(0 && "Unhandled template argument kind!"); + return TemplateArgument(); +} + NestedNameSpecifier * PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) { unsigned N = Record[Idx++]; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index cbc0da673c..fe11ca76d3 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -567,6 +567,28 @@ CXXBaseSpecifier *PCHDeclReader::ReadCXXBaseSpecifier() { void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { // assert(false && "cannot read CXXRecordDecl"); VisitRecordDecl(D); + + enum CXXRecKind { + CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization + }; + switch ((CXXRecKind)Record[Idx++]) { + default: + assert(false && "Out of sync with PCHDeclWriter::VisitCXXRecordDecl?"); + case CXXRecNotTemplate: + break; + case CXXRecTemplate: + D->setDescribedClassTemplate( + cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))); + break; + case CXXRecMemberSpecialization: { + CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); + TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; + SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); + D->setInstantiationOfMemberClass(RD, TSK); + D->getMemberSpecializationInfo()->setPointOfInstantiation(POI); + break; + } + } // FIXME: this is far from complete @@ -618,11 +640,76 @@ void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { } void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) { - assert(false && "cannot read TemplateDecl"); + VisitNamedDecl(D); + + NamedDecl *TemplatedDecl = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); + + // TemplateParams. + SourceLocation TemplateLoc = Reader.ReadSourceLocation(Record, Idx); + SourceLocation LAngleLoc = Reader.ReadSourceLocation(Record, Idx); + SourceLocation RAngleLoc = Reader.ReadSourceLocation(Record, Idx); + + unsigned NumParams = Record[Idx++]; + assert(NumParams && "No template params!"); + llvm::SmallVector<NamedDecl *, 16> Params; + Params.reserve(NumParams); + while (NumParams--) + Params.push_back(cast<NamedDecl>(Reader.GetDecl(Record[Idx++]))); + + TemplateParameterList* TemplateParams = + TemplateParameterList::Create(*Reader.getContext(), TemplateLoc, LAngleLoc, + Params.data(), Params.size(), RAngleLoc); + + D->init(TemplatedDecl, TemplateParams); } void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { - assert(false && "cannot read ClassTemplateDecl"); + VisitTemplateDecl(D); + + ClassTemplateDecl *PrevDecl = + cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])); + D->initPreviousDeclaration(*Reader.getContext(), PrevDecl); + if (PrevDecl == 0) { + // This ClassTemplateDecl owns a CommonPtr; read it. + + unsigned size = Record[Idx++]; + while (size--) { + ClassTemplateSpecializationDecl *CTSD + = cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++])); + llvm::FoldingSetNodeID ID; + void *InsertPos = 0; + ClassTemplateSpecializationDecl::Profile(ID, + CTSD->getTemplateArgs().getFlatArgumentList(), + CTSD->getTemplateArgs().flat_size(), + *Reader.getContext()); + D->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); + D->getSpecializations().InsertNode(CTSD, InsertPos); + } + + size = Record[Idx++]; + while (size--) { + ClassTemplatePartialSpecializationDecl *CTSD + = cast<ClassTemplatePartialSpecializationDecl>( + Reader.GetDecl(Record[Idx++])); + llvm::FoldingSetNodeID ID; + void *InsertPos = 0; + ClassTemplatePartialSpecializationDecl::Profile(ID, + CTSD->getTemplateArgs().getFlatArgumentList(), + CTSD->getTemplateArgs().flat_size(), + *Reader.getContext()); + D->getPartialSpecializations().FindNodeOrInsertPos(ID, InsertPos); + D->getPartialSpecializations().InsertNode(CTSD, InsertPos); + } + + // InjectedClassNameType is computed. + + if (ClassTemplateDecl *CTD + = cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))) { + D->setInstantiatedFromMemberTemplate(CTD); + if (Record[Idx++]) + D->setMemberSpecialization(); + } + } } void PCHDeclReader::VisitClassTemplateSpecializationDecl( @@ -640,7 +727,14 @@ void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) { } void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { - assert(false && "cannot read TemplateTypeParmDecl"); + VisitTypeDecl(D); + + D->setDeclaredWithTypename(Record[Idx++]); + D->setParameterPack(Record[Idx++]); + + bool Inherited = Record[Idx++]; + TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Record, Idx); + D->setDefaultArgument(DefArg, Inherited); } void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { @@ -988,7 +1082,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { assert(false && "cannot read FriendTemplateDecl"); break; case pch::DECL_CLASS_TEMPLATE: - assert(false && "cannot read ClassTemplateDecl"); + D = ClassTemplateDecl::CreateEmpty(*Context); break; case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION: assert(false && "cannot read ClasstemplateSpecializationDecl"); @@ -1000,7 +1094,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { assert(false && "cannot read FunctionTemplateDecl"); break; case pch::DECL_TEMPLATE_TYPE_PARM: - assert(false && "cannot read TemplateTypeParmDecl"); + D = TemplateTypeParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,0,0); break; case pch::DECL_NON_TYPE_TEMPLATE_PARM: assert(false && "cannot read NonTypeTemplateParmDecl"); |