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

John McCall rjmccall at apple.com
Thu Oct 29 01:12:51 PDT 2009


Author: rjmccall
Date: Thu Oct 29 03:12:44 2009
New Revision: 85500

URL: http://llvm.org/viewvc/llvm-project?rev=85500&view=rev
Log:
Track source information for template arguments and template specialization
types.  Preserve it through template instantiation.  Preserve it through PCH,
although TSTs themselves aren't serializable, so that's pretty much meaningless.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprCXX.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/Frontend/PCHReader.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/AST/TemplateBase.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.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=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Oct 29 03:12:44 2009
@@ -531,6 +531,11 @@
                                          unsigned NumArgs,
                                          QualType Canon = QualType());
 
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgumentLoc *Args,
+                                         unsigned NumArgs,
+                                         QualType Canon = QualType());
+
   QualType getQualifiedNameType(NestedNameSpecifier *NNS,
                                 QualType NamedType);
   QualType getTypenameType(NestedNameSpecifier *NNS,

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Oct 29 03:12:44 2009
@@ -572,11 +572,8 @@
   /// \brief Whether this is a parameter pack.
   bool ParameterPack : 1;
 
-  /// \brief The location of the default argument, if any.
-  SourceLocation DefaultArgumentLoc;
-
   /// \brief The default template argument, if any.
-  QualType DefaultArgument;
+  DeclaratorInfo *DefaultArgument;
 
   TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
                        bool Typename, QualType Type, bool ParameterPack)
@@ -598,13 +595,16 @@
 
   /// \brief Determine whether this template parameter has a default
   /// argument.
-  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
+  bool hasDefaultArgument() const { return DefaultArgument != 0; }
 
   /// \brief Retrieve the default argument, if any.
-  QualType getDefaultArgument() const { return DefaultArgument; }
+  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
 
-  /// \brief Retrieve the location of the default argument, if any.
-  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
+  /// \brief Retrieves the default argument's source information, if any.
+  DeclaratorInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+  /// \brief Retrieves the location of the default argument declaration.
+  SourceLocation getDefaultArgumentLoc() const;
 
   /// \brief Determines whether the default argument was inherited
   /// from a previous declaration of this template.
@@ -613,13 +613,17 @@
   /// \brief Set the default argument for this template parameter, and
   /// whether that default argument was inherited from another
   /// declaration.
-  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
-                          bool Inherited) {
+  void setDefaultArgument(DeclaratorInfo *DefArg, bool Inherited) {
     DefaultArgument = DefArg;
-    DefaultArgumentLoc = DefArgLoc;
     InheritedDefault = Inherited;
   }
 
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgument = 0;
+    InheritedDefault = false;
+  }
+
   /// \brief Retrieve the depth of the template parameter.
   unsigned getDepth() const;
   
@@ -917,6 +921,10 @@
   /// \brief The list of template parameters
   TemplateParameterList* TemplateParams;
 
+  /// \brief The source info for the template arguments as written.
+  TemplateArgumentLoc *ArgsAsWritten;
+  unsigned NumArgsAsWritten;
+
   /// \brief The class template partial specialization from which this 
   /// class template partial specialization was instantiated.
   ///
@@ -930,12 +938,15 @@
                                          TemplateParameterList *Params,
                                          ClassTemplateDecl *SpecializedTemplate,
                                          TemplateArgumentListBuilder &Builder,
+                                         TemplateArgumentLoc *ArgInfos,
+                                         unsigned NumArgInfos,
                                ClassTemplatePartialSpecializationDecl *PrevDecl)
     : ClassTemplateSpecializationDecl(Context,
                                       ClassTemplatePartialSpecialization,
                                       DC, L, SpecializedTemplate, Builder,
                                       PrevDecl),
-      TemplateParams(Params), InstantiatedFromMember(0, false) { }
+      TemplateParams(Params), ArgsAsWritten(ArgInfos),
+      NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
 
 public:
   static ClassTemplatePartialSpecializationDecl *
@@ -943,6 +954,8 @@
          TemplateParameterList *Params,
          ClassTemplateDecl *SpecializedTemplate,
          TemplateArgumentListBuilder &Builder,
+         TemplateArgumentLoc *ArgInfos,
+         unsigned NumArgInfos,
          ClassTemplatePartialSpecializationDecl *PrevDecl);
 
   /// Get the list of template parameters
@@ -950,6 +963,16 @@
     return TemplateParams;
   }
 
+  /// Get the template arguments as written.
+  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+    return ArgsAsWritten;
+  }
+
+  /// Get the number of template arguments as written.
+  unsigned getNumTemplateArgsAsWritten() const {
+    return NumArgsAsWritten;
+  }
+
   /// \brief Retrieve the member class template partial specialization from
   /// which this particular class template partial specialization was
   /// instantiated.

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Oct 29 03:12:44 2009
@@ -34,6 +34,7 @@
   class BlockDecl;
   class CXXOperatorCallExpr;
   class CXXMemberCallExpr;
+  class TemplateArgumentLoc;
 
 /// Expr - This represents one expression.  Note that Expr's are subclasses of
 /// Stmt.  This allows an expression to be transparently used any place a Stmt
@@ -351,13 +352,13 @@
   unsigned NumTemplateArgs;
   
   /// \brief Retrieve the template arguments
-  TemplateArgument *getTemplateArgs() {
-    return reinterpret_cast<TemplateArgument *> (this + 1);
+  TemplateArgumentLoc *getTemplateArgs() {
+    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
   }
   
   /// \brief Retrieve the template arguments
-  const TemplateArgument *getTemplateArgs() const {
-    return reinterpret_cast<const TemplateArgument *> (this + 1);
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
   }
 };
   
@@ -418,7 +419,7 @@
               NamedDecl *D, SourceLocation NameLoc,
               bool HasExplicitTemplateArgumentList,
               SourceLocation LAngleLoc,
-              const TemplateArgument *ExplicitTemplateArgs,
+              const TemplateArgumentLoc *ExplicitTemplateArgs,
               unsigned NumExplicitTemplateArgs,
               SourceLocation RAngleLoc,
               QualType T, bool TD, bool VD);
@@ -460,7 +461,7 @@
                              SourceLocation NameLoc,
                              bool HasExplicitTemplateArgumentList,
                              SourceLocation LAngleLoc,
-                             const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                              unsigned NumExplicitTemplateArgs,
                              SourceLocation RAngleLoc,
                              QualType T, bool TD, bool VD);
@@ -513,7 +514,7 @@
   
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
-  const TemplateArgument *getTemplateArgs() const {
+  const TemplateArgumentLoc *getTemplateArgs() const {
     if (!hasExplicitTemplateArgumentList())
       return 0;
     
@@ -1304,7 +1305,7 @@
   MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
              SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
              bool has_explicit, SourceLocation langle,
-             const TemplateArgument *targs, unsigned numtargs,
+             const TemplateArgumentLoc *targs, unsigned numtargs,
              SourceLocation rangle, QualType ty);
 
 public:
@@ -1326,7 +1327,7 @@
                             SourceLocation l,
                             bool has_explicit,
                             SourceLocation langle,
-                            const TemplateArgument *targs,
+                            const TemplateArgumentLoc *targs,
                             unsigned numtargs,
                             SourceLocation rangle,
                             QualType ty);
@@ -1383,7 +1384,7 @@
 
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
-  const TemplateArgument *getTemplateArgs() const {
+  const TemplateArgumentLoc *getTemplateArgs() const {
     if (!HasExplicitTemplateArgumentList)
       return 0;
 

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Oct 29 03:12:44 2009
@@ -1161,7 +1161,7 @@
                     NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
                     TemplateName Template, SourceLocation TemplateNameLoc,
                     SourceLocation LAngleLoc,
-                    const TemplateArgument *TemplateArgs,
+                    const TemplateArgumentLoc *TemplateArgs,
                     unsigned NumTemplateArgs,
                     SourceLocation RAngleLoc);
 
@@ -1172,7 +1172,7 @@
   Create(ASTContext &Context, QualType T,
          NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
          TemplateName Template, SourceLocation TemplateNameLoc,
-         SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+         SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs,
          unsigned NumTemplateArgs, SourceLocation RAngleLoc);
 
   /// \brief Retrieve the nested name specifier used to qualify the name of
@@ -1198,8 +1198,8 @@
 
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
-  const TemplateArgument *getTemplateArgs() const {
-    return reinterpret_cast<const TemplateArgument *>(this + 1);
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
   }
 
   /// \brief Retrieve the number of template arguments provided as part of this
@@ -1443,7 +1443,7 @@
                           SourceLocation MemberLoc,
                           bool HasExplicitTemplateArgs,
                           SourceLocation LAngleLoc,
-                          const TemplateArgument *TemplateArgs,
+                          const TemplateArgumentLoc *TemplateArgs,
                           unsigned NumTemplateArgs,
                           SourceLocation RAngleLoc);
 
@@ -1474,7 +1474,7 @@
          SourceLocation MemberLoc,
          bool HasExplicitTemplateArgs,
          SourceLocation LAngleLoc,
-         const TemplateArgument *TemplateArgs,
+         const TemplateArgumentLoc *TemplateArgs,
          unsigned NumTemplateArgs,
          SourceLocation RAngleLoc);
 
@@ -1542,7 +1542,7 @@
 
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
-  const TemplateArgument *getTemplateArgs() const {
+  const TemplateArgumentLoc *getTemplateArgs() const {
     if (!HasExplicitTemplateArgumentList)
       return 0;
 

Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Thu Oct 29 03:12:44 2009
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_AST_TEMPLATEBASE_H
 
 #include "llvm/ADT/APSInt.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "clang/AST/Type.h"
 
 namespace llvm {
@@ -26,6 +27,7 @@
 
 class Decl;
 class Expr;
+class DeclaratorInfo;
 
 /// \brief Represents a template argument within a class template
 /// specialization.
@@ -43,9 +45,6 @@
     } Args;
   };
 
-  /// \brief Location of the beginning of this template argument.
-  SourceLocation StartLoc;
-
 public:
   /// \brief The type of template argument we're storing.
   enum ArgKind {
@@ -67,30 +66,26 @@
   } Kind;
 
   /// \brief Construct an empty, invalid template argument.
-  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+  TemplateArgument() : TypeOrValue(0), Kind(Null) { }
 
   /// \brief Construct a template type argument.
-  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+  TemplateArgument(QualType T) : Kind(Type) {
     TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-    StartLoc = Loc;
   }
 
   /// \brief Construct a template argument that refers to a
   /// declaration, which is either an external declaration or a
   /// template declaration.
-  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+  TemplateArgument(Decl *D) : Kind(Declaration) {
     // FIXME: Need to be sure we have the "canonical" declaration!
     TypeOrValue = reinterpret_cast<uintptr_t>(D);
-    StartLoc = Loc;
   }
 
   /// \brief Construct an integral constant template argument.
-  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
-                   QualType Type)
+  TemplateArgument(const llvm::APSInt &Value, QualType Type)
   : Kind(Integral) {
     new (Integer.Value) llvm::APSInt(Value);
     Integer.Type = Type.getAsOpaquePtr();
-    StartLoc = Loc;
   }
 
   /// \brief Construct a template argument that is an expression.
@@ -98,7 +93,9 @@
   /// This form of template argument only occurs in template argument
   /// lists used for dependent types and for expression; it will not
   /// occur in a non-dependent, canonical template argument list.
-  TemplateArgument(Expr *E);
+  TemplateArgument(Expr *E) : Kind(Expression) {
+    TypeOrValue = reinterpret_cast<uintptr_t>(E);
+  }
 
   /// \brief Copy constructor for a template argument.
   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
@@ -113,7 +110,6 @@
     }
     else
       TypeOrValue = Other.TypeOrValue;
-    StartLoc = Other.StartLoc;
   }
 
   TemplateArgument& operator=(const TemplateArgument& Other) {
@@ -142,7 +138,6 @@
       } else
         TypeOrValue = Other.TypeOrValue;
     }
-    StartLoc = Other.StartLoc;
 
     return *this;
   }
@@ -234,9 +229,6 @@
     return Args.NumArgs;
   }
 
-  /// \brief Retrieve the location where the template argument starts.
-  SourceLocation getLocation() const { return StartLoc; }
-
   /// \brief Construct a template argument pack.
   void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
 
@@ -244,6 +236,123 @@
   void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
 };
 
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+  void *Union;
+
+#ifndef NDEBUG
+  enum Kind {
+    K_None,
+    K_DeclaratorInfo,
+    K_Expression
+  } Kind;
+#endif
+
+public:
+  TemplateArgumentLocInfo()
+    : Union(), Kind(K_None) {}
+  TemplateArgumentLocInfo(DeclaratorInfo *DInfo)
+    : Union(DInfo), Kind(K_DeclaratorInfo) {}
+  TemplateArgumentLocInfo(Expr *E)
+    : Union(E), Kind(K_Expression) {}
+
+  /// \brief Returns whether this 
+  bool empty() const {
+    return Union == NULL;
+  }
+
+  DeclaratorInfo *getAsDeclaratorInfo() const {
+    assert(Kind == K_DeclaratorInfo);
+    return reinterpret_cast<DeclaratorInfo*>(Union);
+  }
+
+  Expr *getAsExpr() const {
+    assert(Kind == K_Expression);
+    return reinterpret_cast<Expr*>(Union);
+  }
+
+#ifndef NDEBUG
+  void validateForArgument(const TemplateArgument &Arg) {
+    // We permit empty data.  This should be removed when source info
+    // is being uniformly preserved.
+    if (Kind == K_None) return;
+
+    switch (Arg.getKind()) {
+    case TemplateArgument::Type:
+      assert(Kind == K_DeclaratorInfo);
+      break;
+    case TemplateArgument::Expression:
+      assert(Kind == K_Expression);
+      break;
+    case TemplateArgument::Declaration:
+    case TemplateArgument::Integral:
+    case TemplateArgument::Pack:
+      assert(Kind == K_None);
+      break;
+    case TemplateArgument::Null:
+      llvm::llvm_unreachable("source info for null template argument?");
+    }
+  }
+#endif
+};
+
+/// Location wrapper for a TemplateArgument.  TemplateArgument is to
+/// TemplateArgumentLoc as Type is to TypeLoc.
+class TemplateArgumentLoc {
+  TemplateArgument Argument;
+  TemplateArgumentLocInfo LocInfo;
+
+  friend class TemplateSpecializationTypeLoc;
+  TemplateArgumentLoc(const TemplateArgument &Argument,
+                      TemplateArgumentLocInfo Opaque)
+    : Argument(Argument), LocInfo(Opaque) {
+  }
+
+public:
+  TemplateArgumentLoc() {}
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo)
+    : Argument(Argument), LocInfo(DInfo) {
+    assert(Argument.getKind() == TemplateArgument::Type);
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
+    : Argument(Argument), LocInfo(E) {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+  }
+
+  /// This is a temporary measure.
+  TemplateArgumentLoc(const TemplateArgument &Argument)
+    : Argument(Argument), LocInfo() {
+    assert(Argument.getKind() != TemplateArgument::Expression &&
+           Argument.getKind() != TemplateArgument::Type);
+  }
+
+  /// \brief - Fetches the start location of the argument, if possible.
+  SourceLocation getLocation() const;
+
+  const TemplateArgument &getArgument() const {
+    return Argument;
+  }
+
+  TemplateArgumentLocInfo getLocInfo() const {
+    return LocInfo;
+  }
+
+  DeclaratorInfo *getSourceDeclaratorInfo() const {
+    assert(Argument.getKind() == TemplateArgument::Type);
+    if (LocInfo.empty()) return 0;
+    return LocInfo.getAsDeclaratorInfo();
+  }
+
+  Expr *getSourceExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+    if (LocInfo.empty()) return 0;
+    return LocInfo.getAsExpr();
+  }
+};
+
 }
 
 #endif

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Oct 29 03:12:44 2009
@@ -81,6 +81,7 @@
   class SourceLocation;
   class StmtIteratorBase;
   class TemplateArgument;
+  class TemplateArgumentLoc;
   class QualifiedNameType;
   struct PrintingPolicy;
 
@@ -2275,12 +2276,19 @@
   static bool anyDependentTemplateArguments(const TemplateArgument *Args,
                                             unsigned NumArgs);
 
+  static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+                                            unsigned NumArgs);
+
   /// \brief Print a template argument list, including the '<' and '>'
   /// enclosing the template arguments.
   static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
                                                unsigned NumArgs,
                                                const PrintingPolicy &Policy);
 
+  static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
+                                               unsigned NumArgs,
+                                               const PrintingPolicy &Policy);
+
   typedef const TemplateArgument * iterator;
 
   iterator begin() const { return getArgs(); }

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Oct 29 03:12:44 2009
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_TYPELOC_H
 
 #include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
 
 namespace clang {
   class ParmVarDecl;
@@ -82,6 +83,19 @@
     return Data;
   }
 
+  /// \brief Get the full source range.
+  SourceRange getFullSourceRange() const {
+    SourceLocation End = getSourceRange().getEnd();
+    TypeLoc Cur = *this;
+    while (true) {
+      TypeLoc Next = Cur.getNextTypeLoc();
+      if (Next.isNull()) break;
+      Cur = Next;
+    }
+    return SourceRange(Cur.getSourceRange().getBegin(), End);
+  }
+
+  /// \brief Get the local source range.
   SourceRange getSourceRange() const {
     return getSourceRangeImpl(*this);
   }
@@ -810,6 +824,96 @@
                                      VariableArrayType> {
 };
 
+
+// Location information for a TemplateName.  Rudimentary for now.
+struct TemplateNameLocInfo {
+  SourceLocation NameLoc;
+};
+
+struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           TemplateSpecializationTypeLoc,
+                           TemplateSpecializationType,
+                           TemplateSpecializationLocInfo> {
+public:
+  SourceLocation getLAngleLoc() const {
+    return getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    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));
+  }
+
+  SourceLocation getTemplateNameLoc() const {
+    return getLocalData()->NameLoc;
+  }
+  void setTemplateNameLoc(SourceLocation Loc) {
+    getLocalData()->NameLoc = Loc;
+  }
+
+  /// \brief - Copy the location information from the given info.
+  void copy(TemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+
+    // We're potentially copying Expr references here.  We don't
+    // bother retaining them because DeclaratorInfos live forever, so
+    // as long as the Expr was retained when originally written into
+    // the TypeLoc, we're okay.
+    memcpy(Data, Loc.Data, size);
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    setTemplateNameLoc(Loc);
+
+    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+      getArgInfos()[i] = TemplateArgumentLocInfo();
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
+};
+
 // None of these types have proper implementations yet.
 
 class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
@@ -861,11 +965,6 @@
                                                  ElaboratedType> {
 };
 
-class TemplateSpecializationTypeLoc
-  : public TypeSpecTypeLoc<TemplateSpecializationTypeLoc,
-                           TemplateSpecializationType> {
-};
-
 class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
                                                     QualifiedNameType> {
 };

Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Thu Oct 29 03:12:44 2009
@@ -19,6 +19,7 @@
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceManager.h"
@@ -542,6 +543,12 @@
   /// comments in the source code.
   virtual void ReadComments(std::vector<SourceRange> &Comments);
 
+  /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+  /// given TemplateArgument kind.
+  TemplateArgumentLocInfo
+  GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                             const RecordData &Record, unsigned &Idx);
+
   /// \brief Reads a declarator info from the given record.
   virtual DeclaratorInfo *GetDeclaratorInfo(const RecordData &Record,
                                             unsigned &Idx);

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Thu Oct 29 03:12:44 2009
@@ -275,6 +275,10 @@
   /// \brief Emits a reference to a declarator info.
   void AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record);
 
+  /// \brief Emits a template argument location.
+  void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                              RecordData &Record);
+
   /// \brief Emit a reference to a declaration.
   void AddDeclRef(const Decl *D, RecordData &Record);
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Oct 29 03:12:44 2009
@@ -1765,6 +1765,19 @@
 
 QualType
 ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          const TemplateArgumentLoc *Args,
+                                          unsigned NumArgs,
+                                          QualType Canon) {
+  llvm::SmallVector<TemplateArgument, 4> ArgVec;
+  ArgVec.reserve(NumArgs);
+  for (unsigned i = 0; i != NumArgs; ++i)
+    ArgVec.push_back(Args[i].getArgument());
+
+  return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, Canon);
+}
+
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
                                           const TemplateArgument *Args,
                                           unsigned NumArgs,
                                           QualType Canon) {
@@ -2298,17 +2311,14 @@
       return Arg;
 
     case TemplateArgument::Declaration:
-      return TemplateArgument(SourceLocation(),
-                              Arg.getAsDecl()->getCanonicalDecl());
+      return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl());
 
     case TemplateArgument::Integral:
-      return TemplateArgument(SourceLocation(),
-                              *Arg.getAsIntegral(),
+      return TemplateArgument(*Arg.getAsIntegral(),
                               getCanonicalType(Arg.getIntegralType()));
 
     case TemplateArgument::Type:
-      return TemplateArgument(SourceLocation(),
-                              getCanonicalType(Arg.getAsType()));
+      return TemplateArgument(getCanonicalType(Arg.getAsType()));
 
     case TemplateArgument::Pack: {
       // FIXME: Allocate in ASTContext

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Oct 29 03:12:44 2009
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/STLExtras.h"
 using namespace clang;
@@ -209,8 +210,7 @@
        Param != ParamEnd; ++Param) {
     if (isa<TemplateTypeParmDecl>(*Param)) {
       QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
-      TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
-                                              ParamType));
+      TemplateArgs.push_back(TemplateArgument(ParamType));
     } else if (NonTypeTemplateParmDecl *NTTP =
                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
@@ -220,7 +220,7 @@
       TemplateArgs.push_back(TemplateArgument(E));
     } else {
       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
-      TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
+      TemplateArgs.push_back(TemplateArgument(TTP));
     }
   }
 
@@ -244,6 +244,10 @@
   return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
 }
 
+SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
+  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
+}
+
 unsigned TemplateTypeParmDecl::getDepth() const {
   return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
 }
@@ -454,12 +458,19 @@
        TemplateParameterList *Params,
        ClassTemplateDecl *SpecializedTemplate,
        TemplateArgumentListBuilder &Builder,
+       TemplateArgumentLoc *ArgInfos, unsigned N,
        ClassTemplatePartialSpecializationDecl *PrevDecl) {
+  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
+  for (unsigned I = 0; I != N; ++I)
+    ClonedArgs[I] = ArgInfos[I];
+
   ClassTemplatePartialSpecializationDecl *Result
     = new (Context)ClassTemplatePartialSpecializationDecl(Context,
                                                           DC, L, Params,
                                                           SpecializedTemplate,
-                                                          Builder, PrevDecl);
+                                                          Builder,
+                                                          ClonedArgs, N,
+                                                          PrevDecl);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
   Context.getTypeDeclType(Result, PrevDecl);
   return Result;

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Oct 29 03:12:44 2009
@@ -35,7 +35,7 @@
                          NamedDecl *D, SourceLocation NameLoc,
                          bool HasExplicitTemplateArgumentList,
                          SourceLocation LAngleLoc,
-                         const TemplateArgument *ExplicitTemplateArgs,
+                         const TemplateArgumentLoc *ExplicitTemplateArgs,
                          unsigned NumExplicitTemplateArgs,
                          SourceLocation RAngleLoc,
                          QualType T, bool TD, bool VD)
@@ -58,9 +58,9 @@
     ETemplateArgs->RAngleLoc = RAngleLoc;
     ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
     
-    TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+    TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
     for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
-      new (TemplateArgs + I) TemplateArgument(ExplicitTemplateArgs[I]);
+      new (TemplateArgs + I) TemplateArgumentLoc(ExplicitTemplateArgs[I]);
   }
 }
 
@@ -82,7 +82,7 @@
                                  SourceLocation NameLoc,
                                  bool HasExplicitTemplateArgumentList,
                                  SourceLocation LAngleLoc,
-                                 const TemplateArgument *ExplicitTemplateArgs,
+                                 const TemplateArgumentLoc *ExplicitTemplateArgs,
                                  unsigned NumExplicitTemplateArgs,
                                  SourceLocation RAngleLoc,
                                  QualType T, bool TD, bool VD) {
@@ -92,7 +92,7 @@
   
   if (HasExplicitTemplateArgumentList)
     Size += sizeof(ExplicitTemplateArgumentList) +
-            sizeof(TemplateArgument) * NumExplicitTemplateArgs;
+            sizeof(TemplateArgumentLoc) * NumExplicitTemplateArgs;
   
   void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
   return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
@@ -428,7 +428,7 @@
                        SourceRange qualrange, NamedDecl *memberdecl,
                        SourceLocation l, bool has_explicit,
                        SourceLocation langle,
-                       const TemplateArgument *targs, unsigned numtargs,
+                       const TemplateArgumentLoc *targs, unsigned numtargs,
                        SourceLocation rangle, QualType ty)
   : Expr(MemberExprClass, ty,
          base->isTypeDependent() || (qual && qual->isDependent()),
@@ -450,9 +450,9 @@
     ETemplateArgs->RAngleLoc = rangle;
     ETemplateArgs->NumTemplateArgs = numtargs;
 
-    TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+    TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
     for (unsigned I = 0; I < numtargs; ++I)
-      new (TemplateArgs + I) TemplateArgument(targs[I]);
+      new (TemplateArgs + I) TemplateArgumentLoc(targs[I]);
   }
 }
 
@@ -463,7 +463,7 @@
                                SourceLocation l,
                                bool has_explicit,
                                SourceLocation langle,
-                               const TemplateArgument *targs,
+                               const TemplateArgumentLoc *targs,
                                unsigned numtargs,
                                SourceLocation rangle,
                                QualType ty) {
@@ -473,7 +473,7 @@
 
   if (has_explicit)
     Size += sizeof(ExplicitTemplateArgumentList) +
-    sizeof(TemplateArgument) * numtargs;
+    sizeof(TemplateArgumentLoc) * numtargs;
 
   void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
   return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l,

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Thu Oct 29 03:12:44 2009
@@ -151,7 +151,7 @@
                                      TemplateName Template,
                                      SourceLocation TemplateNameLoc,
                                      SourceLocation LAngleLoc,
-                                     const TemplateArgument *TemplateArgs,
+                                     const TemplateArgumentLoc *TemplateArgs,
                                      unsigned NumTemplateArgs,
                                      SourceLocation RAngleLoc)
   : Expr(TemplateIdRefExprClass, T,
@@ -164,10 +164,10 @@
     Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
     TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
     RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs) {
-  TemplateArgument *StoredTemplateArgs
-    = reinterpret_cast<TemplateArgument *> (this+1);
+  TemplateArgumentLoc *StoredTemplateArgs
+    = reinterpret_cast<TemplateArgumentLoc *> (this+1);
   for (unsigned I = 0; I != NumTemplateArgs; ++I)
-    new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+    new (StoredTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
 }
 
 TemplateIdRefExpr *
@@ -176,19 +176,19 @@
                           SourceRange QualifierRange,
                           TemplateName Template, SourceLocation TemplateNameLoc,
                           SourceLocation LAngleLoc,
-                          const TemplateArgument *TemplateArgs,
+                          const TemplateArgumentLoc *TemplateArgs,
                           unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
   void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
-                               sizeof(TemplateArgument) * NumTemplateArgs);
+                               sizeof(TemplateArgumentLoc) * NumTemplateArgs);
   return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
                                      TemplateNameLoc, LAngleLoc, TemplateArgs,
                                      NumTemplateArgs, RAngleLoc);
 }
 
 void TemplateIdRefExpr::DoDestroy(ASTContext &Context) {
-  const TemplateArgument *TemplateArgs = getTemplateArgs();
+  const TemplateArgumentLoc *TemplateArgs = getTemplateArgs();
   for (unsigned I = 0; I != NumTemplateArgs; ++I)
-    if (Expr *E = TemplateArgs[I].getAsExpr())
+    if (Expr *E = TemplateArgs[I].getArgument().getAsExpr())
       E->Destroy(Context);
   this->~TemplateIdRefExpr();
   Context.Deallocate(this);
@@ -528,7 +528,7 @@
                                                  SourceLocation MemberLoc,
                                                  bool HasExplicitTemplateArgs,
                                                  SourceLocation LAngleLoc,
-                                           const TemplateArgument *TemplateArgs,
+                                       const TemplateArgumentLoc *TemplateArgs,
                                                  unsigned NumTemplateArgs,
                                                  SourceLocation RAngleLoc)
   : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
@@ -545,9 +545,9 @@
     ETemplateArgs->RAngleLoc = RAngleLoc;
     ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
 
-    TemplateArgument *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
+    TemplateArgumentLoc *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
     for (unsigned I = 0; I < NumTemplateArgs; ++I)
-      new (SavedTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+      new (SavedTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
   }
 }
 
@@ -562,7 +562,7 @@
                                 SourceLocation MemberLoc,
                                 bool HasExplicitTemplateArgs,
                                 SourceLocation LAngleLoc,
-                                const TemplateArgument *TemplateArgs,
+                                const TemplateArgumentLoc *TemplateArgs,
                                 unsigned NumTemplateArgs,
                                 SourceLocation RAngleLoc) {
   if (!HasExplicitTemplateArgs)
@@ -573,7 +573,7 @@
 
   void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) +
                          sizeof(ExplicitTemplateArgumentList) +
-                         sizeof(TemplateArgument) * NumTemplateArgs,
+                         sizeof(TemplateArgumentLoc) * NumTemplateArgs,
                          llvm::alignof<CXXUnresolvedMemberExpr>());
   return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
                                            Qualifier, QualifierRange,

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Thu Oct 29 03:12:44 2009
@@ -60,7 +60,10 @@
 
     /// \brief Visit template arguments that occur within an expression or
     /// statement.
-    void VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
+    void VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs);
+
+    /// \brief Visit a single template argument.
+    void VisitTemplateArgument(const TemplateArgument &Arg);
   };
 }
 
@@ -674,39 +677,42 @@
   Name.Profile(ID);
 }
 
-void StmtProfiler::VisitTemplateArguments(const TemplateArgument *Args,
+void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
                                           unsigned NumArgs) {
   ID.AddInteger(NumArgs);
-  for (unsigned I = 0; I != NumArgs; ++I) {
-    const TemplateArgument &Arg = Args[I];
+  for (unsigned I = 0; I != NumArgs; ++I)
+    VisitTemplateArgument(Args[I].getArgument());
+}
 
-    // Mostly repetitive with TemplateArgument::Profile!
-    ID.AddInteger(Arg.getKind());
-    switch (Arg.getKind()) {
-      case TemplateArgument::Null:
-        break;
-
-      case TemplateArgument::Type:
-        VisitType(Arg.getAsType());
-        break;
-
-      case TemplateArgument::Declaration:
-        VisitDecl(Arg.getAsDecl());
-        break;
-
-      case TemplateArgument::Integral:
-        Arg.getAsIntegral()->Profile(ID);
-        VisitType(Arg.getIntegralType());
-        break;
-
-      case TemplateArgument::Expression:
-        Visit(Arg.getAsExpr());
-        break;
-
-      case TemplateArgument::Pack:
-        VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size());
-        break;
-    }
+void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
+  // Mostly repetitive with TemplateArgument::Profile!
+  ID.AddInteger(Arg.getKind());
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    break;
+
+  case TemplateArgument::Type:
+    VisitType(Arg.getAsType());
+    break;
+
+  case TemplateArgument::Declaration:
+    VisitDecl(Arg.getAsDecl());
+    break;
+
+  case TemplateArgument::Integral:
+    Arg.getAsIntegral()->Profile(ID);
+    VisitType(Arg.getIntegralType());
+    break;
+
+  case TemplateArgument::Expression:
+    Visit(Arg.getAsExpr());
+    break;
+
+  case TemplateArgument::Pack:
+    const TemplateArgument *Pack = Arg.pack_begin();
+    for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
+      VisitTemplateArgument(Pack[i]);
+    break;
   }
 }
 

Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Thu Oct 29 03:12:44 2009
@@ -16,6 +16,7 @@
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
 
 using namespace clang;
 
@@ -23,11 +24,6 @@
 // TemplateArgument Implementation
 //===----------------------------------------------------------------------===//
 
-TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
-  TypeOrValue = reinterpret_cast<uintptr_t>(E);
-  StartLoc = E->getSourceRange().getBegin();
-}
-
 /// \brief Construct a template argument pack.
 void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
                                        bool CopyArgs) {
@@ -77,3 +73,25 @@
       Args.Args[I].Profile(ID, Context);
   }
 }
+
+//===----------------------------------------------------------------------===//
+// TemplateArgumentLoc Implementation
+//===----------------------------------------------------------------------===//
+
+SourceLocation TemplateArgumentLoc::getLocation() const {
+  switch (Argument.getKind()) {
+  case TemplateArgument::Expression:
+    return getSourceExpression()->getExprLoc();
+  case TemplateArgument::Type:
+    return getSourceDeclaratorInfo()->
+      getTypeLoc().getFullSourceRange().getBegin();
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Pack:
+  case TemplateArgument::Null:
+    return SourceLocation();
+  }
+
+  // Silence bonus gcc warning.
+  return SourceLocation();
+}

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Oct 29 03:12:44 2009
@@ -791,40 +791,48 @@
   return isa<EnumDecl>(TT->getDecl());
 }
 
-bool
-TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
-  for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
-    switch (Args[Idx].getKind()) {
-    case TemplateArgument::Null:
-      assert(false && "Should not have a NULL template argument");
-      break;
-
-    case TemplateArgument::Type:
-      if (Args[Idx].getAsType()->isDependentType())
-        return true;
-      break;
-
-    case TemplateArgument::Declaration:
-    case TemplateArgument::Integral:
-      // Never dependent
-      break;
-
-    case TemplateArgument::Expression:
-      if (Args[Idx].getAsExpr()->isTypeDependent() ||
-          Args[Idx].getAsExpr()->isValueDependent())
-        return true;
-      break;
-
-    case TemplateArgument::Pack:
-      assert(0 && "FIXME: Implement!");
-      break;
-    }
+static bool isDependent(const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    assert(false && "Should not have a NULL template argument");
+    return false;
+
+  case TemplateArgument::Type:
+    return Arg.getAsType()->isDependentType();
+
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+    // Never dependent
+    return false;
+
+  case TemplateArgument::Expression:
+    return (Arg.getAsExpr()->isTypeDependent() ||
+            Arg.getAsExpr()->isValueDependent());
+
+  case TemplateArgument::Pack:
+    assert(0 && "FIXME: Implement!");
+    return false;
   }
 
   return false;
 }
 
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
+  for (unsigned i = 0; i != N; ++i)
+    if (isDependent(Args[i].getArgument()))
+      return true;
+  return false;
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) {
+  for (unsigned i = 0; i != N; ++i)
+    if (isDependent(Args[i]))
+      return true;
+  return false;
+}
+
 TemplateSpecializationType::
 TemplateSpecializationType(ASTContext &Context, TemplateName T,
                            const TemplateArgument *Args,
@@ -1260,6 +1268,38 @@
   getReplacementType().getAsStringInternal(InnerString, Policy);
 }
 
+static void PrintTemplateArgument(std::string &Buffer,
+                                  const TemplateArgument &Arg,
+                                  const PrintingPolicy &Policy) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    assert(false && "Null template argument");
+    break;
+    
+  case TemplateArgument::Type:
+    Arg.getAsType().getAsStringInternal(Buffer, Policy);
+    break;
+
+  case TemplateArgument::Declaration:
+    Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
+    break;
+
+  case TemplateArgument::Integral:
+    Buffer = Arg.getAsIntegral()->toString(10, true);
+    break;
+
+  case TemplateArgument::Expression: {
+    llvm::raw_string_ostream s(Buffer);
+    Arg.getAsExpr()->printPretty(s, 0, Policy);
+    break;
+  }
+
+  case TemplateArgument::Pack:
+    assert(0 && "FIXME: Implement!");
+    break;
+  }
+}
+
 std::string
 TemplateSpecializationType::PrintTemplateArgumentList(
                                                   const TemplateArgument *Args,
@@ -1273,32 +1313,41 @@
 
     // Print the argument into a string.
     std::string ArgString;
-    switch (Args[Arg].getKind()) {
-    case TemplateArgument::Null:
-      assert(false && "Null template argument");
-      break;
-
-    case TemplateArgument::Type:
-      Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
-      break;
-
-    case TemplateArgument::Declaration:
-      ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
-      break;
-
-    case TemplateArgument::Integral:
-      ArgString = Args[Arg].getAsIntegral()->toString(10, true);
-      break;
-
-    case TemplateArgument::Expression: {
-      llvm::raw_string_ostream s(ArgString);
-      Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
-      break;
-    }
-    case TemplateArgument::Pack:
-      assert(0 && "FIXME: Implement!");
-      break;
-    }
+    PrintTemplateArgument(ArgString, Args[Arg], Policy);
+
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+
+    SpecString += ArgString;
+  }
+
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+
+  SpecString += '>';
+
+  return SpecString;
+}
+
+// Sadly, repeat all that with TemplateArgLoc.
+std::string TemplateSpecializationType::
+PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
+                          const PrintingPolicy &Policy) {
+  std::string SpecString;
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+
+    // Print the argument into a string.
+    std::string ArgString;
+    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
 
     // If this is the first argument and its string representation
     // begins with the global scope specifier ('::foo'), add a space

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Oct 29 03:12:44 2009
@@ -32,6 +32,7 @@
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
 #include <iterator>
 #include <cstdio>
@@ -2104,7 +2105,13 @@
 }
 void TypeLocReader::VisitTemplateSpecializationTypeLoc(
                                            TemplateSpecializationTypeLoc TL) {
-  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setTemplateNameLoc(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::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -2197,6 +2204,25 @@
   return TypesLoaded[Index].withFastQualifiers(FastQuals);
 }
 
+TemplateArgumentLocInfo
+PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                      const RecordData &Record,
+                                      unsigned &Index) {
+  switch (Kind) {
+  case TemplateArgument::Expression:
+    return ReadDeclExpr();
+  case TemplateArgument::Type:
+    return GetDeclaratorInfo(Record, Index);
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    return TemplateArgumentLocInfo();
+  }
+  llvm::llvm_unreachable("unexpected template argument loc");
+  return TemplateArgumentLocInfo();
+}
+
 Decl *PCHReader::GetDecl(pch::DeclID ID) {
   if (ID == 0)
     return 0;

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Oct 29 03:12:44 2009
@@ -368,7 +368,11 @@
 }
 void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
                                            TemplateSpecializationTypeLoc TL) {
-  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+  Writer.AddSourceLocation(TL.getTemplateNameLoc(), 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::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
@@ -2105,6 +2109,23 @@
   Record.push_back(SID);
 }
 
+void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                                       RecordData &Record) {
+  switch (Arg.getArgument().getKind()) {
+  case TemplateArgument::Expression:
+    AddStmt(Arg.getLocInfo().getAsExpr());
+    break;
+  case TemplateArgument::Type:
+    AddDeclaratorInfo(Arg.getLocInfo().getAsDeclaratorInfo(), Record);
+    break;
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    break;
+  }
+}
+
 void PCHWriter::AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record) {
   if (DInfo == 0) {
     AddTypeRef(QualType(), Record);

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Oct 29 03:12:44 2009
@@ -73,6 +73,7 @@
   class TypedefDecl;
   class TemplateDecl;
   class TemplateArgument;
+  class TemplateArgumentLoc;
   class TemplateArgumentList;
   class TemplateParameterList;
   class TemplateTemplateParmDecl;
@@ -866,7 +867,7 @@
                           bool ForceRValue = false);
   void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
                                   bool HasExplicitTemplateArgs,
-                                  const TemplateArgument *ExplicitTemplateArgs,
+                              const TemplateArgumentLoc *ExplicitTemplateArgs,
                                   unsigned NumExplicitTemplateArgs,
                                   Expr *Object, Expr **Args, unsigned NumArgs,
                                   OverloadCandidateSet& CandidateSet,
@@ -874,7 +875,7 @@
                                   bool ForceRValue = false);
   void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
                                     bool HasExplicitTemplateArgs,
-                                  const TemplateArgument *ExplicitTemplateArgs,
+                           const TemplateArgumentLoc *ExplicitTemplateArgs,
                                     unsigned NumExplicitTemplateArgs,
                                     Expr **Args, unsigned NumArgs,
                                     OverloadCandidateSet& CandidateSet,
@@ -912,7 +913,7 @@
   void AddArgumentDependentLookupCandidates(DeclarationName Name,
                                             Expr **Args, unsigned NumArgs,
                                             bool HasExplicitTemplateArgs,
-                                  const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                             unsigned NumExplicitTemplateArgs,                                            
                                             OverloadCandidateSet& CandidateSet,
                                             bool PartialOverloading = false);
@@ -934,7 +935,7 @@
                                    DeclarationName &UnqualifiedName,
                                    bool &ArgumentDependentLookup,
                                    bool HasExplicitTemplateArgs,
-                                   const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                    unsigned NumExplicitTemplateArgs,
                                    Expr **Args, unsigned NumArgs,
                                    OverloadCandidateSet &CandidateSet,
@@ -943,7 +944,7 @@
   FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
                                         DeclarationName UnqualifiedName,
                                         bool HasExplicitTemplateArgs,
-                                const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                         unsigned NumExplicitTemplateArgs,
                                         SourceLocation LParenLoc,
                                         Expr **Args, unsigned NumArgs,
@@ -1708,7 +1709,7 @@
                                             DeclarationName MemberName,
                                             bool HasExplicitTemplateArgs,
                                             SourceLocation LAngleLoc,
-                                const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                             unsigned NumExplicitTemplateArgs,
                                             SourceLocation RAngleLoc,
                                             DeclPtrTy ImplDecl,
@@ -1741,7 +1742,7 @@
                                SourceRange &QualifierRange,
                                bool &ArgumentDependentLookup,
                                bool &HasExplicitTemplateArguments,
-                               const TemplateArgument *&ExplicitTemplateArgs,
+                            const TemplateArgumentLoc *&ExplicitTemplateArgs,
                                unsigned &NumExplicitTemplateArgs);
     
   /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
@@ -2505,13 +2506,13 @@
                                 AccessSpecifier AS);
 
   void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
-                                  SourceLocation *TemplateArgLocs,
-                        llvm::SmallVector<TemplateArgument, 16> &TemplateArgs);
+                                  SourceLocation *TemplateArgLocsIn,
+                        llvm::SmallVector<TemplateArgumentLoc, 16> &TempArgs);
     
   QualType CheckTemplateIdType(TemplateName Template,
                                SourceLocation TemplateLoc,
                                SourceLocation LAngleLoc,
-                               const TemplateArgument *TemplateArgs,
+                               const TemplateArgumentLoc *TemplateArgs,
                                unsigned NumTemplateArgs,
                                SourceLocation RAngleLoc);
 
@@ -2532,7 +2533,7 @@
                                        TemplateName Template,
                                        SourceLocation TemplateNameLoc,
                                        SourceLocation LAngleLoc,
-                                       const TemplateArgument *TemplateArgs,
+                                       const TemplateArgumentLoc *TemplateArgs,
                                        unsigned NumTemplateArgs,
                                        SourceLocation RAngleLoc);
 
@@ -2587,7 +2588,7 @@
   bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
                                            bool HasExplicitTemplateArgs,
                                            SourceLocation LAngleLoc,
-                                  const TemplateArgument *ExplicitTemplateArgs,
+                            const TemplateArgumentLoc *ExplicitTemplateArgs,
                                            unsigned NumExplicitTemplateArgs,
                                            SourceLocation RAngleLoc,
                                            NamedDecl *&PrevDecl);
@@ -2627,18 +2628,18 @@
   bool CheckTemplateArgumentList(TemplateDecl *Template,
                                  SourceLocation TemplateLoc,
                                  SourceLocation LAngleLoc,
-                                 const TemplateArgument *TemplateArgs,
+                                 const TemplateArgumentLoc *TemplateArgs,
                                  unsigned NumTemplateArgs,
                                  SourceLocation RAngleLoc,
                                  bool PartialTemplateArgs,
                                  TemplateArgumentListBuilder &Converted);
 
   bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                 const TemplateArgument &Arg,
+                                 const TemplateArgumentLoc &Arg,
                                  TemplateArgumentListBuilder &Converted);
 
-  bool CheckTemplateArgument(TemplateTypeParmDecl *Param, QualType Arg,
-                             SourceLocation ArgLoc);
+  bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
+                             DeclaratorInfo *Arg);
   bool CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
                                                       NamedDecl *&Entity);
   bool CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member);
@@ -2813,7 +2814,7 @@
 
   TemplateDeductionResult
   SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                                const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                       unsigned NumExplicitTemplateArgs,
                             llvm::SmallVectorImpl<TemplateArgument> &Deduced,
                                  llvm::SmallVectorImpl<QualType> &ParamTypes,
@@ -2829,7 +2830,7 @@
   TemplateDeductionResult
   DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
                           bool HasExplicitTemplateArgs,
-                          const TemplateArgument *ExplicitTemplateArgs,
+                          const TemplateArgumentLoc *ExplicitTemplateArgs,
                           unsigned NumExplicitTemplateArgs,
                           Expr **Args, unsigned NumArgs,
                           FunctionDecl *&Specialization,
@@ -2838,7 +2839,7 @@
   TemplateDeductionResult
   DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
                           bool HasExplicitTemplateArgs,
-                          const TemplateArgument *ExplicitTemplateArgs,
+                          const TemplateArgumentLoc *ExplicitTemplateArgs,
                           unsigned NumExplicitTemplateArgs,
                           QualType ArgFunctionType,
                           FunctionDecl *&Specialization,
@@ -3220,8 +3221,8 @@
   TemplateName
   SubstTemplateName(TemplateName Name, SourceLocation Loc,
                     const MultiLevelTemplateArgumentList &TemplateArgs);
-  TemplateArgument Subst(TemplateArgument Arg,
-                         const MultiLevelTemplateArgumentList &TemplateArgs);
+  bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result,
+             const MultiLevelTemplateArgumentList &TemplateArgs);
 
   void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                      FunctionDecl *Function,

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Oct 29 03:12:44 2009
@@ -1234,7 +1234,7 @@
   SourceRange QualifierRange;
   bool ArgumentDependentLookup;
   bool HasExplicitTemplateArgs;
-  const TemplateArgument *ExplicitTemplateArgs;
+  const TemplateArgumentLoc *ExplicitTemplateArgs;
   unsigned NumExplicitTemplateArgs;
   
   DeconstructCallFunction(Fn,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Oct 29 03:12:44 2009
@@ -2796,7 +2796,7 @@
   // If the declarator is a template-id, translate the parser's template 
   // argument list into our AST format.
   bool HasExplicitTemplateArgs = false;
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   SourceLocation LAngleLoc, RAngleLoc;
   if (D.getKind() == Declarator::DK_TemplateId) {
     TemplateIdAnnotation *TemplateId = D.getTemplateId();

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct 29 03:12:44 2009
@@ -1959,7 +1959,7 @@
                                DeclarationName MemberName,
                                bool HasExplicitTemplateArgs,
                                SourceLocation LAngleLoc,
-                               const TemplateArgument *ExplicitTemplateArgs,
+                               const TemplateArgumentLoc *ExplicitTemplateArgs,
                                unsigned NumExplicitTemplateArgs,
                                SourceLocation RAngleLoc,
                                DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS,
@@ -2711,7 +2711,7 @@
                                    SourceRange &QualifierRange,
                                    bool &ArgumentDependentLookup,
                                    bool &HasExplicitTemplateArguments,
-                                 const TemplateArgument *&ExplicitTemplateArgs,
+                           const TemplateArgumentLoc *&ExplicitTemplateArgs,
                                    unsigned &NumExplicitTemplateArgs) {
   // Set defaults for all of the output parameters.
   Function = 0;
@@ -2892,7 +2892,7 @@
   // lookup and whether there were any explicitly-specified template arguments.
   bool ADL = true;
   bool HasExplicitTemplateArgs = 0;
-  const TemplateArgument *ExplicitTemplateArgs = 0;
+  const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
   unsigned NumExplicitTemplateArgs = 0;
   NestedNameSpecifier *Qualifier = 0;
   SourceRange QualifierRange;

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Oct 29 03:12:44 2009
@@ -2191,7 +2191,7 @@
                              TypeTy *T,
                              const CXXScopeSpec &SS,
                              bool HasTrailingLParen) {
-  QualType Type = QualType::getFromOpaquePtr(T);
+  QualType Type = GetTypeFromParser(T);
   CanQualType CanType = Context.getCanonicalType(Type);
   DeclarationName DtorName =
     Context.DeclarationNames.getCXXDestructorName(CanType);

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Oct 29 03:12:44 2009
@@ -2444,7 +2444,7 @@
 void
 Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
                                  bool HasExplicitTemplateArgs,
-                                 const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                  unsigned NumExplicitTemplateArgs,
                                  Expr *Object, Expr **Args, unsigned NumArgs,
                                  OverloadCandidateSet& CandidateSet,
@@ -2489,7 +2489,7 @@
 void
 Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
                                    bool HasExplicitTemplateArgs,
-                                 const TemplateArgument *ExplicitTemplateArgs,
+                          const TemplateArgumentLoc *ExplicitTemplateArgs,
                                    unsigned NumExplicitTemplateArgs,
                                    Expr **Args, unsigned NumArgs,
                                    OverloadCandidateSet& CandidateSet,
@@ -3886,7 +3886,7 @@
 Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
                                            Expr **Args, unsigned NumArgs,
                                            bool HasExplicitTemplateArgs,
-                                const TemplateArgument *ExplicitTemplateArgs,
+                            const TemplateArgumentLoc *ExplicitTemplateArgs,
                                            unsigned NumExplicitTemplateArgs,                                            
                                            OverloadCandidateSet& CandidateSet,
                                            bool PartialOverloading) {
@@ -4278,7 +4278,7 @@
   }
 
   bool HasExplicitTemplateArgs = false;
-  const TemplateArgument *ExplicitTemplateArgs = 0;
+  const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
   unsigned NumExplicitTemplateArgs = 0;
   
   // Try to dig out the overloaded function.
@@ -4451,7 +4451,7 @@
                                        AnyFunctionDecl Callee,
                                        bool &ArgumentDependentLookup,
                                        bool HasExplicitTemplateArgs,
-                                 const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                        unsigned NumExplicitTemplateArgs,
                                        Expr **Args, unsigned NumArgs,
                                        OverloadCandidateSet &CandidateSet,
@@ -4483,7 +4483,7 @@
                                        DeclarationName &UnqualifiedName,
                                        bool &ArgumentDependentLookup,
                                        bool HasExplicitTemplateArgs,
-                                  const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                        unsigned NumExplicitTemplateArgs,
                                        Expr **Args, unsigned NumArgs,
                                        OverloadCandidateSet &CandidateSet,
@@ -4551,7 +4551,7 @@
 FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
                                             DeclarationName UnqualifiedName,
                                             bool HasExplicitTemplateArgs,
-                                 const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                             unsigned NumExplicitTemplateArgs,
                                             SourceLocation LParenLoc,
                                             Expr **Args, unsigned NumArgs,

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Oct 29 03:12:44 2009
@@ -321,8 +321,11 @@
                                      TypeTy *DefaultT) {
   TemplateTypeParmDecl *Parm
     = cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
-  // FIXME: Preserve type source info.
-  QualType Default = GetTypeFromParser(DefaultT);
+
+  DeclaratorInfo *DefaultDInfo;
+  GetTypeFromParser(DefaultT, &DefaultDInfo);
+
+  assert(DefaultDInfo && "expected source information for type");
 
   // C++0x [temp.param]p9:
   // A default template-argument may be specified for any kind of
@@ -337,12 +340,12 @@
   // FIXME: Implement this check! Needs a recursive walk over the types.
 
   // Check the template argument itself.
-  if (CheckTemplateArgument(Parm, Default, DefaultLoc)) {
+  if (CheckTemplateArgument(Parm, DefaultDInfo)) {
     Parm->setInvalidDecl();
     return;
   }
 
-  Parm->setDefaultArgument(Default, DefaultLoc, false);
+  Parm->setDefaultArgument(DefaultDInfo, false);
 }
 
 /// \brief Check that the type of a non-type template parameter is
@@ -843,7 +846,7 @@
         SawParameterPack = true;
         ParameterPackLoc = NewTypeParm->getLocation();
       } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
-          NewTypeParm->hasDefaultArgument()) {
+                 NewTypeParm->hasDefaultArgument()) {
         OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
         NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
         SawDefaultArgument = true;
@@ -853,8 +856,7 @@
         // Merge the default argument from the old declaration to the
         // new declaration.
         SawDefaultArgument = true;
-        NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgument(),
-                                        OldTypeParm->getDefaultArgumentLoc(),
+        NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgumentInfo(),
                                         true);
         PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
       } else if (NewTypeParm->hasDefaultArgument()) {
@@ -1096,24 +1098,28 @@
 /// into template arguments used by semantic analysis.
 void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
                                       SourceLocation *TemplateArgLocs,
-                     llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
+                  llvm::SmallVector<TemplateArgumentLoc, 16> &TemplateArgs) {
   TemplateArgs.reserve(TemplateArgsIn.size());
 
   void **Args = TemplateArgsIn.getArgs();
   bool *ArgIsType = TemplateArgsIn.getArgIsType();
   for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
-    TemplateArgs.push_back(
-      ArgIsType[Arg]? TemplateArgument(TemplateArgLocs[Arg],
-                                       //FIXME: Preserve type source info.
-                                       Sema::GetTypeFromParser(Args[Arg]))
-                    : TemplateArgument(reinterpret_cast<Expr *>(Args[Arg])));
+    if (ArgIsType[Arg]) {
+      DeclaratorInfo *DI;
+      QualType T = Sema::GetTypeFromParser(Args[Arg], &DI);
+      if (!DI) DI = Context.getTrivialDeclaratorInfo(T, TemplateArgLocs[Arg]);
+      TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(T), DI));
+    } else {
+      Expr *E = reinterpret_cast<Expr *>(Args[Arg]);
+      TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
+    }
   }
 }
 
 QualType Sema::CheckTemplateIdType(TemplateName Name,
                                    SourceLocation TemplateLoc,
                                    SourceLocation LAngleLoc,
-                                   const TemplateArgument *TemplateArgs,
+                                   const TemplateArgumentLoc *TemplateArgs,
                                    unsigned NumTemplateArgs,
                                    SourceLocation RAngleLoc) {
   TemplateDecl *Template = Name.getAsTemplateDecl();
@@ -1155,7 +1161,7 @@
                                                    Converted.flatSize());
 
     // FIXME: CanonType is not actually the canonical type, and unfortunately
-    // it is a TemplateTypeSpecializationType that we will never use again.
+    // it is a TemplateSpecializationType that we will never use again.
     // In the future, we need to teach getTemplateSpecializationType to only
     // build the canonical type and return that to us.
     CanonType = Context.getCanonicalType(CanonType);
@@ -1190,7 +1196,6 @@
   // Build the fully-sugared type for this class template
   // specialization, which refers back to the class template
   // specialization we created or found.
-  //FIXME: Preserve type source info.
   return Context.getTemplateSpecializationType(Name, TemplateArgs,
                                                NumTemplateArgs, CanonType);
 }
@@ -1199,13 +1204,13 @@
 Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
                           SourceLocation LAngleLoc,
                           ASTTemplateArgsPtr TemplateArgsIn,
-                          SourceLocation *TemplateArgLocs,
+                          SourceLocation *TemplateArgLocsIn,
                           SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+  translateTemplateArguments(TemplateArgsIn, TemplateArgLocsIn, TemplateArgs);
 
   QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
                                         TemplateArgs.data(),
@@ -1216,7 +1221,16 @@
   if (Result.isNull())
     return true;
 
-  return Result.getAsOpaquePtr();
+  DeclaratorInfo *DI = Context.CreateDeclaratorInfo(Result);
+  TemplateSpecializationTypeLoc TL
+    = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+  TL.setTemplateNameLoc(TemplateLoc);
+  TL.setLAngleLoc(LAngleLoc);
+  TL.setRAngleLoc(RAngleLoc);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
+
+  return CreateLocInfoType(Result, DI).getAsOpaquePtr();
 }
 
 Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
@@ -1226,7 +1240,9 @@
   if (TypeResult.isInvalid())
     return Sema::TypeResult();
 
-  QualType Type = QualType::getFromOpaquePtr(TypeResult.get());
+  // FIXME: preserve source info, ideally without copying the DI.
+  DeclaratorInfo *DI;
+  QualType Type = GetTypeFromParser(TypeResult.get(), &DI);
 
   // Verify the tag specifier.
   TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
@@ -1256,7 +1272,7 @@
                                                  TemplateName Template,
                                                  SourceLocation TemplateNameLoc,
                                                  SourceLocation LAngleLoc,
-                                           const TemplateArgument *TemplateArgs,
+                                        const TemplateArgumentLoc *TemplateArgs,
                                                  unsigned NumTemplateArgs,
                                                  SourceLocation RAngleLoc) {
   // FIXME: Can we do any checking at this point? I guess we could check the
@@ -1296,13 +1312,13 @@
                                                  SourceLocation TemplateNameLoc,
                                                  SourceLocation LAngleLoc,
                                               ASTTemplateArgsPtr TemplateArgsIn,
-                                                SourceLocation *TemplateArgLocs,
+                                                SourceLocation *TemplateArgSLs,
                                                  SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+  translateTemplateArguments(TemplateArgsIn, TemplateArgSLs, TemplateArgs);
   TemplateArgsIn.release();
 
   return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
@@ -1336,7 +1352,7 @@
     Name = Template.getAsDependentTemplateName()->getName();
 
   // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
   TemplateArgsIn.release();
 
@@ -1397,8 +1413,10 @@
 }
 
 bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                     const TemplateArgument &Arg,
+                                     const TemplateArgumentLoc &AL,
                                      TemplateArgumentListBuilder &Converted) {
+  const TemplateArgument &Arg = AL.getArgument();
+
   // Check template type parameter.
   if (Arg.getKind() != TemplateArgument::Type) {
     // C++ [temp.arg.type]p1:
@@ -1407,19 +1425,18 @@
 
     // We have a template type parameter but the template argument
     // is not a type.
-    Diag(Arg.getLocation(), diag::err_template_arg_must_be_type);
+    Diag(AL.getLocation(), diag::err_template_arg_must_be_type);
     Diag(Param->getLocation(), diag::note_template_param_here);
 
     return true;
   }
 
-  if (CheckTemplateArgument(Param, Arg.getAsType(), Arg.getLocation()))
+  if (CheckTemplateArgument(Param, AL.getSourceDeclaratorInfo()))
     return true;
 
   // Add the converted template type argument.
   Converted.Append(
-                 TemplateArgument(Arg.getLocation(),
-                                  Context.getCanonicalType(Arg.getAsType())));
+                 TemplateArgument(Context.getCanonicalType(Arg.getAsType())));
   return false;
 }
 
@@ -1428,7 +1445,7 @@
 bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
                                      SourceLocation TemplateLoc,
                                      SourceLocation LAngleLoc,
-                                     const TemplateArgument *TemplateArgs,
+                                     const TemplateArgumentLoc *TemplateArgs,
                                      unsigned NumTemplateArgs,
                                      SourceLocation RAngleLoc,
                                      bool PartialTemplateArgs,
@@ -1474,7 +1491,8 @@
       break;
 
     // Decode the template argument
-    TemplateArgument Arg;
+    TemplateArgumentLoc Arg;
+
     if (ArgIdx >= NumArgs) {
       // Retrieve the default template argument from the template
       // parameter.
@@ -1489,11 +1507,11 @@
         if (!TTP->hasDefaultArgument())
           break;
 
-        QualType ArgType = TTP->getDefaultArgument();
+        DeclaratorInfo *ArgType = TTP->getDefaultArgumentInfo();
 
         // If the argument type is dependent, instantiate it now based
         // on the previously-computed template arguments.
-        if (ArgType->isDependentType()) {
+        if (ArgType->getType()->isDependentType()) {
           InstantiatingTemplate Inst(*this, TemplateLoc,
                                      Template, Converted.getFlatArguments(),
                                      Converted.flatSize(),
@@ -1507,10 +1525,10 @@
                               TTP->getDeclName());
         }
 
-        if (ArgType.isNull())
+        if (!ArgType)
           return true;
 
-        Arg = TemplateArgument(TTP->getLocation(), ArgType);
+        Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()), ArgType);
       } else if (NonTypeTemplateParmDecl *NTTP
                    = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
         if (!NTTP->hasDefaultArgument())
@@ -1530,7 +1548,8 @@
         if (E.isInvalid())
           return true;
 
-        Arg = TemplateArgument(E.takeAs<Expr>());
+        Expr *Ex = E.takeAs<Expr>();
+        Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
       } else {
         TemplateTemplateParmDecl *TempParm
           = cast<TemplateTemplateParmDecl>(*Param);
@@ -1539,7 +1558,8 @@
           break;
 
         // FIXME: Subst default argument
-        Arg = TemplateArgument(TempParm->getDefaultArgument());
+        // FIXME: preserve source information
+        Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument()));
       }
     } else {
       // Retrieve the template argument produced by the user.
@@ -1592,13 +1612,13 @@
         }
       }
 
-      switch (Arg.getKind()) {
+      switch (Arg.getArgument().getKind()) {
       case TemplateArgument::Null:
         assert(false && "Should never see a NULL template argument here");
         break;
 
       case TemplateArgument::Expression: {
-        Expr *E = Arg.getAsExpr();
+        Expr *E = Arg.getArgument().getAsExpr();
         TemplateArgument Result;
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
           Invalid = true;
@@ -1611,10 +1631,10 @@
       case TemplateArgument::Integral:
         // We've already checked this template argument, so just copy
         // it to the list of converted arguments.
-        Converted.Append(Arg);
+        Converted.Append(Arg.getArgument());
         break;
 
-      case TemplateArgument::Type:
+      case TemplateArgument::Type: {
         // We have a non-type template parameter but the template
         // argument is a type.
 
@@ -1625,14 +1645,16 @@
         //
         // We warn specifically about this case, since it can be rather
         // confusing for users.
-        if (Arg.getAsType()->isFunctionType())
+        QualType T = Arg.getArgument().getAsType();
+        if (T->isFunctionType())
           Diag(Arg.getLocation(), diag::err_template_arg_nontype_ambig)
-            << Arg.getAsType();
+            << T;
         else
           Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr);
         Diag((*Param)->getLocation(), diag::note_template_param_here);
         Invalid = true;
         break;
+      }
 
       case TemplateArgument::Pack:
         assert(0 && "FIXME: Implement!");
@@ -1643,13 +1665,13 @@
       TemplateTemplateParmDecl *TempParm
         = cast<TemplateTemplateParmDecl>(*Param);
 
-      switch (Arg.getKind()) {
+      switch (Arg.getArgument().getKind()) {
       case TemplateArgument::Null:
         assert(false && "Should never see a NULL template argument here");
         break;
 
       case TemplateArgument::Expression: {
-        Expr *ArgExpr = Arg.getAsExpr();
+        Expr *ArgExpr = Arg.getArgument().getAsExpr();
         if (ArgExpr && isa<DeclRefExpr>(ArgExpr) &&
             isa<TemplateDecl>(cast<DeclRefExpr>(ArgExpr)->getDecl())) {
           if (CheckTemplateArgument(TempParm, cast<DeclRefExpr>(ArgExpr)))
@@ -1658,7 +1680,7 @@
           // Add the converted template argument.
           Decl *D
             = cast<DeclRefExpr>(ArgExpr)->getDecl()->getCanonicalDecl();
-          Converted.Append(TemplateArgument(Arg.getLocation(), D));
+          Converted.Append(TemplateArgument(D));
           continue;
         }
       }
@@ -1675,7 +1697,7 @@
       case TemplateArgument::Declaration:
         // We've already checked this template argument, so just copy
         // it to the list of converted arguments.
-        Converted.Append(Arg);
+        Converted.Append(Arg.getArgument());
         break;
 
       case TemplateArgument::Integral:
@@ -1698,7 +1720,10 @@
 /// This routine implements the semantics of C++ [temp.arg.type]. It
 /// returns true if an error occurred, and false otherwise.
 bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
-                                 QualType Arg, SourceLocation ArgLoc) {
+                                 DeclaratorInfo *ArgInfo) {
+  assert(ArgInfo && "invalid DeclaratorInfo");
+  QualType Arg = ArgInfo->getType();
+
   // C++ [temp.arg.type]p2:
   //   A local type, a type with no linkage, an unnamed type or a type
   //   compounded from any of these types shall not be used as a
@@ -1710,12 +1735,14 @@
     Tag = EnumT;
   else if (const RecordType *RecordT = Arg->getAs<RecordType>())
     Tag = RecordT;
-  if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod())
-    return Diag(ArgLoc, diag::err_template_arg_local_type)
-      << QualType(Tag, 0);
-  else if (Tag && !Tag->getDecl()->getDeclName() &&
+  if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
+    SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+    return Diag(SR.getBegin(), diag::err_template_arg_local_type)
+      << QualType(Tag, 0) << SR;
+  } else if (Tag && !Tag->getDecl()->getDeclName() &&
            !Tag->getDecl()->getTypedefForAnonDecl()) {
-    Diag(ArgLoc, diag::err_template_arg_unnamed_type);
+    SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+    Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR;
     Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
     return true;
   }
@@ -2015,7 +2042,7 @@
       return false;
     }
 
-    Converted = TemplateArgument(StartLoc, Value,
+    Converted = TemplateArgument(Value,
                                  ParamType->isEnumeralType() ? ParamType
                                                              : IntegerType);
     return false;
@@ -2089,7 +2116,7 @@
 
       if (Member)
         Member = cast<NamedDecl>(Member->getCanonicalDecl());
-      Converted = TemplateArgument(StartLoc, Member);
+      Converted = TemplateArgument(Member);
       return false;
     }
 
@@ -2099,7 +2126,7 @@
 
     if (Entity)
       Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
-    Converted = TemplateArgument(StartLoc, Entity);
+    Converted = TemplateArgument(Entity);
     return false;
   }
 
@@ -2139,7 +2166,7 @@
 
     if (Entity)
       Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
-    Converted = TemplateArgument(StartLoc, Entity);
+    Converted = TemplateArgument(Entity);
     return false;
   }
 
@@ -2180,7 +2207,7 @@
       return true;
 
     Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
-    Converted = TemplateArgument(StartLoc, Entity);
+    Converted = TemplateArgument(Entity);
     return false;
   }
 
@@ -2210,7 +2237,7 @@
 
   if (Member)
     Member = cast<NamedDecl>(Member->getCanonicalDecl());
-  Converted = TemplateArgument(StartLoc, Member);
+  Converted = TemplateArgument(Member);
   return false;
 }
 
@@ -2722,7 +2749,7 @@
         if (TTP->hasDefaultArgument()) {
           Diag(TTP->getDefaultArgumentLoc(),
                diag::err_default_arg_in_partial_spec);
-          TTP->setDefaultArgument(QualType(), SourceLocation(), false);
+          TTP->removeDefaultArgument();
         }
       } else if (NonTypeTemplateParmDecl *NTTP
                    = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
@@ -2781,7 +2808,7 @@
   }
 
   // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
 
   // Check that the template argument list is well-formed for this
@@ -2889,6 +2916,8 @@
                                                        TemplateParams,
                                                        ClassTemplate,
                                                        Converted,
+                                                       TemplateArgs.data(),
+                                                       TemplateArgs.size(),
                                                        PrevPartial);
 
     if (PrevPartial) {
@@ -3268,7 +3297,7 @@
 Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
                                           bool HasExplicitTemplateArgs,
                                           SourceLocation LAngleLoc,
-                              const TemplateArgument *ExplicitTemplateArgs,
+                           const TemplateArgumentLoc *ExplicitTemplateArgs,
                                           unsigned NumExplicitTemplateArgs,
                                           SourceLocation RAngleLoc,
                                           NamedDecl *&PrevDecl) {
@@ -3624,7 +3653,7 @@
                            : TSK_ExplicitInstantiationDeclaration;
   
   // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
 
   // Check that the template argument list is well-formed for this
@@ -4003,7 +4032,7 @@
   // If the declarator is a template-id, translate the parser's template 
   // argument list into our AST format.
   bool HasExplicitTemplateArgs = false;
-  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   if (D.getKind() == Declarator::DK_TemplateId) {
     TemplateIdAnnotation *TemplateId = D.getTemplateId();
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
@@ -4310,25 +4339,13 @@
     /// refers to a member of the current instantiation, and then
     /// type-checking and building a QualifiedNameType (when possible).
     QualType TransformTypenameType(TypeLocBuilder &TLB, TypenameTypeLoc TL);
-    QualType TransformTypenameType(TypenameType *T);
   };
 }
 
 QualType
 CurrentInstantiationRebuilder::TransformTypenameType(TypeLocBuilder &TLB,
                                                      TypenameTypeLoc TL) {
-  QualType Result = TransformTypenameType(TL.getTypePtr());
-  if (Result.isNull())
-    return QualType();
-
-  TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
-
-  return Result;
-}
-
-QualType
-CurrentInstantiationRebuilder::TransformTypenameType(TypenameType *T) {
+  TypenameType *T = TL.getTypePtr();
 
   NestedNameSpecifier *NNS
     = TransformNestedNameSpecifier(T->getQualifier(),
@@ -4342,12 +4359,14 @@
   CXXScopeSpec SS;
   SS.setRange(SourceRange(getBaseLocation()));
   SS.setScopeRep(NNS);
+
+  QualType Result;
   if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0)
-    return QualType(T, 0);
+    Result = QualType(T, 0);
 
   // Rebuild the typename type, which will probably turn into a
   // QualifiedNameType.
-  if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
+  else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
     QualType NewTemplateId
       = TransformType(QualType(TemplateId, 0));
     if (NewTemplateId.isNull())
@@ -4355,12 +4374,16 @@
 
     if (NNS == T->getQualifier() &&
         NewTemplateId == QualType(TemplateId, 0))
-      return QualType(T, 0);
-
-    return getDerived().RebuildTypenameType(NNS, NewTemplateId);
-  }
+      Result = QualType(T, 0);
+    else
+      Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
+  } else
+    Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(),
+                                              SourceRange(TL.getNameLoc()));
 
-  return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
+  TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
+  NewTL.setNameLoc(TL.getNameLoc());
+  return Result;
 }
 
 /// \brief Rebuilds a type within the context of the current instantiation.

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Oct 29 03:12:44 2009
@@ -90,7 +90,7 @@
       Value.extOrTrunc(AllowedBits);
     Value.setIsSigned(T->isSignedIntegerType());
 
-    Deduced[NTTP->getIndex()] = TemplateArgument(SourceLocation(), Value, T);
+    Deduced[NTTP->getIndex()] = TemplateArgument(Value, T);
     return Sema::TDK_Success;
   }
 
@@ -102,7 +102,7 @@
   if (PrevValuePtr->isNegative()) {
     Info.Param = NTTP;
     Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
+    Info.SecondArg = TemplateArgument(Value, NTTP->getType());
     return Sema::TDK_Inconsistent;
   }
 
@@ -115,7 +115,7 @@
   if (Value != PrevValue) {
     Info.Param = NTTP;
     Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
+    Info.SecondArg = TemplateArgument(Value, NTTP->getType());
     return Sema::TDK_Inconsistent;
   }
 
@@ -433,7 +433,7 @@
     if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
       Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
       Info.FirstArg = Deduced[Index];
-      Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
+      Info.SecondArg = TemplateArgument(Arg);
       return Sema::TDK_InconsistentQuals;
     }
 
@@ -445,7 +445,7 @@
       DeducedType = Context.getCanonicalType(DeducedType);
 
     if (Deduced[Index].isNull())
-      Deduced[Index] = TemplateArgument(SourceLocation(), DeducedType);
+      Deduced[Index] = TemplateArgument(DeducedType);
     else {
       // C++ [temp.deduct.type]p2:
       //   [...] If type deduction cannot be done for any P/A pair, or if for
@@ -457,7 +457,7 @@
         Info.Param
           = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
         Info.FirstArg = Deduced[Index];
-        Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
+        Info.SecondArg = TemplateArgument(Arg);
         return Sema::TDK_Inconsistent;
       }
     }
@@ -465,8 +465,8 @@
   }
 
   // Set up the template argument deduction information for a failure.
-  Info.FirstArg = TemplateArgument(SourceLocation(), ParamIn);
-  Info.SecondArg = TemplateArgument(SourceLocation(), ArgIn);
+  Info.FirstArg = TemplateArgument(ParamIn);
+  Info.SecondArg = TemplateArgument(ArgIn);
 
   // Check the cv-qualifiers on the parameter and argument types.
   if (!(TDF & TDF_IgnoreQualifiers)) {
@@ -982,18 +982,41 @@
   // and are equivalent to the template arguments originally provided
   // to the class template.
   ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
-  const TemplateArgumentList &PartialTemplateArgs = Partial->getTemplateArgs();
-  for (unsigned I = 0, N = PartialTemplateArgs.flat_size(); I != N; ++I) {
+  const TemplateArgumentLoc *PartialTemplateArgs
+    = Partial->getTemplateArgsAsWritten();
+  unsigned N = Partial->getNumTemplateArgsAsWritten();
+  llvm::SmallVector<TemplateArgumentLoc, 16> InstArgs(N);
+  for (unsigned I = 0; I != N; ++I) {
     Decl *Param = const_cast<NamedDecl *>(
                     ClassTemplate->getTemplateParameters()->getParam(I));
-    TemplateArgument InstArg
-      = Subst(PartialTemplateArgs[I],
-              MultiLevelTemplateArgumentList(*DeducedArgumentList));
-    if (InstArg.isNull()) {
+    if (Subst(PartialTemplateArgs[I], InstArgs[I],
+              MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
       Info.Param = makeTemplateParameter(Param);
-      Info.FirstArg = PartialTemplateArgs[I];
+      Info.FirstArg = PartialTemplateArgs[I].getArgument();
       return TDK_SubstitutionFailure;
     }
+  }
+
+  TemplateArgumentListBuilder ConvertedInstArgs(
+                                  ClassTemplate->getTemplateParameters(), N);
+
+  if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
+                                /*LAngle*/ SourceLocation(),
+                                InstArgs.data(), N,
+                                /*RAngle*/ SourceLocation(),
+                                false, ConvertedInstArgs)) {
+    // FIXME: fail with more useful information?
+    return TDK_SubstitutionFailure;
+  }
+  
+  for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
+    // We don't really care if we overwrite the internal structures of
+    // the arg list builder, because we're going to throw it all away.
+    TemplateArgument &InstArg
+      = const_cast<TemplateArgument&>(ConvertedInstArgs.getFlatArguments()[I]);
+
+    Decl *Param = const_cast<NamedDecl *>(
+                    ClassTemplate->getTemplateParameters()->getParam(I));
 
     if (InstArg.getKind() == TemplateArgument::Expression) {
       // When the argument is an expression, check the expression result
@@ -1004,7 +1027,7 @@
             = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
         if (CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
           Info.Param = makeTemplateParameter(Param);
-          Info.FirstArg = PartialTemplateArgs[I];
+          Info.FirstArg = Partial->getTemplateArgs()[I];
           return TDK_SubstitutionFailure;
         }
       } else if (TemplateTemplateParmDecl *TTP
@@ -1013,7 +1036,7 @@
         DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InstExpr);
         if (!DRE || CheckTemplateArgument(TTP, DRE)) {
           Info.Param = makeTemplateParameter(Param);
-          Info.FirstArg = PartialTemplateArgs[I];
+          Info.FirstArg = Partial->getTemplateArgs()[I];
           return TDK_SubstitutionFailure;
         }
       }
@@ -1072,7 +1095,7 @@
 Sema::TemplateDeductionResult
 Sema::SubstituteExplicitTemplateArguments(
                                       FunctionTemplateDecl *FunctionTemplate,
-                                const TemplateArgument *ExplicitTemplateArgs,
+                             const TemplateArgumentLoc *ExplicitTemplateArgs,
                                           unsigned NumExplicitTemplateArgs,
                             llvm::SmallVectorImpl<TemplateArgument> &Deduced,
                                  llvm::SmallVectorImpl<QualType> &ParamTypes,
@@ -1290,7 +1313,7 @@
 Sema::TemplateDeductionResult
 Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
                               bool HasExplicitTemplateArgs,
-                              const TemplateArgument *ExplicitTemplateArgs,
+                              const TemplateArgumentLoc *ExplicitTemplateArgs,
                               unsigned NumExplicitTemplateArgs,
                               Expr **Args, unsigned NumArgs,
                               FunctionDecl *&Specialization,
@@ -1460,7 +1483,7 @@
 Sema::TemplateDeductionResult
 Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
                               bool HasExplicitTemplateArgs,
-                              const TemplateArgument *ExplicitTemplateArgs,
+                              const TemplateArgumentLoc *ExplicitTemplateArgs,
                               unsigned NumExplicitTemplateArgs,
                               QualType ArgFunctionType,
                               FunctionDecl *&Specialization,

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Oct 29 03:12:44 2009
@@ -1261,9 +1261,10 @@
   return Instantiator.TransformTemplateName(Name);
 }
 
-TemplateArgument Sema::Subst(TemplateArgument Arg,
-                         const MultiLevelTemplateArgumentList &TemplateArgs) {
+bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
+                 const MultiLevelTemplateArgumentList &TemplateArgs) {
   TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
                                     DeclarationName());
-  return Instantiator.TransformTemplateArgument(Arg);
+
+  return Instantiator.TransformTemplateArgument(Input, Output);
 }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Oct 29 03:12:44 2009
@@ -886,14 +886,13 @@
   // FIXME: Do we actually want to perform substitution here? I don't think
   // we do.
   if (D->hasDefaultArgument()) {
-    QualType DefaultPattern = D->getDefaultArgument();
-    QualType DefaultInst
+    DeclaratorInfo *DefaultPattern = D->getDefaultArgumentInfo();
+    DeclaratorInfo *DefaultInst
       = SemaRef.SubstType(DefaultPattern, TemplateArgs,
                           D->getDefaultArgumentLoc(),
                           D->getDeclName());
 
     Inst->setDefaultArgument(DefaultInst,
-                             D->getDefaultArgumentLoc(),
                              D->defaultArgumentWasInherited() /* preserve? */);
   }
 
@@ -1026,16 +1025,15 @@
   
   // Substitute into the template arguments of the class template partial
   // specialization.
-  const TemplateArgumentList &PartialSpecTemplateArgs 
-    = PartialSpec->getTemplateInstantiationArgs();
-  llvm::SmallVector<TemplateArgument, 4> InstTemplateArgs;
-  for (unsigned I = 0, N = PartialSpecTemplateArgs.size(); I != N; ++I) {
-    TemplateArgument Inst = SemaRef.Subst(PartialSpecTemplateArgs[I], 
-                                          TemplateArgs);
-    if (Inst.isNull())
+  const TemplateArgumentLoc *PartialSpecTemplateArgs
+    = PartialSpec->getTemplateArgsAsWritten();
+  unsigned N = PartialSpec->getNumTemplateArgsAsWritten();
+
+  llvm::SmallVector<TemplateArgumentLoc, 4> InstTemplateArgs(N);
+  for (unsigned I = 0; I != N; ++I) {
+    if (SemaRef.Subst(PartialSpecTemplateArgs[I], InstTemplateArgs[I],
+                      TemplateArgs))
       return true;
-    
-    InstTemplateArgs.push_back(Inst);
   }
   
 
@@ -1116,6 +1114,8 @@
                                                      InstParams,
                                                      ClassTemplate, 
                                                      Converted,
+                                                     InstTemplateArgs.data(),
+                                                     InstTemplateArgs.size(),
                                                      0);
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Oct 29 03:12:44 2009
@@ -1328,6 +1328,21 @@
         Visit(TL.getBaseTypeLoc());
       }
     }
+    void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+      DeclaratorInfo *DInfo = 0;
+      Sema::GetTypeFromParser(DS.getTypeRep(), &DInfo);
+
+      // If we got no declarator info from previous Sema routines,
+      // just fill with the typespec loc.
+      if (!DInfo) {
+        TL.initialize(DS.getTypeSpecTypeLoc());
+        return;
+      }
+
+      TemplateSpecializationTypeLoc OldTL =
+        cast<TemplateSpecializationTypeLoc>(DInfo->getTypeLoc());
+      TL.copy(OldTL);
+    }
     void VisitTypeLoc(TypeLoc TL) {
       // FIXME: add other typespec types and change this to an assert.
       TL.initialize(DS.getTypeSpecTypeLoc());

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=85500&r1=85499&r2=85500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Oct 29 03:12:44 2009
@@ -290,7 +290,20 @@
   /// declaration stored within the template argument and constructs a
   /// new template argument from the transformed result. Subclasses may
   /// override this function to provide alternate behavior.
-  TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
+  ///
+  /// Returns true if there was an error.
+  bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
+                                 TemplateArgumentLoc &Output);
+
+  /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
+  void InventTemplateArgumentLoc(const TemplateArgument &Arg,
+                                 TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Fakes up a DeclaratorInfo for a type.
+  DeclaratorInfo *InventDeclaratorInfo(QualType T) {
+    return SemaRef.Context.getTrivialDeclaratorInfo(T,
+                       getDerived().getBaseLocation());
+  }
 
 #define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT)                                   \
@@ -300,6 +313,11 @@
   QualType 
   TransformTemplateSpecializationType(const TemplateSpecializationType *T,
                                       QualType ObjectType);
+
+  QualType
+  TransformTemplateSpecializationType(TypeLocBuilder &TLB,
+                                      TemplateSpecializationTypeLoc TL,
+                                      QualType ObjectType);
   
   OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
 
@@ -478,8 +496,11 @@
   /// specialization type. Subclasses may override this routine to provide
   /// different behavior.
   QualType RebuildTemplateSpecializationType(TemplateName Template,
-                                             const TemplateArgument *Args,
-                                             unsigned NumArgs);
+                                             SourceLocation TemplateLoc,
+                                             SourceLocation LAngleLoc,
+                                             const TemplateArgumentLoc *Args,
+                                             unsigned NumArgs,
+                                             SourceLocation RAngleLoc);
 
   /// \brief Build a new qualified name type.
   ///
@@ -509,9 +530,9 @@
   /// (or qualified name type). Subclasses may override this routine to provide
   /// different behavior.
   QualType RebuildTypenameType(NestedNameSpecifier *NNS,
-                               const IdentifierInfo *Id) {
-    return SemaRef.CheckTypenameType(NNS, *Id,
-                                  SourceRange(getDerived().getBaseLocation()));
+                               const IdentifierInfo *Id,
+                               SourceRange SR) {
+    return SemaRef.CheckTypenameType(NNS, *Id, SR);
   }
 
   /// \brief Build a new nested-name-specifier given the prefix and an
@@ -1427,7 +1448,7 @@
                                          TemplateName Template,
                                          SourceLocation TemplateLoc,
                                          SourceLocation LAngleLoc,
-                                         TemplateArgument *TemplateArgs,
+                                         TemplateArgumentLoc *TemplateArgs,
                                          unsigned NumTemplateArgs,
                                          SourceLocation RAngleLoc) {
     return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
@@ -1530,7 +1551,7 @@
                                                 SourceLocation TemplateNameLoc,
                                               NamedDecl *FirstQualifierInScope,
                                                   SourceLocation LAngleLoc,
-                                          const TemplateArgument *TemplateArgs,
+                                       const TemplateArgumentLoc *TemplateArgs,
                                                   unsigned NumTemplateArgs,
                                                   SourceLocation RAngleLoc) {
     OwningExprResult Base = move(BaseE);
@@ -1876,30 +1897,67 @@
 }
 
 template<typename Derived>
-TemplateArgument
-TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
+void TreeTransform<Derived>::InventTemplateArgumentLoc(
+                                         const TemplateArgument &Arg,
+                                         TemplateArgumentLoc &Output) {
+  SourceLocation Loc = getDerived().getBaseLocation();
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    llvm::llvm_unreachable("null template argument in TreeTransform");
+    break;
+
+  case TemplateArgument::Type:
+    Output = TemplateArgumentLoc(Arg,
+               SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
+                                            
+    break;
+
+  case TemplateArgument::Expression:
+    Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
+    break;
+
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Pack:
+    Output = TemplateArgumentLoc(Arg);
+    break;
+  }
+}
+
+template<typename Derived>
+bool TreeTransform<Derived>::TransformTemplateArgument(
+                                         const TemplateArgumentLoc &Input,
+                                         TemplateArgumentLoc &Output) {
+  const TemplateArgument &Arg = Input.getArgument();
   switch (Arg.getKind()) {
   case TemplateArgument::Null:
   case TemplateArgument::Integral:
-    return Arg;
+    Output = Input;
+    return false;
 
   case TemplateArgument::Type: {
-    TemporaryBase Rebase(*this, Arg.getLocation(), DeclarationName());
-    QualType T = getDerived().TransformType(Arg.getAsType());
-    if (T.isNull())
-      return TemplateArgument();
-    return TemplateArgument(Arg.getLocation(), T);
+    DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
+    if (DI == NULL)
+      DI = InventDeclaratorInfo(Input.getArgument().getAsType());
+
+    DI = getDerived().TransformType(DI);
+    if (!DI) return true;
+
+    Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
+    return false;
   }
 
   case TemplateArgument::Declaration: {
+    // FIXME: we should never have to transform one of these.
     DeclarationName Name;
     if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
       Name = ND->getDeclName();
-    TemporaryBase Rebase(*this, Arg.getLocation(), Name);
+    TemporaryBase Rebase(*this, SourceLocation(), Name);
     Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
-    if (!D)
-      return TemplateArgument();
-    return TemplateArgument(Arg.getLocation(), D);
+    if (!D) return true;
+
+    Output = TemplateArgumentLoc(TemplateArgument(D));
+    return false;
   }
 
   case TemplateArgument::Expression: {
@@ -1907,10 +1965,16 @@
     EnterExpressionEvaluationContext Unevaluated(getSema(),
                                                  Action::Unevaluated);
 
-    Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
-    if (E.isInvalid())
-      return TemplateArgument();
-    return TemplateArgument(E.takeAs<Expr>());
+    Expr *InputExpr = Input.getSourceExpression();
+    if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
+
+    Sema::OwningExprResult E
+      = getDerived().TransformExpr(InputExpr);
+    if (E.isInvalid()) return true;
+
+    Expr *ETaken = E.takeAs<Expr>();
+    Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+    return false;
   }
 
   case TemplateArgument::Pack: {
@@ -1919,21 +1983,28 @@
     for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
                                       AEnd = Arg.pack_end();
          A != AEnd; ++A) {
-      TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
-      if (TA.isNull())
-        return TA;
 
-      TransformedArgs.push_back(TA);
+      // FIXME: preserve source information here when we start
+      // caring about parameter packs.
+
+      TemplateArgumentLoc Input;
+      TemplateArgumentLoc Output;
+      getDerived().InventTemplateArgumentLoc(*A, Input);
+      if (getDerived().TransformTemplateArgument(Input, Output))
+        return true;
+
+      TransformedArgs.push_back(Output.getArgument());
     }
     TemplateArgument Result;
     Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
                            true);
-    return Result;
+    Output = TemplateArgumentLoc(Result);
+    return false;
   }
   }
 
   // Work around bogus GCC warning
-  return TemplateArgument();
+  return true;
 }
 
 //===----------------------------------------------------------------------===//
@@ -2678,46 +2749,74 @@
 TreeTransform<Derived>::TransformTemplateSpecializationType(
                                           TypeLocBuilder &TLB,
                                           TemplateSpecializationTypeLoc TL) {
-  // TODO: figure out how make this work with an ObjectType.
-  QualType Result
-    = TransformTemplateSpecializationType(TL.getTypePtr(), QualType());
-  if (Result.isNull())
-    return QualType();
+  return TransformTemplateSpecializationType(TLB, TL, QualType());
+}
 
-  TemplateSpecializationTypeLoc NewTL
-    = TLB.push<TemplateSpecializationTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
+                                      const TemplateSpecializationType *TST,
+                                                        QualType ObjectType) {
+  // FIXME: this entire method is a temporary workaround; callers
+  // should be rewritten to provide real type locs.
 
-  return Result;
+  // Fake up a TemplateSpecializationTypeLoc.
+  TypeLocBuilder TLB;
+  TemplateSpecializationTypeLoc TL
+    = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
+
+  TL.setTemplateNameLoc(getDerived().getBaseLocation());
+  TL.setLAngleLoc(SourceLocation());
+  TL.setRAngleLoc(SourceLocation());
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+    const TemplateArgument &TA = TST->getArg(i);
+    TemplateArgumentLoc TAL;
+    getDerived().InventTemplateArgumentLoc(TA, TAL);
+    TL.setArgLocInfo(i, TAL.getLocInfo());
+  }
+
+  TypeLocBuilder IgnoredTLB;
+  return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
 }
   
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
-                                        const TemplateSpecializationType *T,
-                                                          QualType ObjectType) {
+                                                        TypeLocBuilder &TLB,
+                                           TemplateSpecializationTypeLoc TL,
+                                                        QualType ObjectType) {
+  const TemplateSpecializationType *T = TL.getTypePtr();
+
   TemplateName Template
     = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
   if (Template.isNull())
     return QualType();
 
-  llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
-  NewTemplateArgs.reserve(T->getNumArgs());
-  for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
-       Arg != ArgEnd; ++Arg) {
-    TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
-    if (NewArg.isNull())
+  llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
+    if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
+                                               NewTemplateArgs[i]))
       return QualType();
 
-    NewTemplateArgs.push_back(NewArg);
-  }
+  // FIXME: maybe don't rebuild if all the template arguments are the same.
 
-  // FIXME: early abort if all of the template arguments and such are the
-  // same.
+  QualType Result =
+    getDerived().RebuildTemplateSpecializationType(Template,
+                                                   TL.getTemplateNameLoc(),
+                                                   TL.getLAngleLoc(),
+                                                   NewTemplateArgs.data(),
+                                                   NewTemplateArgs.size(),
+                                                   TL.getRAngleLoc());
+
+  if (!Result.isNull()) {
+    TemplateSpecializationTypeLoc NewTL
+      = TLB.push<TemplateSpecializationTypeLoc>(Result);
+    NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
+    NewTL.setLAngleLoc(TL.getLAngleLoc());
+    NewTL.setRAngleLoc(TL.getRAngleLoc());
+    for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
+      NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
+  }
 
-  // FIXME: We're missing the locations of the template name, '<', and '>'.
-  return getDerived().RebuildTemplateSpecializationType(Template,
-                                                        NewTemplateArgs.data(),
-                                                        NewTemplateArgs.size());
+  return Result;
 }
 
 template<typename Derived>
@@ -2754,9 +2853,12 @@
 QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
                                                        TypenameTypeLoc TL) {
   TypenameType *T = TL.getTypePtr();
+
+  /* FIXME: preserve source information better than this */
+  SourceRange SR(TL.getNameLoc());
+
   NestedNameSpecifier *NNS
-    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
-                        SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
   if (!NNS)
     return QualType();
 
@@ -2775,7 +2877,7 @@
 
     Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
   } else {
-    Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier());
+    Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
   }
   if (Result.isNull())
     return QualType();
@@ -3287,14 +3389,11 @@
 
   // FIXME: We're losing the explicit template arguments in this transformation.
 
-  llvm::SmallVector<TemplateArgument, 4> TransArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
-    TemplateArgument TransArg
-      = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
-    if (TransArg.isNull())
+    if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+                                               TransArgs[I]))
       return SemaRef.ExprError();
-    
-    TransArgs.push_back(TransArg);
   }
   
   // FIXME: Pass the qualifier/qualifier range along.
@@ -4367,14 +4466,11 @@
       return SemaRef.ExprError();
   }
   
-  llvm::SmallVector<TemplateArgument, 4> TransArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
-    TemplateArgument TransArg
-      = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
-    if (TransArg.isNull())
+    if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+                                               TransArgs[I]))
       return SemaRef.ExprError();
-
-    TransArgs.push_back(TransArg);
   }
 
   // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
@@ -4627,14 +4723,11 @@
   if (Template.isNull())
     return SemaRef.ExprError();
 
-  llvm::SmallVector<TemplateArgument, 4> TransArgs;
+  llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
-    TemplateArgument TransArg
-    = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
-    if (TransArg.isNull())
+    if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+                                               TransArgs[I]))
       return SemaRef.ExprError();
-
-    TransArgs.push_back(TransArg);
   }
 
   return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
@@ -4980,13 +5073,14 @@
 
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
-                                                        TemplateName Template,
-                                                 const TemplateArgument *Args,
-                                                           unsigned NumArgs) {
-  // FIXME: Missing source locations for the template name, <, >.
-  return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
-                                     SourceLocation(), Args, NumArgs,
-                                     SourceLocation());
+                                                      TemplateName Template,
+                                             SourceLocation TemplateNameLoc,
+                                                   SourceLocation LAngleLoc,
+                                            const TemplateArgumentLoc *Args,
+                                                           unsigned NumArgs,
+                                                   SourceLocation RAngleLoc) {
+  return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
+                                     Args, NumArgs, RAngleLoc);
 }
 
 template<typename Derived>





More information about the cfe-commits mailing list