<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Feb 25, 2014 at 9:26 AM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@googlemail.com" target="_blank">benny.kra@googlemail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: d0k<br>
Date: Tue Feb 25 11:26:26 2014<br>
New Revision: 202167<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=202167&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=202167&view=rev</a><br>
Log:<br>
Pretty Printer: Fix printing of conversion operator decls and calls.<br>
<br>
- Don't emit anything when we encounter a call to a conversion operator.<br>
    "bar(a & b)" instead of "bar(a & b.operator int())"<br>
  This preserves the semantics and is still idempotent if we print the AST multiple times.<br>
<br>
- Properly print declarations of conversion operators.<br>
    "explicit operator bool();" instead of "bool operator _Bool();"<br>
<br>
PR18776.<br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/DeclPrinter.cpp<br>
    cfe/trunk/lib/AST/DeclarationName.cpp<br>
    cfe/trunk/lib/AST/StmtPrinter.cpp<br>
    cfe/trunk/test/SemaCXX/ast-print.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/DeclPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=202167&r1=202166&r2=202167&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=202167&r1=202166&r2=202167&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Feb 25 11:26:26 2014<br>
@@ -385,6 +385,7 @@ void DeclPrinter::VisitEnumConstantDecl(<br>
<br>
 void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {<br>
   CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);<br>
+  CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);<br>
   if (!Policy.SuppressSpecifiers) {<br>
     switch (D->getStorageClass()) {<br>
     case SC_None: break;<br>
@@ -398,7 +399,8 @@ void DeclPrinter::VisitFunctionDecl(Func<br>
     if (D->isInlineSpecified())  Out << "inline ";<br>
     if (D->isVirtualAsWritten()) Out << "virtual ";<br>
     if (D->isModulePrivate())    Out << "__module_private__ ";<br>
-    if (CDecl && CDecl->isExplicitSpecified())<br>
+    if ((CDecl && CDecl->isExplicitSpecified()) ||<br>
+        (ConversionDecl && ConversionDecl->isExplicit()))<br>
       Out << "explicit ";<br>
   }<br>
<br>
@@ -536,15 +538,15 @@ void DeclPrinter::VisitFunctionDecl(Func<br>
         }<br>
         Out << ")";<br>
       }<br>
-      if (!Proto.empty())<br>
-        Out << Proto;<br>
-    } else {<br>
+    } else if (!ConversionDecl) {<br>
       if (FT && FT->hasTrailingReturn()) {<br>
         Out << "auto " << Proto << " -> ";<br>
         Proto.clear();<br>
       }<br>
       AFT->getReturnType().print(Out, Policy, Proto);<br>
+      Proto.clear();<br>
     }<br>
+    Out << Proto;<br>
   } else {<br>
     Ty.print(Out, Policy, Proto);<br>
   }<br>
<br>
Modified: cfe/trunk/lib/AST/DeclarationName.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=202167&r1=202166&r2=202167&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=202167&r1=202166&r2=202167&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclarationName.cpp Tue Feb 25 11:26:26 2014<br>
@@ -191,6 +191,7 @@ raw_ostream &operator<<(raw_ostream &OS,<br>
       return OS << *Rec->getDecl();<br>
     LangOptions LO;<br>
     LO.CPlusPlus = true;<br>
+    LO.Bool = true;<br>
     return OS << Type.getAsString(PrintingPolicy(LO));<br>
   }<br>
   case DeclarationName::CXXUsingDirective:<br>
@@ -546,6 +547,7 @@ void DeclarationNameInfo::printName(raw_<br>
         OS << "operator ";<br>
       LangOptions LO;<br>
       LO.CPlusPlus = true;<br>
+      LO.Bool = true;<br>
       OS << TInfo->getType().getAsString(PrintingPolicy(LO));<br>
     } else<br>
       OS << Name;<br>
<br>
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=202167&r1=202166&r2=202167&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=202167&r1=202166&r2=202167&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Feb 25 11:26:26 2014<br>
@@ -1296,6 +1296,12 @@ void StmtPrinter::VisitCXXOperatorCallEx<br>
 }<br>
<br>
 void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {<br>
+  // If we have a conversion operator call only print the argument.<br>
+  CXXMethodDecl *MD = Node->getMethodDecl();<br>
+  if (MD && isa<CXXConversionDecl>(MD)) {<br>
+    PrintExpr(Node->getImplicitObjectArgument());<br>
+    return;<br>
+  }<br></blockquote><div><br></div><div>You should only do this if we have an implicit call to a conversion operator. Given:</div><div><br></div><div>  auto x = (a & b).operator void*();</div><div><br></div><div>... we should print out the call to 'operator void*'. I think the way to detect this in the current AST is to look for a CastExpr whose cast kind is CK_UserDefinedConversion, and to skip the CXXMemberCallExpr or CXXConstructExpr inside it -- but maybe we should change the AST representation here to more directly distinguish between an implicit conversion operator call and an explicit one?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   VisitCallExpr(cast<CallExpr>(Node));<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/ast-print.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ast-print.cpp?rev=202167&r1=202166&r2=202167&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ast-print.cpp?rev=202167&r1=202166&r2=202167&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/ast-print.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/ast-print.cpp Tue Feb 25 11:26:26 2014<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -ast-print %s -std=gnu++11 | FileCheck %s<br>
<br>
 // CHECK: r;<br>
 // CHECK-NEXT: (r->method());<br>
@@ -173,3 +173,26 @@ void test14() {<br>
 float test15() {<br>
   return __builtin_asinf(1.0F);<br>
 }<br>
+<br>
+namespace PR18776 {<br>
+struct A {<br>
+  operator void *();<br>
+  explicit operator bool();<br>
+  A operator&(A);<br>
+};<br>
+<br>
+// CHECK: struct A<br>
+// CHECK-NEXT: {{^[ ]*operator}} void *();<br>
+// CHECK-NEXT: {{^[ ]*explicit}} operator bool();<br>
+<br>
+void bar(void *);<br>
+<br>
+void foo() {<br>
+  A a, b;<br>
+  bar(a & b);<br>
+// CHECK: bar(a & b);<br>
+  if (a & b)<br>
+// CHECK: if (a & b)<br>
+    return;<br>
+}<br>
+};<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>