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,
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;
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();
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.
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;
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++]);
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() {
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();
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++];
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
}
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(
}
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) {
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");
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");