[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