[cfe-commits] r106391 - in /cfe/trunk: include/clang/AST/TemplateName.h include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHWriter.h lib/AST/TemplateName.cpp 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
Sat Jun 19 12:28:53 PDT 2010


Author: akirtzidis
Date: Sat Jun 19 14:28:53 2010
New Revision: 106391

URL: http://llvm.org/viewvc/llvm-project?rev=106391&view=rev
Log:
Initial support for writing templates to PCH.

Added:
    cfe/trunk/test/PCH/cxx-templates.cpp
    cfe/trunk/test/PCH/cxx-templates.h
Modified:
    cfe/trunk/include/clang/AST/TemplateName.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/AST/TemplateName.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (original)
+++ cfe/trunk/include/clang/AST/TemplateName.h Sat Jun 19 14:28:53 2010
@@ -101,6 +101,14 @@
   }
 
 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 @@
 
   /// \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.

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Sat Jun 19 14:28:53 2010
@@ -417,7 +417,11 @@
       /// \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 @@
       // allocates the order in which
       DECL_FRIEND,
       DECL_FRIEND_TEMPLATE,
-      DECL_TEMPLATE,
       DECL_CLASS_TEMPLATE,
       DECL_CLASS_TEMPLATE_SPECIALIZATION,
       DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Sat Jun 19 14:28:53 2010
@@ -315,6 +315,12 @@
 
   /// \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);

Modified: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (original)
+++ cfe/trunk/lib/AST/TemplateName.cpp Sat Jun 19 14:28:53 2010
@@ -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;

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sat Jun 19 14:28:53 2010
@@ -2207,6 +2207,14 @@
     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();

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Sat Jun 19 14:28:53 2010
@@ -987,10 +987,6 @@
   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;

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sat Jun 19 14:28:53 2010
@@ -61,9 +61,7 @@
 
 #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 @@
   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 @@
 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 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 template specialization types");
+  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 @@
 #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::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;
+  }
+}

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=106391&r1=106390&r2=106391&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Sat Jun 19 14:28:53 2010
@@ -574,6 +574,23 @@
 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::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::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) {

Added: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=106391&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (added)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Sat Jun 19 14:28:53 2010
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
+
+// Placeholder for stuff using the header.

Added: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=106391&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (added)
+++ cfe/trunk/test/PCH/cxx-templates.h Sat Jun 19 14:28:53 2010
@@ -0,0 +1,6 @@
+// Header for PCH test cxx-templates.cpp
+
+template <typename T>
+struct S {
+    T x;
+};





More information about the cfe-commits mailing list