courbet updated this revision to Diff 178010.
courbet added a comment.

Handle remaining static_assert categories inside the prettyprinter.


Repository:
  rC Clang

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

https://reviews.llvm.org/D55552

Files:
  include/clang/AST/Stmt.h
  lib/AST/StmtPrinter.cpp
  lib/Sema/SemaTemplate.cpp
  test/SemaCXX/static-assert-cxx17.cpp
  test/SemaCXX/static-assert.cpp

Index: test/SemaCXX/static-assert.cpp
===================================================================
--- test/SemaCXX/static-assert.cpp
+++ test/SemaCXX/static-assert.cpp
@@ -76,6 +76,8 @@
   static const Tp value = v;
   typedef Tp value_type;
   typedef integral_constant type;
+  constexpr operator value_type() const noexcept { return value; }
+  constexpr value_type operator()() const noexcept { return value; }
 };
 
 template <class Tp, Tp v>
@@ -103,6 +105,7 @@
 } // namespace std
 
 struct ExampleTypes {
+  explicit ExampleTypes(int);
   using T = int;
   using U = float;
 };
@@ -119,6 +122,18 @@
 // expected-error@-1{{static_assert failed due to requirement 'std::is_const<const int>::value == false' "message"}}
 static_assert(!(std::is_const<const ExampleTypes::T>::value == true), "message");
 // expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>::value == true)' "message"}}
+static_assert(std::is_const<ExampleTypes::T>(), "message");
+// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>()' "message"}}
+static_assert(!(std::is_const<const ExampleTypes::T>()()), "message");
+// expected-error@-1{{static_assert failed due to requirement '!(std::is_const<const int>()())' "message"}}
+static_assert(std::is_same<decltype(std::is_const<const ExampleTypes::T>()), int>::value, "message");
+// expected-error@-1{{static_assert failed due to requirement 'std::is_same<std::is_const<const int>, int>::value' "message"}}
+static_assert(std::is_const<decltype(ExampleTypes::T(3))>::value, "message");
+// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}}
+static_assert(std::is_const<decltype(ExampleTypes::T())>::value, "message");
+// expected-error@-1{{static_assert failed due to requirement 'std::is_const<int>::value' "message"}}
+static_assert(std::is_const<decltype(ExampleTypes(3))>::value, "message");
+// expected-error@-1{{static_assert failed due to requirement 'std::is_const<ExampleTypes>::value' "message"}}
 
 struct BI_tag {};
 struct RAI_tag : BI_tag {};
Index: test/SemaCXX/static-assert-cxx17.cpp
===================================================================
--- test/SemaCXX/static-assert-cxx17.cpp
+++ test/SemaCXX/static-assert-cxx17.cpp
@@ -54,3 +54,42 @@
 }
 template void foo5<int, float>();
 // expected-note@-1{{in instantiation of function template specialization 'foo5<int, float>' requested here}}
+
+struct ExampleTypes {
+  explicit ExampleTypes(int);
+  using T = int;
+  using U = float;
+};
+
+template<class T> struct X {
+  int i=0;
+  int j=0;
+  constexpr operator bool() const { return false; }
+};
+
+template<class T> void foo6() {
+    static_assert(X<typename T::T>());
+    // expected-error@-1{{static_assert failed due to requirement 'X<int>()'}}
+    static_assert(X<typename T::T>{});
+    // expected-error@-1{{static_assert failed due to requirement 'X<int>{}'}}
+    static_assert(X<typename T::T>{1,2});
+    // expected-error@-1{{static_assert failed due to requirement 'X<int>{1, 2}'}}
+    static_assert(X<typename T::T>({1,2}));
+    // expected-error@-1{{static_assert failed due to requirement 'X<int>({1, 2})'}}
+    static_assert(typename T::T{0});
+    // expected-error@-1{{static_assert failed due to requirement 'int{0}'}}
+    static_assert(typename T::T(0));
+    // expected-error@-1{{static_assert failed due to requirement 'int(0)'}}
+    static_assert(sizeof(X<typename T::T>) == 0);
+    // expected-error@-1{{static_assert failed due to requirement 'sizeof(X<int>) == 0'}}
+    static_assert((const X<typename T::T>*)nullptr);
+    // expected-error@-1{{static_assert failed due to requirement '(const X<int> *)nullptr'}}
+    static_assert(static_cast<const X<typename T::T>*>(nullptr));
+    // expected-error@-1{{static_assert failed due to requirement 'static_cast<const X<int> *>(nullptr)'}}
+    static_assert((const X<typename T::T>[]){} == nullptr);
+    // expected-error@-1{{static_assert failed due to requirement '(X<int> const[0]){} == nullptr'}}
+    static_assert(sizeof(X<decltype(X<typename T::T>().X<typename T::T>::~X())>) == 0);
+    // expected-error@-1{{static_assert failed due to requirement 'sizeof(X<void>) == 0'}}
+}
+template void foo6<ExampleTypes>();
+// expected-note@-1{{in instantiation of function template specialization 'foo6<ExampleTypes>' requested here}}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -3059,8 +3059,9 @@
 // for actual types.
 class FailedBooleanConditionPrinterHelper : public PrinterHelper {
 public:
-  explicit FailedBooleanConditionPrinterHelper(const PrintingPolicy &P)
-      : Policy(P) {}
+  FailedBooleanConditionPrinterHelper(const ASTContext &Context,
+                                      const PrintingPolicy &P)
+      : Context(Context), Policy(P) {}
 
   bool handledStmt(Stmt *E, raw_ostream &OS) override {
     const auto *DR = dyn_cast<DeclRefExpr>(E);
@@ -3081,6 +3082,7 @@
   }
 
 private:
+  const ASTContext &Context;
   const PrintingPolicy Policy;
 };
 
@@ -3122,8 +3124,8 @@
   std::string Description;
   {
     llvm::raw_string_ostream Out(Description);
-    FailedBooleanConditionPrinterHelper Helper(getPrintingPolicy());
-    FailedCond->printPretty(Out, &Helper, getPrintingPolicy());
+    FailedBooleanConditionPrinterHelper Helper(Context, getPrintingPolicy());
+    FailedCond->printPretty(Out, &Helper, getPrintingPolicy(), 0, "\n", nullptr, true);
   }
   return { FailedCond, Description };
 }
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -71,14 +71,16 @@
     PrintingPolicy Policy;
     std::string NL;
     const ASTContext *Context;
+    const bool PrintCanonicalTypes;
 
   public:
     StmtPrinter(raw_ostream &os, PrinterHelper *helper,
-                const PrintingPolicy &Policy, unsigned Indentation = 0,
-                StringRef NL = "\n",
-                const ASTContext *Context = nullptr)
+                const PrintingPolicy &Policy, unsigned Indentation,
+                StringRef NL,
+                const ASTContext *Context,
+                bool PrintCanonicalTypes)
         : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
-          NL(NL), Context(Context) {}
+          NL(NL), Context(Context), PrintCanonicalTypes(PrintCanonicalTypes) {}
 
     void PrintStmt(Stmt *S) {
       PrintStmt(S, Policy.Indentation);
@@ -165,6 +167,14 @@
 #define STMT(CLASS, PARENT) \
     void Visit##CLASS(CLASS *Node);
 #include "clang/AST/StmtNodes.inc"
+
+private:
+    void PrintType(const QualType& T) const {
+      if (PrintCanonicalTypes)
+        T.getCanonicalType().print(OS, Policy);
+      else
+        T.print(OS, Policy);
+    }
   };
 
 } // namespace
@@ -1194,7 +1204,7 @@
 
 void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
   OS << "__builtin_offsetof(";
-  Node->getTypeSourceInfo()->getType().print(OS, Policy);
+  PrintType(Node->getTypeSourceInfo()->getType());
   OS << ", ";
   bool PrintedSomething = false;
   for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
@@ -1251,7 +1261,7 @@
   }
   if (Node->isArgumentType()) {
     OS << '(';
-    Node->getArgumentType().print(OS, Policy);
+    PrintType(Node->getArgumentType());
     OS << ')';
   } else {
     OS << " ";
@@ -1268,7 +1278,7 @@
     if (T.isNull())
       OS << "default";
     else
-      T.print(OS, Policy);
+      PrintType(T);
     OS << ": ";
     PrintExpr(Node->getAssocExpr(i));
   }
@@ -1359,14 +1369,14 @@
 
 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
   OS << '(';
-  Node->getTypeAsWritten().print(OS, Policy);
+  PrintType(Node->getTypeAsWritten());
   OS << ')';
   PrintExpr(Node->getSubExpr());
 }
 
 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
   OS << '(';
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   OS << ')';
   PrintExpr(Node->getInitializer());
 }
@@ -1442,7 +1452,7 @@
   OS << "__builtin_convertvector(";
   PrintExpr(Node->getSrcExpr());
   OS << ", ";
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   OS << ")";
 }
 
@@ -1535,11 +1545,11 @@
 void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
   if (Node->getType()->getAsCXXRecordDecl()) {
     OS << "/*implicit*/";
-    Node->getType().print(OS, Policy);
+    PrintType(Node->getType());
     OS << "()";
   } else {
     OS << "/*implicit*/(";
-    Node->getType().print(OS, Policy);
+    PrintType(Node->getType());
     OS << ')';
     if (Node->getType()->isRecordType())
       OS << "{}";
@@ -1552,7 +1562,7 @@
   OS << "__builtin_va_arg(";
   PrintExpr(Node->getSubExpr());
   OS << ", ";
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   OS << ")";
 }
 
@@ -1670,7 +1680,7 @@
 
 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
   OS << Node->getCastName() << '<';
-  Node->getTypeAsWritten().print(OS, Policy);
+  PrintType(Node->getTypeAsWritten());
   OS << ">(";
   PrintExpr(Node->getSubExpr());
   OS << ")";
@@ -1695,7 +1705,7 @@
 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
   OS << "typeid(";
   if (Node->isTypeOperand()) {
-    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
+    PrintType(Node->getTypeOperandSourceInfo()->getType());
   } else {
     PrintExpr(Node->getExprOperand());
   }
@@ -1705,7 +1715,7 @@
 void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
   OS << "__uuidof(";
   if (Node->isTypeOperand()) {
-    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
+    PrintType(Node->getTypeOperandSourceInfo()->getType());
   } else {
     PrintExpr(Node->getExprOperand());
   }
@@ -1806,7 +1816,7 @@
 }
 
 void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   // If there are no parens, this is list-initialization, and the braces are
   // part of the syntax of the inner construct.
   if (Node->getLParenLoc().isValid())
@@ -1821,7 +1831,7 @@
 }
 
 void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   if (Node->isStdInitListInitialization())
     /* Nothing to do; braces are part of creating the std::initializer_list. */;
   else if (Node->isListInitialization())
@@ -1932,7 +1942,7 @@
     // Print the trailing return type if it was specified in the source.
     if (Node->hasExplicitResultType()) {
       OS << " -> ";
-      Proto->getReturnType().print(OS, Policy);
+      PrintType(Proto->getReturnType());
     }
   }
 
@@ -1944,9 +1954,9 @@
 
 void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
   if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
-    TSInfo->getType().print(OS, Policy);
+    PrintType(TSInfo->getType());
   else
-    Node->getType().print(OS, Policy);
+    PrintType(Node->getType());
   OS << "()";
 }
 
@@ -2011,7 +2021,7 @@
   if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
     OS << II->getName();
   else
-    E->getDestroyedType().print(OS, Policy);
+    PrintType(E->getDestroyedType());
 }
 
 void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
@@ -2049,7 +2059,7 @@
 void
 StmtPrinter::VisitCXXUnresolvedConstructExpr(
                                            CXXUnresolvedConstructExpr *Node) {
-  Node->getTypeAsWritten().print(OS, Policy);
+  PrintType(Node->getTypeAsWritten());
   OS << "(";
   for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
                                              ArgEnd = Node->arg_end();
@@ -2124,14 +2134,14 @@
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
     if (I > 0)
       OS << ", ";
-    E->getArg(I)->getType().print(OS, Policy);
+    PrintType(E->getArg(I)->getType());
   }
   OS << ")";
 }
 
 void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   OS << getTypeTraitName(E->getTrait()) << '(';
-  E->getQueriedType().print(OS, Policy);
+  PrintType(E->getQueriedType());
   OS << ')';
 }
 
@@ -2259,7 +2269,7 @@
 
 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
   OS << "@encode(";
-  Node->getEncodedType().print(OS, Policy);
+  PrintType(Node->getEncodedType());
   OS << ')';
 }
 
@@ -2281,7 +2291,7 @@
     break;
 
   case ObjCMessageExpr::Class:
-    Mess->getClassReceiver().print(OS, Policy);
+    PrintType(Mess->getClassReceiver());
     break;
 
   case ObjCMessageExpr::SuperInstance:
@@ -2323,7 +2333,7 @@
 void
 StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
   OS << '(' << E->getBridgeKindName();
-  E->getType().print(OS, Policy);
+  PrintType(E->getType());
   OS << ')';
   PrintExpr(E->getSubExpr());
 }
@@ -2368,7 +2378,7 @@
   OS << "__builtin_astype(";
   PrintExpr(Node->getSrcExpr());
   OS << ", ";
-  Node->getType().print(OS, Policy);
+  PrintType(Node->getType());
   OS << ")";
 }
 
@@ -2383,8 +2393,9 @@
 void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
                        const PrintingPolicy &Policy, unsigned Indentation,
                        StringRef NL,
-                       const ASTContext *Context) const {
-  StmtPrinter P(OS, Helper, Policy, Indentation, NL, Context);
+                       const ASTContext *Context,
+                       bool PrintCanonicalTypes) const {
+  StmtPrinter P(OS, Helper, Policy, Indentation, NL, Context, PrintCanonicalTypes);
   P.Visit(const_cast<Stmt*>(this));
 }
 
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -843,7 +843,8 @@
   void printPretty(raw_ostream &OS, PrinterHelper *Helper,
                    const PrintingPolicy &Policy, unsigned Indentation = 0,
                    StringRef NewlineSymbol = "\n",
-                   const ASTContext *Context = nullptr) const;
+                   const ASTContext *Context = nullptr,
+                   bool PrintCanonicalTypes = false) const;
 
   /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
   ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to