[cfe-commits] r106534 - in /cfe/trunk: lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp test/PCH/cxx-templates.cpp test/PCH/cxx-templates.h

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Jun 22 02:55:07 PDT 2010


Author: akirtzidis
Date: Tue Jun 22 04:55:07 2010
New Revision: 106534

URL: http://llvm.org/viewvc/llvm-project?rev=106534&view=rev
Log:
Support emitting/reading function templates to/from PCH.

Modified:
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/test/PCH/cxx-templates.cpp
    cfe/trunk/test/PCH/cxx-templates.h

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=106534&r1=106533&r2=106534&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue Jun 22 04:55:07 2010
@@ -74,7 +74,7 @@
     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 @@
   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 @@
   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 @@
     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);

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=106534&r1=106533&r2=106534&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Tue Jun 22 04:55:07 2010
@@ -75,7 +75,7 @@
     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 @@
   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 @@
   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) {

Modified: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=106534&r1=106533&r2=106534&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (original)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Tue Jun 22 04:55:07 2010
@@ -2,3 +2,7 @@
 // RUN: %clang_cc1 -include-pch %t -fsyntax-only %s 
 
 S<float> v;
+
+void test() {
+  int x = templ_f(3);
+}

Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=106534&r1=106533&r2=106534&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Tue Jun 22 04:55:07 2010
@@ -4,3 +4,8 @@
 struct S {
     T x;
 };
+
+template <typename T>
+T templ_f(T x) {
+  return x;
+}





More information about the cfe-commits mailing list