]> granicus.if.org Git - clang/commitdiff
[AST] String literal operator templates have two template args, not one
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 5 Apr 2015 05:32:54 +0000 (05:32 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 5 Apr 2015 05:32:54 +0000 (05:32 +0000)
StmtPrinter assumed that the first template arg was the pack and
attempted to iterate it.  However, the GNU extension (which is really
just N3599), has two template arguments.  In this case, the second
argument is the pack containing the string contents.

Handle this by desugaring the call to the explicit operator.

For example:
"qux" _zombocom will be shown as
operator "" _zombocom<char, 'q', 'u', 'x'>() in diagnostics and AST
dumps.

N.B.  It is actually impossible to render the arguments back to the
source form without storing more information in the AST.  For example,
we cannot tell if the user wrote u8"qux" or "qux".  We also lose
fidelity when it comes to non-char types for this exact reason (e.g. it
is hard to render a list of wchar_t back to something that can be
printed to the screen even if you don't have to consider surrogate
pairs).

This fixes PR23120.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234110 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/StmtPrinter.cpp
test/SemaCXX/cxx11-ast-print.cpp

index 8f0edd075680d64af63cda6fd6e21bfa400d03d5..b68f3a3a26edb9e7b43ed48ddca07c1a03b6e647 100644 (file)
@@ -1622,6 +1622,15 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
     const TemplateArgumentList *Args =
       cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
     assert(Args);
+
+    if (Args->size() != 1) {
+      OS << "operator \"\" " << Node->getUDSuffix()->getName();
+      TemplateSpecializationType::PrintTemplateArgumentList(
+          OS, Args->data(), Args->size(), Policy);
+      OS << "()";
+      return;
+    }
+
     const TemplateArgument &Pack = Args->get(0);
     for (const auto &P : Pack.pack_elements()) {
       char C = (char)P.getAsIntegral().getZExtValue();
index 5604374c5610f8d04db05ce30c878e8090958198..9770e45fe27fd07c022b400cdb3f6d26a82079dc 100644 (file)
@@ -38,6 +38,11 @@ const char *p8 = 4.9_quux;
 const char *p9 = 0x42e3F_fritz;
 // CHECK: const char *p10 = 3.300e+15_fritz;
 const char *p10 = 3.300e+15_fritz;
+
+template <class C, C...> const char *operator"" _suffix();
+// CHECK: const char *PR23120 = operator "" _suffix<wchar_t, 66615>();
+const char *PR23120 = L"𐐷"_suffix;
+
 // CHECK: ;
 ;
 // CHECK-NOT: ;