[cfe-commits] r80783 - in /cfe/trunk: lib/AST/Type.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/typename-specifier-4.cpp

Douglas Gregor dgregor at apple.com
Wed Sep 2 06:05:45 PDT 2009


Author: dgregor
Date: Wed Sep  2 08:05:45 2009
New Revision: 80783

URL: http://llvm.org/viewvc/llvm-project?rev=80783&view=rev
Log:
When parsing typename specifiers (with either the identifier or
simple-template-id form), check whether the scope specifier is
computable as a declaration context rather than checking whether it is
dependent, so that we properly cope with members of the current
instantiation. 

Improve testing for typename specifiers that terminate in a
simpe-template-id.

Added:
    cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp   (with props)
Modified:
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

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

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Sep  2 08:05:45 2009
@@ -530,7 +530,7 @@
 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<TemplateSpecializationType>(CanonicalType);
+  return this->getAs<TemplateSpecializationType>();
 }
 
 bool Type::isIntegerType() const {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Sep  2 08:05:45 2009
@@ -1137,9 +1137,7 @@
   NestedNameSpecifier *Qualifier 
     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
 
-  // FIXME: member of the current instantiation
-
-  if (!Qualifier->isDependent()) {
+  if (computeDeclContext(SS, false)) {
     // C++0x [temp.names]p5:
     //   If a name prefixed by the keyword template is not the name of
     //   a template, the program is ill-formed. [Note: the keyword
@@ -3010,10 +3008,16 @@
     = T->getAsTemplateSpecializationType();
   assert(TemplateId && "Expected a template specialization type");
 
-  if (NNS->isDependent())
-    return Context.getTypenameType(NNS, TemplateId).getAsOpaquePtr();
-
-  return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+  if (computeDeclContext(SS, false)) {
+    // If we can compute a declaration context, then the "typename"
+    // keyword was superfluous. Just build a QualifiedNameType to keep
+    // track of the nested-name-specifier.
+    
+    // FIXME: Note that the QualifiedNameType had the "typename" keyword!
+    return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+  }
+  
+  return Context.getTypenameType(NNS, TemplateId).getAsOpaquePtr();
 }
 
 /// \brief Build the type that describes a C++ typename specifier,

Added: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp?rev=80783&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp (added)
+++ cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp Wed Sep  2 08:05:45 2009
@@ -0,0 +1,56 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template<typename T, typename U> 
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
+template<typename MetaFun, typename T1, typename T2>
+struct metafun_apply2 {
+  typedef typename MetaFun::template apply<T1, T2> inner;
+  typedef typename inner::type type;
+};
+
+template<typename T, typename U> struct pair;
+
+struct make_pair {
+  template<typename T1, typename T2>
+  struct apply {
+    typedef pair<T1, T2> type;
+  };
+};
+
+int a0[is_same<metafun_apply2<make_pair, int, float>::type, 
+               pair<int, float> >::value? 1 : -1];
+int a1[is_same<
+         typename make_pair::template apply<int, float>,
+         make_pair::apply<int, float>
+       >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2 {
+  template<typename T1, typename T2>
+  struct apply {
+    typedef typename MetaFun::template apply<T2, T1> new_metafun;
+    typedef typename new_metafun::type type;
+  };
+};
+
+int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, 
+               pair<float, int> >::value? 1 : -1];
+
+template<typename T>
+struct X0 {
+  template<typename U, typename V>
+  struct Inner;
+  
+  void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+  void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
+
+  void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+  void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
+};

Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp

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

Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp

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

Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp

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





More information about the cfe-commits mailing list