Author: rtrieu
Date: Thu Jan 14 23:48:38 2016
New Revision: 257870

URL: http://llvm.org/viewvc/llvm-project?rev=257870&view=rev
Log:
Fixing more issues with template type diffing

1) Print qualifiers for templates with zero arguments
2) Add a few more tests for the template type diffing refactoring.
Specifically, PR24587 has been fixed and has a test case from
http://reviews.llvm.org/D15384
3) Adds asserts to check the DiffTree is in correct state when moving nodes
4) Rename the field FromType and ToType since it is heavily used within
member functions.

Modified:
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/test/Misc/diag-template-diffing.cpp

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=257870&r1=257869&r2=257870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Thu Jan 14 23:48:38 2016
@@ -473,14 +473,14 @@ class TemplateDiff {
   /// ShowColor - Diagnostics support color, so bolding will be used.
   bool ShowColor;
 
-  /// FromType - When single type printing is selected, this is the type to be
-  /// be printed.  When tree printing is selected, this type will show up first
-  /// in the tree.
-  QualType FromType;
-
-  /// ToType - The type that FromType is compared to.  Only in tree printing
-  /// will this type be outputed.
-  QualType ToType;
+  /// FromTemplateType - When single type printing is selected, this is the
+  /// type to be be printed.  When tree printing is selected, this type will
+  /// show up first in the tree.
+  QualType FromTemplateType;
+
+  /// ToTemplateType - The type that FromType is compared to.  Only in tree
+  /// printing will this type be outputed.
+  QualType ToTemplateType;
 
   /// OS - The stream used to construct the output strings.
   raw_ostream &OS;
@@ -704,12 +704,16 @@ class TemplateDiff {
 
     /// Up - Changes the node to the parent of the current node.
     void Up() {
+      assert(FlatTree[CurrentNode].Kind != Invalid &&
+             "Cannot exit node before setting node information.");
       CurrentNode = FlatTree[CurrentNode].ParentNode;
     }
 
     /// AddNode - Adds a child node to the current node, then sets that node
     /// node as the current node.
     void AddNode() {
+      assert(FlatTree[CurrentNode].Kind == Template &&
+             "Only Template nodes can have children nodes.");
       FlatTree.push_back(DiffNode(CurrentNode));
       DiffNode &Node = FlatTree[CurrentNode];
       if (Node.ChildNode == 0) {
@@ -1032,7 +1036,7 @@ class TemplateDiff {
   // These functions build up the template diff tree, including functions to
   // retrieve and compare template arguments.
 
-  static const TemplateSpecializationType * GetTemplateSpecializationType(
+  static const TemplateSpecializationType *GetTemplateSpecializationType(
       ASTContext &Context, QualType Ty) {
     if (const TemplateSpecializationType *TST =
             Ty->getAs<TemplateSpecializationType>())
@@ -1507,6 +1511,8 @@ class TemplateDiff {
         Qualifiers FromQual, ToQual;
         Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
 
+        PrintQualifiers(FromQual, ToQual);
+
         if (!Tree.HasChildren()) {
           // If we're dealing with a template specialization with zero
           // arguments, there are no children; special-case this.
@@ -1514,8 +1520,6 @@ class TemplateDiff {
           return;
         }
 
-        PrintQualifiers(FromQual, ToQual);
-
         OS << FromTD->getNameAsString() << '<';
         Tree.MoveToChild();
         unsigned NumElideArgs = 0;
@@ -1962,21 +1966,21 @@ public:
       PrintTree(PrintTree),
       ShowColor(ShowColor),
       // When printing a single type, the FromType is the one printed.
-      FromType(PrintFromType ? FromType : ToType),
-      ToType(PrintFromType ? ToType : FromType),
+      FromTemplateType(PrintFromType ? FromType : ToType),
+      ToTemplateType(PrintFromType ? ToType : FromType),
       OS(OS),
       IsBold(false) {
   }
 
   /// DiffTemplate - Start the template type diffing.
   void DiffTemplate() {
-    Qualifiers FromQual = FromType.getQualifiers(),
-               ToQual = ToType.getQualifiers();
+    Qualifiers FromQual = FromTemplateType.getQualifiers(),
+               ToQual = ToTemplateType.getQualifiers();
 
     const TemplateSpecializationType *FromOrigTST =
-        GetTemplateSpecializationType(Context, FromType);
+        GetTemplateSpecializationType(Context, FromTemplateType);
     const TemplateSpecializationType *ToOrigTST =
-        GetTemplateSpecializationType(Context, ToType);
+        GetTemplateSpecializationType(Context, ToTemplateType);
 
     // Only checking templates.
     if (!FromOrigTST || !ToOrigTST)

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=257870&r1=257869&r2=257870&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Thu Jan 14 23:48:38 2016
@@ -1371,6 +1371,62 @@ C<int &, x> c2 = C<int>();
 // CHECK-ELIDE-TREE:     [(default) 11 != x]>
 }
 
+namespace default_args {
+  template <int x, int y = 1+1, int z = 2>
+  class A {};
+
+  void foo(A<0> &M) {
+    // CHECK-ELIDE-NOTREE: no viable conversion from 'A<[...], (default) 1 + 1 
aka 2, (default) 2>' to 'A<[...], 0, 0>'
+    A<0, 0, 0> N = M;
+
+    // CHECK-ELIDE-NOTREE: no viable conversion from 'A<[2 * ...], (default) 
2>' to 'A<[2 * ...], 0>'
+    A<0, 2, 0> N2 = M;
+  }
+}
+
+namespace DefaultNonTypeArgWithDependentType {
+// We used to crash diffing integer template arguments when the argument type
+// is dependent and default arguments were used.
+template <typename SizeType = int, SizeType = 0> struct A {};
+template <typename R = A<>> R bar();
+A<> &foo() { return bar(); }
+// CHECK-ELIDE-NOTREE: error: non-const lvalue reference to type 'A<[2 * 
...]>' cannot bind to a temporary of type 'A<[2 * ...]>'
+// CHECK-NOELIDE-NOTREE: error: non-const lvalue reference to type 'A<int, 0>' 
cannot bind to a temporary of type 'A<int, 0>'
+}
+
+namespace PR24587 {
+template <typename T, T v>
+struct integral_constant {};
+
+auto false_ = integral_constant<bool, false> {};
+
+template <typename T>
+void f(T, decltype(false_));
+
+void run() {
+  f(1, integral_constant<bool, true>{});
+}
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'f'
+// CHECK-ELIDE-NOTREE: note: candidate function [with T = int] not viable: no 
known conversion from 'integral_constant<[...], true>' to 
'integral_constant<[...], false>' for 2nd argument
+}
+
+namespace ZeroArgs {
+template <int N = 0> class A {};
+template <class T = A<>> class B {};
+A<1> a1 = A<>();
+A<> a2 = A<1>();
+B<> b1 = B<int>();
+B<int> b2 = B<>();
+B<> b3 = B<const A<>>();
+B<const A<>> b4 = B<>();
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'A<(default) 0>' to 
'A<1>'
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'A<1>' to 'A<(default) 
0>'
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'B<int>' to 
'B<(default) ZeroArgs::A<0>>'
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'B<(default) 
ZeroArgs::A<0>>' to 'B<int>'
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'B<const A<[...]>>' to 
'B<A<[...]>>'
+// CHECK-ELIDE-NOTREE: error: no viable conversion from 'B<A<[...]>>' to 
'B<const A<[...]>>'
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to