[cfe-commits] r106625 - in /cfe/trunk: include/clang/Frontend/PCHReader.h include/clang/Frontend/PCHWriter.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp lib/Frontend/PCHWriterDecl.cpp test/PCH/cxx-templates.cpp test/PCH/cxx-templates.h
Argyrios Kyrtzidis
akyrtzi at gmail.com
Wed Jun 23 06:48:31 PDT 2010
Author: akirtzidis
Date: Wed Jun 23 08:48:30 2010
New Revision: 106625
URL: http://llvm.org/viewvc/llvm-project?rev=106625&view=rev
Log:
Support C++ class template specializations and partial specializations for PCH.
Modified:
cfe/trunk/include/clang/Frontend/PCHReader.h
cfe/trunk/include/clang/Frontend/PCHWriter.h
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
cfe/trunk/test/PCH/cxx-templates.cpp
cfe/trunk/test/PCH/cxx-templates.h
Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Wed Jun 23 08:48:30 2010
@@ -702,6 +702,15 @@
/// \brief Read a template argument.
TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx);
+
+ /// \brief Read a template parameter list.
+ TemplateParameterList *ReadTemplateParameterList(const RecordData &Record,
+ unsigned &Idx);
+
+ /// \brief Read a template argument array.
+ void
+ ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+ const RecordData &Record, unsigned &Idx);
/// \brief Read a source location.
SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Wed Jun 23 08:48:30 2010
@@ -328,6 +328,14 @@
/// \brief Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg, RecordData &Record);
+ /// \brief Emit a template parameter list.
+ void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+ RecordData &Record);
+
+ /// \brief Emit a template argument list.
+ void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+ RecordData &Record);
+
/// \brief Add a string to the given record.
void AddString(const std::string &Str, RecordData &Record);
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Jun 23 08:48:30 2010
@@ -2220,13 +2220,11 @@
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));
+ ReadTemplateArgumentList(Args, Record, Idx);
+ QualType Canon = GetType(Record[Idx++]);
return Context->getTemplateSpecializationType(Name, Args.data(),Args.size(),
- QualType());
+ Canon);
}
}
// Suppress a GCC warning
@@ -3020,6 +3018,34 @@
return TemplateArgument();
}
+TemplateParameterList *
+PCHReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
+ SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
+ SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
+ SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
+
+ unsigned NumParams = Record[Idx++];
+ llvm::SmallVector<NamedDecl *, 16> Params;
+ Params.reserve(NumParams);
+ while (NumParams--)
+ Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
+
+ TemplateParameterList* TemplateParams =
+ TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
+ Params.data(), Params.size(), RAngleLoc);
+ return TemplateParams;
+}
+
+void
+PCHReader::
+ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+ const RecordData &Record, unsigned &Idx) {
+ unsigned NumTemplateArgs = Record[Idx++];
+ TemplArgs.reserve(NumTemplateArgs);
+ while (NumTemplateArgs--)
+ TemplArgs.push_back(ReadTemplateArgument(Record, Idx));
+}
+
NestedNameSpecifier *
PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
unsigned N = Record[Idx++];
Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Wed Jun 23 08:48:30 2010
@@ -236,11 +236,8 @@
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));
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
// Template args as written.
unsigned NumTemplateArgLocs = Record[Idx++];
@@ -255,7 +252,7 @@
RAngleLoc = Reader.ReadSourceLocation(Record, Idx);
}
- FD->setFunctionTemplateSpecialization(Template, NumTemplateArgs,
+ FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
TemplArgs.data(), TSK,
NumTemplateArgLocs,
NumTemplateArgLocs ? TemplArgLocs.data() : 0,
@@ -711,23 +708,8 @@
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);
-
+ TemplateParameterList* TemplateParams
+ = Reader.ReadTemplateParameterList(Record, Idx);
D->init(TemplatedDecl, TemplateParams);
}
@@ -782,12 +764,57 @@
void PCHDeclReader::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
- assert(false && "cannot read ClassTemplateSpecializationDecl");
+ VisitCXXRecordDecl(D);
+
+ if (Decl *InstD = Reader.GetDecl(Record[Idx++])) {
+ if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
+ D->setInstantiationOf(CTD);
+ } else {
+ llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
+ D->setInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(InstD),
+ TemplArgs.data(), TemplArgs.size());
+ }
+ }
+
+ // Explicit info.
+ if (TypeSourceInfo *TyInfo = Reader.GetTypeSourceInfo(Record, Idx)) {
+ D->setTypeAsWritten(TyInfo);
+ D->setExternLoc(Reader.ReadSourceLocation(Record, Idx));
+ D->setTemplateKeywordLoc(Reader.ReadSourceLocation(Record, Idx));
+ }
+
+ llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
+ D->initTemplateArgs(TemplArgs.data(), TemplArgs.size());
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+ if (POI.isValid())
+ D->setPointOfInstantiation(POI);
+ D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]);
}
void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
- assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+ VisitClassTemplateSpecializationDecl(D);
+
+ D->initTemplateParameters(Reader.ReadTemplateParameterList(Record, Idx));
+
+ TemplateArgumentListInfo ArgInfos;
+ unsigned NumArgs = Record[Idx++];
+ while (NumArgs--)
+ ArgInfos.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
+ D->initTemplateArgsAsWritten(ArgInfos);
+
+ D->setSequenceNumber(Record[Idx++]);
+
+ // These are read/set from/to the first declaration.
+ if (D->getPreviousDeclaration() == 0) {
+ D->setInstantiatedFromMember(
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(
+ Reader.GetDecl(Record[Idx++])));
+ if (Record[Idx++])
+ D->isMemberSpecialization();
+ }
}
void PCHDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
@@ -1172,10 +1199,10 @@
DeclarationName(), 0, 0, 0);
break;
case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
- assert(false && "cannot read ClasstemplateSpecializationDecl");
+ D = ClassTemplateSpecializationDecl::CreateEmpty(*Context);
break;
case pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
- assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+ D = ClassTemplatePartialSpecializationDecl::CreateEmpty(*Context);
break;
case pch::DECL_FUNCTION_TEMPLATE:
D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(),
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Jun 23 08:48:30 2010
@@ -223,6 +223,8 @@
for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end();
ArgI != ArgE; ++ArgI)
Writer.AddTemplateArgument(*ArgI, Record);
+ QualType Canon = T->getCanonicalTypeInternal();
+ Writer.AddTypeRef(Canon.getTypePtr() != T ? Canon : QualType(), Record);
Code = pch::TYPE_TEMPLATE_SPECIALIZATION;
}
@@ -2572,3 +2574,27 @@
break;
}
}
+
+void
+PCHWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+ RecordData &Record) {
+ assert(TemplateParams && "No TemplateParams!");
+ AddSourceLocation(TemplateParams->getTemplateLoc(), Record);
+ AddSourceLocation(TemplateParams->getLAngleLoc(), Record);
+ AddSourceLocation(TemplateParams->getRAngleLoc(), Record);
+ Record.push_back(TemplateParams->size());
+ for (TemplateParameterList::const_iterator
+ P = TemplateParams->begin(), PEnd = TemplateParams->end();
+ P != PEnd; ++P)
+ AddDeclRef(*P, Record);
+}
+
+/// \brief Emit a template argument list.
+void
+PCHWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+ RecordData &Record) {
+ assert(TemplateArgs && "No TemplateArgs!");
+ Record.push_back(TemplateArgs->flat_size());
+ for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i)
+ AddTemplateArgument(TemplateArgs->get(i), Record);
+}
Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Wed Jun 23 08:48:30 2010
@@ -244,10 +244,7 @@
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);
+ Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
// Template args as written.
if (FTSInfo->TemplateArgumentsAsWritten) {
@@ -705,18 +702,7 @@
VisitNamedDecl(D);
Writer.AddDeclRef(D->getTemplatedDecl(), Record);
- {
- // TemplateParams.
- TemplateParameterList *TPL = D->getTemplateParameters();
- assert(TPL && "No TemplateParameters!");
- Writer.AddSourceLocation(TPL->getTemplateLoc(), Record);
- Writer.AddSourceLocation(TPL->getLAngleLoc(), Record);
- Writer.AddSourceLocation(TPL->getRAngleLoc(), Record);
- Record.push_back(TPL->size());
- for (TemplateParameterList::iterator P = TPL->begin(), PEnd = TPL->end();
- P != PEnd; ++P)
- Writer.AddDeclRef(*P, Record);
- }
+ Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
}
void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
@@ -749,12 +735,52 @@
void PCHDeclWriter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
- assert(false && "cannot write ClassTemplateSpecializationDecl");
+ VisitCXXRecordDecl(D);
+
+ llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *> InstFrom
+ = D->getSpecializedTemplateOrPartial();
+ if (InstFrom.is<ClassTemplateDecl *>()) {
+ Writer.AddDeclRef(InstFrom.get<ClassTemplateDecl *>(), Record);
+ } else {
+ Writer.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>(),
+ Record);
+ Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
+ }
+
+ // Explicit info.
+ Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
+ if (D->getTypeAsWritten()) {
+ Writer.AddSourceLocation(D->getExternLoc(), Record);
+ Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
+ }
+
+ Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
+ Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
+ Record.push_back(D->getSpecializationKind());
+
+ Code = pch::DECL_CLASS_TEMPLATE_SPECIALIZATION;
}
void PCHDeclWriter::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
- assert(false && "cannot write ClassTemplatePartialSpecializationDecl");
+ VisitClassTemplateSpecializationDecl(D);
+
+ Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
+
+ Record.push_back(D->getNumTemplateArgsAsWritten());
+ for (int i = 0, e = D->getNumTemplateArgsAsWritten(); i != e; ++i)
+ Writer.AddTemplateArgumentLoc(D->getTemplateArgsAsWritten()[i], Record);
+
+ Record.push_back(D->getSequenceNumber());
+
+ // These are read/set from/to the first declaration.
+ if (D->getPreviousDeclaration() == 0) {
+ Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
+ Record.push_back(D->isMemberSpecialization());
+ }
+
+ Code = pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
}
void PCHDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
Modified: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (original)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Wed Jun 23 08:48:30 2010
@@ -1,8 +1,14 @@
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-templates.h -fsyntax-only -verify %s
-S<float> v;
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
void test() {
int x = templ_f(3);
+
+ S<char, float>::templ();
+ S<int, char>::partial();
+ S<int, float>::explicit_special();
}
Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=106625&r1=106624&r2=106625&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Wed Jun 23 08:48:30 2010
@@ -1,8 +1,18 @@
// Header for PCH test cxx-templates.cpp
-template <typename T>
+template <typename T1, typename T2>
struct S {
- T x;
+ static void templ();
+};
+
+template <typename T>
+struct S<int, T> {
+ static void partial();
+};
+
+template <>
+struct S<int, float> {
+ static void explicit_special();
};
template <typename T>
More information about the cfe-commits
mailing list