[cfe-commits] r71152 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/dependent-type-identity.cpp

Douglas Gregor dgregor at apple.com
Wed May 6 23:41:54 PDT 2009


Author: dgregor
Date: Thu May  7 01:41:52 2009
New Revision: 71152

URL: http://llvm.org/viewvc/llvm-project?rev=71152&view=rev
Log:
Start canonicalizing template names. This is not yet complete, but it
improves type identity with dependent types.

Added:
    cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp   (with props)
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu May  7 01:41:52 2009
@@ -604,6 +604,26 @@
   NestedNameSpecifier *
   getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS);
 
+  /// \brief Retrieves the "canonical" template name that refers to a
+  /// given template.
+  ///
+  /// The canonical template name is the simplest expression that can
+  /// be used to refer to a given template. For most templates, this
+  /// expression is just the template declaration itself. For example,
+  /// the template std::vector can be referred to via a variety of
+  /// names---std::vector, ::std::vector, vector (if vector is in
+  /// scope), etc.---but all of these names map down to the same
+  /// TemplateDecl, which is used to form the canonical template name.
+  ///
+  /// Dependent template names are more interesting. Here, the
+  /// template name could be something like T::template apply or
+  /// std::allocator<T>::template rebind, where the nested name
+  /// specifier itself is dependent. In this case, the canonical
+  /// template name uses the shortest form of the dependent
+  /// nested-name-specifier, which itself contains all canonical
+  /// types, values, and templates.
+  TemplateName getCanonicalTemplateName(TemplateName Name);
+
   /// Type Query functions.  If the type is an instance of the specified class,
   /// return the Type pointer for the underlying maximally pretty type.  This
   /// is a member of ASTContext because this may need to do some amount of

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu May  7 01:41:52 2009
@@ -1700,6 +1700,17 @@
                               VAT->getIndexTypeQualifier());
 }
 
+TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
+  // If this template name refers to a template, the canonical
+  // template name merely stores the template itself.
+  if (TemplateDecl *Template = Name.getAsTemplateDecl())
+    return TemplateName(Template);
+
+  DependentTemplateName *DTN = Name.getAsDependentTemplateName();
+  assert(DTN && "Non-dependent template names must refer to template decls.");
+  return DTN->CanonicalTemplateName;
+}
+
 NestedNameSpecifier *
 ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
   if (!NNS) 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu May  7 01:41:52 2009
@@ -818,8 +818,8 @@
     // A<T, T> have identical types when A is declared as:
     //
     //   template<typename T, typename U = T> struct A;
-
-    CanonType = Context.getTemplateSpecializationType(Name, 
+    TemplateName CanonName = Context.getCanonicalTemplateName(Name);
+    CanonType = Context.getTemplateSpecializationType(CanonName, 
                                                     &ConvertedTemplateArgs[0],
                                                 ConvertedTemplateArgs.size());
   } else if (ClassTemplateDecl *ClassTemplate 

Added: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp?rev=71152&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp (added)
+++ cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp Thu May  7 01:41:52 2009
@@ -0,0 +1,40 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 { };
+
+template<typename T, typename U>
+struct X1 {
+  typedef T type;
+
+  void f0(T); // expected-note{{previous}}
+  void f0(U);
+  void f0(type); // expected-error{{redeclar}}
+
+  void f1(T*); // expected-note{{previous}}
+  void f1(U*);
+  void f1(type*); // expected-error{{redeclar}}
+
+  void f2(X0<T>*); // expected-note{{previous}}
+  void f2(X0<U>*);
+  void f2(X0<type>*); // expected-error{{redeclar}}
+
+  void f3(X0<T>*); // expected-note{{previous}}
+  void f3(X0<U>*);
+  void f3(::X0<type>*); // expected-error{{redeclar}}  
+
+  void f4(typename T::template apply<U>*);
+  void f4(typename U::template apply<U>*);
+  void f4(typename type::template apply<T>*);
+  // FIXME: this is a duplicate of the first f4, but we are not fully
+  // canonicalizing nested-name-specifiers yet.
+  void f4(typename type::template apply<U>*);
+
+  void f5(typename T::template apply<U>::type*);
+  void f5(typename U::template apply<U>::type*);
+  void f5(typename U::template apply<T>::type*);
+  void f5(typename type::template apply<T>::type*);
+  // FIXME: this is a duplicate of the first f5, but we are not fully
+  // canonicalizing nested-name-specifiers yet.
+  void f5(typename type::template apply<U>::type*);
+};

Propchange: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp

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

Propchange: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp

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

Propchange: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp

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





More information about the cfe-commits mailing list