Initial support for reading templates from PCH.

llvm-svn: 106392
This commit is contained in:
Argyrios Kyrtzidis 2010-06-19 19:29:09 +00:00
parent 106caf92cd
commit 95c04caf92
5 changed files with 238 additions and 24 deletions

View File

@ -272,6 +272,16 @@ public:
protected: protected:
NamedDecl *TemplatedDecl; NamedDecl *TemplatedDecl;
TemplateParameterList* TemplateParams; 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, /// \brief Provides information about a function template specialization,
@ -716,6 +726,13 @@ public:
DefaultArgument = 0; DefaultArgument = 0;
InheritedDefault = false; 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. /// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const; unsigned getDepth() const;
@ -1292,10 +1309,9 @@ protected:
Common *CommonPtr; Common *CommonPtr;
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl, TemplateParameterList *Params, NamedDecl *Decl)
ClassTemplateDecl *PrevDecl, Common *CommonPtr)
: TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl), : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { } PreviousDeclaration(0), CommonPtr(0) { }
~ClassTemplateDecl(); ~ClassTemplateDecl();
@ -1310,6 +1326,10 @@ public:
return PreviousDeclaration; 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(); virtual ClassTemplateDecl *getCanonicalDecl();
/// Create a class template node. /// Create a class template node.
@ -1320,6 +1340,11 @@ public:
NamedDecl *Decl, NamedDecl *Decl,
ClassTemplateDecl *PrevDecl); 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. /// \brief Retrieve the set of specializations of this class template.
llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() { llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
return CommonPtr->Specializations; return CommonPtr->Specializations;

View File

@ -693,6 +693,12 @@ public:
NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record, NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
unsigned &Idx); 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. /// \brief Read a source location.
SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) { SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
return SourceLocation::getFromRawEncoding(Record[Idx++]); return SourceLocation::getFromRawEncoding(Record[Idx++]);

View File

@ -155,6 +155,21 @@ ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
return Template; return Template;
} }
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);
}
}
ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
DeclContext *DC, DeclContext *DC,
SourceLocation L, SourceLocation L,
@ -162,16 +177,9 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
TemplateParameterList *Params, TemplateParameterList *Params,
NamedDecl *Decl, NamedDecl *Decl,
ClassTemplateDecl *PrevDecl) { ClassTemplateDecl *PrevDecl) {
Common *CommonPtr; ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
if (PrevDecl) New->initPreviousDeclaration(C, PrevDecl);
CommonPtr = PrevDecl->CommonPtr; return New;
else {
CommonPtr = new (C) Common;
C.AddDeallocation(DeallocateCommon, CommonPtr);
}
return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
CommonPtr);
} }
ClassTemplateDecl::~ClassTemplateDecl() { ClassTemplateDecl::~ClassTemplateDecl() {

View File

@ -2208,13 +2208,26 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
return Context->getInjectedClassNameType(D, TST); return Context->getInjectedClassNameType(D, TST);
} }
case pch::TYPE_TEMPLATE_TYPE_PARM: case pch::TYPE_TEMPLATE_TYPE_PARM: {
assert(false && "can't read template type parm types yet"); unsigned Idx = 0;
break; 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: case pch::TYPE_TEMPLATE_SPECIALIZATION: {
assert(false && "can't read template specialization types yet"); unsigned Idx = 0;
break; 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 // Suppress a GCC warning
return QualType(); return QualType();
@ -2932,6 +2945,74 @@ PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
return DeclarationName(); 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 * NestedNameSpecifier *
PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) { PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
unsigned N = Record[Idx++]; unsigned N = Record[Idx++];

View File

@ -567,6 +567,28 @@ CXXBaseSpecifier *PCHDeclReader::ReadCXXBaseSpecifier() {
void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
// assert(false && "cannot read CXXRecordDecl"); // assert(false && "cannot read CXXRecordDecl");
VisitRecordDecl(D); 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 // FIXME: this is far from complete
@ -618,11 +640,76 @@ void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
} }
void PCHDeclReader::VisitTemplateDecl(TemplateDecl *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) { 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::VisitClassTemplateSpecializationDecl(
@ -640,7 +727,14 @@ void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
} }
void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *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) { void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
@ -988,7 +1082,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
assert(false && "cannot read FriendTemplateDecl"); assert(false && "cannot read FriendTemplateDecl");
break; break;
case pch::DECL_CLASS_TEMPLATE: case pch::DECL_CLASS_TEMPLATE:
assert(false && "cannot read ClassTemplateDecl"); D = ClassTemplateDecl::CreateEmpty(*Context);
break; break;
case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION: case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
assert(false && "cannot read ClasstemplateSpecializationDecl"); assert(false && "cannot read ClasstemplateSpecializationDecl");
@ -1000,7 +1094,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
assert(false && "cannot read FunctionTemplateDecl"); assert(false && "cannot read FunctionTemplateDecl");
break; break;
case pch::DECL_TEMPLATE_TYPE_PARM: case pch::DECL_TEMPLATE_TYPE_PARM:
assert(false && "cannot read TemplateTypeParmDecl"); D = TemplateTypeParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,0,0);
break; break;
case pch::DECL_NON_TYPE_TEMPLATE_PARM: case pch::DECL_NON_TYPE_TEMPLATE_PARM:
assert(false && "cannot read NonTypeTemplateParmDecl"); assert(false && "cannot read NonTypeTemplateParmDecl");