[cfe-commits] r105801 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Sema/

John McCall rjmccall at apple.com
Thu Jun 10 17:33:02 PDT 2010


Author: rjmccall
Date: Thu Jun 10 19:33:02 2010
New Revision: 105801

URL: http://llvm.org/viewvc/llvm-project?rev=105801&view=rev
Log:
Split DependentNameType into two types.  DependentNameType represents the
case of an elaborated-type-specifier like 'typename A<T>::foo', and
DependentTemplateSpecializationType represents the case of an
elaborated-type-specifier like 'typename A<T>::template B<T>'.  The TypeLoc
representation of a DependentTST conveniently exactly matches that of an
ElaboratedType wrapping a TST.

Kill off the explicit rebuild methods for RebuildInCurrentInstantiation;
the standard implementations work fine because the nested name specifier
is computable in the newly-entered context.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/TemplateBase.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/include/clang/Frontend/TypeXML.def
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/TemplateBase.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jun 10 19:33:02 2010
@@ -98,6 +98,8 @@
   llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
   llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
   llvm::FoldingSet<DependentNameType> DependentNameTypes;
+  llvm::FoldingSet<DependentTemplateSpecializationType>
+    DependentTemplateSpecializationTypes;
   llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
   llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
 
@@ -621,10 +623,16 @@
                                 NestedNameSpecifier *NNS,
                                 const IdentifierInfo *Name,
                                 QualType Canon = QualType());
-  QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
-                                NestedNameSpecifier *NNS,
-                                const TemplateSpecializationType *TemplateId,
-                                QualType Canon = QualType());
+
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                          const TemplateArgumentListInfo &Args);
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                                  unsigned NumArgs,
+                                                  const TemplateArgument *Args);
 
   QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
 

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Jun 10 19:33:02 2010
@@ -586,14 +586,12 @@
   })
 
 DEF_TRAVERSE_TYPE(DependentNameType, {
-    if (T->getQualifier()) {
-      TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-    }
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  })
 
-    if (T->getTemplateId()) {
-      TRY_TO(VisitTemplateSpecializationType(
-          const_cast<TemplateSpecializationType *>(T->getTemplateId())));
-    }
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
   })
 
 DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })

Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Thu Jun 10 19:33:02 2010
@@ -256,6 +256,10 @@
     return Args.NumArgs;
   }
 
+  /// Determines whether two template arguments are superficially the
+  /// same.
+  bool structurallyEquals(const TemplateArgument &Other) const;
+
   /// \brief Construct a template argument pack.
   void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
 
@@ -476,6 +480,28 @@
 
 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                     const TemplateArgument &Arg);
+
+inline TemplateSpecializationType::iterator
+    TemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
+}
+
+inline DependentTemplateSpecializationType::iterator
+    DependentTemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
+}
+
+inline const TemplateArgument &
+    TemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+
+inline const TemplateArgument &
+    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
   
 } // end namespace clang
 

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jun 10 19:33:02 2010
@@ -2426,7 +2426,7 @@
   // The bool is whether this is a current instantiation.
   llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
 
-    /// \brief The name of the template being specialized.
+  /// \brief The name of the template being specialized.
   TemplateName Template;
 
   /// \brief - The number of template arguments named in this class
@@ -2476,7 +2476,7 @@
   typedef const TemplateArgument * iterator;
 
   iterator begin() const { return getArgs(); }
-  iterator end() const;
+  iterator end() const; // defined inline in TemplateBase.h
 
   /// \brief Retrieve the name of the template that we are specializing.
   TemplateName getTemplateName() const { return Template; }
@@ -2491,7 +2491,7 @@
 
   /// \brief Retrieve a specific template argument as a type.
   /// \precondition @c isArgType(Arg)
-  const TemplateArgument &getArg(unsigned Idx) const;
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   bool isSugared() const {
     return !isDependentType() || isCurrentInstantiation();
@@ -2682,6 +2682,7 @@
   friend class ASTContext;  // ASTContext creates these
 
 public:
+  ~ElaboratedType();
 
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2726,11 +2727,8 @@
   /// \brief The nested name specifier containing the qualifier.
   NestedNameSpecifier *NNS;
 
-  typedef llvm::PointerUnion<const IdentifierInfo *,
-                             const TemplateSpecializationType *> NameType;
-
   /// \brief The type that this typename specifier refers to.
-  NameType Name;
+  const IdentifierInfo *Name;
 
   DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 
                     const IdentifierInfo *Name, QualType CanonType)
@@ -2740,17 +2738,10 @@
            "DependentNameType requires a dependent nested-name-specifier");
   }
 
-  DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
-                    const TemplateSpecializationType *Ty, QualType CanonType)
-    : TypeWithKeyword(Keyword, DependentName, CanonType, true),
-      NNS(NNS), Name(Ty) {
-    assert(NNS->isDependent() &&
-           "DependentNameType requires a dependent nested-name-specifier");
-  }
-
   friend class ASTContext;  // ASTContext creates these
 
 public:
+  virtual ~DependentNameType();
 
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2762,13 +2753,7 @@
   /// form of the original typename was terminated by an identifier,
   /// e.g., "typename T::type".
   const IdentifierInfo *getIdentifier() const {
-    return Name.dyn_cast<const IdentifierInfo *>();
-  }
-
-  /// \brief Retrieve the type named by the typename specifier as a
-  /// type specialization.
-  const TemplateSpecializationType *getTemplateId() const {
-    return Name.dyn_cast<const TemplateSpecializationType *>();
+    return Name;
   }
 
   bool isSugared() const { return false; }
@@ -2779,10 +2764,10 @@
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
-                      NestedNameSpecifier *NNS, NameType Name) {
+                      NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
     ID.AddInteger(Keyword);
     ID.AddPointer(NNS);
-    ID.AddPointer(Name.getOpaqueValue());
+    ID.AddPointer(Name);
   }
 
   static bool classof(const Type *T) {
@@ -2791,6 +2776,88 @@
   static bool classof(const DependentNameType *T) { return true; }
 };
 
+/// DependentTemplateSpecializationType - Represents a template
+/// specialization type whose template cannot be resolved, e.g.
+///   A<T>::template B<T>
+class DependentTemplateSpecializationType :
+  public TypeWithKeyword, public llvm::FoldingSetNode {
+
+  /// The AST context.  Unfortunately required in order to profile
+  /// template arguments.
+  ASTContext &Context;
+
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The identifier of the template.
+  const IdentifierInfo *Name;
+
+  /// \brief - The number of template arguments named in this class
+  /// template specialization.
+  unsigned NumArgs;
+
+  const TemplateArgument *getArgBuffer() const {
+    return reinterpret_cast<const TemplateArgument*>(this+1);
+  }
+  TemplateArgument *getArgBuffer() {
+    return reinterpret_cast<TemplateArgument*>(this+1);
+  }
+
+  DependentTemplateSpecializationType(ASTContext &Context,
+                                      ElaboratedTypeKeyword Keyword,
+                                      NestedNameSpecifier *NNS,
+                                      const IdentifierInfo *Name,
+                                      unsigned NumArgs,
+                                      const TemplateArgument *Args,
+                                      QualType Canon);
+
+  virtual void Destroy(ASTContext& C);
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  virtual ~DependentTemplateSpecializationType();
+
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+  const IdentifierInfo *getIdentifier() const { return Name; }
+
+  /// \brief Retrieve the template arguments.
+  const TemplateArgument *getArgs() const {
+    return getArgBuffer();
+  }
+
+  /// \brief Retrieve the number of template arguments.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+  typedef const TemplateArgument * iterator;
+  iterator begin() const { return getArgs(); }
+  iterator end() const; // inline in TemplateBase.h
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      ASTContext &Context,
+                      ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *Qualifier,
+                      const IdentifierInfo *Name,
+                      unsigned NumArgs,
+                      const TemplateArgument *Args);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentTemplateSpecialization;
+  }
+  static bool classof(const DependentTemplateSpecializationType *T) {
+    return true;
+  }  
+};
+
 /// ObjCObjectType - Represents a class type in Objective C.
 /// Every Objective C type is a combination of a base type and a
 /// list of protocols.

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Jun 10 19:33:02 2010
@@ -1033,13 +1033,20 @@
     setLAngleLoc(Loc);
     setRAngleLoc(Loc);
     setTemplateNameLoc(Loc);
+    initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
+                      getArgInfos(), Loc);
+  }
 
-    for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+  static void initializeArgLocs(unsigned NumArgs,
+                                const TemplateArgument *Args,
+                                TemplateArgumentLocInfo *ArgInfos,
+                                SourceLocation Loc) {
+    for (unsigned i = 0, e = NumArgs; i != e; ++i) {
       TemplateArgumentLocInfo Info;
 #ifndef NDEBUG
       // If asserts are enabled, be sure to initialize the argument
       // loc with the right kind of pointer.
-      switch (getTypePtr()->getArg(i).getKind()) {
+      switch (Args[i].getKind()) {
       case TemplateArgument::Expression:
       case TemplateArgument::Declaration:
         Info = TemplateArgumentLocInfo((Expr*) 0);
@@ -1050,7 +1057,7 @@
         break;
 
       case TemplateArgument::Template:
-        Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+        Info = TemplateArgumentLocInfo(SourceRange(Loc), Loc);
         break;
           
       case TemplateArgument::Integral:
@@ -1060,7 +1067,7 @@
         break;
       }
 #endif
-      getArgInfos()[i] = Info;
+      ArgInfos[i] = Info;
     }
   }
 
@@ -1251,9 +1258,9 @@
   }
 };
 
-struct DependentNameLocInfo {
-  SourceLocation KeywordLoc;
-  SourceRange QualifierRange;
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TypeDeclTypeLoc.
+struct DependentNameLocInfo : ElaboratedLocInfo {
   SourceLocation NameLoc;
 };
 
@@ -1303,6 +1310,107 @@
   }
 };
 
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TemplateSpecializationTypeLoc.
+struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+  // followed by a TemplateArgumentLocInfo[]
+};
+
+class DependentTemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           DependentTemplateSpecializationTypeLoc,
+                           DependentTemplateSpecializationType,
+                           DependentTemplateSpecializationLocInfo> {
+public:
+  SourceLocation getKeywordLoc() const {
+    return this->getLocalData()->KeywordLoc;
+  }
+  void setKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->KeywordLoc = Loc;
+  }
+
+  SourceRange getQualifierRange() const {
+    return this->getLocalData()->QualifierRange;
+  }
+  void setQualifierRange(SourceRange Range) {
+    this->getLocalData()->QualifierRange = Range;
+  }
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+
+  SourceLocation getLAngleLoc() const {
+    return this->getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return this->getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumArgs() const {
+    return getTypePtr()->getNumArgs();
+  }
+
+  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+    AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+    getArgInfos()[i] = AI;
+  }
+  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+    return getArgInfos()[i];
+  }
+
+  TemplateArgumentLoc getArgLoc(unsigned i) const {
+    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getKeywordLoc().isValid())
+      return SourceRange(getKeywordLoc(), getRAngleLoc());
+    else
+      return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+  }
+
+  void copy(DependentTemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setKeywordLoc(Loc);
+    setQualifierRange(SourceRange(Loc));
+    setNameLoc(Loc);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
+                                                     getTypePtr()->getArgs(),
+                                                     getArgInfos(), Loc);
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
+};
+
 }
 
 #endif

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Thu Jun 10 19:33:02 2010
@@ -92,6 +92,7 @@
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
 DEPENDENT_TYPE(InjectedClassName, Type)
 DEPENDENT_TYPE(DependentName, Type)
+DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
 TYPE(ObjCObject, Type)
 TYPE(ObjCInterface, ObjCObjectType)
 TYPE(ObjCObjectPointer, Type)

Modified: cfe/trunk/include/clang/Frontend/TypeXML.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TypeXML.def?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TypeXML.def (original)
+++ cfe/trunk/include/clang/Frontend/TypeXML.def Thu Jun 10 19:33:02 2010
@@ -253,6 +253,11 @@
   ID_ATTRIBUTE_XML
 END_NODE_XML
 
+NODE_XML(DependentTemplateSpecializationType,
+         "DependentTemplateSpecializationType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
 NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
   ID_ATTRIBUTE_XML
 END_NODE_XML

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jun 10 19:33:02 2010
@@ -1911,44 +1911,69 @@
 }
 
 QualType
-ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
+ASTContext::getDependentTemplateSpecializationType(
+                                 ElaboratedTypeKeyword Keyword,
                                  NestedNameSpecifier *NNS,
-                                 const TemplateSpecializationType *TemplateId,
-                                 QualType Canon) {
+                                 const IdentifierInfo *Name,
+                                 const TemplateArgumentListInfo &Args) {
+  // TODO: avoid this copy
+  llvm::SmallVector<TemplateArgument, 16> ArgCopy;
+  for (unsigned I = 0, E = Args.size(); I != E; ++I)
+    ArgCopy.push_back(Args[I].getArgument());
+  return getDependentTemplateSpecializationType(Keyword, NNS, Name,
+                                                ArgCopy.size(),
+                                                ArgCopy.data());
+}
+
+QualType
+ASTContext::getDependentTemplateSpecializationType(
+                                 ElaboratedTypeKeyword Keyword,
+                                 NestedNameSpecifier *NNS,
+                                 const IdentifierInfo *Name,
+                                 unsigned NumArgs,
+                                 const TemplateArgument *Args) {
   assert(NNS->isDependent() && "nested-name-specifier must be dependent");
 
   llvm::FoldingSetNodeID ID;
-  DependentNameType::Profile(ID, Keyword, NNS, TemplateId);
+  DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
+                                               Name, NumArgs, Args);
 
   void *InsertPos = 0;
-  DependentNameType *T
-    = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  DependentTemplateSpecializationType *T
+    = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
     return QualType(T, 0);
 
-  if (Canon.isNull()) {
-    NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
-    QualType CanonType = getCanonicalType(QualType(TemplateId, 0));
-    ElaboratedTypeKeyword CanonKeyword = Keyword;
-    if (Keyword == ETK_None)
-      CanonKeyword = ETK_Typename;
-    if (CanonNNS != NNS || CanonKeyword != Keyword ||
-        CanonType != QualType(TemplateId, 0)) {
-      const TemplateSpecializationType *CanonTemplateId
-        = CanonType->getAs<TemplateSpecializationType>();
-      assert(CanonTemplateId &&
-             "Canonical type must also be a template specialization type");
-      Canon = getDependentNameType(CanonKeyword, CanonNNS, CanonTemplateId);
-    }
-
-    DependentNameType *CheckT
-      = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(!CheckT && "Typename canonical type is broken"); (void)CheckT;
-  }
+  NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+
+  ElaboratedTypeKeyword CanonKeyword = Keyword;
+  if (Keyword == ETK_None) CanonKeyword = ETK_Typename;
 
-  T = new (*this) DependentNameType(Keyword, NNS, TemplateId, Canon);
+  bool AnyNonCanonArgs = false;
+  llvm::SmallVector<TemplateArgument, 16> CanonArgs(NumArgs);
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    CanonArgs[I] = getCanonicalTemplateArgument(Args[I]);
+    if (!CanonArgs[I].structurallyEquals(Args[I]))
+      AnyNonCanonArgs = true;
+  }
+
+  QualType Canon;
+  if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) {
+    Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS,
+                                                   Name, NumArgs,
+                                                   CanonArgs.data());
+
+    // Find the insert position again.
+    DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +
+                        sizeof(TemplateArgument) * NumArgs),
+                       TypeAlignment);
+  T = new (Mem) DependentTemplateSpecializationType(*this, Keyword, NNS,
+                                                    Name, NumArgs, Args, Canon);
   Types.push_back(T);
-  DependentNameTypes.InsertNode(T, InsertPos);
+  DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);
   return QualType(T, 0);
 }
 

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jun 10 19:33:02 2010
@@ -73,6 +73,7 @@
     // FIXME: TemplateSpecializationType
     QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: DependentNameType
+    // FIXME: DependentTemplateSpecializationType
     QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
     QualType VisitObjCObjectType(ObjCObjectType *T);
     QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
@@ -619,14 +620,32 @@
     if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
                                   Typename2->getIdentifier()))
       return false;
-    if (!IsStructurallyEquivalent(Context,
-                                  QualType(Typename1->getTemplateId(), 0),
-                                  QualType(Typename2->getTemplateId(), 0)))
-      return false;
     
     break;
   }
   
+  case Type::DependentTemplateSpecialization: {
+    const DependentTemplateSpecializationType *Spec1 =
+      cast<DependentTemplateSpecializationType>(T1);
+    const DependentTemplateSpecializationType *Spec2 =
+      cast<DependentTemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Spec1->getQualifier(),
+                                  Spec2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
+                                  Spec2->getIdentifier()))
+      return false;
+    if (Spec1->getNumArgs() != Spec2->getNumArgs())
+      return false;
+    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context,
+                                    Spec1->getArg(I), Spec2->getArg(I)))
+        return false;
+    }
+    break;
+  }
+  
   case Type::ObjCInterface: {
     const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
     const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);

Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Thu Jun 10 19:33:02 2010
@@ -90,6 +90,33 @@
   }
 }
 
+bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
+  if (getKind() != Other.getKind()) return false;
+
+  switch (getKind()) {
+  case Null:
+  case Type:
+  case Declaration:
+  case Template:
+  case Expression:
+    return TypeOrValue == Other.TypeOrValue;
+
+  case Integral:
+    return getIntegralType() == Other.getIntegralType() &&
+           *getAsIntegral() == *Other.getAsIntegral();
+
+  case Pack:
+    if (Args.NumArgs != Other.Args.NumArgs) return false;
+    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
+      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
+        return false;
+    return true;
+  }
+
+  // Suppress warnings.
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // TemplateArgumentLoc Implementation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jun 10 19:33:02 2010
@@ -768,6 +768,7 @@
   case TemplateSpecialization:
   case Elaborated:
   case DependentName:
+  case DependentTemplateSpecialization:
   case ObjCInterface:
   case ObjCObject:
   case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers
@@ -856,12 +857,56 @@
   }
 }
 
+ElaboratedType::~ElaboratedType() {}
+DependentNameType::~DependentNameType() {}
+DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {}
+
+void DependentTemplateSpecializationType::Destroy(ASTContext &C) {
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    // FIXME: Not all expressions get cloned, so we can't yet perform
+    // this destruction.
+    //    if (Expr *E = getArg(Arg).getAsExpr())
+    //      E->Destroy(C);
+  }
+}
+
+DependentTemplateSpecializationType::DependentTemplateSpecializationType(
+                         ASTContext &Context, ElaboratedTypeKeyword Keyword,
+                         NestedNameSpecifier *NNS, const IdentifierInfo *Name,
+                         unsigned NumArgs, const TemplateArgument *Args,
+                         QualType Canon)
+  : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true),
+    Context(Context), NNS(NNS), Name(Name), NumArgs(NumArgs) {
+  assert(NNS && NNS->isDependent() &&
+         "DependentTemplateSpecializatonType requires dependent qualifier");
+  for (unsigned I = 0; I != NumArgs; ++I)
+    new (&getArgBuffer()[I]) TemplateArgument(Args[I]);
+}
+
+void
+DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+                                             ASTContext &Context,
+                                             ElaboratedTypeKeyword Keyword,
+                                             NestedNameSpecifier *Qualifier,
+                                             const IdentifierInfo *Name,
+                                             unsigned NumArgs,
+                                             const TemplateArgument *Args) {
+  ID.AddInteger(Keyword);
+  ID.AddPointer(Qualifier);
+  ID.AddPointer(Name);
+  for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
+    Args[Idx].Profile(ID, Context);
+}
+
 bool Type::isElaboratedTypeSpecifier() const {
   ElaboratedTypeKeyword Keyword;
   if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this))
     Keyword = Elab->getKeyword();
   else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this))
     Keyword = DepName->getKeyword();
+  else if (const DependentTemplateSpecializationType *DepTST =
+             dyn_cast<DependentTemplateSpecializationType>(this))
+    Keyword = DepTST->getKeyword();
   else
     return false;
 
@@ -1113,17 +1158,6 @@
   }
 }
 
-TemplateSpecializationType::iterator
-TemplateSpecializationType::end() const {
-  return begin() + getNumArgs();
-}
-
-const TemplateArgument &
-TemplateSpecializationType::getArg(unsigned Idx) const {
-  assert(Idx < getNumArgs() && "Template argument out of range");
-  return getArgs()[Idx];
-}
-
 void
 TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
                                     TemplateName T,

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Jun 10 19:33:02 2010
@@ -580,15 +580,31 @@
     
     T->getQualifier()->print(OS, Policy);
     
-    if (const IdentifierInfo *Ident = T->getIdentifier())
-      OS << Ident->getName();
-    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
-      Spec->getTemplateName().print(OS, Policy, true);
-      OS << TemplateSpecializationType::PrintTemplateArgumentList(
-                                                            Spec->getArgs(),
-                                                            Spec->getNumArgs(),
+    OS << T->getIdentifier()->getName();
+  }
+  
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;
+}
+
+void TypePrinter::PrintDependentTemplateSpecialization(
+        const DependentTemplateSpecializationType *T, std::string &S) { 
+  std::string MyString;
+  {
+    llvm::raw_string_ostream OS(MyString);
+  
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
+    
+    T->getQualifier()->print(OS, Policy);    
+    OS << T->getIdentifier()->getName();
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                            T->getArgs(),
+                                                            T->getNumArgs(),
                                                             Policy);
-    }
   }
   
   if (S.empty())

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Thu Jun 10 19:33:02 2010
@@ -1369,21 +1369,25 @@
 void CXXNameMangler::mangleType(const DependentNameType *T) {
   // Typename types are always nested
   Out << 'N';
-  if (T->getIdentifier()) {
-    mangleUnresolvedScope(T->getQualifier());
-    mangleSourceName(T->getIdentifier());
-  } else {
-    const TemplateSpecializationType *TST = T->getTemplateId();
+  mangleUnresolvedScope(T->getQualifier());
+  mangleSourceName(T->getIdentifier());    
+  Out << 'E';
+}
 
-    mangleTemplatePrefix(TST->getTemplateName());
-      
-    // FIXME: GCC does not appear to mangle the template arguments when
-    // the template in question is a dependent template name. Should we
-    // emulate that badness?
-    mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
-                       TST->getNumArgs());    
-  }
-    
+void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
+  // Dependently-scoped template types are always nested
+  Out << 'N';
+
+  // TODO: avoid making this TemplateName.
+  TemplateName Prefix =
+    getASTContext().getDependentTemplateName(T->getQualifier(),
+                                             T->getIdentifier());
+  mangleTemplatePrefix(Prefix);
+
+  // FIXME: GCC does not appear to mangle the template arguments when
+  // the template in question is a dependent template name. Should we
+  // emulate that badness?
+  mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs());    
   Out << 'E';
 }
 

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Jun 10 19:33:02 2010
@@ -2367,6 +2367,18 @@
   TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
+void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
+       DependentTemplateSpecializationTypeLoc TL) {
+  TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+    TL.setArgLocInfo(I,
+        Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
+                                          Record, Idx));
+}
 void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Jun 10 19:33:02 2010
@@ -408,6 +408,16 @@
   Writer.AddSourceRange(TL.getQualifierRange(), Record);
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
+void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
+       DependentTemplateSpecializationTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
+  Writer.AddSourceRange(TL.getQualifierRange(), Record);
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+    Writer.AddTemplateArgumentLoc(TL.getArgLoc(I), Record);
+}
 void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jun 10 19:33:02 2010
@@ -87,8 +87,8 @@
         if (!isClassName)
           return 0;
         
-        // We know from the grammar that this name refers to a type, so build a
-        // DependentNameType node to describe the type.
+        // We know from the grammar that this name refers to a type,
+        // so build a dependent node to describe the type.
         return CheckTypenameType(ETK_None,
                                  (NestedNameSpecifier *)SS->getScopeRep(), II,
                                  SourceLocation(), SS->getRange(), NameLoc
@@ -196,12 +196,6 @@
     
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     T = Context.getObjCInterfaceType(IDecl);
-  } else if (UnresolvedUsingTypenameDecl *UUDecl =
-               dyn_cast<UnresolvedUsingTypenameDecl>(IIDecl)) {
-    // FIXME: preserve source structure information.
-    T = Context.getDependentNameType(ETK_None, 
-                                     UUDecl->getTargetNestedNameSpecifier(), 
-                                     &II);
   } else {
     // If it's not plausibly a type, suppress diagnostics.
     Result.suppressDiagnostics();

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jun 10 19:33:02 2010
@@ -5288,15 +5288,31 @@
     return CreateLocInfoType(T, TSI).getAsOpaquePtr();
   }
 
-  T = Context.getDependentNameType(ETK_Typename, NNS,
-                                   cast<TemplateSpecializationType>(T));
+  // TODO: it's really silly that we make a template specialization
+  // type earlier only to drop it again here.
+  TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T);
+  DependentTemplateName *DTN =
+    TST->getTemplateName().getAsDependentTemplateName();
+  assert(DTN && "dependent template has non-dependent name?");
+  T = Context.getDependentTemplateSpecializationType(ETK_Typename, NNS,
+                                                     DTN->getIdentifier(),
+                                                     TST->getNumArgs(),
+                                                     TST->getArgs());
   TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
-  DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
+  DependentTemplateSpecializationTypeLoc TL =
+    cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc());
+  if (InnerTSI) {
+    TemplateSpecializationTypeLoc TSTL =
+      cast<TemplateSpecializationTypeLoc>(InnerTSI->getTypeLoc());
+    TL.setLAngleLoc(TSTL.getLAngleLoc());
+    TL.setRAngleLoc(TSTL.getRAngleLoc());
+    for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I)
+      TL.setArgLocInfo(I, TSTL.getArgLocInfo(I));
+  } else {
+    TL.initializeLocal(SourceLocation());
+  }
   TL.setKeywordLoc(TypenameLoc);
   TL.setQualifierRange(SS.getRange());
-
-  // FIXME: the inner type is a template here; remember its full source info
-  TL.setNameLoc(InnerTSI ? InnerTSI->getTypeLoc().getBeginLoc() : TemplateLoc);
   return CreateLocInfoType(T, TSI).getAsOpaquePtr();
 }
 
@@ -5425,87 +5441,9 @@
     Sema::OwningExprResult TransformExpr(Expr *E) {
       return getSema().Owned(E->Retain());
     }
-
-    /// \brief Transforms a typename type by determining whether the type now
-    /// refers to a member of the current instantiation, and then
-    /// type-checking and building an ElaboratedType (when possible).
-    QualType TransformDependentNameType(TypeLocBuilder &TLB,
-                                        DependentNameTypeLoc TL,
-                                        QualType ObjectType);
   };
 }
 
-QualType
-CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
-                                                     DependentNameTypeLoc TL, 
-                                                     QualType ObjectType) {
-  DependentNameType *T = TL.getTypePtr();
-
-  NestedNameSpecifier *NNS
-    = TransformNestedNameSpecifier(T->getQualifier(),
-                                   TL.getQualifierRange(),
-                                   ObjectType);
-  if (!NNS)
-    return QualType();
-
-  // If the nested-name-specifier did not change, and we cannot compute the
-  // context corresponding to the nested-name-specifier, then this
-  // typename type will not change; exit early.
-  CXXScopeSpec SS;
-  SS.setRange(TL.getQualifierRange());
-  SS.setScopeRep(NNS);
-
-  QualType Result;
-  if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0)
-    Result = QualType(T, 0);
-
-  // Rebuild the typename type, which will probably turn into a
-  // ElaboratedType.
-  else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
-    QualType NewTemplateId
-      = TransformType(QualType(TemplateId, 0));
-    if (NewTemplateId.isNull())
-      return QualType();
-
-    if (NNS == T->getQualifier() &&
-        NewTemplateId == QualType(TemplateId, 0))
-      Result = QualType(T, 0);
-    else
-      Result = getDerived().RebuildDependentNameType(T->getKeyword(),
-                                                     NNS, NewTemplateId);
-  } else
-    Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
-                                                   T->getIdentifier(),
-                                                   TL.getKeywordLoc(),
-                                                   TL.getQualifierRange(),
-                                                   TL.getNameLoc());
-
-  if (Result.isNull())
-    return QualType();
-
-  if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
-    QualType NamedT = ElabT->getNamedType();
-    if (isa<TemplateSpecializationType>(NamedT)) {
-      TemplateSpecializationTypeLoc NamedTLoc
-        = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
-      // FIXME: fill locations
-      NamedTLoc.initializeLocal(TL.getNameLoc());
-    } else {
-      TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
-    }
-    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
-    NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(TL.getQualifierRange());
-  }
-  else {
-    DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
-    NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(TL.getQualifierRange());
-    NewTL.setNameLoc(TL.getNameLoc());
-  }
-  return Result;
-}
-
 /// \brief Rebuilds a type within the context of the current instantiation.
 ///
 /// The type \p T is part of the type of an out-of-line member definition of

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jun 10 19:33:02 2010
@@ -2624,6 +2624,18 @@
                                  OnlyDeduced, Depth, Used);
     break;
 
+  case Type::DependentTemplateSpecialization: {
+    const DependentTemplateSpecializationType *Spec
+      = cast<DependentTemplateSpecializationType>(T);
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(),
+                                 OnlyDeduced, Depth, Used);
+    for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+      MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
+                                 Used);
+    break;
+  }
+
   case Type::TypeOf:
     if (!OnlyDeduced)
       MarkUsedTemplateParameters(SemaRef,

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun 10 19:33:02 2010
@@ -1492,6 +1492,28 @@
       // FIXME: load appropriate source location.
       TL.setNameLoc(DS.getTypeSpecTypeLoc());
     }
+    void VisitDependentTemplateSpecializationTypeLoc(
+                                 DependentTemplateSpecializationTypeLoc TL) {
+      ElaboratedTypeKeyword Keyword
+        = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+      if (Keyword == ETK_Typename) {
+        TypeSourceInfo *TInfo = 0;
+        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        if (TInfo) {
+          TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
+                    TInfo->getTypeLoc()));
+          return;
+        }
+      }
+      TL.initializeLocal(SourceLocation());
+      TL.setKeywordLoc(Keyword != ETK_None
+                       ? DS.getTypeSpecTypeLoc()
+                       : SourceLocation());
+      const CXXScopeSpec& SS = DS.getTypeSpecScope();
+      TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
+      // FIXME: load appropriate source location.
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
 
     void VisitTypeLoc(TypeLoc TL) {
       // FIXME: add other typespec types and change this to an assert.

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 10 19:33:02 2010
@@ -533,16 +533,27 @@
   /// By default, builds a new DependentNameType type from the
   /// nested-name-specifier and the given type. Subclasses may override
   /// this routine to provide different behavior.
-  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
-                                    NestedNameSpecifier *NNS, QualType T) {
-    if (NNS->isDependent()) {
-      // If the name is still dependent, just build a new dependent name type.
-      CXXScopeSpec SS;
-      SS.setScopeRep(NNS);
-      if (!SemaRef.computeDeclContext(SS))
-        return SemaRef.Context.getDependentNameType(Keyword, NNS,
-                                          cast<TemplateSpecializationType>(T));
-    }
+  QualType RebuildDependentTemplateSpecializationType(
+                                    ElaboratedTypeKeyword Keyword,
+                                    NestedNameSpecifier *NNS,
+                                    const IdentifierInfo *Name,
+                                    SourceLocation NameLoc,
+                                    const TemplateArgumentListInfo &Args) {
+    // Rebuild the template name.
+    // TODO: avoid TemplateName abstraction
+    TemplateName InstName =
+      getDerived().RebuildTemplateName(NNS, *Name, QualType());
+    
+    // If it's still dependent, make a dependent specialization.
+    if (InstName.getAsDependentTemplateName())
+      return SemaRef.Context.getDependentTemplateSpecializationType(
+                                          Keyword, NNS, Name, Args);
+
+    // Otherwise, make an elaborated type wrapping a non-dependent
+    // specialization.
+    QualType T =
+      getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
+    if (T.isNull()) return QualType();
 
     return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
   }
@@ -3298,46 +3309,23 @@
   if (!NNS)
     return QualType();
 
-  QualType Result;
-
-  if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
-    QualType NewTemplateId
-      = getDerived().TransformType(QualType(TemplateId, 0));
-    if (NewTemplateId.isNull())
-      return QualType();
-
-    if (!getDerived().AlwaysRebuild() &&
-        NNS == T->getQualifier() &&
-        NewTemplateId == QualType(TemplateId, 0))
-      return QualType(T, 0);
-
-    Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
-                                                   NewTemplateId);
-  } else {
-    Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
-                                                   T->getIdentifier(),
-                                                   TL.getKeywordLoc(),
-                                                   TL.getQualifierRange(),
-                                                   TL.getNameLoc());
-  }
+  QualType Result
+    = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
+                                            T->getIdentifier(),
+                                            TL.getKeywordLoc(),
+                                            TL.getQualifierRange(),
+                                            TL.getNameLoc());
   if (Result.isNull())
     return QualType();
 
   if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
     QualType NamedT = ElabT->getNamedType();
-    if (isa<TemplateSpecializationType>(NamedT)) {
-      TemplateSpecializationTypeLoc NamedTLoc
-        = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
-      // FIXME: fill locations
-      NamedTLoc.initializeLocal(TL.getNameLoc());
-    } else {
-      TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
-    }
+    TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
+
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
     NewTL.setQualifierRange(TL.getQualifierRange());
-  }
-  else {
+  } else {
     DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
     NewTL.setQualifierRange(TL.getQualifierRange());
@@ -3347,6 +3335,61 @@
 }
 
 template<typename Derived>
+QualType TreeTransform<Derived>::
+          TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+                                 DependentTemplateSpecializationTypeLoc TL,
+                                                       QualType ObjectType) {
+  DependentTemplateSpecializationType *T = TL.getTypePtr();
+
+  NestedNameSpecifier *NNS
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                TL.getQualifierRange(),
+                                                ObjectType);
+  if (!NNS)
+    return QualType();
+
+  TemplateArgumentListInfo NewTemplateArgs;
+  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
+  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+
+  for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I) {
+    TemplateArgumentLoc Loc;
+    if (getDerived().TransformTemplateArgument(TL.getArgLoc(I), Loc))
+      return QualType();
+    NewTemplateArgs.addArgument(Loc);
+  }
+
+  QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
+                                                     T->getKeyword(),
+                                                     NNS,
+                                                     T->getIdentifier(),
+                                                     TL.getNameLoc(),
+                                                     NewTemplateArgs);
+  if (Result.isNull())
+    return QualType();
+
+  if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
+    QualType NamedT = ElabT->getNamedType();
+
+    // Copy information relevant to the template specialization.
+    TemplateSpecializationTypeLoc NamedTL
+      = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+    NamedTL.setLAngleLoc(TL.getLAngleLoc());
+    NamedTL.setRAngleLoc(TL.getRAngleLoc());
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+      NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I));
+
+    // Copy information relevant to the elaborated type.
+    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+    NewTL.setKeywordLoc(TL.getKeywordLoc());
+    NewTL.setQualifierRange(TL.getQualifierRange());
+  } else {
+    TLB.pushFullCopy(TL);
+  }
+  return Result;
+}
+
+template<typename Derived>
 QualType
 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
                                                    ObjCInterfaceTypeLoc TL,





More information about the cfe-commits mailing list