[cfe-commits] r86708 - in /cfe/trunk: include/clang/Lex/Token.h include/clang/Parse/Action.h include/clang/Parse/DeclSpec.h include/clang/Parse/Ownership.h include/clang/Parse/Parser.h include/clang/Parse/Template.h lib/Parse/DeclSpec.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp

Douglas Gregor dgregor at apple.com
Tue Nov 10 11:49:08 PST 2009


Author: dgregor
Date: Tue Nov 10 13:49:08 2009
New Revision: 86708

URL: http://llvm.org/viewvc/llvm-project?rev=86708&view=rev
Log:
Improve parsing of template arguments to lay the foundation for
handling template template parameters properly. This refactoring:

  - Parses template template arguments as id-expressions, representing
    the result of the parse as a template name (Action::TemplateTy)
    rather than as an expression (lame!).

  - Represents all parsed template arguments via a new parser-specific
    type, ParsedTemplateArgument, which stores the kind of template
    argument (type, non-type, template) along with all of the source
    information about the template argument. This replaces an ad hoc
    set of 3 vectors (one for a void*, which was either a type or an
    expression; one for a bit telling whether the first was a type or
    an expression; and one for a single source location pointing at
    the template argument).

  - Moves TemplateIdAnnotation into the new Parse/Template.h. It never
    belonged in the Basic library anyway.


Added:
    cfe/trunk/include/clang/Parse/Template.h   (with props)
Modified:
    cfe/trunk/include/clang/Lex/Token.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/include/clang/Parse/Ownership.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/DeclSpec.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Lex/Token.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Token.h?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/Token.h (original)
+++ cfe/trunk/include/clang/Lex/Token.h Tue Nov 10 13:49:08 2009
@@ -248,69 +248,6 @@
   bool FoundElse;
 };
 
-/// TemplateIdAnnotation - Information about a template-id annotation
-/// token, which contains the template declaration, template
-/// arguments, whether those template arguments were types or
-/// expressions, and the source locations for important tokens. All of
-/// the information about template arguments is allocated directly
-/// after this structure.
-struct TemplateIdAnnotation {
-  /// TemplateNameLoc - The location of the template name within the
-  /// source.
-  SourceLocation TemplateNameLoc;
-
-  /// FIXME: Temporarily stores the name of a specialization
-  IdentifierInfo *Name;
-
-  /// FIXME: Temporarily stores the overloaded operator kind.
-  OverloadedOperatorKind Operator;
-  
-  /// The declaration of the template corresponding to the
-  /// template-name. This is an Action::DeclTy*.
-  void *Template;
-
-  /// The kind of template that Template refers to.
-  TemplateNameKind Kind;
-
-  /// The location of the '<' before the template argument
-  /// list.
-  SourceLocation LAngleLoc;
-
-  /// The location of the '>' after the template argument
-  /// list.
-  SourceLocation RAngleLoc;
-
-  /// NumArgs - The number of template arguments.
-  unsigned NumArgs;
-
-  /// \brief Retrieves a pointer to the template arguments
-  void **getTemplateArgs() { return (void **)(this + 1); }
-
-  /// \brief Retrieves a pointer to the array of template argument
-  /// locations.
-  SourceLocation *getTemplateArgLocations() {
-    return (SourceLocation *)(getTemplateArgs() + NumArgs);
-  }
-
-  /// \brief Retrieves a pointer to the array of flags that states
-  /// whether the template arguments are types.
-  bool *getTemplateArgIsType() {
-    return (bool *)(getTemplateArgLocations() + NumArgs);
-  }
-
-  static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
-    TemplateIdAnnotation *TemplateId
-      = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
-                                            sizeof(void*) * NumArgs +
-                                            sizeof(SourceLocation) * NumArgs +
-                                            sizeof(bool) * NumArgs);
-    TemplateId->NumArgs = NumArgs;
-    return TemplateId;
-  }
-
-  void Destroy() { free(this); }
-};
-
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Nov 10 13:49:08 2009
@@ -1632,7 +1632,6 @@
                                          SourceLocation TemplateLoc,
                                          SourceLocation LAngleLoc,
                                          ASTTemplateArgsPtr TemplateArgs,
-                                         SourceLocation *TemplateArgLocs,
                                          SourceLocation RAngleLoc) {
     return TypeResult();
   };
@@ -1737,7 +1736,6 @@
                                    SourceLocation TemplateNameLoc,
                                    SourceLocation LAngleLoc,
                                    ASTTemplateArgsPtr TemplateArgs,
-                                   SourceLocation *TemplateArgLocs,
                                    SourceLocation RAngleLoc,
                                    AttributeList *Attr,
                               MultiTemplateParamsArg TemplateParameterLists) {
@@ -1817,7 +1815,6 @@
                              SourceLocation TemplateNameLoc,
                              SourceLocation LAngleLoc,
                              ASTTemplateArgsPtr TemplateArgs,
-                             SourceLocation *TemplateArgLocs,
                              SourceLocation RAngleLoc,
                              AttributeList *Attr) {
     return DeclResult();

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Tue Nov 10 13:49:08 2009
@@ -25,7 +25,8 @@
   class IdentifierInfo;
   class Preprocessor;
   class Declarator;
-
+  struct TemplateIdAnnotation;
+  
 /// DeclSpec - This class captures information about "declaration specifiers",
 /// which encompasses storage-class-specifiers, type-specifiers,
 /// type-qualifiers, and function-specifiers.
@@ -642,13 +643,7 @@
   /// \param TemplateId the template-id annotation that describes the parsed
   /// template-id. This UnqualifiedId instance will take ownership of the
   /// \p TemplateId and will free it on destruction.
-  void setTemplateId(TemplateIdAnnotation *TemplateId) {
-    assert(TemplateId && "NULL template-id annotation?");
-    Kind = IK_TemplateId;
-    this->TemplateId = TemplateId;
-    StartLocation = TemplateId->TemplateNameLoc;
-    EndLocation = TemplateId->RAngleLoc;
-  }
+  void setTemplateId(TemplateIdAnnotation *TemplateId);
 
   /// \brief Return the source range that covers this unqualified-id.
   SourceRange getSourceRange() const { 

Modified: cfe/trunk/include/clang/Parse/Ownership.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Ownership.h?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Ownership.h (original)
+++ cfe/trunk/include/clang/Parse/Ownership.h Tue Nov 10 13:49:08 2009
@@ -654,41 +654,33 @@
 #endif
   };
 
+  class ParsedTemplateArgument;
+    
   class ASTTemplateArgsPtr {
 #if !defined(DISABLE_SMART_POINTERS)
     ActionBase &Actions;
 #endif
-    void **Args;
-    bool *ArgIsType;
+    ParsedTemplateArgument *Args;
     mutable unsigned Count;
 
 #if !defined(DISABLE_SMART_POINTERS)
-    void destroy() {
-      if (!Count)
-        return;
-
-      for (unsigned i = 0; i != Count; ++i)
-        if (Args[i] && !ArgIsType[i])
-          Actions.DeleteExpr((ActionBase::ExprTy *)Args[i]);
-
-      Count = 0;
-    }
+    void destroy();
 #endif
-
+    
   public:
-    ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType,
+    ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
                        unsigned count) :
 #if !defined(DISABLE_SMART_POINTERS)
       Actions(actions),
 #endif
-      Args(args), ArgIsType(argIsType), Count(count) { }
+      Args(args), Count(count) { }
 
     // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
     ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
 #if !defined(DISABLE_SMART_POINTERS)
       Actions(Other.Actions),
 #endif
-      Args(Other.Args), ArgIsType(Other.ArgIsType), Count(Other.Count) {
+      Args(Other.Args), Count(Other.Count) {
 #if !defined(DISABLE_SMART_POINTERS)
       Other.Count = 0;
 #endif
@@ -700,7 +692,6 @@
       Actions = Other.Actions;
 #endif
       Args = Other.Args;
-      ArgIsType = Other.ArgIsType;
       Count = Other.Count;
 #if !defined(DISABLE_SMART_POINTERS)
       Other.Count = 0;
@@ -712,22 +703,20 @@
     ~ASTTemplateArgsPtr() { destroy(); }
 #endif
 
-    void **getArgs() const { return Args; }
-    bool *getArgIsType() const {return ArgIsType; }
+    ParsedTemplateArgument *getArgs() const { return Args; }
     unsigned size() const { return Count; }
 
-    void reset(void **args, bool *argIsType, unsigned count) {
+    void reset(ParsedTemplateArgument *args, unsigned count) {
 #if !defined(DISABLE_SMART_POINTERS)
       destroy();
 #endif
       Args = args;
-      ArgIsType = argIsType;
       Count = count;
     }
 
-    void *operator[](unsigned Arg) const { return Args[Arg]; }
+    const ParsedTemplateArgument &operator[](unsigned Arg) const;
 
-    void **release() const {
+    ParsedTemplateArgument *release() const {
 #if !defined(DISABLE_SMART_POINTERS)
       Count = 0;
 #endif

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Nov 10 13:49:08 2009
@@ -331,7 +331,7 @@
   /// either "commit the consumed tokens" or revert to the previously marked
   /// token position. Example:
   ///
-  ///   TentativeParsingAction TPA;
+  ///   TentativeParsingAction TPA(*this);
   ///   ConsumeToken();
   ///   ....
   ///   TPA.Revert();
@@ -1347,9 +1347,7 @@
   DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
   DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
   // C++ 14.3: Template arguments [temp.arg]
-  typedef llvm::SmallVector<void *, 16> TemplateArgList;
-  typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
-  typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList;
+  typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
 
   bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
                                         SourceLocation TemplateNameLoc,
@@ -1357,8 +1355,6 @@
                                         bool ConsumeLastToken,
                                         SourceLocation &LAngleLoc,
                                         TemplateArgList &TemplateArgs,
-                                    TemplateArgIsTypeList &TemplateArgIsType,
-                               TemplateArgLocationList &TemplateArgLocations,
                                         SourceLocation &RAngleLoc);
 
   bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
@@ -1367,10 +1363,8 @@
                                SourceLocation TemplateKWLoc = SourceLocation(),
                                bool AllowTypeAnnotation = true);
   void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
-  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
-                                 TemplateArgIsTypeList &TemplateArgIsType,
-                                 TemplateArgLocationList &TemplateArgLocations);
-  void *ParseTemplateArgument(bool &ArgIsType);
+  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+  ParsedTemplateArgument ParseTemplateArgument();
   DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
                                        SourceLocation TemplateLoc,
                                        SourceLocation &DeclEnd);

Added: cfe/trunk/include/clang/Parse/Template.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Template.h?rev=86708&view=auto

==============================================================================
--- cfe/trunk/include/clang/Parse/Template.h (added)
+++ cfe/trunk/include/clang/Parse/Template.h Tue Nov 10 13:49:08 2009
@@ -0,0 +1,183 @@
+//===--- Template.h - Template Parsing Data Types -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides data structures that store the parsed representation of
+//  templates.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_PARSE_TEMPLATE_H
+#define LLVM_CLANG_PARSE_TEMPLATE_H
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include <cassert>
+
+namespace clang {  
+  /// \brief Represents the parsed form of a C++ template argument.
+  class ParsedTemplateArgument {
+  public:
+    /// \brief Describes the kind of template argument that was parsed.
+    enum KindType {
+      /// \brief A template type parameter, stored as a type.
+      Type,
+      /// \brief A non-type template parameter, stored as an expression.
+      NonType,
+      /// \brief A template template argument, stored as a template name.
+      Template
+    };
+
+    /// \brief Build an empty template argument. This template argument 
+    ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+    
+    /// \brief Create a template type argument or non-type template argument.
+    ///
+    /// \param Arg the template type argument or non-type template argument.
+    /// \param Loc the location of the type.
+    ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
+      : Kind(Kind), Arg(Arg), Loc(Loc) { }
+    
+    /// \brief Create a template template argument.
+    ///
+    /// \param SS the C++ scope specifier that precedes the template name, if
+    /// any.
+    ///
+    /// \param Template the template to which this template template 
+    /// argument refers.
+    ///
+    /// \param TemplateLoc the location of the template name.
+    ParsedTemplateArgument(const CXXScopeSpec &SS,
+                           ActionBase::TemplateTy Template, 
+                           SourceLocation TemplateLoc) 
+      : Kind(ParsedTemplateArgument::Template), Arg(Template.get()), 
+        Loc(TemplateLoc), SS(SS) { }
+    
+    /// \brief Determine whether the given template argument is invalid.
+    bool isInvalid() { return Arg == 0; }
+    
+    /// \brief Determine what kind of template argument we have.
+    KindType getKind() const { return Kind; }
+    
+    /// \brief Retrieve the template type argument's type.
+    ActionBase::TypeTy *getAsType() const {
+      assert(Kind == Type && "Not a template type argument");
+      return Arg;
+    }
+    
+    /// \brief Retrieve the non-type template argument's expression.
+    ActionBase::ExprTy *getAsExpr() const {
+      assert(Kind == NonType && "Not a non-type template argument");
+      return Arg;
+    }
+    
+    /// \brief Retrieve the template template argument's template name.
+    ActionBase::TemplateTy getAsTemplate() const {
+      assert(Kind == Template && "Not a template template argument");
+      return ActionBase::TemplateTy::make(Arg);
+    }
+    
+    /// \brief Retrieve the location of the template argument.
+    SourceLocation getLocation() const { return Loc; }
+    
+    /// \brief Retrieve the nested-name-specifier that precedes the template
+    /// name in a template template argument.
+    const CXXScopeSpec &getScopeSpec() const {
+      assert(Kind == Template && 
+             "Only template template arguments can have a scope specifier");
+      return SS;
+    }
+    
+  private:
+    KindType Kind;
+    
+    /// \brief The actual template argument representation, which may be
+    /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
+    /// expression), or an ActionBase::TemplateTy (for a template).
+    void *Arg;
+
+    /// \brief the location of the template argument.
+    SourceLocation Loc;
+    
+    /// \brief The nested-name-specifier that can accompany a template template
+    /// argument.
+    CXXScopeSpec SS;
+  };
+  
+  /// \brief Information about a template-id annotation
+  /// token.
+  ///
+  /// A template-id annotation token contains the template declaration, 
+  /// template arguments, whether those template arguments were types, 
+  /// expressions, or template names, and the source locations for important 
+  /// tokens. All of the information about template arguments is allocated 
+  /// directly after this structure.
+  struct TemplateIdAnnotation {
+    /// TemplateNameLoc - The location of the template name within the
+    /// source.
+    SourceLocation TemplateNameLoc;
+    
+    /// FIXME: Temporarily stores the name of a specialization
+    IdentifierInfo *Name;
+    
+    /// FIXME: Temporarily stores the overloaded operator kind.
+    OverloadedOperatorKind Operator;
+    
+    /// The declaration of the template corresponding to the
+    /// template-name. This is an Action::TemplateTy.
+    void *Template;
+    
+    /// The kind of template that Template refers to.
+    TemplateNameKind Kind;
+    
+    /// The location of the '<' before the template argument
+    /// list.
+    SourceLocation LAngleLoc;
+    
+    /// The location of the '>' after the template argument
+    /// list.
+    SourceLocation RAngleLoc;
+    
+    /// NumArgs - The number of template arguments.
+    unsigned NumArgs;
+    
+    /// \brief Retrieves a pointer to the template arguments
+    ParsedTemplateArgument *getTemplateArgs() { 
+      return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
+    }
+    
+    static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+      TemplateIdAnnotation *TemplateId
+      = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+                                      sizeof(ParsedTemplateArgument) * NumArgs);
+      TemplateId->NumArgs = NumArgs;
+      return TemplateId;
+    }
+    
+    void Destroy() { free(this); }
+  };
+  
+#if !defined(DISABLE_SMART_POINTERS)
+  inline void ASTTemplateArgsPtr::destroy() {
+    if (!Count)
+      return;
+    
+    for (unsigned I = 0; I != Count; ++I)
+      if (Args[I].getKind() == ParsedTemplateArgument::NonType)
+        Actions.DeleteExpr(Args[I].getAsExpr());
+    
+    Count = 0;
+  }
+#endif
+  
+  inline const ParsedTemplateArgument &
+  ASTTemplateArgsPtr::operator[](unsigned Arg) const { 
+    return Args[Arg]; 
+  }
+}
+
+#endif
\ No newline at end of file

Propchange: cfe/trunk/include/clang/Parse/Template.h

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/include/clang/Parse/Template.h

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/include/clang/Parse/Template.h

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Tue Nov 10 13:49:08 2009
@@ -13,6 +13,7 @@
 
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Template.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/LangOptions.h"
 #include "llvm/ADT/STLExtras.h"
@@ -26,6 +27,15 @@
   return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
 }
 
+
+void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
+  assert(TemplateId && "NULL template-id annotation?");
+  Kind = IK_TemplateId;
+  this->TemplateId = TemplateId;
+  StartLocation = TemplateId->TemplateNameLoc;
+  EndLocation = TemplateId->RAngleLoc;
+}
+
 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
 /// "TheDeclarator" is the declarator that this will be added to.
 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Nov 10 13:49:08 2009
@@ -14,6 +14,7 @@
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
 #include "ExtensionRAIIObject.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace clang;

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Nov 10 13:49:08 2009
@@ -16,6 +16,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
 #include "ExtensionRAIIObject.h"
 using namespace clang;
 
@@ -586,13 +587,10 @@
       // Eat the template argument list and try to continue parsing this as
       // a class (or template thereof).
       TemplateArgList TemplateArgs;
-      TemplateArgIsTypeList TemplateArgIsType;
-      TemplateArgLocationList TemplateArgLocations;
       SourceLocation LAngleLoc, RAngleLoc;
       if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS, 
                                            true, LAngleLoc,
-                                           TemplateArgs, TemplateArgIsType,
-                                           TemplateArgLocations, RAngleLoc)) {
+                                           TemplateArgs, RAngleLoc)) {
         // We couldn't parse the template argument list at all, so don't
         // try to give any location information for the list.
         LAngleLoc = RAngleLoc = SourceLocation();
@@ -704,7 +702,6 @@
     // or explicit instantiation.
     ASTTemplateArgsPtr TemplateArgsPtr(Actions,
                                        TemplateId->getTemplateArgs(),
-                                       TemplateId->getTemplateArgIsType(),
                                        TemplateId->NumArgs);
     if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
         TUK == Action::TUK_Declaration) {
@@ -720,7 +717,6 @@
                                              TemplateId->TemplateNameLoc,
                                              TemplateId->LAngleLoc,
                                              TemplateArgsPtr,
-                                      TemplateId->getTemplateArgLocations(),
                                              TemplateId->RAngleLoc,
                                              Attr);
     } else if (TUK == Action::TUK_Reference) {
@@ -729,7 +725,6 @@
                                       TemplateId->TemplateNameLoc,
                                       TemplateId->LAngleLoc,
                                       TemplateArgsPtr,
-                                      TemplateId->getTemplateArgLocations(),
                                       TemplateId->RAngleLoc);
 
       TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
@@ -777,7 +772,6 @@
                        TemplateId->TemplateNameLoc,
                        TemplateId->LAngleLoc,
                        TemplateArgsPtr,
-                       TemplateId->getTemplateArgLocations(),
                        TemplateId->RAngleLoc,
                        Attr,
                        Action::MultiTemplateParamsArg(Actions,

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Nov 10 13:49:08 2009
@@ -14,6 +14,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -814,13 +815,9 @@
   // Parse the enclosed template argument list.
   SourceLocation LAngleLoc, RAngleLoc;
   TemplateArgList TemplateArgs;
-  TemplateArgIsTypeList TemplateArgIsType;
-  TemplateArgLocationList TemplateArgLocations;
   if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
                                        &SS, true, LAngleLoc,
                                        TemplateArgs,
-                                       TemplateArgIsType,
-                                       TemplateArgLocations,
                                        RAngleLoc))
     return true;
   
@@ -845,15 +842,10 @@
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
     TemplateId->RAngleLoc = RAngleLoc;
-    void **Args = TemplateId->getTemplateArgs();
-    bool *ArgIsType = TemplateId->getTemplateArgIsType();
-    SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations();
+    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
     for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 
-         Arg != ArgEnd; ++Arg) {
+         Arg != ArgEnd; ++Arg)
       Args[Arg] = TemplateArgs[Arg];
-      ArgIsType[Arg] = TemplateArgIsType[Arg];
-      ArgLocs[Arg] = TemplateArgLocations[Arg];
-    }
     
     Id.setTemplateId(TemplateId);
     return false;
@@ -861,14 +853,12 @@
 
   // Bundle the template arguments together.
   ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
-                                     TemplateArgIsType.data(),
                                      TemplateArgs.size());
   
   // Constructor and destructor names.
   Action::TypeResult Type
     = Actions.ActOnTemplateIdType(Template, NameLoc,
                                   LAngleLoc, TemplateArgsPtr,
-                                  &TemplateArgLocations[0],
                                   RAngleLoc);
   if (Type.isInvalid())
     return true;

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Nov 10 13:49:08 2009
@@ -15,6 +15,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
 #include "llvm/Support/Compiler.h"
 using namespace clang;
 
@@ -582,8 +583,6 @@
                                          bool ConsumeLastToken,
                                          SourceLocation &LAngleLoc,
                                          TemplateArgList &TemplateArgs,
-                                    TemplateArgIsTypeList &TemplateArgIsType,
-                               TemplateArgLocationList &TemplateArgLocations,
                                          SourceLocation &RAngleLoc) {
   assert(Tok.is(tok::less) && "Must have already parsed the template-name");
 
@@ -595,8 +594,7 @@
   {
     GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
     if (Tok.isNot(tok::greater))
-      Invalid = ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType,
-                                          TemplateArgLocations);
+      Invalid = ParseTemplateArgumentList(TemplateArgs);
 
     if (Invalid) {
       // Try to find the closing '>'.
@@ -688,14 +686,10 @@
   // Parse the enclosed template argument list.
   SourceLocation LAngleLoc, RAngleLoc;
   TemplateArgList TemplateArgs;
-  TemplateArgIsTypeList TemplateArgIsType;
-  TemplateArgLocationList TemplateArgLocations;
   bool Invalid = ParseTemplateIdAfterTemplateName(Template, 
                                                   TemplateNameLoc,
                                                   SS, false, LAngleLoc,
                                                   TemplateArgs,
-                                                  TemplateArgIsType,
-                                                  TemplateArgLocations,
                                                   RAngleLoc);
 
   if (Invalid) {
@@ -707,7 +701,6 @@
   }
 
   ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
-                                     TemplateArgIsType.data(),
                                      TemplateArgs.size());
 
   // Build the annotation token.
@@ -715,7 +708,6 @@
     Action::TypeResult Type
       = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
                                     LAngleLoc, TemplateArgsPtr,
-                                    &TemplateArgLocations[0],
                                     RAngleLoc);
     if (Type.isInvalid()) {
       // If we failed to parse the template ID but skipped ahead to a >, we're not
@@ -751,14 +743,9 @@
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
     TemplateId->RAngleLoc = RAngleLoc;
-    void **Args = TemplateId->getTemplateArgs();
-    bool *ArgIsType = TemplateId->getTemplateArgIsType();
-    SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations();
-    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) {
+    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
+    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
       Args[Arg] = TemplateArgs[Arg];
-      ArgIsType[Arg] = TemplateArgIsType[Arg];
-      ArgLocs[Arg] = TemplateArgLocations[Arg];
-    }
     Tok.setAnnotationValue(TemplateId);
     if (TemplateKWLoc.isValid())
       Tok.setLocation(TemplateKWLoc);
@@ -794,7 +781,6 @@
 
   ASTTemplateArgsPtr TemplateArgsPtr(Actions,
                                      TemplateId->getTemplateArgs(),
-                                     TemplateId->getTemplateArgIsType(),
                                      TemplateId->NumArgs);
 
   Action::TypeResult Type
@@ -802,7 +788,6 @@
                                   TemplateId->TemplateNameLoc,
                                   TemplateId->LAngleLoc,
                                   TemplateArgsPtr,
-                                  TemplateId->getTemplateArgLocations(),
                                   TemplateId->RAngleLoc);
   // Create the new "type" annotation token.
   Tok.setKind(tok::annot_typename);
@@ -817,33 +802,112 @@
   TemplateId->Destroy();
 }
 
+/// \brief Determine whether the given token can end a template argument.
+static const bool isEndOfTemplateArgument(Token Tok) {
+  return Tok.is(tok::comma) || Tok.is(tok::greater) || 
+         Tok.is(tok::greatergreater);
+}
+
 /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
 ///
 ///       template-argument: [C++ 14.2]
 ///         constant-expression
 ///         type-id
 ///         id-expression
-void *Parser::ParseTemplateArgument(bool &ArgIsType) {
+ParsedTemplateArgument Parser::ParseTemplateArgument() {
   // C++ [temp.arg]p2:
   //   In a template-argument, an ambiguity between a type-id and an
   //   expression is resolved to a type-id, regardless of the form of
   //   the corresponding template-parameter.
   //
-  // Therefore, we initially try to parse a type-id.
+  // Therefore, we initially try to parse a type-id.  
   if (isCXXTypeId(TypeIdAsTemplateArgument)) {
-    ArgIsType = true;
+    SourceLocation Loc = Tok.getLocation();
     TypeResult TypeArg = ParseTypeName();
     if (TypeArg.isInvalid())
-      return 0;
-    return TypeArg.get();
+      return ParsedTemplateArgument();
+    
+    return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), 
+                                  Loc);
   }
 
+  // C++0x [temp.arg.template]p1:
+  //   A template-argument for a template template-parameter shall be the name
+  //   of a class template or a template alias, expressed as id-expression.
+  // 
+  // We perform some tentative parsing at this point, to determine whether
+  // we have an id-expression that refers to a class template or template
+  // alias. The grammar we tentatively parse is:
+  //
+  //   nested-name-specifier[opt] template[opt] identifier
+  //
+  // followed by a token that terminates a template argument, such as ',', 
+  // '>', or (in some cases) '>>'.
+  if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+      Tok.is(tok::annot_cxxscope)) {
+    TentativeParsingAction TPA(*this);
+    CXXScopeSpec SS; // nested-name-specifier, if present
+    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, 
+                                   /*EnteringContext=*/false);
+
+    if (SS.isSet() && Tok.is(tok::kw_template)) {
+      // Parse the optional 'template' keyword following the 
+      // nested-name-specifier.
+      SourceLocation TemplateLoc = ConsumeToken();
+      
+      if (Tok.is(tok::identifier)) {
+        // We appear to have a dependent template name.
+        UnqualifiedId Name;
+        Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+        ConsumeToken(); // the identifier
+        
+        // If the next token signals the end of a template argument,
+        // then we have a dependent template name that could be a template
+        // template argument.
+        if (isEndOfTemplateArgument(Tok)) {
+          TemplateTy Template
+            = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, 
+                                                 /*ObjectType=*/0);
+          if (Template.get()) {
+            TPA.Commit();
+            return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+          }
+        }
+      } 
+    } else if (Tok.is(tok::identifier)) {
+      // We may have a (non-dependent) template name.
+      TemplateTy Template;
+      UnqualifiedId Name;
+      Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+      ConsumeToken(); // the identifier
+
+      if (isEndOfTemplateArgument(Tok)) {
+        TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name, 
+                                                      /*ObjectType=*/0, 
+                                                      /*EnteringContext=*/false, 
+                                                      Template);
+        if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
+          // We have an id-expression that refers to a class template or
+          // (C++0x) template alias. 
+          TPA.Commit();
+          return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+        }
+      }
+    }
+    
+    // We don't have a template template argument; revert everything we have
+    // tentatively parsed.
+    TPA.Revert();
+  }
+  
+  // Parse a non-type template argument. 
+  SourceLocation Loc = Tok.getLocation();
   OwningExprResult ExprArg = ParseConstantExpression();
   if (ExprArg.isInvalid() || !ExprArg.get())
-    return 0;
+    return ParsedTemplateArgument();
 
-  ArgIsType = false;
-  return ExprArg.release();
+  return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
+                                ExprArg.release(), Loc);
 }
 
 /// ParseTemplateArgumentList - Parse a C++ template-argument-list
@@ -853,22 +917,17 @@
 ///         template-argument
 ///         template-argument-list ',' template-argument
 bool
-Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
-                                  TemplateArgIsTypeList &TemplateArgIsType,
-                              TemplateArgLocationList &TemplateArgLocations) {
+Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
   while (true) {
-    bool IsType = false;
-    SourceLocation Loc = Tok.getLocation();
-    void *Arg = ParseTemplateArgument(IsType);
-    if (Arg) {
-      TemplateArgs.push_back(Arg);
-      TemplateArgIsType.push_back(IsType);
-      TemplateArgLocations.push_back(Loc);
-    } else {
+    ParsedTemplateArgument Arg = ParseTemplateArgument();
+    if (Arg.isInvalid()) {
       SkipUntil(tok::comma, tok::greater, true, true);
       return true;
     }
 
+    // Save this template argument.
+    TemplateArgs.push_back(Arg);
+      
     // If the next token is a comma, consume it and keep reading
     // arguments.
     if (Tok.isNot(tok::comma)) break;

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=86708&r1=86707&r2=86708&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Nov 10 13:49:08 2009
@@ -15,6 +15,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
 #include "llvm/Support/raw_ostream.h"
 #include "ExtensionRAIIObject.h"
 #include "ParsePragma.h"

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 10 13:49:08 2009
@@ -2472,8 +2472,7 @@
                                 AccessSpecifier AS);
 
   void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
-                                  SourceLocation *TemplateArgLocsIn,
-                        llvm::SmallVector<TemplateArgumentLoc, 16> &TempArgs);
+                        llvm::SmallVectorImpl<TemplateArgumentLoc> &TempArgs);
     
   QualType CheckTemplateIdType(TemplateName Template,
                                SourceLocation TemplateLoc,
@@ -2486,7 +2485,6 @@
   ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
                       SourceLocation LAngleLoc,
                       ASTTemplateArgsPtr TemplateArgs,
-                      SourceLocation *TemplateArgLocs,
                       SourceLocation RAngleLoc);
 
   virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
@@ -2508,7 +2506,6 @@
                                        SourceLocation TemplateNameLoc,
                                        SourceLocation LAngleLoc,
                                        ASTTemplateArgsPtr TemplateArgs,
-                                       SourceLocation *TemplateArgLocs,
                                        SourceLocation RAngleLoc);
 
   virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
@@ -2529,7 +2526,6 @@
                                    SourceLocation TemplateNameLoc,
                                    SourceLocation LAngleLoc,
                                    ASTTemplateArgsPtr TemplateArgs,
-                                   SourceLocation *TemplateArgLocs,
                                    SourceLocation RAngleLoc,
                                    AttributeList *Attr,
                                  MultiTemplateParamsArg TemplateParameterLists);
@@ -2570,7 +2566,6 @@
                              SourceLocation TemplateNameLoc,
                              SourceLocation LAngleLoc,
                              ASTTemplateArgsPtr TemplateArgs,
-                             SourceLocation *TemplateArgLocs,
                              SourceLocation RAngleLoc,
                              AttributeList *Attr);
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Nov 10 13:49:08 2009
@@ -24,6 +24,7 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Template.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -1669,7 +1670,7 @@
       
     case UnqualifiedId::IK_TemplateId: {
       TemplateName TName
-      = TemplateName::getFromVoidPointer(Name.TemplateId->Template);    
+        = TemplateName::getFromVoidPointer(Name.TemplateId->Template);    
       if (TemplateDecl *Template = TName.getAsTemplateDecl())
         return Template->getDeclName();
       if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
@@ -2835,10 +2836,8 @@
     TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
-                                       TemplateId->getTemplateArgIsType(),
                                        TemplateId->NumArgs);
     translateTemplateArguments(TemplateArgsPtr,
-                               TemplateId->getTemplateArgLocations(),
                                TemplateArgs);
     TemplateArgsPtr.release();
     

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Nov 10 13:49:08 2009
@@ -18,9 +18,10 @@
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
 #include <algorithm> // for std::equal

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 10 13:49:08 2009
@@ -25,6 +25,7 @@
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Designator.h"
 #include "clang/Parse/Scope.h"
+#include "clang/Parse/Template.h"
 using namespace clang;
 
 
@@ -622,14 +623,12 @@
   if (Name.getKind() == UnqualifiedId::IK_TemplateId) {
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        Name.TemplateId->getTemplateArgs(),
-                                       Name.TemplateId->getTemplateArgIsType(),
                                        Name.TemplateId->NumArgs);
     return ActOnTemplateIdExpr(SS, 
                                TemplateTy::make(Name.TemplateId->Template), 
                                Name.TemplateId->TemplateNameLoc,
                                Name.TemplateId->LAngleLoc,
                                TemplateArgsPtr,
-                               Name.TemplateId->getTemplateArgLocations(),
                                Name.TemplateId->RAngleLoc);
   }
   
@@ -2501,12 +2500,10 @@
     // Translate the parser's template argument list in our AST format.
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        Member.TemplateId->getTemplateArgs(),
-                                       Member.TemplateId->getTemplateArgIsType(),
                                        Member.TemplateId->NumArgs);
     
     llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
     translateTemplateArguments(TemplateArgsPtr, 
-                               Member.TemplateId->getTemplateArgLocations(),
                                TemplateArgs);
     TemplateArgsPtr.release();
     

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov 10 13:49:08 2009
@@ -16,6 +16,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Template.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "llvm/Support/Compiler.h"
@@ -1121,22 +1122,44 @@
 /// \brief Translates template arguments as provided by the parser
 /// into template arguments used by semantic analysis.
 void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
-                                      SourceLocation *TemplateArgLocs,
-                  llvm::SmallVector<TemplateArgumentLoc, 16> &TemplateArgs) {
+                     llvm::SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
   TemplateArgs.reserve(TemplateArgsIn.size());
 
-  void **Args = TemplateArgsIn.getArgs();
-  bool *ArgIsType = TemplateArgsIn.getArgIsType();
-  for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
-    if (ArgIsType[Arg]) {
+  for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I) {
+    const ParsedTemplateArgument &Arg = TemplateArgsIn[I];
+    switch (Arg.getKind()) {
+    case ParsedTemplateArgument::Type: {
       DeclaratorInfo *DI;
-      QualType T = Sema::GetTypeFromParser(Args[Arg], &DI);
-      if (!DI) DI = Context.getTrivialDeclaratorInfo(T, TemplateArgLocs[Arg]);
+      QualType T = Sema::GetTypeFromParser(Arg.getAsType(), &DI);
+      if (!DI) DI = Context.getTrivialDeclaratorInfo(T, Arg.getLocation());
       TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(T), DI));
-    } else {
-      Expr *E = reinterpret_cast<Expr *>(Args[Arg]);
+      break;
+    }
+        
+    case ParsedTemplateArgument::NonType: {
+      Expr *E = static_cast<Expr *>(Arg.getAsExpr());
+      TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
+      break;
+    }
+      
+    case ParsedTemplateArgument::Template: {
+      TemplateName Template
+        = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
+      
+      // FIXME: This is an egregious hack. We turn a nicely-parsed template name
+      // into a DeclRefExpr, because that's how we previously parsed template
+      // template parameters. This will disappear as part of the upcoming
+      // implementation of template template parameters.
+      const CXXScopeSpec &SS = Arg.getScopeSpec();
+      Expr *E = DeclRefExpr::Create(Context, 
+                                    (NestedNameSpecifier *)SS.getScopeRep(),
+                                    SS.getRange(), 
+                                    Template.getAsTemplateDecl(),
+                                    Arg.getLocation(),
+                                    Context.DependentTy, false, false);
       TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
     }
+    }
   }
 }
 
@@ -1228,13 +1251,12 @@
 Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
                           SourceLocation LAngleLoc,
                           ASTTemplateArgsPtr TemplateArgsIn,
-                          SourceLocation *TemplateArgLocsIn,
                           SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocsIn, TemplateArgs);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
 
   QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
                                         TemplateArgs.data(),
@@ -1336,13 +1358,12 @@
                                                  SourceLocation TemplateNameLoc,
                                                  SourceLocation LAngleLoc,
                                               ASTTemplateArgsPtr TemplateArgsIn,
-                                                SourceLocation *TemplateArgSLs,
                                                  SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgSLs, TemplateArgs);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
   TemplateArgsIn.release();
 
   return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
@@ -2803,7 +2824,6 @@
                                        SourceLocation TemplateNameLoc,
                                        SourceLocation LAngleLoc,
                                        ASTTemplateArgsPtr TemplateArgsIn,
-                                       SourceLocation *TemplateArgLocs,
                                        SourceLocation RAngleLoc,
                                        AttributeList *Attr,
                                MultiTemplateParamsArg TemplateParameterLists) {
@@ -2898,7 +2918,7 @@
 
   // Translate the parser's template argument list in our AST format.
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
 
   // Check that the template argument list is well-formed for this
   // template.
@@ -3704,7 +3724,6 @@
                                  SourceLocation TemplateNameLoc,
                                  SourceLocation LAngleLoc,
                                  ASTTemplateArgsPtr TemplateArgsIn,
-                                 SourceLocation *TemplateArgLocs,
                                  SourceLocation RAngleLoc,
                                  AttributeList *Attr) {
   // Find the class template we're specializing
@@ -3743,7 +3762,7 @@
   
   // Translate the parser's template argument list in our AST format.
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
 
   // Check that the template argument list is well-formed for this
   // template.
@@ -4126,10 +4145,8 @@
     TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
-                                       TemplateId->getTemplateArgIsType(),
                                        TemplateId->NumArgs);
     translateTemplateArguments(TemplateArgsPtr,
-                               TemplateId->getTemplateArgLocations(),
                                TemplateArgs);
     HasExplicitTemplateArgs = true;
     TemplateArgsPtr.release();





More information about the cfe-commits mailing list