[cfe-commits] r164655 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp test/CXX/temp/temp.param/p15-cxx0x.cpp test/Misc/diag-template-diffing.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Sep 25 19:18:14 PDT 2012


Author: rsmith
Date: Tue Sep 25 21:18:13 2012
New Revision: 164655

URL: http://llvm.org/viewvc/llvm-project?rev=164655&view=rev
Log:
Teach Type::getAs<TemplateSpecializationType> that a TemplateSpecializationType
for a type alias template can appear as sugar at any level of desugaring, just
like a TypedefType.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/test/CXX/temp/temp.param/p15-cxx0x.cpp
    cfe/trunk/test/Misc/diag-template-diffing.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=164655&r1=164654&r2=164655&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Sep 25 21:18:13 2012
@@ -1804,6 +1804,11 @@
 /// until it reaches a TypedefType or a non-sugared type.
 template <> const TypedefType *Type::getAs() const;
 
+/// \brief This will check for a TemplateSpecializationType by removing any
+/// existing sugar until it reaches a TemplateSpecializationType or a
+/// non-sugared type.
+template <> const TemplateSpecializationType *Type::getAs() const;
+
 // We can do canonical leaf types faster, because we don't have to
 // worry about preserving child type decoration.
 #define TYPE(Class, Base)

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=164655&r1=164654&r2=164655&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue Sep 25 21:18:13 2012
@@ -288,18 +288,17 @@
   return T;
 }
 
-/// \brief This will check for a TypedefType by removing any existing sugar
-/// until it reaches a TypedefType or a non-sugared type.
-template <> const TypedefType *Type::getAs() const {
-  const Type *Cur = this;
-
+/// \brief This will check for a T (which should be a Type which can act as
+/// sugar, such as a TypedefType) by removing any existing sugar until it
+/// reaches a T or a non-sugared type.
+template<typename T> static const T *getAsSugar(const Type *Cur) {
   while (true) {
-    if (const TypedefType *TDT = dyn_cast<TypedefType>(Cur))
-      return TDT;
+    if (const T *Sugar = dyn_cast<T>(Cur))
+      return Sugar;
     switch (Cur->getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
 #define TYPE(Class, Parent) \
-    case Class: { \
+    case Type::Class: { \
       const Class##Type *Ty = cast<Class##Type>(Cur); \
       if (!Ty->isSugared()) return 0; \
       Cur = Ty->desugar().getTypePtr(); \
@@ -310,6 +309,14 @@
   }
 }
 
+template <> const TypedefType *Type::getAs() const {
+  return getAsSugar<TypedefType>(this);
+}
+
+template <> const TemplateSpecializationType *Type::getAs() const {
+  return getAsSugar<TemplateSpecializationType>(this);
+}
+
 /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
 /// sugar off the given type.  This should produce an object of the
 /// same dynamic type as the canonical type.

Modified: cfe/trunk/test/CXX/temp/temp.param/p15-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p15-cxx0x.cpp?rev=164655&r1=164654&r2=164655&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.param/p15-cxx0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.param/p15-cxx0x.cpp Tue Sep 25 21:18:13 2012
@@ -95,13 +95,17 @@
 };
 
 using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}}
-using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<int, char, double, (no argument)>'}}
+// FIXME: Desguar the types on the RHS in this diagnostic.
+// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, (no argument)>'}}
+using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, (no argument)>'}}
 using D1 = drop<3, int, char, double, long>::type;
 using D1 = types<long>;
 
 using T2 = take<4, int, char, double, long>::type; // expected-note {{previous}}
 using T2 = types<int, char, double, long>;
-using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<int, char, double, long>'}}
+// FIXME: Desguar the types on the RHS in this diagnostic.
+// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, long>'}}
+using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, typename inner<_>::type>'}}
 using D2 = drop<4, int, char, double, long>::type;
 using D2 = types<>;
 

Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=164655&r1=164654&r2=164655&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Tue Sep 25 21:18:13 2012
@@ -426,6 +426,24 @@
 // CHECK-NOELIDE-TREE:     &b13, 
 // CHECK-NOELIDE-TREE:     [&d13 != (no argument)]>
 
+template<typename T> struct s14 {};
+template<typename T> using a14 = s14<T>;
+typedef a14<int> b14;
+template<typename T> using c14 = b14;
+int f14(c14<int>);
+int k14 = f14(a14<char>());
+// CHECK-ELIDE-NOTREE: no matching function for call to 'f14'
+// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'a14<char>' to 'a14<int>' for 1st argument
+// CHECK-NOELIDE-NOTREE: no matching function for call to 'f14'
+// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'a14<char>' to 'a14<int>' for 1st argument
+// CHECK-ELIDE-TREE: no matching function for call to 'f14'
+// CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
+// CHECK-ELIDE-TREE:   a14<
+// CHECK-ELIDE-TREE:     [char != int]>
+// CHECK-NOELIDE-TREE: no matching function for call to 'f14'
+// CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
+// CHECK-NOELIDE-TREE:   a14<
+// CHECK-NOELIDE-TREE:     [char != int]>
 
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.





More information about the cfe-commits mailing list