]> granicus.if.org Git - clang/commitdiff
Initial support for reading templates from PCH.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 19 Jun 2010 19:29:09 +0000 (19:29 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 19 Jun 2010 19:29:09 +0000 (19:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106392 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclTemplate.h
include/clang/Frontend/PCHReader.h
lib/AST/DeclTemplate.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHReaderDecl.cpp

index 74c579b6022e035305f7f4e45c3c0c1a95cdb19b..cf42fa03fad210d6dd0bc9562771c8bc3f79a258 100644 (file)
@@ -272,6 +272,16 @@ public:
 protected:
   NamedDecl *TemplatedDecl;
   TemplateParameterList* TemplateParams;
+  
+public:
+  /// \brief Initialize the underlying templated declaration and
+  /// template parameters.
+  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
+    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
+    assert(TemplateParams == 0 && "TemplateParams already set!");
+    TemplatedDecl = templatedDecl;
+    TemplateParams = templateParams;
+  }
 };
 
 /// \brief Provides information about a function template specialization,
@@ -716,6 +726,13 @@ public:
     DefaultArgument = 0;
     InheritedDefault = false;
   }
+  
+  /// \brief Set whether this template type parameter was declared with
+  /// the 'typename' or 'class' keyword.
+  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
+
+  /// \brief Set whether this is a parameter pack.
+  void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
 
   /// \brief Retrieve the depth of the template parameter.
   unsigned getDepth() const;
@@ -1292,10 +1309,9 @@ protected:
   Common *CommonPtr;
 
   ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                    TemplateParameterList *Params, NamedDecl *Decl,
-                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
+                    TemplateParameterList *Params, NamedDecl *Decl)
     : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
-      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
+      PreviousDeclaration(0), CommonPtr(0) { }
 
   ~ClassTemplateDecl();
 
@@ -1310,6 +1326,10 @@ public:
     return PreviousDeclaration;
   }
 
+  /// \brief Initialize the previous declaration. Only valid to call on a
+  /// ClassTemplateDecl that is created using ClassTemplateDecl::CreateEmpty.
+  void initPreviousDeclaration(ASTContext &C, ClassTemplateDecl *PrevDecl);
+
   virtual ClassTemplateDecl *getCanonicalDecl();
 
   /// Create a class template node.
@@ -1320,6 +1340,11 @@ public:
                                    NamedDecl *Decl,
                                    ClassTemplateDecl *PrevDecl);
 
+  /// \brief Create an empty class template node. Mainly used for PCH reading.
+  static ClassTemplateDecl *CreateEmpty(ASTContext &C) {
+    return new (C) ClassTemplateDecl(0,SourceLocation(),DeclarationName(),0,0);
+  }
+
   /// \brief Retrieve the set of specializations of this class template.
   llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
     return CommonPtr->Specializations;
index b6881edce9439fd4741420c94de4a39f55c528a1..8139066c4b96561a0729e68d677b840471afaf7a 100644 (file)
@@ -693,6 +693,12 @@ public:
   NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
                                                unsigned &Idx);
 
+  /// \brief Read a template name.
+  TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a template argument.
+  TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx);
+
   /// \brief Read a source location.
   SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
     return SourceLocation::getFromRawEncoding(Record[Idx++]);
index 85b796007548d6990163dec89ff06707f586f7cc..1fcf92309b7fba87a83b3195d61e212f3bb7fe68 100644 (file)
@@ -155,23 +155,31 @@ ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
   return Template;
 }
 
-ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
-                                             DeclContext *DC,
-                                             SourceLocation L,
-                                             DeclarationName Name,
-                                             TemplateParameterList *Params,
-                                             NamedDecl *Decl,
-                                             ClassTemplateDecl *PrevDecl) {
-  Common *CommonPtr;
+void ClassTemplateDecl::initPreviousDeclaration(ASTContext &C,
+                                                ClassTemplateDecl *PrevDecl) {
+  assert(PreviousDeclaration == 0 && "PreviousDeclaration already set!");
+  assert(CommonPtr == 0 && "initPreviousDeclaration already called!");
+
+  PreviousDeclaration = PrevDecl;
+
   if (PrevDecl)
     CommonPtr = PrevDecl->CommonPtr;
   else {
     CommonPtr = new (C) Common;
     C.AddDeallocation(DeallocateCommon, CommonPtr);
   }
+}
 
-  return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
-                                   CommonPtr);
+ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
+                                             DeclContext *DC,
+                                             SourceLocation L,
+                                             DeclarationName Name,
+                                             TemplateParameterList *Params,
+                                             NamedDecl *Decl,
+                                             ClassTemplateDecl *PrevDecl) {
+  ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
+  New->initPreviousDeclaration(C, PrevDecl);
+  return New;
 }
 
 ClassTemplateDecl::~ClassTemplateDecl() {
index 99c28d4f030afea0fcf6a0aa68efbc9ef42f8f04..c8663bc702b35a367e7b8592be80e261fab6ab3a 100644 (file)
@@ -2208,13 +2208,26 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
     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_TYPE_PARM: {
+    unsigned Idx = 0;
+    unsigned Depth = Record[Idx++];
+    unsigned Index = Record[Idx++];
+    bool Pack = Record[Idx++];
+    IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
+    return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
+  }
 
-  case pch::TYPE_TEMPLATE_SPECIALIZATION:
-    assert(false && "can't read template specialization types yet");
-    break;
+  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));
+    return Context->getTemplateSpecializationType(Name, Args.data(),Args.size(),
+                                                  QualType());
+  }
   }
   // Suppress a GCC warning
   return QualType();
@@ -2932,6 +2945,74 @@ PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
   return DeclarationName();
 }
 
+TemplateName
+PCHReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
+  TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; 
+  switch (Kind) {
+  case TemplateName::Template:
+    return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
+
+  case TemplateName::OverloadedTemplate: {
+    unsigned size = Record[Idx++];
+    UnresolvedSet<8> Decls;
+    while (size--)
+      Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
+
+    return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
+  }
+    
+  case TemplateName::QualifiedTemplate: {
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    bool hasTemplKeyword = Record[Idx++];
+    TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
+    return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
+  }
+    
+  case TemplateName::DependentTemplate: {
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    if (Record[Idx++])  // isIdentifier
+      return Context->getDependentTemplateName(NNS,
+                                               GetIdentifierInfo(Record, Idx));
+    return Context->getDependentTemplateName(NNS,
+                                             (OverloadedOperatorKind)Record[Idx++]);
+  }
+  }
+  
+  assert(0 && "Unhandled template name kind!");
+  return TemplateName();
+}
+
+TemplateArgument
+PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
+  switch ((TemplateArgument::ArgKind)Record[Idx++]) {
+  case TemplateArgument::Null:
+    return TemplateArgument();
+  case TemplateArgument::Type:
+    return TemplateArgument(GetType(Record[Idx++]));
+  case TemplateArgument::Declaration:
+    return TemplateArgument(GetDecl(Record[Idx++]));
+  case TemplateArgument::Integral:
+    return TemplateArgument(ReadAPSInt(Record, Idx), GetType(Record[Idx++]));
+  case TemplateArgument::Template:
+    return TemplateArgument(ReadTemplateName(Record, Idx));
+  case TemplateArgument::Expression:
+    return TemplateArgument(ReadDeclExpr());
+  case TemplateArgument::Pack: {
+    unsigned NumArgs = Record[Idx++];
+    llvm::SmallVector<TemplateArgument, 8> Args;
+    Args.reserve(NumArgs);
+    while (NumArgs--)
+      Args.push_back(ReadTemplateArgument(Record, Idx));
+    TemplateArgument TemplArg;
+    TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
+    return TemplArg;
+  }
+  }
+  
+  assert(0 && "Unhandled template argument kind!");
+  return TemplateArgument();
+}
+
 NestedNameSpecifier *
 PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
   unsigned N = Record[Idx++];
index cbc0da673cd755328cbf3a859dd80d981035b5cc..fe11ca76d3ebed04fc34db787e561906e8115b96 100644 (file)
@@ -567,6 +567,28 @@ CXXBaseSpecifier *PCHDeclReader::ReadCXXBaseSpecifier() {
 void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
   // assert(false && "cannot read CXXRecordDecl");
   VisitRecordDecl(D);
+  
+  enum CXXRecKind {
+    CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
+  };
+  switch ((CXXRecKind)Record[Idx++]) {
+  default:
+    assert(false && "Out of sync with PCHDeclWriter::VisitCXXRecordDecl?");
+  case CXXRecNotTemplate:
+    break;
+  case CXXRecTemplate:
+    D->setDescribedClassTemplate(
+                        cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+    break;
+  case CXXRecMemberSpecialization: {
+    CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+    D->setInstantiationOfMemberClass(RD, TSK);
+    D->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+    break;
+  }
+  }
 
   // FIXME: this is far from complete
 
@@ -618,11 +640,76 @@ void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
 }
 
 void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) {
-  assert(false && "cannot read TemplateDecl");
+  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);
+  
+  D->init(TemplatedDecl, TemplateParams);
 }
 
 void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
-  assert(false && "cannot read ClassTemplateDecl");
+  VisitTemplateDecl(D);
+
+  ClassTemplateDecl *PrevDecl =
+      cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+  D->initPreviousDeclaration(*Reader.getContext(), PrevDecl);
+  if (PrevDecl == 0) {
+    // This ClassTemplateDecl owns a CommonPtr; read it.
+
+    unsigned size = Record[Idx++];
+    while (size--) {
+      ClassTemplateSpecializationDecl *CTSD
+         = cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++]));
+      llvm::FoldingSetNodeID ID;
+      void *InsertPos = 0;
+      ClassTemplateSpecializationDecl::Profile(ID, 
+                                  CTSD->getTemplateArgs().getFlatArgumentList(),
+                                            CTSD->getTemplateArgs().flat_size(),
+                                               *Reader.getContext());
+      D->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      D->getSpecializations().InsertNode(CTSD, InsertPos);
+    }
+
+    size = Record[Idx++];
+    while (size--) {
+      ClassTemplatePartialSpecializationDecl *CTSD
+         = cast<ClassTemplatePartialSpecializationDecl>(
+                                                 Reader.GetDecl(Record[Idx++]));
+      llvm::FoldingSetNodeID ID;
+      void *InsertPos = 0;
+      ClassTemplatePartialSpecializationDecl::Profile(ID, 
+                                  CTSD->getTemplateArgs().getFlatArgumentList(),
+                                            CTSD->getTemplateArgs().flat_size(),
+                                               *Reader.getContext());
+      D->getPartialSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      D->getPartialSpecializations().InsertNode(CTSD, InsertPos);
+    }
+
+    // InjectedClassNameType is computed.
+
+    if (ClassTemplateDecl *CTD
+          = cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+      D->setInstantiatedFromMemberTemplate(CTD);
+      if (Record[Idx++])
+        D->setMemberSpecialization();
+    }
+  }
 }
 
 void PCHDeclReader::VisitClassTemplateSpecializationDecl(
@@ -640,7 +727,14 @@ void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
 }
 
 void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
-  assert(false && "cannot read TemplateTypeParmDecl");
+  VisitTypeDecl(D);
+
+  D->setDeclaredWithTypename(Record[Idx++]);
+  D->setParameterPack(Record[Idx++]);
+
+  bool Inherited = Record[Idx++];
+  TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Record, Idx);
+  D->setDefaultArgument(DefArg, Inherited);
 }
 
 void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
@@ -988,7 +1082,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
     assert(false && "cannot read FriendTemplateDecl");
     break;
   case pch::DECL_CLASS_TEMPLATE:
-    assert(false && "cannot read ClassTemplateDecl");
+    D = ClassTemplateDecl::CreateEmpty(*Context);
     break;
   case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
     assert(false && "cannot read ClasstemplateSpecializationDecl");
@@ -1000,7 +1094,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
     assert(false && "cannot read FunctionTemplateDecl");
     break;
   case pch::DECL_TEMPLATE_TYPE_PARM:
-    assert(false && "cannot read TemplateTypeParmDecl");
+    D = TemplateTypeParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,0,0);
     break;
   case pch::DECL_NON_TYPE_TEMPLATE_PARM:
     assert(false && "cannot read NonTypeTemplateParmDecl");