Support emitting/reading function templates to/from PCH.

llvm-svn: 106534
This commit is contained in:
Argyrios Kyrtzidis 2010-06-22 09:55:07 +00:00
parent ae85e2414c
commit 69da4a8f07
4 changed files with 169 additions and 9 deletions

View File

@ -74,7 +74,7 @@ namespace {
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
@ -214,8 +214,71 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setCopyAssignment(Record[Idx++]);
FD->setHasImplicitReturnZero(Record[Idx++]);
FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
// FIXME: C++ TemplateOrInstantiation
switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
case FunctionDecl::TK_NonTemplate:
break;
case FunctionDecl::TK_FunctionTemplate:
FD->setDescribedFunctionTemplate(
cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])));
break;
case FunctionDecl::TK_MemberSpecialization: {
FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
FD->setInstantiationOfMemberFunction(InstFD, TSK);
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
break;
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
FunctionTemplateDecl *Template
= cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
// Template arguments.
unsigned NumTemplateArgs = Record[Idx++];
llvm::SmallVector<TemplateArgument, 8> TemplArgs;
TemplArgs.reserve(NumTemplateArgs);
for (unsigned i=0; i != NumTemplateArgs; ++i)
TemplArgs.push_back(Reader.ReadTemplateArgument(Record, Idx));
// Template args as written.
unsigned NumTemplateArgLocs = Record[Idx++];
llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
TemplArgLocs.reserve(NumTemplateArgLocs);
for (unsigned i=0; i != NumTemplateArgLocs; ++i)
TemplArgLocs.push_back(Reader.ReadTemplateArgumentLoc(Record, Idx));
SourceLocation LAngleLoc, RAngleLoc;
if (NumTemplateArgLocs) {
LAngleLoc = Reader.ReadSourceLocation(Record, Idx);
RAngleLoc = Reader.ReadSourceLocation(Record, Idx);
}
FD->setFunctionTemplateSpecialization(Template, NumTemplateArgs,
TemplArgs.data(), TSK,
NumTemplateArgLocs,
NumTemplateArgLocs ? TemplArgLocs.data() : 0,
LAngleLoc, RAngleLoc);
}
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
// Templates.
UnresolvedSet<8> TemplDecls;
unsigned NumTemplates = Record[Idx++];
while (NumTemplates--)
TemplDecls.addDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
// Templates args.
TemplateArgumentListInfo TemplArgs;
unsigned NumArgs = Record[Idx++];
while (NumArgs--)
TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
FD->setDependentTemplateSpecialization(*Reader.getContext(),
TemplDecls, TemplArgs);
}
}
// Read in the parameters.
unsigned NumParams = Record[Idx++];
llvm::SmallVector<ParmVarDecl *, 16> Params;
@ -725,8 +788,26 @@ void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(
assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
}
void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
assert(false && "cannot read FunctionTemplateDecl");
void PCHDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
VisitTemplateDecl(D);
FunctionTemplateDecl *PrevDecl =
cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
D->setPreviousDeclaration(PrevDecl);
if (PrevDecl == 0) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
// FunctionTemplateSpecializationInfos are filled through the
// templated FunctionDecl's setFunctionTemplateSpecialization, no need to
// read them here.
if (FunctionTemplateDecl *CTD
= cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
D->setInstantiatedFromMemberTemplate(CTD);
if (Record[Idx++])
D->setMemberSpecialization();
}
}
}
void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
@ -1095,7 +1176,8 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
break;
case pch::DECL_FUNCTION_TEMPLATE:
assert(false && "cannot read FunctionTemplateDecl");
D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(),
DeclarationName(), 0, 0);
break;
case pch::DECL_TEMPLATE_TYPE_PARM:
D = TemplateTypeParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,0,0);

View File

@ -75,7 +75,7 @@ namespace {
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
@ -221,8 +221,63 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->isTrivial());
Record.push_back(D->isCopyAssignment());
Record.push_back(D->hasImplicitReturnZero());
// FIXME: C++ TemplateOrInstantiation???
Writer.AddSourceLocation(D->getLocEnd(), Record);
Record.push_back(D->getTemplatedKind());
switch (D->getTemplatedKind()) {
case FunctionDecl::TK_NonTemplate:
break;
case FunctionDecl::TK_FunctionTemplate:
Writer.AddDeclRef(D->getDescribedFunctionTemplate(), Record);
break;
case FunctionDecl::TK_MemberSpecialization: {
MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
Record.push_back(MemberInfo->getTemplateSpecializationKind());
Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
break;
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
FunctionTemplateSpecializationInfo *
FTSInfo = D->getTemplateSpecializationInfo();
Writer.AddDeclRef(FTSInfo->getTemplate(), Record);
Record.push_back(FTSInfo->getTemplateSpecializationKind());
// Template arguments.
assert(FTSInfo->TemplateArguments && "No template args!");
Record.push_back(FTSInfo->TemplateArguments->flat_size());
for (int i=0, e = FTSInfo->TemplateArguments->flat_size(); i != e; ++i)
Writer.AddTemplateArgument(FTSInfo->TemplateArguments->get(i), Record);
// Template args as written.
if (FTSInfo->TemplateArgumentsAsWritten) {
Record.push_back(FTSInfo->TemplateArgumentsAsWritten->size());
for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->size(); i!=e; ++i)
Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
Record);
Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getLAngleLoc(),
Record);
Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getRAngleLoc(),
Record);
} else {
Record.push_back(0);
}
}
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
DependentFunctionTemplateSpecializationInfo *
DFTSInfo = D->getDependentSpecializationInfo();
// Templates.
Record.push_back(DFTSInfo->getNumTemplates());
for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
Writer.AddDeclRef(DFTSInfo->getTemplate(i), Record);
// Templates args.
Record.push_back(DFTSInfo->getNumTemplateArgs());
for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
Writer.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i), Record);
}
}
Record.push_back(D->param_size());
for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
@ -701,8 +756,22 @@ void PCHDeclWriter::VisitClassTemplatePartialSpecializationDecl(
assert(false && "cannot write ClassTemplatePartialSpecializationDecl");
}
void PCHDeclWriter::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
assert(false && "cannot write FunctionTemplateDecl");
void PCHDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
VisitTemplateDecl(D);
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
if (D->getPreviousDeclaration() == 0) {
// This FunctionTemplateDecl owns the CommonPtr; write it.
// FunctionTemplateSpecializationInfos are filled through the
// templated FunctionDecl's setFunctionTemplateSpecialization, no need to
// write them here.
Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
if (D->getInstantiatedFromMemberTemplate())
Record.push_back(D->isMemberSpecialization());
}
Code = pch::DECL_FUNCTION_TEMPLATE;
}
void PCHDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {

View File

@ -2,3 +2,7 @@
// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s
S<float> v;
void test() {
int x = templ_f(3);
}

View File

@ -4,3 +4,8 @@ template <typename T>
struct S {
T x;
};
template <typename T>
T templ_f(T x) {
return x;
}