Initial support for reading templates from PCH.
llvm-svn: 106392
This commit is contained in:
parent
106caf92cd
commit
95c04caf92
|
@ -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;
|
||||
|
|
|
@ -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++]);
|
||||
|
|
|
@ -155,6 +155,21 @@ ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
|
|||
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,
|
||||
DeclContext *DC,
|
||||
SourceLocation L,
|
||||
|
@ -162,16 +177,9 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
|
|||
TemplateParameterList *Params,
|
||||
NamedDecl *Decl,
|
||||
ClassTemplateDecl *PrevDecl) {
|
||||
Common *CommonPtr;
|
||||
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 *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
|
||||
New->initPreviousDeclaration(C, PrevDecl);
|
||||
return New;
|
||||
}
|
||||
|
||||
ClassTemplateDecl::~ClassTemplateDecl() {
|
||||
|
|
|
@ -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++];
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue