reikdas updated this revision to Diff 293432.
reikdas added a comment.

Attempt an alternate approach, following @rsmith 's inline suggestions. 
Unfortunately, one of the tests added in this revision unexpectedly fail in 
this approach :(


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77598/new/

https://reviews.llvm.org/D77598

Files:
  clang/include/clang/AST/StmtDataCollectors.td
  clang/include/clang/AST/TemplateBase.h
  clang/lib/AST/ASTTypeTraits.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Analysis/PathDiagnostic.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/temp_arg_nontype.cpp
  clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
  
clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp

Index: clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
===================================================================
--- clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
+++ clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
@@ -20,7 +20,11 @@
     llvm::raw_string_ostream Stream(ArgStr);
     const TemplateArgument &Arg = ArgLoc.getArgument();
 
-    Arg.print(Context->getPrintingPolicy(), Stream);
+    bool knownType = true;
+    if (auto *DRE = dyn_cast<DeclRefExpr>(Arg.getAsExpr()))
+      if (DRE->hadMultipleCandidates())
+        knownType = false;
+    Arg.print(Context->getPrintingPolicy(), Stream, knownType);
     Match(Stream.str(), ArgLoc.getLocation());
     return ExpectedLocationVisitor<TemplateArgumentLocTraverser>::
       TraverseTemplateArgumentLoc(ArgLoc);
Index: clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -459,3 +459,13 @@
   X<f> y;
   int n = y.call(); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}
 }
+
+namespace PR9227 {
+  template <auto N> struct S {};
+  template <> struct S<1> { using type = int; }; // expected-note {{'S<1>::type' declared here}}
+  S<1L>::type t; // expected-error {{no type named 'type' in 'PR9227::S<1L>'; did you mean 'S<1>::type'?}}
+
+  template <auto N> struct A {};
+  template <> struct A<1> { using type = int; }; // expected-note {{'A<1>::type' declared here}}
+  A<2>::type x; // expected-error {{no type named 'type' in 'PR9227::A<2>'; did you mean 'A<1>::type'?}}
+}
Index: clang/test/SemaTemplate/temp_arg_nontype.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -270,6 +270,23 @@
   void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>'; did you mean 'enable_if_char<'a'>::type'?}}
   void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>'; did you mean 'enable_if_char<'a'>::type'?}}
   void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>'; did you mean 'enable_if_char<'a'>::type'?}}
+
+  template <int N> struct enable_if_int {};
+  template <> struct enable_if_int<1> { typedef int type; }; // expected-note{{'enable_if_int<1>::type' declared here}}
+  void test_int() { enable_if_int<2>::type i; } // expected-error{{enable_if_int<2>'; did you mean 'enable_if_int<1>::type'?}}
+
+  template <unsigned int N> struct enable_if_unsigned_int {};
+  template <> struct enable_if_unsigned_int<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_int<1>::type' declared here}}
+  void test_unsigned_int() { enable_if_unsigned_int<2>::type i; } // expected-error{{enable_if_unsigned_int<2>'; did you mean 'enable_if_unsigned_int<1>::type'?}}
+
+  template <unsigned long long N> struct enable_if_unsigned_long_long {};
+  template <> struct enable_if_unsigned_long_long<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_long_long<1>::type' declared here}}
+  void test_unsigned_long_long() { enable_if_unsigned_long_long<2>::type i; } // expected-error{{enable_if_unsigned_long_long<2>'; did you mean 'enable_if_unsigned_long_long<1>::type'?}}
+
+  template <long long N> struct enable_if_long_long {};
+  template <> struct enable_if_long_long<1> { typedef int type; }; // expected-note{{'enable_if_long_long<1>::type' declared here}}
+  void test_long_long() { enable_if_long_long<2>::type i; } // expected-error{{enable_if_long_long<2>'; did you mean 'enable_if_long_long<1>::type'?}}
+
 }
 
 namespace PR10579 {
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4694,8 +4694,14 @@
     OS << "'" << Concept->getName();
     if (TypeLoc.hasExplicitTemplateArgs()) {
       OS << "<";
-      for (const auto &Arg : Type.getTypeConstraintArguments())
-        Arg.print(S.getPrintingPolicy(), OS);
+      for (const auto &Arg : Type.getTypeConstraintArguments()) {
+        bool knownType = true;
+        if (auto *DRE = dyn_cast<DeclRefExpr>(Arg.getAsExpr())) {
+          if (DRE->hadMultipleCandidates())
+            knownType = false;
+        }
+        Arg.print(S.getPrintingPolicy(), OS, knownType);
+      }
       OS << ">";
     }
     OS << "'";
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10769,7 +10769,7 @@
     }
 
     Out << " = ";
-    Args[I].print(getPrintingPolicy(), Out);
+    Args[I].print(getPrintingPolicy(), Out, true);
   }
 
   Out << ']';
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -963,7 +963,11 @@
   for (auto &Arg : Args.arguments()) {
     if (!First)
       OS << ", ";
-    Arg.getArgument().print(PrintingPolicy, OS);
+    bool knownType = true;
+    if (auto *DRE = dyn_cast<DeclRefExpr>(Arg.getArgument().getAsExpr()))
+      if (DRE->hadMultipleCandidates())
+        knownType = false;
+    Arg.getArgument().print(PrintingPolicy, OS, knownType);
     First = false;
   }
   return std::string(OS.str());
Index: clang/lib/Analysis/PathDiagnostic.cpp
===================================================================
--- clang/lib/Analysis/PathDiagnostic.cpp
+++ clang/lib/Analysis/PathDiagnostic.cpp
@@ -898,7 +898,7 @@
   if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
     describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
   } else {
-    TArg.print(PrintingPolicy(LO), Out);
+    TArg.print(PrintingPolicy(LO), Out, true);
   }
 }
 
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1778,7 +1778,7 @@
 
 static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
                           llvm::raw_ostream &OS) {
-  A.print(PP, OS);
+  A.print(PP, OS, true);
 }
 
 static void printArgument(const TemplateArgumentLoc &A,
@@ -1786,7 +1786,11 @@
   const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
   if (Kind == TemplateArgument::ArgKind::Type)
     return A.getTypeSourceInfo()->getType().print(OS, PP);
-  return A.getArgument().print(PP, OS);
+  bool knownType = true;
+  if (auto *DRE = dyn_cast<DeclRefExpr>(A.getArgument().getAsExpr()))
+    if (DRE->hadMultipleCandidates())
+      knownType = false;
+  return A.getArgument().print(PP, OS, knownType);
 }
 
 template<typename TA>
Index: clang/lib/AST/TemplateBase.cpp
===================================================================
--- clang/lib/AST/TemplateBase.cpp
+++ clang/lib/AST/TemplateBase.cpp
@@ -50,8 +50,10 @@
 /// \param Out the raw_ostream instance to use for printing.
 ///
 /// \param Policy the printing policy for EnumConstantDecl printing.
-static void printIntegral(const TemplateArgument &TemplArg,
-                          raw_ostream &Out, const PrintingPolicy& Policy) {
+///
+/// \param knownType the flag to determine printing suffix/prefix type.
+static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
+                          const PrintingPolicy &Policy, bool knownType) {
   const Type *T = TemplArg.getIntegralType().getTypePtr();
   const llvm::APSInt &Val = TemplArg.getAsIntegral();
 
@@ -70,13 +72,52 @@
 
   if (T->isBooleanType() && !Policy.MSVCFormatting) {
     Out << (Val.getBoolValue() ? "true" : "false");
+  } else if (T->isBooleanType()) {
+    Out << Val;
   } else if (T->isCharType()) {
     const char Ch = Val.getZExtValue();
     Out << ((Ch == '\'') ? "'\\" : "'");
     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
     Out << "'";
   } else {
-    Out << Val;
+    if (knownType) {
+      if (auto *autoT = T->getAs<AutoType>()) {
+        if (autoT->getAs<DeducedType>()) {
+          knownType = false;
+        }
+      } else if (T->getAs<DeducedType>()) {
+        knownType = false;
+      }
+    }
+    if (!knownType) {
+      if (auto *BT = T->getAs<BuiltinType>()) {
+        switch (BT->getKind()) {
+        case BuiltinType::ULongLong:
+          Out << Val << "ULL";
+          break;
+        case BuiltinType::LongLong:
+          Out << Val << "LL";
+          break;
+        case BuiltinType::ULong:
+          Out << Val << "UL";
+          break;
+        case BuiltinType::Long:
+          Out << Val << "L";
+          break;
+        case BuiltinType::UInt:
+          Out << Val << "U";
+          break;
+        case BuiltinType::Int:
+          Out << Val;
+          break;
+        default:
+          Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
+              << Val;
+          break;
+        }
+      }
+    } else
+      Out << Val;
   }
 }
 
@@ -336,8 +377,9 @@
   llvm_unreachable("Invalid TemplateArgument Kind!");
 }
 
-void TemplateArgument::print(const PrintingPolicy &Policy,
-                             raw_ostream &Out) const {
+void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
+                             bool knownType) const {
+
   switch (getKind()) {
   case Null:
     Out << "(no value)";
@@ -372,7 +414,7 @@
     break;
 
   case Integral:
-    printIntegral(*this, Out, Policy);
+    printIntegral(*this, Out, Policy, knownType);
     break;
 
   case Expression:
@@ -388,7 +430,7 @@
       else
         Out << ", ";
 
-      P.print(Policy, Out);
+      P.print(Policy, Out, knownType);
     }
     Out << ">";
     break;
@@ -399,7 +441,7 @@
   LangOptions LO; // FIXME! see also TemplateName::dump().
   LO.CPlusPlus = true;
   LO.Bool = true;
-  print(PrintingPolicy(LO), Out);
+  print(PrintingPolicy(LO), Out, false);
 }
 
 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
@@ -494,7 +536,7 @@
     LangOptions LangOpts;
     LangOpts.CPlusPlus = true;
     PrintingPolicy Policy(LangOpts);
-    Arg.print(Policy, OS);
+    Arg.print(Policy, OS, true);
     return DB << OS.str();
   }
   }
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -771,7 +771,7 @@
         StringRef Param = Params->getParam(i)->getName();
         if (Param.empty()) continue;
         TOut << Param << " = ";
-        Args.get(i).print(Policy, TOut);
+        Args.get(i).print(Policy, TOut, true);
         TOut << ", ";
       }
     }
@@ -787,7 +787,7 @@
         StringRef Param = Params->getParam(i)->getName();
         if (Param.empty()) continue;
         TOut << Param << " = ";
-        Args->get(i).print(Policy, TOut);
+        Args->get(i).print(Policy, TOut, true);
         TOut << ", ";
       }
     }
Index: clang/lib/AST/DeclTemplate.cpp
===================================================================
--- clang/lib/AST/DeclTemplate.cpp
+++ clang/lib/AST/DeclTemplate.cpp
@@ -1426,8 +1426,13 @@
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
     OS << "<";
-    for (auto &ArgLoc : ArgsAsWritten->arguments())
-      ArgLoc.getArgument().print(Policy, OS);
+    for (auto &ArgLoc : ArgsAsWritten->arguments()) {
+      bool knownType = true;
+      if (auto *DRE = dyn_cast<DeclRefExpr>(ArgLoc.getArgument().getAsExpr()))
+        if (DRE->hadMultipleCandidates())
+          knownType = false;
+      ArgLoc.getArgument().print(Policy, OS, knownType);
+    }
     OS << ">";
   }
 }
Index: clang/lib/AST/DeclPrinter.cpp
===================================================================
--- clang/lib/AST/DeclPrinter.cpp
+++ clang/lib/AST/DeclPrinter.cpp
@@ -1077,7 +1077,7 @@
   for (size_t I = 0, E = Args.size(); I < E; ++I) {
     if (I)
       Out << ", ";
-    Args[I].print(Policy, Out);
+    Args[I].print(Policy, Out, true);
   }
   Out << ">";
 }
@@ -1087,7 +1087,11 @@
   for (size_t I = 0, E = Args.size(); I < E; ++I) {
     if (I)
       Out << ", ";
-    Args[I].getArgument().print(Policy, Out);
+    bool knownType = true;
+    if (auto *DRE = dyn_cast<DeclRefExpr>(Args[I].getArgument().getAsExpr()))
+      if (DRE->hadMultipleCandidates())
+        knownType = false;
+    Args[I].getArgument().print(Policy, Out, knownType);
   }
   Out << ">";
 }
Index: clang/lib/AST/ASTTypeTraits.cpp
===================================================================
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -128,11 +128,15 @@
 
 void DynTypedNode::print(llvm::raw_ostream &OS,
                          const PrintingPolicy &PP) const {
-  if (const TemplateArgument *TA = get<TemplateArgument>())
-    TA->print(PP, OS);
-  else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
-    TAL->getArgument().print(PP, OS);
-  else if (const TemplateName *TN = get<TemplateName>())
+  if (const TemplateArgument *TA = get<TemplateArgument>()) {
+    bool knownType = true;
+    if (auto *DRE = dyn_cast<DeclRefExpr>(TA->getAsExpr()))
+      if (DRE->hadMultipleCandidates())
+        knownType = false;
+    TA->print(PP, OS, knownType);
+  } else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>()) {
+    TAL->getArgument().print(PP, OS, true);
+  } else if (const TemplateName *TN = get<TemplateName>())
     TN->print(OS, PP);
   else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
     NNS->print(OS, PP);
Index: clang/include/clang/AST/TemplateBase.h
===================================================================
--- clang/include/clang/AST/TemplateBase.h
+++ clang/include/clang/AST/TemplateBase.h
@@ -378,7 +378,8 @@
   TemplateArgument getPackExpansionPattern() const;
 
   /// Print this template argument to the given output stream.
-  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
+  void print(const PrintingPolicy &Policy, raw_ostream &Out,
+             bool knownType) const;
 
   /// Debugging aid that dumps the template argument.
   void dump(raw_ostream &Out) const;
Index: clang/include/clang/AST/StmtDataCollectors.td
===================================================================
--- clang/include/clang/AST/StmtDataCollectors.td
+++ clang/include/clang/AST/StmtDataCollectors.td
@@ -51,7 +51,7 @@
         // Print all template arguments into ArgString
         llvm::raw_string_ostream OS(ArgString);
         for (unsigned i = 0; i < Args->size(); ++i) {
-          Args->get(i).print(Context.getLangOpts(), OS);
+          Args->get(i).print(Context.getLangOpts(), OS, true);
           // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
           OS << '\n';
         }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D77598: I... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D775... Pratyush Das via Phabricator via cfe-commits
    • [PATCH] D775... Pratyush Das via Phabricator via cfe-commits
    • [PATCH] D775... Reid Kleckner via Phabricator via cfe-commits

Reply via email to