[cfe-commits] r134137 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/TemplateName.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/ItaniumMangle.cpp lib/AST/TemplateName.cpp lib/AST/Type.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp tools/libclang/CIndex.cpp

John McCall rjmccall at apple.com
Thu Jun 30 01:33:18 PDT 2011


Author: rjmccall
Date: Thu Jun 30 03:33:18 2011
New Revision: 134137

URL: http://llvm.org/viewvc/llvm-project?rev=134137&view=rev
Log:
Preserve that a TemplateName was arrived at by substituting
for a template template parameter.

Uses to follow.

I've also made the uniquing of SubstTemplateTemplateParmPacks
use a ContextualFoldingSet as a minor space efficiency.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/TemplateName.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/TemplateName.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jun 30 03:33:18 2011
@@ -124,7 +124,10 @@
 
   mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
   mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
-  mutable llvm::FoldingSet<SubstTemplateTemplateParmPackStorage> 
+  mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage> 
+    SubstTemplateTemplateParms;
+  mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
+                                     ASTContext&> 
     SubstTemplateTemplateParmPacks;
   
   /// \brief The set of nested name specifiers.
@@ -1019,6 +1022,8 @@
                                         const IdentifierInfo *Name) const;
   TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
                                         OverloadedOperatorKind Operator) const;
+  TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
+                                            TemplateName replacement) const;
   TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
                                         const TemplateArgument &ArgPack) const;
   

Modified: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (original)
+++ cfe/trunk/include/clang/AST/TemplateName.h Thu Jun 30 03:33:18 2011
@@ -33,6 +33,7 @@
 struct PrintingPolicy;
 class QualifiedTemplateName;
 class NamedDecl;
+class SubstTemplateTemplateParmStorage;
 class SubstTemplateTemplateParmPackStorage;
 class TemplateArgument;
 class TemplateDecl;
@@ -42,38 +43,49 @@
 /// template names or an already-substituted template template parameter pack.
 class UncommonTemplateNameStorage {
 protected:
+  enum Kind {
+    Overloaded,
+    SubstTemplateTemplateParm,
+    SubstTemplateTemplateParmPack
+  };
+
   union {
     struct {
-      /// \brief If true, this is an OverloadedTemplateStorage instance; 
-      /// otherwise, it's a SubstTemplateTemplateParmPackStorage instance.
-      unsigned IsOverloadedStorage : 1;
+      /// \brief A Kind.
+      unsigned Kind : 2;
       
       /// \brief The number of stored templates or template arguments,
       /// depending on which subclass we have.
-      unsigned Size : 31;
+      unsigned Size : 30;
     } Bits;
     
     void *PointerAlignment;
   };
   
-  UncommonTemplateNameStorage(unsigned Size, bool OverloadedStorage) {
-    Bits.IsOverloadedStorage = OverloadedStorage;
-    Bits.Size = Size;
+  UncommonTemplateNameStorage(Kind kind, unsigned size) {
+    Bits.Kind = kind;
+    Bits.Size = size;
   }
   
 public:
   unsigned size() const { return Bits.Size; }
   
   OverloadedTemplateStorage *getAsOverloadedStorage()  {
-    return Bits.IsOverloadedStorage
+    return Bits.Kind == Overloaded
              ? reinterpret_cast<OverloadedTemplateStorage *>(this) 
              : 0;
   }
   
+  SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
+    return Bits.Kind == SubstTemplateTemplateParm
+             ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
+             : 0;
+  }
+
   SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
-    return Bits.IsOverloadedStorage
-             ? 0
-             : reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) ;
+    return Bits.Kind == SubstTemplateTemplateParmPack
+             ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
+             : 0;
   }
 };
   
@@ -82,8 +94,8 @@
 class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
   friend class ASTContext;
 
-  OverloadedTemplateStorage(unsigned Size) 
-    : UncommonTemplateNameStorage(Size, true) { }
+  OverloadedTemplateStorage(unsigned size) 
+    : UncommonTemplateNameStorage(Overloaded, size) { }
 
   NamedDecl **getStorage() {
     return reinterpret_cast<NamedDecl **>(this + 1);
@@ -98,8 +110,7 @@
   iterator begin() const { return getStorage(); }
   iterator end() const { return getStorage() + size(); }
 };
-  
-  
+
 /// \brief A structure for storing an already-substituted template template
 /// parameter pack.
 ///
@@ -109,16 +120,14 @@
 class SubstTemplateTemplateParmPackStorage
   : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
 {
-  ASTContext &Context;
   TemplateTemplateParmDecl *Parameter;
   const TemplateArgument *Arguments;
   
 public:
-  SubstTemplateTemplateParmPackStorage(ASTContext &Context,
-                                       TemplateTemplateParmDecl *Parameter,
+  SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
                                        unsigned Size, 
                                        const TemplateArgument *Arguments)
-    : UncommonTemplateNameStorage(Size, false), Context(Context),
+    : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
       Parameter(Parameter), Arguments(Arguments) { }
   
   /// \brief Retrieve the template template parameter pack being substituted.
@@ -130,9 +139,10 @@
   /// parameter was substituted.
   TemplateArgument getArgumentPack() const;
   
-  void Profile(llvm::FoldingSetNodeID &ID);
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
   
-  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      ASTContext &Context,
                       TemplateTemplateParmDecl *Parameter,
                       const TemplateArgument &ArgPack);
 };
@@ -189,6 +199,9 @@
     /// \brief A dependent template name that has not been resolved to a 
     /// template (or set of templates).
     DependentTemplate,
+    /// \brief A template template parameter that has been substituted
+    /// for some other template name.
+    SubstTemplateTemplateParm,
     /// \brief A template template parameter pack that has been substituted for 
     /// a template template argument pack, but has not yet been expanded into
     /// individual arguments.
@@ -199,6 +212,7 @@
   explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
   explicit TemplateName(OverloadedTemplateStorage *Storage)
     : Storage(Storage) { }
+  explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
   explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
     : Storage(Storage) { }
   explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
@@ -234,6 +248,19 @@
     return 0;
   }
 
+  /// \brief Retrieve the substituted template template parameter, if 
+  /// known.
+  ///
+  /// \returns The storage for the substituted template template parameter,
+  /// if known. Otherwise, returns NULL.
+  SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
+    if (UncommonTemplateNameStorage *uncommon = 
+          Storage.dyn_cast<UncommonTemplateNameStorage *>())
+      return uncommon->getAsSubstTemplateTemplateParm();
+    
+    return 0;
+  }
+
   /// \brief Retrieve the substituted template template parameter pack, if 
   /// known.
   ///
@@ -260,6 +287,8 @@
     return Storage.dyn_cast<DependentTemplateName *>();
   }
 
+  TemplateName getUnderlying() const;
+
   /// \brief Determines whether this is a dependent template name.
   bool isDependent() const;
 
@@ -300,6 +329,41 @@
 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                     TemplateName N);
 
+/// \brief A structure for storing the information associated with a
+/// substituted template template parameter.
+class SubstTemplateTemplateParmStorage
+  : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
+  friend class ASTContext;
+
+  TemplateTemplateParmDecl *Parameter;
+  TemplateName Replacement;
+
+  SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
+                                   TemplateName replacement)
+    : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
+      Parameter(parameter), Replacement(replacement) {}
+
+public:
+  TemplateTemplateParmDecl *getParameter() const { return Parameter; }
+  TemplateName getReplacement() const { return Replacement; }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      TemplateTemplateParmDecl *parameter,
+                      TemplateName replacement);
+};
+
+inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
+  : Storage(Storage) { }
+
+inline TemplateName TemplateName::getUnderlying() const {
+  if (SubstTemplateTemplateParmStorage *subst
+        = getAsSubstTemplateTemplateParm())
+    return subst->getReplacement().getUnderlying();
+  return *this;
+}
+
 /// \brief Represents a template name that was expressed as a
 /// qualified name.
 ///

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jun 30 03:33:18 2011
@@ -3457,8 +3457,10 @@
   /// \brief The name of the template being specialized.  This is
   /// either a TemplateName::Template (in which case it is a
   /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
-  /// TypeAliasTemplateDecl*) or a
-  /// TemplateName::SubstTemplateTemplateParmPack.
+  /// TypeAliasTemplateDecl*), a
+  /// TemplateName::SubstTemplateTemplateParmPack, or a
+  /// TemplateName::SubstTemplateTemplateParm (in which case the
+  /// replacement must, recursively, be one of these).
   TemplateName Template;
 
   /// \brief - The number of template arguments named in this class

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jun 30 03:33:18 2011
@@ -219,6 +219,7 @@
   FunctionProtoTypes(this_()),
   TemplateSpecializationTypes(this_()),
   DependentTemplateSpecializationTypes(this_()),
+  SubstTemplateTemplateParmPacks(this_()),
   GlobalNestedNameSpecifier(0), IsInt128Installed(false),
   CFConstantStringTypeDecl(0), NSConstantStringTypeDecl(0),
   ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), 
@@ -3036,11 +3037,21 @@
 DeclarationNameInfo
 ASTContext::getNameForTemplate(TemplateName Name,
                                SourceLocation NameLoc) const {
-  if (TemplateDecl *TD = Name.getAsTemplateDecl())
+  switch (Name.getKind()) {
+  case TemplateName::QualifiedTemplate:
+  case TemplateName::Template:
     // DNInfo work in progress: CHECKME: what about DNLoc?
-    return DeclarationNameInfo(TD->getDeclName(), NameLoc);
+    return DeclarationNameInfo(Name.getAsTemplateDecl()->getDeclName(),
+                               NameLoc);
 
-  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+  case TemplateName::OverloadedTemplate: {
+    OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
+    // DNInfo work in progress: CHECKME: what about DNLoc?
+    return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);
+  }
+
+  case TemplateName::DependentTemplate: {
+    DependentTemplateName *DTN = Name.getAsDependentTemplateName();
     DeclarationName DName;
     if (DTN->isIdentifier()) {
       DName = DeclarationNames.getIdentifier(DTN->getIdentifier());
@@ -3055,36 +3066,64 @@
     }
   }
 
-  OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
-  assert(Storage);
-  // DNInfo work in progress: CHECKME: what about DNLoc?
-  return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);
+  case TemplateName::SubstTemplateTemplateParm: {
+    SubstTemplateTemplateParmStorage *subst
+      = Name.getAsSubstTemplateTemplateParm();
+    return DeclarationNameInfo(subst->getParameter()->getDeclName(),
+                               NameLoc);
+  }
+
+  case TemplateName::SubstTemplateTemplateParmPack: {
+    SubstTemplateTemplateParmPackStorage *subst
+      = Name.getAsSubstTemplateTemplateParmPack();
+    return DeclarationNameInfo(subst->getParameterPack()->getDeclName(),
+                               NameLoc);
+  }
+  }
+
+  llvm_unreachable("bad template name kind!");
 }
 
 TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
-  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+  switch (Name.getKind()) {
+  case TemplateName::QualifiedTemplate:
+  case TemplateName::Template: {
+    TemplateDecl *Template = Name.getAsTemplateDecl();
     if (TemplateTemplateParmDecl *TTP 
-                              = dyn_cast<TemplateTemplateParmDecl>(Template))
+          = dyn_cast<TemplateTemplateParmDecl>(Template))
       Template = getCanonicalTemplateTemplateParmDecl(TTP);
   
     // The canonical template name is the canonical template declaration.
     return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
   }
 
-  if (SubstTemplateTemplateParmPackStorage *SubstPack
-                                  = Name.getAsSubstTemplateTemplateParmPack()) {
-    TemplateTemplateParmDecl *CanonParam
-      = getCanonicalTemplateTemplateParmDecl(SubstPack->getParameterPack());
-    TemplateArgument CanonArgPack
-      = getCanonicalTemplateArgument(SubstPack->getArgumentPack());
-    return getSubstTemplateTemplateParmPack(CanonParam, CanonArgPack);
+  case TemplateName::OverloadedTemplate:
+    llvm_unreachable("cannot canonicalize overloaded template");
+
+  case TemplateName::DependentTemplate: {
+    DependentTemplateName *DTN = Name.getAsDependentTemplateName();
+    assert(DTN && "Non-dependent template names must refer to template decls.");
+    return DTN->CanonicalTemplateName;
+  }
+
+  case TemplateName::SubstTemplateTemplateParm: {
+    SubstTemplateTemplateParmStorage *subst
+      = Name.getAsSubstTemplateTemplateParm();
+    return getCanonicalTemplateName(subst->getReplacement());
   }
-      
-  assert(!Name.getAsOverloadedTemplate());
 
-  DependentTemplateName *DTN = Name.getAsDependentTemplateName();
-  assert(DTN && "Non-dependent template names must refer to template decls.");
-  return DTN->CanonicalTemplateName;
+  case TemplateName::SubstTemplateTemplateParmPack: {
+    SubstTemplateTemplateParmPackStorage *subst
+                                  = Name.getAsSubstTemplateTemplateParmPack();
+    TemplateTemplateParmDecl *canonParameter
+      = getCanonicalTemplateTemplateParmDecl(subst->getParameterPack());
+    TemplateArgument canonArgPack
+      = getCanonicalTemplateArgument(subst->getArgumentPack());
+    return getSubstTemplateTemplateParmPack(canonParameter, canonArgPack);
+  }
+  }
+
+  llvm_unreachable("bad template name!");
 }
 
 bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) {
@@ -4791,6 +4830,24 @@
 }
 
 TemplateName 
+ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
+                                         TemplateName replacement) const {
+  llvm::FoldingSetNodeID ID;
+  SubstTemplateTemplateParmStorage::Profile(ID, param, replacement);
+  
+  void *insertPos = 0;
+  SubstTemplateTemplateParmStorage *subst
+    = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
+  
+  if (!subst) {
+    subst = new (*this) SubstTemplateTemplateParmStorage(param, replacement);
+    SubstTemplateTemplateParms.InsertNode(subst, insertPos);
+  }
+
+  return TemplateName(subst);
+}
+
+TemplateName 
 ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
                                        const TemplateArgument &ArgPack) const {
   ASTContext &Self = const_cast<ASTContext &>(*this);
@@ -4802,7 +4859,7 @@
     = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
   
   if (!Subst) {
-    Subst = new (*this) SubstTemplateTemplateParmPackStorage(Self, Param, 
+    Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param, 
                                                            ArgPack.pack_size(),
                                                          ArgPack.pack_begin());
     SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos);

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jun 30 03:33:18 2011
@@ -4201,6 +4201,20 @@
     
     return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
   }
+
+  case TemplateName::SubstTemplateTemplateParm: {
+    SubstTemplateTemplateParmStorage *subst
+      = From.getAsSubstTemplateTemplateParm();
+    TemplateTemplateParmDecl *param
+      = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
+    if (!param)
+      return TemplateName();
+
+    TemplateName replacement = Import(subst->getReplacement());
+    if (replacement.isNull()) return TemplateName();
+    
+    return ToContext.getSubstTemplateTemplateParm(param, replacement);
+  }
       
   case TemplateName::SubstTemplateTemplateParmPack: {
     SubstTemplateTemplateParmPackStorage *SubstPack

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Jun 30 03:33:18 2011
@@ -1369,6 +1369,10 @@
     break;
   }
 
+  case TemplateName::SubstTemplateTemplateParm:
+    llvm_unreachable("mangling a substituted template name!");
+    break;
+
   case TemplateName::SubstTemplateTemplateParmPack: {
     SubstTemplateTemplateParmPackStorage *SubstPack
       = TN.getAsSubstTemplateTemplateParmPack();

Modified: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (original)
+++ cfe/trunk/lib/AST/TemplateName.cpp Thu Jun 30 03:33:18 2011
@@ -27,7 +27,19 @@
   return TemplateArgument(Arguments, size());
 }
 
-void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID) {
+void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, Parameter, Replacement);
+}
+
+void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID, 
+                                           TemplateTemplateParmDecl *parameter,
+                                               TemplateName replacement) {
+  ID.AddPointer(parameter);
+  ID.AddPointer(replacement.getAsVoidPointer());
+}
+
+void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
+                                                   ASTContext &Context) {
   Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
 }
 
@@ -46,9 +58,14 @@
     return DependentTemplate;
   if (Storage.is<QualifiedTemplateName *>())
     return QualifiedTemplate;
-  
-  return getAsOverloadedTemplate()? OverloadedTemplate
-                                  : SubstTemplateTemplateParmPack;
+
+  UncommonTemplateNameStorage *uncommon
+    = Storage.get<UncommonTemplateNameStorage*>();
+  if (uncommon->getAsOverloadedStorage())
+    return OverloadedTemplate;
+  if (uncommon->getAsSubstTemplateTemplateParm())
+    return SubstTemplateTemplateParm;
+  return SubstTemplateTemplateParmPack;
 }
 
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
@@ -58,6 +75,9 @@
   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
     return QTN->getTemplateDecl();
 
+  if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
+    return sub->getReplacement().getAsTemplateDecl();
+
   return 0;
 }
 
@@ -115,6 +135,9 @@
       OS << DTN->getIdentifier()->getName();
     else
       OS << "operator " << getOperatorSpelling(DTN->getOperator());
+  } else if (SubstTemplateTemplateParmStorage *subst
+               = getAsSubstTemplateTemplateParm()) {
+    subst->getReplacement().print(OS, Policy, SuppressNNS);
   } else if (SubstTemplateTemplateParmPackStorage *SubstPack
                                         = getAsSubstTemplateTemplateParmPack())
     OS << SubstPack->getParameterPack()->getNameAsString();

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jun 30 03:33:18 2011
@@ -1764,6 +1764,7 @@
   assert(!T.getAsDependentTemplateName() && 
          "Use DependentTemplateSpecializationType for dependent template-name");
   assert((T.getKind() == TemplateName::Template ||
+          T.getKind() == TemplateName::SubstTemplateTemplateParm ||
           T.getKind() == TemplateName::SubstTemplateTemplateParmPack) &&
          "Unexpected template name for TemplateSpecializationType");
   assert((!Canon.isNull() ||

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jun 30 03:33:18 2011
@@ -1861,7 +1861,8 @@
 QualType Sema::CheckTemplateIdType(TemplateName Name,
                                    SourceLocation TemplateLoc,
                                    TemplateArgumentListInfo &TemplateArgs) {
-  DependentTemplateName *DTN = Name.getAsDependentTemplateName();
+  DependentTemplateName *DTN
+    = Name.getUnderlying().getAsDependentTemplateName();
   if (DTN && DTN->isIdentifier())
     // When building a template-id where the template-name is dependent,
     // assume the template is a type template. Either our assumption is

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Jun 30 03:33:18 2011
@@ -992,13 +992,14 @@
       
       TemplateName Template = Arg.getAsTemplate();
       assert(!Template.isNull() && "Null template template argument");
-      
+
       // We don't ever want to substitute for a qualified template name, since
       // the qualifier is handled separately. So, look through the qualified
       // template name to its underlying declaration.
       if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
         Template = TemplateName(QTN->getTemplateDecl());
-          
+
+      Template = getSema().Context.getSubstTemplateTemplateParm(TTP, Template);
       return Template;
     }
   }

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Jun 30 03:33:18 2011
@@ -4742,6 +4742,14 @@
     return Context->getDependentTemplateName(NNS,
                                          (OverloadedOperatorKind)Record[Idx++]);
   }
+
+  case TemplateName::SubstTemplateTemplateParm: {
+    TemplateTemplateParmDecl *param
+      = cast_or_null<TemplateTemplateParmDecl>(GetDecl(Record[Idx++]));
+    if (!param) return TemplateName();
+    TemplateName replacement = ReadTemplateName(F, Record, Idx);
+    return Context->getSubstTemplateTemplateParm(param, replacement);
+  }
       
   case TemplateName::SubstTemplateTemplateParmPack: {
     TemplateTemplateParmDecl *Param 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Jun 30 03:33:18 2011
@@ -3694,6 +3694,14 @@
       Record.push_back(DepT->getOperator());
     break;
   }
+
+  case TemplateName::SubstTemplateTemplateParm: {
+    SubstTemplateTemplateParmStorage *subst
+      = Name.getAsSubstTemplateTemplateParm();
+    AddDeclRef(subst->getParameter(), Record);
+    AddTemplateName(subst->getReplacement(), Record);
+    break;
+  }
       
   case TemplateName::SubstTemplateTemplateParmPack: {
     SubstTemplateTemplateParmPackStorage *SubstPack

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=134137&r1=134136&r2=134137&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Jun 30 03:33:18 2011
@@ -1330,6 +1330,11 @@
     return Visit(MakeCursorTemplateRef(
                                   Name.getAsQualifiedTemplateName()->getDecl(), 
                                        Loc, TU));
+
+  case TemplateName::SubstTemplateTemplateParm:
+    return Visit(MakeCursorTemplateRef(
+                         Name.getAsSubstTemplateTemplateParm()->getParameter(),
+                                       Loc, TU));
       
   case TemplateName::SubstTemplateTemplateParmPack:
     return Visit(MakeCursorTemplateRef(





More information about the cfe-commits mailing list