[cfe-commits] r68074 - in /cfe/trunk: include/clang/AST/ include/clang/Parse/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Sema/

Douglas Gregor dgregor at apple.com
Mon Mar 30 15:58:21 PDT 2009


Author: dgregor
Date: Mon Mar 30 17:58:21 2009
New Revision: 68074

URL: http://llvm.org/viewvc/llvm-project?rev=68074&view=rev
Log:
Improve the representation of template names in the AST. This
representation handles the various ways in which one can name a
template, including unqualified references ("vector"), qualified
references ("std::vector"), and dependent template names
("MetaFun::template apply").

One immediate effect of this change is that the representation of
nested-name-specifiers in type names for class template
specializations (e.g., std::vector<int>) is more accurate. Rather than
representing std::vector<int> as

  std::(vector<int>)

we represent it as

  (std::vector)<int>

which more closely follows the C++ grammar. 

Additionally, templates are no longer represented as declarations
(DeclPtrTy) in Parse-Sema interactions. Instead, I've introduced a new
OpaquePtr type (TemplateTy) that holds the representation of a
TemplateName. This will simplify the handling of dependent
template-names, once we get there.





Added:
    cfe/trunk/include/clang/AST/TemplateName.h
    cfe/trunk/lib/AST/TemplateName.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypeSerialization.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/Parse/MinimalAction.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/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Mar 30 17:58:21 2009
@@ -19,6 +19,7 @@
 #include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/DenseMap.h"
@@ -71,13 +72,15 @@
   llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
   llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
   llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
-  llvm::FoldingSet<ClassTemplateSpecializationType> 
-    ClassTemplateSpecializationTypes;
+  llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
   llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
   llvm::FoldingSet<TypenameType> TypenameTypes;
   llvm::FoldingSet<ObjCQualifiedInterfaceType> ObjCQualifiedInterfaceTypes;
   llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes;
 
+  llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
+  llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
+
   /// \brief The set of nested name specifiers.
   ///
   /// This set is managed by the NestedNameSpecifier class.
@@ -291,10 +294,10 @@
   QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, 
                                    IdentifierInfo *Name = 0);
 
-  QualType getClassTemplateSpecializationType(TemplateDecl *Template,
-                                              const TemplateArgument *Args,
-                                              unsigned NumArgs,
-                                              QualType Canon = QualType());
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgument *Args,
+                                         unsigned NumArgs,
+                                         QualType Canon = QualType());
 
   QualType getQualifiedNameType(NestedNameSpecifier *NNS,
                                 QualType NamedType);
@@ -407,6 +410,13 @@
 
   QualType getFixedWidthIntType(unsigned Width, bool Signed);
 
+  TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, 
+                                        bool TemplateKeyword,
+                                        TemplateDecl *Template);
+
+  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, 
+                                        const IdentifierInfo *Name);
+
 private:
   QualType getFromTargetType(unsigned Type) const;
 

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Mon Mar 30 17:58:21 2009
@@ -705,7 +705,7 @@
     llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
   };
 
-  /// \brief Previous declaration of 
+  /// \brief Previous declaration of this class template.
   ClassTemplateDecl *PreviousDeclaration;
 
   /// \brief Pointer to the data that is common to all of the

Added: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=68074&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (added)
+++ cfe/trunk/include/clang/AST/TemplateName.h Mon Mar 30 17:58:21 2009
@@ -0,0 +1,246 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
+#define LLVM_CLANG_AST_TEMPLATENAME_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class DependentTemplateName;
+class IdentifierInfo;
+class NestedNameSpecifier;
+class QualifiedTemplateName;
+class TemplateDecl;
+
+/// \brief Represents a C++ template name within the type system.
+///
+/// A C++ template name refers to a template within the C++ type
+/// system. In most cases, a template name is simply a reference to a
+/// class template, e.g.
+///
+/// \code
+/// template<typename T> class X { };
+///
+/// X<int> xi;
+/// \endcode
+///
+/// Here, the 'X' in \c X<int> is a template name that refers to the
+/// declaration of the class template X, above. Template names can
+/// also refer to function templates, C++0x template aliases, etc.
+///
+/// Some template names are dependent. For example, consider:
+///
+/// \code
+/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
+///   typedef typename MetaFun::template apply<T1, T2>::type type;
+/// };
+/// \endcode
+///
+/// Here, "apply" is treated as a template name within the typename
+/// specifier in the typedef. "apply" is a nested template, and can
+/// only be understood in the context of
+class TemplateName {
+  typedef llvm::PointerUnion3<TemplateDecl *, QualifiedTemplateName *, 
+                              DependentTemplateName *> StorageType;
+
+  StorageType Storage;
+
+  explicit TemplateName(void *Ptr) {
+    Storage = StorageType::getFromOpaqueValue(Ptr);
+  }
+
+public:
+  TemplateName() : Storage() { }
+  explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
+  explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
+  explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
+
+  /// \brief Retrieve the the underlying template declaration that
+  /// this template name refers to, if known.
+  ///
+  /// \returns The template declaration that this template name refers
+  /// to, if any. If the template name does not refer to a specific
+  /// declaration because it is a dependent name, returns NULL.
+  TemplateDecl *getAsTemplateDecl() const;
+
+  /// \brief Retrieve the underlying qualified template name
+  /// structure, if any.
+  QualifiedTemplateName *getAsQualifiedTemplateName() const {
+    return Storage.dyn_cast<QualifiedTemplateName *>();
+  }
+
+  /// \brief Retrieve the underlying dependent template name
+  /// structure, if any.
+  DependentTemplateName *getAsDependentTemplateName() const {
+    return Storage.dyn_cast<DependentTemplateName *>();
+  }
+
+  /// \brief Determines whether this is a dependent template name.
+  bool isDependent() const;
+
+  /// \brief Print the template name.
+  void Print(llvm::raw_ostream &OS) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddPointer(Storage.getOpaqueValue());
+  }
+
+  /// \brief Retrieve the template name as a void pointer.
+  void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
+
+  /// \brief Build a template name from a void pointer.
+  static TemplateName getFromVoidPointer(void *Ptr) { 
+    return TemplateName(Ptr); 
+  }
+};
+
+/// \brief Represents a template name that was expressed as a
+/// qualified name.
+///
+/// This kind of template name refers to a template name that was
+/// preceded by a nested name specifier, e.g., \c std::vector. Here,
+/// the nested name specifier is "std::" and the template name is the
+/// declaration for "vector". The QualifiedTemplateName class is only
+/// used to provide "sugar" for template names that were expressed
+/// with a qualified name, and has no semantic meaning. In this
+/// manner, it is to TemplateName what QualifiedNameType is to Type,
+/// providing extra syntactic sugar for downstream clients.
+class QualifiedTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template name.
+  ///
+  /// The bit is used to indicate whether the "template" keyword was
+  /// present before the template name itself. Note that the
+  /// "template" keyword is always redundant in this case (otherwise,
+  /// the template name would be a dependent name and we would express
+  /// this name with DependentTemplateName).
+  llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
+
+  /// \brief The template declaration that this qualified name refers
+  /// to.
+  TemplateDecl *Template;
+
+  friend class ASTContext;
+
+  QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
+                        TemplateDecl *Template)
+    : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) { }
+
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+  /// \brief Whether the template name was prefixed by the "template"
+  /// keyword.
+  bool hasTemplateKeyword() const { return Qualifier.getInt(); }
+
+  /// \brief The template declaration to which this qualified name
+  /// refers.
+  TemplateDecl *getTemplateDecl() const { return Template; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, 
+                      bool TemplateKeyword, TemplateDecl *Template) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(TemplateKeyword);
+    ID.AddPointer(Template);
+  }
+};
+
+/// \brief Represents a dependent template name that cannot be
+/// resolved prior to template instantiation.
+///
+/// This kind of template name refers to a dependent template name,
+/// including its nested name specifier. For example,
+/// DependentTemplateName can refer to "MetaFun::template apply",
+/// where "MetaFun::" is the nested name specifier and "apply" is the
+/// template name referenced. The "template" keyword is implied.
+class DependentTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template
+  /// name.
+  NestedNameSpecifier *Qualifier;
+
+  /// \brief The dependent template name.
+  const IdentifierInfo *Name;
+
+  /// \brief The canonical template name to which this dependent
+  /// template name refers.
+  ///
+  /// The canonical template name for a dependent template name is
+  /// another dependent template name whose nested name specifier is
+  /// canonical.
+  TemplateName CanonicalTemplateName;
+
+  friend class ASTContext;
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier, 
+                        const IdentifierInfo *Name)
+    : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(this) { }
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier, 
+                        const IdentifierInfo *Name,
+                        TemplateName Canon)
+    : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(Canon) { }
+
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// \brief Return the name to which this dependent template name
+  /// refers.
+  const IdentifierInfo *getName() const { return Name; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getQualifier(), getName());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, 
+                      const IdentifierInfo *Name) {
+    ID.AddPointer(NNS);
+    ID.AddPointer(Name);
+  }
+};
+
+}
+
+namespace llvm {
+
+/// \brief The clang::TemplateName class is effectively a pointer.
+template<>
+class PointerLikeTypeTraits<clang::TemplateName> {
+public:
+  static inline void *getAsVoidPointer(clang::TemplateName TN) {
+    return TN.getAsVoidPointer();
+  }
+
+  static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
+    return clang::TemplateName::getFromVoidPointer(Ptr);
+  }
+
+  // No bits are available!
+  enum { NumLowBitsAvailable = 0 };
+};
+
+}
+
+#endif

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

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Mar 30 17:58:21 2009
@@ -16,11 +16,13 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Bitcode/SerializationFwd.h"
+
 using llvm::isa;
 using llvm::cast;
 using llvm::cast_or_null;
@@ -39,7 +41,7 @@
   class TemplateDecl;
   class TemplateTypeParmDecl;
   class NonTypeTemplateParmDecl;
-  class TemplateTemplateParamDecl;
+  class TemplateTemplateParmDecl;
   class TagDecl;
   class RecordDecl;
   class CXXRecordDecl;
@@ -437,8 +439,8 @@
   const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
   const TemplateTypeParmType *getAsTemplateTypeParmType() const;
 
-  const ClassTemplateSpecializationType *
-    getAsClassTemplateSpecializationType() const;
+  const TemplateSpecializationType *
+    getAsTemplateSpecializationType() const;
   
   /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
   /// interface, return the interface type, otherwise return null.
@@ -1494,32 +1496,34 @@
   friend class Type;
 };
 
-/// \brief Represents the type of a class template specialization as
-/// written in the source code.
+/// \brief Represents the type of a template specialization as written
+/// in the source code.
 ///
-/// Class template specialization types represent the syntactic form
-/// of a template-id that refers to a type, e.g., @c vector<int>. All
-/// class template specialization types are syntactic sugar, whose
-/// canonical type will point to some other type node that represents
-/// the instantiation or class template specialization. For example, a
+/// Template specialization types represent the syntactic form of a
+/// template-id that refers to a type, e.g., @c vector<int>. Some
+/// template specialization types are syntactic sugar, whose canonical
+/// type will point to some other type node that represents the
+/// instantiation or class template specialization. For example, a
 /// class template specialization type of @c vector<int> will refer to
-/// a tag type for the instantiation
+/// a tag type for the instantiation 
 /// @c std::vector<int, std::allocator<int>>.
-class ClassTemplateSpecializationType 
+///
+/// Other template specialization types, for which the template name
+/// is dependent, may be canonical types. These types are always
+/// dependent.
+class TemplateSpecializationType 
   : public Type, public llvm::FoldingSetNode {
 
-  // FIXME: Do we want templates to have a representation in the type
-  // system? It will probably help with dependent templates and
-  // possibly with template-names preceded by a nested-name-specifier.
-  TemplateDecl *Template;
+  /// \brief The name of the template being specialized.
+  TemplateName Template;
 
   /// \brief - The number of template arguments named in this class
   /// template specialization.
   unsigned NumArgs;
 
-  ClassTemplateSpecializationType(TemplateDecl *T, 
-                                  const TemplateArgument *Args,
-                                  unsigned NumArgs, QualType Canon);
+  TemplateSpecializationType(TemplateName T,
+                             const TemplateArgument *Args,
+                             unsigned NumArgs, QualType Canon);
 
   virtual void Destroy(ASTContext& C);
 
@@ -1541,8 +1545,8 @@
   iterator begin() const { return getArgs(); }
   iterator end() const;
 
-  /// \brief Retrieve the template that we are specializing.
-  TemplateDecl *getTemplate() const { return Template; }
+  /// \brief Retrieve the name of the template that we are specializing.
+  TemplateName getTemplateName() const { return Template; }
 
   /// \brief Retrieve the template arguments.
   const TemplateArgument *getArgs() const { 
@@ -1562,13 +1566,13 @@
     Profile(ID, Template, getArgs(), NumArgs);
   }
 
-  static void Profile(llvm::FoldingSetNodeID &ID, TemplateDecl *T,
+  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
                       const TemplateArgument *Args, unsigned NumArgs);
 
   static bool classof(const Type *T) { 
-    return T->getTypeClass() == ClassTemplateSpecialization; 
+    return T->getTypeClass() == TemplateSpecialization; 
   }
-  static bool classof(const ClassTemplateSpecializationType *T) { return true; }
+  static bool classof(const TemplateSpecializationType *T) { return true; }
 
 protected:
   virtual void EmitImpl(llvm::Serializer& S) const;

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=68074&r1=68073&r2=68074&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Mon Mar 30 17:58:21 2009
@@ -72,7 +72,7 @@
 TYPE(Record, TagType)
 TYPE(Enum, TagType)
 DEPENDENT_TYPE(TemplateTypeParm, Type)
-NON_CANONICAL_TYPE(ClassTemplateSpecialization, Type)
+TYPE(TemplateSpecialization, Type)
 NON_CANONICAL_TYPE(QualifiedName, Type)
 DEPENDENT_TYPE(Typename, Type)
 TYPE(ObjCInterface, Type)

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Mar 30 17:58:21 2009
@@ -72,7 +72,8 @@
   typedef ActionBase::StmtTy StmtTy;
   typedef OpaquePtr<0> DeclPtrTy;
   typedef OpaquePtr<1> DeclGroupPtrTy;
-  typedef void TypeTy;  // FIXME: Change TypeTy to use OpaquePtr<1>.
+  typedef void TypeTy;  // FIXME: Change TypeTy to use OpaquePtr<N>.
+  typedef OpaquePtr<2> TemplateTy;
   typedef void AttrTy;
   typedef void BaseTy;
   typedef void MemInitTy;
@@ -157,7 +158,7 @@
   /// optional CXXScope can be passed to indicate the C++ scope in
   /// which the identifier will be found.
   virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
-                                          DeclPtrTy &TemplateDecl,
+                                          TemplateTy &Template,
                                           const CXXScopeSpec *SS = 0) = 0;
 
   /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
@@ -1206,8 +1207,8 @@
     return DeclResult();
   }
 
-  /// \brief Form a class template specialization from a template and
-  /// a list of template arguments.
+  /// \brief Form a type from a template and a list of template
+  /// arguments.
   ///
   /// This action merely forms the type for the template-id, possibly
   /// checking well-formedness of the template arguments. It does not
@@ -1219,13 +1220,12 @@
   /// \param IsSpecialization true when we are naming the class
   /// template specialization as part of an explicit class
   /// specialization or class template partial specialization.
-  virtual TypeResult ActOnClassTemplateId(DeclPtrTy Template,
-                                          SourceLocation TemplateLoc,
-                                          SourceLocation LAngleLoc,
-                                          ASTTemplateArgsPtr TemplateArgs,
-                                          SourceLocation *TemplateArgLocs,
-                                          SourceLocation RAngleLoc,
-                                          const CXXScopeSpec *SS) {
+  virtual TypeResult ActOnTemplateIdType(TemplateTy Template,
+                                         SourceLocation TemplateLoc,
+                                         SourceLocation LAngleLoc,
+                                         ASTTemplateArgsPtr TemplateArgs,
+                                         SourceLocation *TemplateArgLocs,
+                                         SourceLocation RAngleLoc) {
     return TypeResult();
   };
 
@@ -1279,7 +1279,7 @@
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                    SourceLocation KWLoc, 
                                    const CXXScopeSpec &SS,
-                                   DeclPtrTy Template,
+                                   TemplateTy Template,
                                    SourceLocation TemplateNameLoc,
                                    SourceLocation LAngleLoc,
                                    ASTTemplateArgsPtr TemplateArgs,
@@ -1569,7 +1569,7 @@
                                   const CXXScopeSpec *SS);
 
   virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
-                                          DeclPtrTy &TemplateDecl,
+                                          TemplateTy &Template,
                                           const CXXScopeSpec *SS = 0);
 
   /// ActOnDeclarator - If this is a typedef declarator, we modify the

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Mar 30 17:58:21 2009
@@ -126,6 +126,7 @@
   typedef Action::MemInitTy MemInitTy;
   typedef Action::CXXScopeTy CXXScopeTy;
   typedef Action::TemplateParamsTy TemplateParamsTy;
+  typedef Action::TemplateTy TemplateTy;
 
   typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
 
@@ -1050,7 +1051,7 @@
   typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
   typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList;
 
-  bool ParseTemplateIdAfterTemplateName(DeclPtrTy Template,
+  bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
                                         SourceLocation TemplateNameLoc, 
                                         const CXXScopeSpec *SS,
                                         bool ConsumeLastToken,
@@ -1060,7 +1061,7 @@
                                TemplateArgLocationList &TemplateArgLocations,
                                         SourceLocation &RAngleLoc);
 
-  void AnnotateTemplateIdToken(DeclPtrTy Template, TemplateNameKind TNK,
+  void AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                const CXXScopeSpec *SS,
                                SourceLocation TemplateKWLoc = SourceLocation(),
                                bool AllowTypeAnnotation = true);

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar 30 17:58:21 2009
@@ -483,6 +483,10 @@
     Align = Layout.getAlignment();
     break;
   }
+
+  case Type::TemplateSpecialization:
+    assert(false && "Dependent types have no size");
+    break;
   }
   
   assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
@@ -1358,30 +1362,31 @@
 }
 
 QualType 
-ASTContext::getClassTemplateSpecializationType(TemplateDecl *Template,
-                                               const TemplateArgument *Args,
-                                               unsigned NumArgs,
-                                               QualType Canon) {
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          const TemplateArgument *Args,
+                                          unsigned NumArgs,
+                                          QualType Canon) {
+  // FIXME: If Template is dependent, canonicalize it!
+
   if (!Canon.isNull())
     Canon = getCanonicalType(Canon);
 
   llvm::FoldingSetNodeID ID;
-  ClassTemplateSpecializationType::Profile(ID, Template, Args, NumArgs);
+  TemplateSpecializationType::Profile(ID, Template, Args, NumArgs);
 
   void *InsertPos = 0;
-  ClassTemplateSpecializationType *Spec
-    = ClassTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+  TemplateSpecializationType *Spec
+    = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
 
   if (Spec)
     return QualType(Spec, 0);
   
-  void *Mem = Allocate((sizeof(ClassTemplateSpecializationType) + 
+  void *Mem = Allocate((sizeof(TemplateSpecializationType) + 
                         sizeof(TemplateArgument) * NumArgs),
                        8);
-  Spec = new (Mem) ClassTemplateSpecializationType(Template, Args, NumArgs, 
-                                                   Canon);
+  Spec = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, Canon);
   Types.push_back(Spec);
-  ClassTemplateSpecializationTypes.InsertNode(Spec, InsertPos);
+  TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
 
   return QualType(Spec, 0);  
 }
@@ -2486,6 +2491,53 @@
   ObjCConstantStringType = getObjCInterfaceType(Decl);
 }
 
+/// \brief Retrieve the template name that represents a qualified
+/// template name such as \c std::vector.
+TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, 
+                                                  bool TemplateKeyword,
+                                                  TemplateDecl *Template) {
+  llvm::FoldingSetNodeID ID;
+  QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
+
+  void *InsertPos = 0;
+  QualifiedTemplateName *QTN =
+    QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+  if (!QTN) {
+    QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
+    QualifiedTemplateNames.InsertNode(QTN, InsertPos);
+  }
+
+  return TemplateName(QTN);
+}
+
+/// \brief Retrieve the template name that represents a dependent
+/// template name such as \c MetaFun::template apply.
+TemplateName ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, 
+                                                  const IdentifierInfo *Name) {
+  assert(NNS->isDependent() && "Nested name specifier must be dependent");
+
+  llvm::FoldingSetNodeID ID;
+  DependentTemplateName::Profile(ID, NNS, Name);
+
+  void *InsertPos = 0;
+  DependentTemplateName *QTN =
+    DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (QTN)
+    return TemplateName(QTN);
+
+  NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+  if (CanonNNS == NNS) {
+    QTN = new (*this,4) DependentTemplateName(NNS, Name);
+  } else {
+    TemplateName Canon = getDependentTemplateName(CanonNNS, Name);
+    QTN = new (*this,4) DependentTemplateName(NNS, Name, Canon);
+  }
+
+  DependentTemplateNames.InsertNode(QTN, InsertPos);
+  return TemplateName(QTN);
+}
+
 /// getFromTargetType - Given one of the integer types provided by
 /// TargetInfo, produce the corresponding type. The unsigned @p Type
 /// is actually a value of type @c TargetInfo::IntType.
@@ -3033,6 +3085,10 @@
     ResultType.setCVRQualifiers(LHSCan.getCVRQualifiers());
     return ResultType;
 #endif
+
+  case Type::TemplateSpecialization:
+    assert(false && "Dependent types have no size");
+    break;
   }
 
   return QualType();

Added: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=68074&view=auto

==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (added)
+++ cfe/trunk/lib/AST/TemplateName.cpp Mon Mar 30 17:58:21 2009
@@ -0,0 +1,54 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+TemplateDecl *TemplateName::getAsTemplateDecl() const {
+  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
+    return Template;
+  
+  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
+    return QTN->getTemplateDecl();
+
+  return 0;
+}
+
+bool TemplateName::isDependent() const {
+  if (TemplateDecl *Template = getAsTemplateDecl()) {
+    // FIXME: We don't yet have a notion of dependent
+    // declarations. When we do, check that. This hack won't last
+    // long!.
+    return isa<TemplateTemplateParmDecl>(Template);
+  }
+
+  return true;
+}
+
+void TemplateName::Print(llvm::raw_ostream &OS) const {
+  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
+    OS << Template->getIdentifier()->getName();
+  else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
+    QTN->getQualifier()->Print(OS);
+    if (QTN->hasTemplateKeyword())
+      OS << "template ";
+    OS << QTN->getTemplateDecl()->getIdentifier()->getName();
+  } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
+    DTN->getQualifier()->Print(OS);
+    OS << "template ";
+    OS << DTN->getName()->getName();
+  }
+}

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

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Mar 30 17:58:21 2009
@@ -93,8 +93,8 @@
     return TOE->getUnderlyingExpr()->getType().getDesugaredType();
   if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
     return TOT->getUnderlyingType().getDesugaredType();
-  if (const ClassTemplateSpecializationType *Spec 
-        = dyn_cast<ClassTemplateSpecializationType>(this))
+  if (const TemplateSpecializationType *Spec 
+        = dyn_cast<TemplateSpecializationType>(this))
     return Spec->getCanonicalTypeInternal().getDesugaredType();
   if (const QualifiedNameType *QualName  = dyn_cast<QualifiedNameType>(this))
     return QualName->getNamedType().getDesugaredType();
@@ -549,11 +549,11 @@
   return dyn_cast<TemplateTypeParmType>(CanonicalType);
 }
 
-const ClassTemplateSpecializationType *
-Type::getAsClassTemplateSpecializationType() const {
+const TemplateSpecializationType *
+Type::getAsTemplateSpecializationType() const {
   // There is no sugar for class template specialization types, so
   // just return the canonical type pointer if it is the right class.
-  return dyn_cast<ClassTemplateSpecializationType>(CanonicalType);
+  return dyn_cast<TemplateSpecializationType>(CanonicalType);
 }
 
 bool Type::isIntegerType() const {
@@ -972,7 +972,7 @@
 }
 
 bool 
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
 anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
   for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
     switch (Args[Idx].getKind()) {
@@ -997,17 +997,16 @@
   return false;
 }
 
-ClassTemplateSpecializationType::
-ClassTemplateSpecializationType(TemplateDecl *T, const TemplateArgument *Args,
-                                unsigned NumArgs, QualType Canon)
-  : Type(ClassTemplateSpecialization, 
+TemplateSpecializationType::
+TemplateSpecializationType(TemplateName T, const TemplateArgument *Args,
+                           unsigned NumArgs, QualType Canon)
+  : Type(TemplateSpecialization, 
          Canon.isNull()? QualType(this, 0) : Canon,
-         /*FIXME: Check for dependent template */
-         anyDependentTemplateArguments(Args, NumArgs)),
+         T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
     Template(T), NumArgs(NumArgs)
 {
   assert((!Canon.isNull() || 
-          anyDependentTemplateArguments(Args, NumArgs)) &&
+          T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
          "No canonical type for non-dependent class template specialization");
 
   TemplateArgument *TemplateArgs 
@@ -1016,7 +1015,7 @@
     new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
 }
 
-void ClassTemplateSpecializationType::Destroy(ASTContext& C) {
+void TemplateSpecializationType::Destroy(ASTContext& C) {
   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
     // FIXME: Not all expressions get cloned, so we can't yet perform
     // this destruction.
@@ -1025,24 +1024,23 @@
   }
 }
 
-ClassTemplateSpecializationType::iterator
-ClassTemplateSpecializationType::end() const {
+TemplateSpecializationType::iterator
+TemplateSpecializationType::end() const {
   return begin() + getNumArgs();
 }
 
 const TemplateArgument &
-ClassTemplateSpecializationType::getArg(unsigned Idx) const {
+TemplateSpecializationType::getArg(unsigned Idx) const {
   assert(Idx < getNumArgs() && "Template argument out of range");
   return getArgs()[Idx];
 }
 
 void 
-ClassTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, 
-                                         TemplateDecl *T, 
-                                         const TemplateArgument *Args, 
-                                         unsigned NumArgs) {
-  ID.AddPointer(T);
-
+TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, 
+                                    TemplateName T, 
+                                    const TemplateArgument *Args, 
+                                    unsigned NumArgs) {
+  T.Profile(ID);
   for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
     Args[Idx].Profile(ID);
 }
@@ -1351,7 +1349,7 @@
     InnerString = Name->getName() + InnerString;
 }
 
-std::string ClassTemplateSpecializationType::PrintTemplateArgumentList(
+std::string TemplateSpecializationType::PrintTemplateArgumentList(
                                               const TemplateArgument *Args,
                                               unsigned NumArgs) {
   std::string SpecString;
@@ -1403,9 +1401,15 @@
 }
 
 void 
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
 getAsStringInternal(std::string &InnerString) const {
-  std::string SpecString = Template->getNameAsString();
+  std::string SpecString;
+
+  {
+    llvm::raw_string_ostream OS(SpecString);
+    Template.Print(OS);
+  }
+
   SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs());
   if (InnerString.empty())
     InnerString.swap(SpecString);
@@ -1515,7 +1519,7 @@
   if (ClassTemplateSpecializationDecl *Spec 
         = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
     std::string TemplateArgs 
-      = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+      = TemplateSpecializationType::PrintTemplateArgumentList(
                                                   Spec->getTemplateArgs(),
                                                   Spec->getNumTemplateArgs());
     InnerString = TemplateArgs + InnerString;
@@ -1534,7 +1538,7 @@
       } else if (ClassTemplateSpecializationDecl *Spec 
                    = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
         std::string TemplateArgs 
-          = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+          = TemplateSpecializationType::PrintTemplateArgumentList(
                                                   Spec->getTemplateArgs(),
                                                   Spec->getNumTemplateArgs());
         MyPart = Spec->getIdentifier()->getName() + TemplateArgs;

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

==============================================================================
--- cfe/trunk/lib/AST/TypeSerialization.cpp (original)
+++ cfe/trunk/lib/AST/TypeSerialization.cpp Mon Mar 30 17:58:21 2009
@@ -391,29 +391,17 @@
 }
 
 //===----------------------------------------------------------------------===//
-// ClassTemplateSpecializationType
+// TemplateSpecializationType
 //===----------------------------------------------------------------------===//
 
-void ClassTemplateSpecializationType::EmitImpl(Serializer& S) const {
-  S.Emit(getCanonicalTypeInternal());
-  S.EmitPtr(Template);
-  S.EmitInt(NumArgs);
-  // FIXME: Serialize class template specialization types
+void TemplateSpecializationType::EmitImpl(Serializer& S) const {
+  // FIXME: Serialization support
 }
 
 Type* 
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
 CreateImpl(ASTContext& Context, Deserializer& D) {
-  llvm::SmallVector<uintptr_t, 16> Args;
-  llvm::SmallVector<bool, 16> ArgIsType;
-
-  QualType Canon = QualType::ReadVal(D);
-  TemplateDecl *Template = cast<TemplateDecl>(D.ReadPtr<Decl>());
-  unsigned NumArgs = D.ReadInt();
-
-  // FIXME: De-serialize class template specialization types
-  (void)Template;
-  (void)NumArgs;
+  // FIXME: Deserialization support
   return 0;
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=68074&r1=68073&r2=68074&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Mar 30 17:58:21 2009
@@ -561,7 +561,7 @@
   case Type::FixedWidthInt:
   case Type::BlockPointer:
   case Type::MemberPointer:
-  case Type::ClassTemplateSpecialization:
+  case Type::TemplateSpecialization:
   case Type::QualifiedName:
   case Type::ObjCQualifiedClass:
     // Unsupported types

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=68074&r1=68073&r2=68074&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Mar 30 17:58:21 2009
@@ -392,6 +392,9 @@
     // http://gcc.gnu.org/onlinedocs/gccint/Type-Layout.html#Type-Layout
     assert(0 && "FIXME: We can't handle member pointers yet.");
     return llvm::OpaqueType::get();
+
+  case Type::TemplateSpecialization:
+    assert(false && "Dependent types can't get here");
   }
   
   // FIXME: implement.

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

==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Mon Mar 30 17:58:21 2009
@@ -135,7 +135,7 @@
 
 TemplateNameKind 
 MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
-                              DeclPtrTy &TemplateDecl,
+                              TemplateTy &TemplateDecl,
                               const CXXScopeSpec *SS) {
   return TNK_Non_template;
 }

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Mar 30 17:58:21 2009
@@ -474,7 +474,7 @@
     TagOrTempResult
       = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
                        StartLoc, SS,
-                       DeclPtrTy::make(TemplateId->Template), 
+                       TemplateTy::make(TemplateId->Template), 
                        TemplateId->TemplateNameLoc, 
                        TemplateId->LAngleLoc, 
                        TemplateArgsPtr,

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Mar 30 17:58:21 2009
@@ -117,7 +117,7 @@
         // an operator and not as part of a simple-template-id.
       }
 
-      DeclPtrTy Template;
+      TemplateTy Template;
       TemplateNameKind TNK = TNK_Non_template;
       // FIXME: If the nested-name-specifier thus far is dependent,
       // set TNK = TNK_Dependent_template_name and skip the

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Mar 30 17:58:21 2009
@@ -406,7 +406,7 @@
 /// last token in the stream (e.g., so that it can be replaced with an
 /// annotation token).
 bool 
-Parser::ParseTemplateIdAfterTemplateName(DeclPtrTy Template,
+Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
                                          SourceLocation TemplateNameLoc, 
                                          const CXXScopeSpec *SS,
                                          bool ConsumeLastToken,
@@ -499,7 +499,7 @@
 /// replaced with a type annotation token. Otherwise, the
 /// simple-template-id is always replaced with a template-id
 /// annotation token.
-void Parser::AnnotateTemplateIdToken(DeclPtrTy Template, TemplateNameKind TNK,
+void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                      const CXXScopeSpec *SS, 
                                      SourceLocation TemplateKWLoc,
                                      bool AllowTypeAnnotation) {
@@ -531,12 +531,13 @@
     return; 
 
   // Build the annotation token.
+  // FIXME: Not just for class templates!
   if (TNK == TNK_Class_template && AllowTypeAnnotation) {
     Action::TypeResult Type 
-      = Actions.ActOnClassTemplateId(Template, TemplateNameLoc,
-                                     LAngleLoc, TemplateArgsPtr,
-                                     &TemplateArgLocations[0],
-                                     RAngleLoc, SS);
+      = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
+                                    LAngleLoc, TemplateArgsPtr,
+                                    &TemplateArgLocations[0],
+                                    RAngleLoc);
     if (Type.isInvalid()) // FIXME: better recovery?
       return;
 
@@ -603,12 +604,12 @@
                                      TemplateId->NumArgs);
 
   Action::TypeResult Type 
-    = Actions.ActOnClassTemplateId(DeclPtrTy::make(TemplateId->Template),
-                                   TemplateId->TemplateNameLoc,
-                                   TemplateId->LAngleLoc, 
-                                   TemplateArgsPtr,
-                                   TemplateId->getTemplateArgLocations(),
-                                   TemplateId->RAngleLoc, SS);
+    = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+                                  TemplateId->TemplateNameLoc,
+                                  TemplateId->LAngleLoc, 
+                                  TemplateArgsPtr,
+                                  TemplateId->getTemplateArgLocations(),
+                                  TemplateId->RAngleLoc);
   if (Type.isInvalid()) {
     // FIXME: better recovery?
     ConsumeToken();

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

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Mar 30 17:58:21 2009
@@ -885,7 +885,7 @@
     
     // If this is a template-id, annotate with a template-id or type token.
     if (NextToken().is(tok::less)) {
-      DeclPtrTy Template;
+      TemplateTy Template;
       if (TemplateNameKind TNK 
             = Actions.isTemplateName(*Tok.getIdentifierInfo(),
                                      CurScope, Template, &SS))

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Mar 30 17:58:21 2009
@@ -1691,7 +1691,7 @@
   // C++ Templates [C++ 14]
   //
   virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
-                                          DeclPtrTy &TemplateDecl,
+                                          TemplateTy &Template,
                                           const CXXScopeSpec *SS = 0);
   bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
   TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
@@ -1742,20 +1742,19 @@
                      MultiTemplateParamsArg TemplateParameterLists,
                      AccessSpecifier AS);
 
-  QualType CheckClassTemplateId(ClassTemplateDecl *ClassTemplate,
-                                SourceLocation TemplateLoc,
-                                SourceLocation LAngleLoc,
-                                const TemplateArgument *TemplateArgs,
-                                unsigned NumTemplateArgs,
-                                SourceLocation RAngleLoc);
+  QualType CheckTemplateIdType(TemplateName Template,
+                               SourceLocation TemplateLoc,
+                               SourceLocation LAngleLoc,
+                               const TemplateArgument *TemplateArgs,
+                               unsigned NumTemplateArgs,
+                               SourceLocation RAngleLoc);
 
   virtual TypeResult
-  ActOnClassTemplateId(DeclPtrTy Template, SourceLocation TemplateLoc,
-                       SourceLocation LAngleLoc,
-                       ASTTemplateArgsPtr TemplateArgs,
-                       SourceLocation *TemplateArgLocs,
-                       SourceLocation RAngleLoc,
-                       const CXXScopeSpec *SS);
+  ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
+                      SourceLocation LAngleLoc,
+                      ASTTemplateArgsPtr TemplateArgs,
+                      SourceLocation *TemplateArgLocs,
+                      SourceLocation RAngleLoc);
   
   bool CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate,
                                     ClassTemplateSpecializationDecl *PrevDecl,
@@ -1766,7 +1765,7 @@
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                    SourceLocation KWLoc, 
                                    const CXXScopeSpec &SS,
-                                   DeclPtrTy Template,
+                                   TemplateTy Template,
                                    SourceLocation TemplateNameLoc,
                                    SourceLocation LAngleLoc,
                                    ASTTemplateArgsPtr TemplateArgs,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Mar 30 17:58:21 2009
@@ -27,19 +27,23 @@
 /// passed to indicate the C++ scope in which the identifier will be
 /// found. 
 TemplateNameKind Sema::isTemplateName(IdentifierInfo &II, Scope *S,
-                                      DeclPtrTy &Template,
+                                      TemplateTy &TemplateResult,
                                       const CXXScopeSpec *SS) {
   NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
 
+  TemplateNameKind TNK = TNK_Non_template;
+  TemplateDecl *Template = 0;
+
   if (IIDecl) {
-    if (isa<TemplateDecl>(IIDecl)) {
-      Template = DeclPtrTy::make(IIDecl);
+    if ((Template = dyn_cast<TemplateDecl>(IIDecl))) {
       if (isa<FunctionTemplateDecl>(IIDecl))
-        return TNK_Function_template;
-      if (isa<ClassTemplateDecl>(IIDecl))
-        return TNK_Class_template;
-      assert(isa<TemplateTemplateParmDecl>(IIDecl) && "Unknown TemplateDecl");
-      return TNK_Template_template_parm;
+        TNK = TNK_Function_template;
+      else if (isa<ClassTemplateDecl>(IIDecl))
+        TNK = TNK_Class_template;
+      else if (isa<TemplateTemplateParmDecl>(IIDecl))
+        TNK = TNK_Template_template_parm;
+      else
+        assert(false && "Unknown template declaration kind");
     } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(IIDecl)) {
       // C++ [temp.local]p1:
       //   Like normal (non-template) classes, class templates have an
@@ -54,12 +58,12 @@
       //   specialization.
       if (Record->isInjectedClassName()) {
         Record = cast<CXXRecordDecl>(Context.getCanonicalDecl(Record));
-        if ((Template = DeclPtrTy::make(Record->getDescribedClassTemplate())))
-          return TNK_Class_template;
-        if (ClassTemplateSpecializationDecl *Spec
+        if ((Template = Record->getDescribedClassTemplate()))
+          TNK = TNK_Class_template;
+        else if (ClassTemplateSpecializationDecl *Spec
                    = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
-          Template = DeclPtrTy::make(Spec->getSpecializedTemplate());
-          return TNK_Class_template;
+          Template = Spec->getSpecializedTemplate();
+          TNK = TNK_Class_template;
         }
       }
     }
@@ -67,7 +71,7 @@
     // FIXME: What follows is a gross hack.
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
       if (FD->getType()->isDependentType()) {
-        Template = DeclPtrTy::make(FD);
+        TemplateResult = TemplateTy::make(FD);
         return TNK_Function_template;
       }
     } else if (OverloadedFunctionDecl *Ovl 
@@ -76,13 +80,25 @@
                                                   FEnd = Ovl->function_end();
            F != FEnd; ++F) {
         if ((*F)->getType()->isDependentType()) {
-          Template = DeclPtrTy::make(Ovl);
+          TemplateResult = TemplateTy::make(Ovl);
           return TNK_Function_template;
         }
       }
     }
+
+    if (TNK != TNK_Non_template) {
+      if (SS && SS->isSet() && !SS->isInvalid()) {
+        NestedNameSpecifier *Qualifier 
+          = static_cast<NestedNameSpecifier *>(SS->getScopeRep());
+        TemplateResult 
+          = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier, 
+                                                              false,
+                                                              Template));
+      } else
+        TemplateResult = TemplateTy::make(TemplateName(Template));
+    }
   }
-  return TNK_Non_template;
+  return TNK;
 }
 
 /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
@@ -700,27 +716,30 @@
   }
 }
 
-QualType Sema::CheckClassTemplateId(ClassTemplateDecl *ClassTemplate,
-                                    SourceLocation TemplateLoc,
-                                    SourceLocation LAngleLoc,
-                                    const TemplateArgument *TemplateArgs,
-                                    unsigned NumTemplateArgs,
-                                    SourceLocation RAngleLoc) {
+QualType Sema::CheckTemplateIdType(TemplateName Name,
+                                   SourceLocation TemplateLoc,
+                                   SourceLocation LAngleLoc,
+                                   const TemplateArgument *TemplateArgs,
+                                   unsigned NumTemplateArgs,
+                                   SourceLocation RAngleLoc) {
+  TemplateDecl *Template = Name.getAsTemplateDecl();
+  assert(Template && "Cannot handle dependent template-names yet");
+
   // Check that the template argument list is well-formed for this
   // template.
   llvm::SmallVector<TemplateArgument, 16> ConvertedTemplateArgs;
-  if (CheckTemplateArgumentList(ClassTemplate, TemplateLoc, LAngleLoc, 
+  if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc, 
                                 TemplateArgs, NumTemplateArgs, RAngleLoc,
                                 ConvertedTemplateArgs))
     return QualType();
 
   assert((ConvertedTemplateArgs.size() == 
-            ClassTemplate->getTemplateParameters()->size()) &&
+            Template->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
 
   QualType CanonType;
 
-  if (ClassTemplateSpecializationType::anyDependentTemplateArguments(
+  if (TemplateSpecializationType::anyDependentTemplateArguments(
                                                       TemplateArgs,
                                                       NumTemplateArgs)) {
     // This class template specialization is a dependent
@@ -731,10 +750,11 @@
     //
     //   template<typename T, typename U = T> struct A;
 
-    CanonType = Context.getClassTemplateSpecializationType(ClassTemplate, 
+    CanonType = Context.getTemplateSpecializationType(Name, 
                                                     &ConvertedTemplateArgs[0],
                                                 ConvertedTemplateArgs.size());
-  } else {
+  } else if (ClassTemplateDecl *ClassTemplate 
+               = dyn_cast<ClassTemplateDecl>(Template)) {
     // Find the class template specialization declaration that
     // corresponds to these arguments.
     llvm::FoldingSetNodeID ID;
@@ -764,35 +784,26 @@
   // Build the fully-sugared type for this class template
   // specialization, which refers back to the class template
   // specialization we created or found.
-  return Context.getClassTemplateSpecializationType(ClassTemplate, 
-                                                    TemplateArgs,
-                                                    NumTemplateArgs, 
-                                                    CanonType);
+  return Context.getTemplateSpecializationType(Name, TemplateArgs,
+                                               NumTemplateArgs, CanonType);
 }
 
 Action::TypeResult
-Sema::ActOnClassTemplateId(DeclPtrTy TemplateD, SourceLocation TemplateLoc,
-                           SourceLocation LAngleLoc, 
-                           ASTTemplateArgsPtr TemplateArgsIn,
-                           SourceLocation *TemplateArgLocs,
-                           SourceLocation RAngleLoc,
-                           const CXXScopeSpec *SS) {
-  TemplateDecl *Template = cast<TemplateDecl>(TemplateD.getAs<Decl>());
-  ClassTemplateDecl *ClassTemplate = cast<ClassTemplateDecl>(Template);
+Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
+                          SourceLocation LAngleLoc, 
+                          ASTTemplateArgsPtr TemplateArgsIn,
+                          SourceLocation *TemplateArgLocs,
+                          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);
 
-  QualType Result = CheckClassTemplateId(ClassTemplate, TemplateLoc,
-                                         LAngleLoc, 
-                                         &TemplateArgs[0],
-                                         TemplateArgs.size(),
-                                         RAngleLoc);
+  QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
+                                        &TemplateArgs[0], TemplateArgs.size(),
+                                        RAngleLoc);
   
-  if (SS)
-    Result = getQualifiedNameType(*SS, Result);
-
   TemplateArgsIn.release();
   return Result.getAsOpaquePtr();
 }
@@ -1795,7 +1806,7 @@
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                        SourceLocation KWLoc, 
                                        const CXXScopeSpec &SS,
-                                       DeclPtrTy TemplateD,
+                                       TemplateTy TemplateD,
                                        SourceLocation TemplateNameLoc,
                                        SourceLocation LAngleLoc,
                                        ASTTemplateArgsPtr TemplateArgsIn,
@@ -1804,10 +1815,9 @@
                                        AttributeList *Attr,
                                MultiTemplateParamsArg TemplateParameterLists) {
   // Find the class template we're specializing
+  TemplateName Name = TemplateD.getAsVal<TemplateName>();
   ClassTemplateDecl *ClassTemplate 
-    = dyn_cast_or_null<ClassTemplateDecl>(TemplateD.getAs<Decl>());
-  if (!ClassTemplate)
-    return true;
+    = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
 
   // Check the validity of the template headers that introduce this
   // template.
@@ -1937,11 +1947,11 @@
   // name based on the "canonical" representation used to store the
   // template arguments in the specialization.
   QualType WrittenTy 
-    = Context.getClassTemplateSpecializationType(ClassTemplate, 
-                                                 &TemplateArgs[0],
-                                                 TemplateArgs.size(),
+    = Context.getTemplateSpecializationType(Name, 
+                                            &TemplateArgs[0],
+                                            TemplateArgs.size(),
                                   Context.getTypeDeclType(Specialization));
-  Specialization->setTypeAsWritten(getQualifiedNameType(SS, WrittenTy));
+  Specialization->setTypeAsWritten(WrittenTy);
   TemplateArgsIn.release();
 
   // C++ [temp.expl.spec]p9:

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Mar 30 17:58:21 2009
@@ -114,7 +114,7 @@
     case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
       TemplateDecl *Template = cast<TemplateDecl>((Decl *)Active->Entity);
       std::string TemplateArgsStr
-        = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+        = TemplateSpecializationType::PrintTemplateArgumentList(
                                                       Active->TemplateArgs, 
                                                       Active->NumTemplateArgs);
       Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
@@ -433,13 +433,12 @@
 
 QualType 
 TemplateTypeInstantiator::
-InstantiateClassTemplateSpecializationType(
-                                  const ClassTemplateSpecializationType *T,
+InstantiateTemplateSpecializationType(
+                                  const TemplateSpecializationType *T,
                                   unsigned Quals) const {
   llvm::SmallVector<TemplateArgument, 16> InstantiatedTemplateArgs;
   InstantiatedTemplateArgs.reserve(T->getNumArgs());
-  for (ClassTemplateSpecializationType::iterator Arg = T->begin(), 
-                                              ArgEnd = T->end();
+  for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
        Arg != ArgEnd; ++Arg) {
     switch (Arg->getKind()) {
     case TemplateArgument::Type: {
@@ -473,12 +472,13 @@
 
   // FIXME: We're missing the locations of the template name, '<', and
   // '>'.
-  return SemaRef.CheckClassTemplateId(cast<ClassTemplateDecl>(T->getTemplate()),
-                                      Loc,
-                                      SourceLocation(),
-                                      &InstantiatedTemplateArgs[0],
-                                      InstantiatedTemplateArgs.size(),
-                                      SourceLocation());
+  // FIXME: Need to instantiate into the template name.
+  return SemaRef.CheckTemplateIdType(T->getTemplateName(),
+                                     Loc,
+                                     SourceLocation(),
+                                     &InstantiatedTemplateArgs[0],
+                                     InstantiatedTemplateArgs.size(),
+                                     SourceLocation());
 }
 
 QualType 





More information about the cfe-commits mailing list