forked from OSchip/llvm-project
Initial support for writing templates to PCH.
llvm-svn: 106391
This commit is contained in:
parent
bf5c3d42ba
commit
106caf92cd
|
@ -101,6 +101,14 @@ class TemplateName {
|
|||
}
|
||||
|
||||
public:
|
||||
// \brief Kind of name that is actually stored.
|
||||
enum NameKind {
|
||||
Template,
|
||||
OverloadedTemplate,
|
||||
QualifiedTemplate,
|
||||
DependentTemplate
|
||||
};
|
||||
|
||||
TemplateName() : Storage() { }
|
||||
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
|
||||
explicit TemplateName(OverloadedTemplateStorage *Storage)
|
||||
|
@ -110,6 +118,9 @@ public:
|
|||
|
||||
/// \brief Determine whether this template name is NULL.
|
||||
bool isNull() const { return Storage.isNull(); }
|
||||
|
||||
// \brief Get the kind of name that is actually stored.
|
||||
NameKind getKind() const;
|
||||
|
||||
/// \brief Retrieve the the underlying template declaration that
|
||||
/// this template name refers to, if known.
|
||||
|
|
|
@ -417,7 +417,11 @@ namespace clang {
|
|||
/// \brief An InjectedClassNameType record.
|
||||
TYPE_INJECTED_CLASS_NAME = 27,
|
||||
/// \brief An ObjCObjectType record.
|
||||
TYPE_OBJC_OBJECT = 28
|
||||
TYPE_OBJC_OBJECT = 28,
|
||||
/// \brief An TemplateTypeParmType record.
|
||||
TYPE_TEMPLATE_TYPE_PARM = 29,
|
||||
/// \brief An TemplateSpecializationType record.
|
||||
TYPE_TEMPLATE_SPECIALIZATION = 30
|
||||
};
|
||||
|
||||
/// \brief The type IDs for special types constructed by semantic
|
||||
|
@ -569,7 +573,6 @@ namespace clang {
|
|||
// allocates the order in which
|
||||
DECL_FRIEND,
|
||||
DECL_FRIEND_TEMPLATE,
|
||||
DECL_TEMPLATE,
|
||||
DECL_CLASS_TEMPLATE,
|
||||
DECL_CLASS_TEMPLATE_SPECIALIZATION,
|
||||
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
|
||||
|
|
|
@ -315,6 +315,12 @@ public:
|
|||
|
||||
/// \brief Emit a nested name specifier.
|
||||
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
|
||||
|
||||
/// \brief Emit a template name.
|
||||
void AddTemplateName(TemplateName Name, RecordData &Record);
|
||||
|
||||
/// \brief Emit a template argument.
|
||||
void AddTemplateArgument(const TemplateArgument &Arg, RecordData &Record);
|
||||
|
||||
/// \brief Add a string to the given record.
|
||||
void AddString(const std::string &Str, RecordData &Record);
|
||||
|
|
|
@ -21,6 +21,17 @@
|
|||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
||||
TemplateName::NameKind TemplateName::getKind() const {
|
||||
if (Storage.is<TemplateDecl *>())
|
||||
return Template;
|
||||
if (Storage.is<OverloadedTemplateStorage *>())
|
||||
return OverloadedTemplate;
|
||||
if (Storage.is<QualifiedTemplateName *>())
|
||||
return QualifiedTemplate;
|
||||
assert(Storage.is<DependentTemplateName *>() && "There's a case unhandled!");
|
||||
return DependentTemplate;
|
||||
}
|
||||
|
||||
TemplateDecl *TemplateName::getAsTemplateDecl() const {
|
||||
if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
|
||||
return Template;
|
||||
|
|
|
@ -2207,6 +2207,14 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
|
|||
QualType TST = GetType(Record[1]); // probably derivable
|
||||
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_SPECIALIZATION:
|
||||
assert(false && "can't read template specialization types yet");
|
||||
break;
|
||||
}
|
||||
// Suppress a GCC warning
|
||||
return QualType();
|
||||
|
|
|
@ -987,10 +987,6 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
|
|||
case pch::DECL_FRIEND_TEMPLATE:
|
||||
assert(false && "cannot read FriendTemplateDecl");
|
||||
break;
|
||||
case pch::DECL_TEMPLATE:
|
||||
// FIXME: Should TemplateDecl be ABSTRACT_DECL???
|
||||
assert(false && "TemplateDecl should be abstract!");
|
||||
break;
|
||||
case pch::DECL_CLASS_TEMPLATE:
|
||||
assert(false && "cannot read ClassTemplateDecl");
|
||||
break;
|
||||
|
|
|
@ -61,9 +61,7 @@ namespace {
|
|||
|
||||
#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
|
||||
#define ABSTRACT_TYPE(Class, Base)
|
||||
#define DEPENDENT_TYPE(Class, Base)
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
void VisitInjectedClassNameType(const InjectedClassNameType *T);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -169,13 +167,10 @@ void PCHTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
|
|||
Code = pch::TYPE_FUNCTION_PROTO;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// For when we want it....
|
||||
void PCHTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
|
||||
Writer.AddDeclRef(T->getDecl(), Record);
|
||||
Code = pch::TYPE_UNRESOLVED_USING;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PCHTypeWriter::VisitTypedefType(const TypedefType *T) {
|
||||
Writer.AddDeclRef(T->getDecl(), Record);
|
||||
|
@ -224,8 +219,47 @@ PCHTypeWriter::VisitSubstTemplateTypeParmType(
|
|||
void
|
||||
PCHTypeWriter::VisitTemplateSpecializationType(
|
||||
const TemplateSpecializationType *T) {
|
||||
Writer.AddTemplateName(T->getTemplateName(), Record);
|
||||
Record.push_back(T->getNumArgs());
|
||||
for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end();
|
||||
ArgI != ArgE; ++ArgI)
|
||||
Writer.AddTemplateArgument(*ArgI, Record);
|
||||
Code = pch::TYPE_TEMPLATE_SPECIALIZATION;
|
||||
}
|
||||
|
||||
void
|
||||
PCHTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
|
||||
// FIXME: Serialize this type (C++ only)
|
||||
assert(false && "Cannot serialize template specialization types");
|
||||
assert(false && "Cannot serialize dependent sized array types");
|
||||
}
|
||||
|
||||
void
|
||||
PCHTypeWriter::VisitDependentSizedExtVectorType(
|
||||
const DependentSizedExtVectorType *T) {
|
||||
// FIXME: Serialize this type (C++ only)
|
||||
assert(false && "Cannot serialize dependent sized extended vector types");
|
||||
}
|
||||
|
||||
void
|
||||
PCHTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
|
||||
Record.push_back(T->getDepth());
|
||||
Record.push_back(T->getIndex());
|
||||
Record.push_back(T->isParameterPack());
|
||||
Writer.AddIdentifierRef(T->getName(), Record);
|
||||
Code = pch::TYPE_TEMPLATE_TYPE_PARM;
|
||||
}
|
||||
|
||||
void
|
||||
PCHTypeWriter::VisitDependentNameType(const DependentNameType *T) {
|
||||
// FIXME: Serialize this type (C++ only)
|
||||
assert(false && "Cannot serialize dependent name types");
|
||||
}
|
||||
|
||||
void
|
||||
PCHTypeWriter::VisitDependentTemplateSpecializationType(
|
||||
const DependentTemplateSpecializationType *T) {
|
||||
// FIXME: Serialize this type (C++ only)
|
||||
assert(false && "Cannot serialize dependent template specialization types");
|
||||
}
|
||||
|
||||
void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
|
||||
|
@ -1357,16 +1391,7 @@ void PCHWriter::WriteType(QualType T) {
|
|||
#define TYPE(Class, Base) \
|
||||
case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
|
||||
#define ABSTRACT_TYPE(Class, Base)
|
||||
#define DEPENDENT_TYPE(Class, Base)
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
|
||||
// For all of the dependent type nodes (which only occur in C++
|
||||
// templates), produce an error.
|
||||
#define TYPE(Class, Base)
|
||||
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
|
||||
#include "clang/AST/TypeNodes.def"
|
||||
assert(false && "Cannot serialize dependent type nodes");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2469,3 +2494,72 @@ void PCHWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PCHWriter::AddTemplateName(TemplateName Name, RecordData &Record) {
|
||||
TemplateName::NameKind Kind = Name.getKind();
|
||||
Record.push_back(Kind);
|
||||
switch (Kind) {
|
||||
case TemplateName::Template:
|
||||
AddDeclRef(Name.getAsTemplateDecl(), Record);
|
||||
break;
|
||||
|
||||
case TemplateName::OverloadedTemplate: {
|
||||
OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate();
|
||||
Record.push_back(OvT->size());
|
||||
for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end();
|
||||
I != E; ++I)
|
||||
AddDeclRef(*I, Record);
|
||||
break;
|
||||
}
|
||||
|
||||
case TemplateName::QualifiedTemplate: {
|
||||
QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName();
|
||||
AddNestedNameSpecifier(QualT->getQualifier(), Record);
|
||||
Record.push_back(QualT->hasTemplateKeyword());
|
||||
AddDeclRef(QualT->getTemplateDecl(), Record);
|
||||
break;
|
||||
}
|
||||
|
||||
case TemplateName::DependentTemplate: {
|
||||
DependentTemplateName *DepT = Name.getAsDependentTemplateName();
|
||||
AddNestedNameSpecifier(DepT->getQualifier(), Record);
|
||||
Record.push_back(DepT->isIdentifier());
|
||||
if (DepT->isIdentifier())
|
||||
AddIdentifierRef(DepT->getIdentifier(), Record);
|
||||
else
|
||||
Record.push_back(DepT->getOperator());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PCHWriter::AddTemplateArgument(const TemplateArgument &Arg,
|
||||
RecordData &Record) {
|
||||
Record.push_back(Arg.getKind());
|
||||
switch (Arg.getKind()) {
|
||||
case TemplateArgument::Null:
|
||||
break;
|
||||
case TemplateArgument::Type:
|
||||
AddTypeRef(Arg.getAsType(), Record);
|
||||
break;
|
||||
case TemplateArgument::Declaration:
|
||||
AddDeclRef(Arg.getAsDecl(), Record);
|
||||
break;
|
||||
case TemplateArgument::Integral:
|
||||
AddAPSInt(*Arg.getAsIntegral(), Record);
|
||||
AddTypeRef(Arg.getIntegralType(), Record);
|
||||
break;
|
||||
case TemplateArgument::Template:
|
||||
AddTemplateName(Arg.getAsTemplate(), Record);
|
||||
break;
|
||||
case TemplateArgument::Expression:
|
||||
AddStmt(Arg.getAsExpr());
|
||||
break;
|
||||
case TemplateArgument::Pack:
|
||||
Record.push_back(Arg.pack_size());
|
||||
for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
|
||||
I != E; ++I)
|
||||
AddTemplateArgument(*I, Record);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -574,6 +574,23 @@ void PCHDeclWriter::WriteCXXBaseSpecifier(const CXXBaseSpecifier *Base) {
|
|||
void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||
// assert(false && "cannot write CXXRecordDecl");
|
||||
VisitRecordDecl(D);
|
||||
|
||||
enum {
|
||||
CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
|
||||
};
|
||||
if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
|
||||
Record.push_back(CXXRecTemplate);
|
||||
Writer.AddDeclRef(TemplD, Record);
|
||||
} else if (MemberSpecializationInfo *MSInfo
|
||||
= D->getMemberSpecializationInfo()) {
|
||||
Record.push_back(CXXRecMemberSpecialization);
|
||||
Writer.AddDeclRef(MSInfo->getInstantiatedFrom(), Record);
|
||||
Record.push_back(MSInfo->getTemplateSpecializationKind());
|
||||
Writer.AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
|
||||
} else {
|
||||
Record.push_back(CXXRecNotTemplate);
|
||||
}
|
||||
|
||||
if (D->isDefinition()) {
|
||||
unsigned NumBases = D->getNumBases();
|
||||
Record.push_back(NumBases);
|
||||
|
@ -619,11 +636,49 @@ void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
|||
}
|
||||
|
||||
void PCHDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
|
||||
assert(false && "cannot write TemplateDecl");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||
assert(false && "cannot write ClassTemplateDecl");
|
||||
VisitTemplateDecl(D);
|
||||
|
||||
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
|
||||
if (D->getPreviousDeclaration() == 0) {
|
||||
// This ClassTemplateDecl owns the CommonPtr; write it.
|
||||
|
||||
typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
|
||||
CTSDSetTy &CTSDSet = D->getSpecializations();
|
||||
Record.push_back(CTSDSet.size());
|
||||
for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I)
|
||||
Writer.AddDeclRef(&*I, Record);
|
||||
|
||||
typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> CTPSDSetTy;
|
||||
CTPSDSetTy &CTPSDSet = D->getPartialSpecializations();
|
||||
Record.push_back(CTPSDSet.size());
|
||||
for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E = CTPSDSet.end(); I!=E; ++I)
|
||||
Writer.AddDeclRef(&*I, Record);
|
||||
|
||||
// InjectedClassNameType is computed, no need to write it.
|
||||
|
||||
Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
|
||||
if (D->getInstantiatedFromMemberTemplate())
|
||||
Record.push_back(D->isMemberSpecialization());
|
||||
}
|
||||
Code = pch::DECL_CLASS_TEMPLATE;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitClassTemplateSpecializationDecl(
|
||||
|
@ -641,7 +696,14 @@ void PCHDeclWriter::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
}
|
||||
|
||||
void PCHDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
||||
assert(false && "cannot write TemplateTypeParmDecl");
|
||||
VisitTypeDecl(D);
|
||||
|
||||
Record.push_back(D->wasDeclaredWithTypename());
|
||||
Record.push_back(D->isParameterPack());
|
||||
Record.push_back(D->defaultArgumentWasInherited());
|
||||
Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
|
||||
|
||||
Code = pch::DECL_TEMPLATE_TYPE_PARM;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
|
||||
|
||||
// Placeholder for stuff using the header.
|
|
@ -0,0 +1,6 @@
|
|||
// Header for PCH test cxx-templates.cpp
|
||||
|
||||
template <typename T>
|
||||
struct S {
|
||||
T x;
|
||||
};
|
Loading…
Reference in New Issue