[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-03-01 Thread Zhihao Yuan via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG44eee659f1c5: [AST] Print NTTP args as string-literals when 
possible (authored by lichray).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-03-01 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 412289.
lichray added a comment.
Herald added a project: All.

- Add a trigraph test case


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-03-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

Aside from a testing nit, this LGTM!




Comment at: clang/include/clang/Basic/CharInfo.h:199-200
+return "\\t";
+  case '\v':
+return "\\v";
+  }

lichray wrote:
> aaron.ballman wrote:
> > lichray wrote:
> > > aaron.ballman wrote:
> > > > We're also missing `\?` right?
> > > `?` does not seem to need `"escaping?"`
> > It's the only simple escape sequence we're not handling here: 
> > http://eel.is/c++draft/lex.literal#nt:simple-escape-sequence-char
> > 
> > (You need to escape `?` thanks to trigraphs. Consider a string literal like 
> > `"This does what now??!"`.)
> > It's the only simple escape sequence we're not handling here: 
> > http://eel.is/c++draft/lex.literal#nt:simple-escape-sequence-char
> > 
> > (You need to escape `?` thanks to trigraphs. Consider a string literal like 
> > `"This does what now??!"`.)
> 
> Hmm, I think we're safe here
> ```
> ~/devel/llvm-project> ./build/bin/clang++ -fsyntax-only -std=c++14 c.cc
> c.cc:1:50: warning: trigraph converted to '|' character [-Wtrigraphs]
> void foo() { char const s[] = "This does what now??!"; }
>  ^
> 1 warning generated.
> ~/devel/llvm-project> ./build/bin/clang++ -fsyntax-only -std=c++20 c.cc
> c.cc:1:50: warning: trigraph ignored [-Wtrigraphs]
> void foo() { char const s[] = "This does what now??!"; }
>  ^
> 1 warning generated.
> ```
> For these reasons,
> 1. I don't want users to copy diagnosis messages, paste them into a program, 
> and get something different. This has been prevented by the warnings.
> 2. We support trigraph up to C++14, way behind the version (C++20) we can use 
> string literals in NTTP. So it should be mostly fine.
> 3. In C++14 we can use the characters in NTTP, but that one has a different 
> diagnosis:
> 
> ```
> template  class ASCII {};
> 
> void Foo(ASCII<'?'>);
> void Foo(ASCII<'??!'>);
> void test_pascal() {
>   ASCII<'!'> a;
>   Foo(a);
> }
> ```
> 
> ```
> c.cc:4:17: warning: trigraph converted to '|' character [-Wtrigraphs]
> void Foo(ASCII<'??!'>);
> ^
> c.cc:7:3: error: no matching function for call to 'Foo'
>   Foo(a);
>   ^~~
> c.cc:3:6: note: candidate function not viable: no known conversion from 
> 'ASCII<'!' aka 33>' to 'ASCII<'?' aka 63>' for 1st argument
> void Foo(ASCII<'?'>);
>  ^
> c.cc:4:6: note: candidate function not viable: no known conversion from 
> 'ASCII<'!' aka 33>' to 'ASCII<'|' aka 124>' for 1st argument
> void Foo(ASCII<'??!'>);
>  ^
> 1 warning and 1 error generated.
> ```
> Looks nice to me even if we don't escape.
Okay, that sounds reasonable to me, thank you for checking! Can you add a 
trigraph test case so that it's clear we purposefully don't escape the `\?` 
(with some comment to that effect)?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 4 inline comments as done.
lichray added inline comments.



Comment at: clang/include/clang/Basic/CharInfo.h:199-200
+return "\\t";
+  case '\v':
+return "\\v";
+  }

aaron.ballman wrote:
> lichray wrote:
> > aaron.ballman wrote:
> > > We're also missing `\?` right?
> > `?` does not seem to need `"escaping?"`
> It's the only simple escape sequence we're not handling here: 
> http://eel.is/c++draft/lex.literal#nt:simple-escape-sequence-char
> 
> (You need to escape `?` thanks to trigraphs. Consider a string literal like 
> `"This does what now??!"`.)
> It's the only simple escape sequence we're not handling here: 
> http://eel.is/c++draft/lex.literal#nt:simple-escape-sequence-char
> 
> (You need to escape `?` thanks to trigraphs. Consider a string literal like 
> `"This does what now??!"`.)

Hmm, I think we're safe here
```
~/devel/llvm-project> ./build/bin/clang++ -fsyntax-only -std=c++14 c.cc
c.cc:1:50: warning: trigraph converted to '|' character [-Wtrigraphs]
void foo() { char const s[] = "This does what now??!"; }
 ^
1 warning generated.
~/devel/llvm-project> ./build/bin/clang++ -fsyntax-only -std=c++20 c.cc
c.cc:1:50: warning: trigraph ignored [-Wtrigraphs]
void foo() { char const s[] = "This does what now??!"; }
 ^
1 warning generated.
```
For these reasons,
1. I don't want users to copy diagnosis messages, paste them into a program, 
and get something different. This has been prevented by the warnings.
2. We support trigraph up to C++14, way behind the version (C++20) we can use 
string literals in NTTP. So it should be mostly fine.
3. In C++14 we can use the characters in NTTP, but that one has a different 
diagnosis:

```
template  class ASCII {};

void Foo(ASCII<'?'>);
void Foo(ASCII<'??!'>);
void test_pascal() {
  ASCII<'!'> a;
  Foo(a);
}
```

```
c.cc:4:17: warning: trigraph converted to '|' character [-Wtrigraphs]
void Foo(ASCII<'??!'>);
^
c.cc:7:3: error: no matching function for call to 'Foo'
  Foo(a);
  ^~~
c.cc:3:6: note: candidate function not viable: no known conversion from 
'ASCII<'!' aka 33>' to 'ASCII<'?' aka 63>' for 1st argument
void Foo(ASCII<'?'>);
 ^
c.cc:4:6: note: candidate function not viable: no known conversion from 
'ASCII<'!' aka 33>' to 'ASCII<'|' aka 124>' for 1st argument
void Foo(ASCII<'??!'>);
 ^
1 warning and 1 error generated.
```
Looks nice to me even if we don't escape.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-28 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/CharInfo.h:199-200
+return "\\t";
+  case '\v':
+return "\\v";
+  }

lichray wrote:
> aaron.ballman wrote:
> > We're also missing `\?` right?
> `?` does not seem to need `"escaping?"`
It's the only simple escape sequence we're not handling here: 
http://eel.is/c++draft/lex.literal#nt:simple-escape-sequence-char

(You need to escape `?` thanks to trigraphs. Consider a string literal like 
`"This does what now??!"`.)



Comment at: clang/lib/AST/APValue.cpp:676-683
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())

lichray wrote:
> aaron.ballman wrote:
> > Not quite the same thing, but do we have to worry about printing pascal 
> > strings here? (e.g., do we need to do `"\pwhatever"`?
> This is in `APValue` where we lost the context of StringLiteral; nothing 
> tells me that this array was created from a Pascal string literal. Unless you 
> want to do some heuristics, like printing `"\pthis"` when seens an `unsigned 
> char[6]` where the first element = 4 (last element = 0 is checked at the 
> beginning).
Whelp, that explains that. I think the current behavior is fine (I have to 
imagine the number of people still using Pascal strings is as high as four or 
five these days).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 3 inline comments as done.
lichray added inline comments.



Comment at: clang/include/clang/Basic/CharInfo.h:199-200
+return "\\t";
+  case '\v':
+return "\\v";
+  }

aaron.ballman wrote:
> We're also missing `\?` right?
`?` does not seem to need `"escaping?"`



Comment at: clang/lib/AST/APValue.cpp:676-683
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())

aaron.ballman wrote:
> Not quite the same thing, but do we have to worry about printing pascal 
> strings here? (e.g., do we need to do `"\pwhatever"`?
This is in `APValue` where we lost the context of StringLiteral; nothing tells 
me that this array was created from a Pascal string literal. Unless you want to 
do some heuristics, like printing `"\pthis"` when seens an `unsigned char[6]` 
where the first element = 4 (last element = 0 is checked at the beginning).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 411856.
lichray added a comment.

- Revert some auto's


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-28 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/CharInfo.h:199-200
+return "\\t";
+  case '\v':
+return "\\v";
+  }

We're also missing `\?` right?



Comment at: clang/lib/AST/APValue.cpp:658
+  for (auto  : Inits) {
+auto Char64 = Val.getInt().getExtValue();
+if (!isASCII(Char64))





Comment at: clang/lib/AST/APValue.cpp:663
+// The diagnostic message is 'quoted'
+auto Escaped = escapeCStyle(Ch);
+if (Escaped.empty()) {





Comment at: clang/lib/AST/APValue.cpp:676-683
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())

Not quite the same thing, but do we have to worry about printing pascal strings 
here? (e.g., do we need to do `"\pwhatever"`?



Comment at: clang/lib/AST/Expr.cpp:1137
+uint32_t Char = getCodeUnit(I);
+auto Escaped = escapeCStyle(Char);
+if (Escaped.empty()) {




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-11 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 408137.
lichray added a comment.

Rerun pre-merge checks


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-02-10 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 407464.
lichray added a comment.

Rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-27 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 403760.
lichray added a comment.

Rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -80,3 +80,34 @@
  varDecl(hasType(qualType().bind("id"))),
  "const f *", Clean));
 }
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-25 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-22 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked an inline comment as done.
lichray added a comment.

Restricted the ellipsis only to diagnosis. Type comparison now shows full 
initializers, which could be made smarter next time.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-21 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 402180.
lichray added a comment.

- Flip the default and set EntireContentsOfLargeArray off only in diagnosis


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTDiagnostic.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/Sema/Sema.cpp
  clang/test/SemaCXX/cxx2a-nttp-printing.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -62,4 +62,35 @@
   ASSERT_TRUE(PrintedTypeMatches(
   Code, {}, Matcher, "const N::Type &",
   [](PrintingPolicy ) { Policy.FullyQualifiedName = true; }));
-}
\ No newline at end of file
+}
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}>
+  new ASCII<"print more characters as string, no uplimit">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-12 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/include/clang/AST/PrettyPrinter.h:288
+  /// template parameters, no matter how many elements there are.
+  unsigned EntireContentsOfLargeArray : 1;
+

lichray wrote:
> rsmith wrote:
> > It looks like nothing is setting this to `true` yet, so that part of this 
> > patch seems untested. The places I think we want to set this to `true` are:
> > 
> > 1) When forming types in a diagnostic, if we have two types that differ 
> > only in the contents of large arrays. That's checked in here: 
> > https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L259
> > 
> > I think what we'd want is: if we still have a collision between type 
> > names after comparing the canonical strings 
> > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L291),
> >  then set this policy to `true` for the rest of the function, and recompute 
> > `S` and `CanS`.
> > 
> > This should be detectable in a case such as:
> > 
> > ```
> > void f(X<{"some very long string that differs here: x"}>);
> > void g() {
> >   f(X<{"some very long string that differs here: y"}>());
> > }
> > ```
> > 
> > ... where the diagnostic should include the whole string, not elide the 
> > differing portion at the end.
> > 
> > 2) In the `-ast-print` output: when pretty-printing as code, we want to 
> > produce correct, non-elided template arguments. I think this will require 
> > passing a printing policy into `TemplateParamObjectDecl::printAsInit` and 
> > `::printAsExpr` 
> > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/DeclTemplate.cpp#L1509).
> >  This should be detectable in the output of `-ast-print`, where we do not 
> > want to elide any part of template arguments. Perhaps `StmtPrinter` and 
> > `DeclPrinter` should enable this `PrintingPolicy` flag?
> > 
> > 3) When generating debug information: 
> > https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGDebugInfo.cpp#L230
> > 
> > It's generally important that debug information has complete type names.
> Added `PrintingPolicy` parameter to `TemplateParamObjectDecl::printAsInit` 
> and `printAsExpr`, fixed the implementation, and added tests for the effect 
> of the new `EntireContentsOfLargeArray` bit.
> 
> Whether how diagnosis, codegen, and higher-level printers should make use of 
> them, I think they're outside the scope of this patch.
Generally I agree, we don't need to fix all the places that should be setting 
this new flag as part of the same patch, but I think at least `-ast-print` 
should be fixed here, given how obviously broken it currently is. That would 
also remove the need to add a unit test for the new flag.



Comment at: clang/test/SemaTemplate/temp_arg_string_printing.cpp:1
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+

Please use something like diagnostics to test that elision happens, rather than 
`-ast-print`, because `-ast-print` aims to produce valid C++ code that has the 
same meaning as the input -- this is a canonical example of a case that should 
*not* elide large array contents.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 399433.
lichray added a comment.

  Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -62,4 +62,35 @@
   ASSERT_TRUE(PrintedTypeMatches(
   Code, {}, Matcher, "const N::Type &",
   [](PrintingPolicy ) { Policy.FullyQualifiedName = true; }));
-}
\ No newline at end of file
+}
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more than[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"}>
+  new ASCII<"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2022-01-12 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 399415.
lichray added a comment.

- clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -62,4 +62,35 @@
   ASSERT_TRUE(PrintedTypeMatches(
   Code, {}, Matcher, "const N::Type &",
   [](PrintingPolicy ) { Policy.FullyQualifiedName = true; }));
-}
\ No newline at end of file
+}
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more than[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"}>
+  new ASCII<"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-28 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 396408.
lichray added a comment.

- Put tests in TypePrinterTest.cpp


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/TypePrinterTest.cpp

Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- clang/unittests/AST/TypePrinterTest.cpp
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -62,4 +62,35 @@
   ASSERT_TRUE(PrintedTypeMatches(
   Code, {}, Matcher, "const N::Type &",
   [](PrintingPolicy ) { Policy.FullyQualifiedName = true; }));
-}
\ No newline at end of file
+}
+
+TEST(TypePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(
+  hasName("ASCII"), has(cxxConstructorDecl(
+isMoveConstructor(),
+has(parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is [...]"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(ASCII<{"this nontype template argument is too long to print"}> &&)",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more than[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"}>
+  new ASCII<"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-24 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 2 inline comments as done.
lichray added inline comments.



Comment at: clang/include/clang/AST/PrettyPrinter.h:288
+  /// template parameters, no matter how many elements there are.
+  unsigned EntireContentsOfLargeArray : 1;
+

rsmith wrote:
> It looks like nothing is setting this to `true` yet, so that part of this 
> patch seems untested. The places I think we want to set this to `true` are:
> 
> 1) When forming types in a diagnostic, if we have two types that differ only 
> in the contents of large arrays. That's checked in here: 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L259
> 
> I think what we'd want is: if we still have a collision between type 
> names after comparing the canonical strings 
> (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L291),
>  then set this policy to `true` for the rest of the function, and recompute 
> `S` and `CanS`.
> 
> This should be detectable in a case such as:
> 
> ```
> void f(X<{"some very long string that differs here: x"}>);
> void g() {
>   f(X<{"some very long string that differs here: y"}>());
> }
> ```
> 
> ... where the diagnostic should include the whole string, not elide the 
> differing portion at the end.
> 
> 2) In the `-ast-print` output: when pretty-printing as code, we want to 
> produce correct, non-elided template arguments. I think this will require 
> passing a printing policy into `TemplateParamObjectDecl::printAsInit` and 
> `::printAsExpr` 
> (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/DeclTemplate.cpp#L1509).
>  This should be detectable in the output of `-ast-print`, where we do not 
> want to elide any part of template arguments. Perhaps `StmtPrinter` and 
> `DeclPrinter` should enable this `PrintingPolicy` flag?
> 
> 3) When generating debug information: 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGDebugInfo.cpp#L230
> 
> It's generally important that debug information has complete type names.
Added `PrintingPolicy` parameter to `TemplateParamObjectDecl::printAsInit` and 
`printAsExpr`, fixed the implementation, and added tests for the effect of the 
new `EntireContentsOfLargeArray` bit.

Whether how diagnosis, codegen, and higher-level printers should make use of 
them, I think they're outside the scope of this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-24 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 396187.
lichray marked an inline comment as done.
lichray added a comment.
Herald added a subscriber: mgorny.

- Fix categorizing int64_t chars of negative values
- More ArrayRef
- Fix and test the EntireContentsOfLargeArray bit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp
  clang/unittests/AST/CMakeLists.txt
  clang/unittests/AST/ElidePrinterTest.cpp

Index: clang/unittests/AST/ElidePrinterTest.cpp
===
--- /dev/null
+++ clang/unittests/AST/ElidePrinterTest.cpp
@@ -0,0 +1,74 @@
+//===- unittests/AST/ElidePrinterTest.cpp --- Elide printer output tests --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file contains tests for shortening NTTP in AST printer.
+//
+//===--===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+void PrintDecl(raw_ostream , const ASTContext *Context, const Decl *D,
+   PrintingPolicyAdjuster PolicyModifier) {
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  Policy.Indentation = 0;
+  if (PolicyModifier)
+PolicyModifier(Policy);
+  D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);
+}
+
+::testing::AssertionResult
+PrintedDeclMatches(StringRef Code, const std::vector ,
+   const DeclarationMatcher ,
+   StringRef ExpectedPrinted,
+   PrintingPolicyAdjuster PolicyModifier) {
+  return PrintedNodeMatches(Code, Args, NodeMatch, ExpectedPrinted, "",
+  PrintDecl, PolicyModifier);
+}
+
+} // unnamed namespace
+
+TEST(ElidePrinter, TemplateIdWithNTTP) {
+  constexpr char Code[] = R"cpp(
+template 
+struct Str {
+  constexpr Str(char const ()[N]) { __builtin_memcpy(value, s, N); }
+  char value[N];
+};
+template  class ASCII {};
+
+ASCII<"this nontype template argument is too long to print"> x;
+  )cpp";
+  auto Matcher = classTemplateSpecializationDecl(hasName("ASCII")).bind("id");
+
+  ASSERT_TRUE(PrintedDeclMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(template<> class ASCII<{"this nontype template argument is [...]"}> {
+})",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = false;
+  }));
+
+  ASSERT_TRUE(PrintedDeclMatches(
+  Code, {"-std=c++20"}, Matcher,
+  R"(template<> class ASCII<{"this nontype template argument is too long to print"}> {
+})",
+  [](PrintingPolicy ) {
+Policy.EntireContentsOfLargeArray = true;
+  }));
+}
Index: clang/unittests/AST/CMakeLists.txt
===
--- clang/unittests/AST/CMakeLists.txt
+++ clang/unittests/AST/CMakeLists.txt
@@ -22,6 +22,7 @@
   DataCollectionTest.cpp
   DeclPrinterTest.cpp
   DeclTest.cpp
+  ElidePrinterTest.cpp
   EvaluateAsRValueTest.cpp
   ExternalASTSourceTest.cpp
   NamedDeclPrinterTest.cpp
Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-15 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/include/clang/AST/PrettyPrinter.h:288
+  /// template parameters, no matter how many elements there are.
+  unsigned EntireContentsOfLargeArray : 1;
+

It looks like nothing is setting this to `true` yet, so that part of this patch 
seems untested. The places I think we want to set this to `true` are:

1) When forming types in a diagnostic, if we have two types that differ only in 
the contents of large arrays. That's checked in here: 
https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L259

I think what we'd want is: if we still have a collision between type names 
after comparing the canonical strings 
(https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTDiagnostic.cpp#L291),
 then set this policy to `true` for the rest of the function, and recompute `S` 
and `CanS`.

This should be detectable in a case such as:

```
void f(X<{"some very long string that differs here: x"}>);
void g() {
  f(X<{"some very long string that differs here: y"}>());
}
```

... where the diagnostic should include the whole string, not elide the 
differing portion at the end.

2) In the `-ast-print` output: when pretty-printing as code, we want to produce 
correct, non-elided template arguments. I think this will require passing a 
printing policy into `TemplateParamObjectDecl::printAsInit` and `::printAsExpr` 
(https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/DeclTemplate.cpp#L1509).
 This should be detectable in the output of `-ast-print`, where we do not want 
to elide any part of template arguments. Perhaps `StmtPrinter` and 
`DeclPrinter` should enable this `PrintingPolicy` flag?

3) When generating debug information: 
https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGDebugInfo.cpp#L230

It's generally important that debug information has complete type names.



Comment at: clang/include/clang/Basic/CharInfo.h:50
 LLVM_READNONE inline bool isASCII(uint32_t c) { return c <= 127; }
+LLVM_READNONE inline bool isASCII(int64_t c) { return c <= 127; }
 

I think this should also return false for negative values.



Comment at: clang/lib/AST/APValue.cpp:630-631
+const PrintingPolicy ,
+const ArrayType *ATy, const APValue *Data,
+size_t Size) {
+  if (Size == 0)

Consider passing in an `ArrayRef` here instead of forming one below.



Comment at: clang/lib/AST/APValue.cpp:654
+
+  for (auto  : ArrayRef(Data, Size)) {
+auto Char64 = Val.getInt().getExtValue();

I think `ArrayRef` and `ArrayRef` are effectively the same thing 
(you'd need `MutableArrayRef` to remove the implied `const`), so you should be 
able to just use `ArrayRef` here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-15 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

@rsmith Ping. I'm all on you :) You are almost the only one designed these 
files.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-07 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Ping. Ready to review again.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-04 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391833.
lichray marked an inline comment as done.
lichray added a comment.

- Switch to `llvm::SmallString`
- Refactor code that prints C-style builtin escape sequences
- Stop printing strings with embedded NULs in NTTP types
- Add an `EntireContentsOfLargeArray` pretty-print policy


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Basic/CharInfo.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/Expr.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp

Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void not_string() {
+  // CHECK{LITERAL}: ASCII<{{9, -1, 42}}>
+  new ASCII<(int[]){9, -1, 42}>;
+  // CHECK{LITERAL}: ASCII<{{3.14e+00, 0.00e+00, 4.20e+01}}>
+  new ASCII<(double[]){3.14, 0., 42.}>;
+}
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}>
+  new ASCII<"escape\\\t\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more than[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"}>
+  new ASCII<"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, ...}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print even more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print many characters no more than[...]"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII;
+}
+
+void utf8() {
+  // CHECK{LITERAL}: ASCII<{u8""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{229, 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-04 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray marked 5 inline comments as done.
lichray added inline comments.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

lichray wrote:
> lichray wrote:
> > rsmith wrote:
> > > lichray wrote:
> > > > rsmith wrote:
> > > > > We should drop all trailing zeroes here, because array initialization 
> > > > > from a string literal will reconstruct them.
> > > > Are you sure? `MyType<{""}>` and `MyType<{"\0\0\0"}>` are different 
> > > > types.
> > > That's a separate bug. `APValue`'s printing is not intended to identify 
> > > the type of the result, only to identify the value in the case where we 
> > > already know the type. Eg, we don't print a type suffix on a 
> > > pretty-printed integer value. For the specific case of template 
> > > parameters, it's the responsibility of the template argument printing 
> > > code to uniquely identify the template argument.
> > > 
> > > When a template parameter has a deduced class type, we should include 
> > > that type in the printed output in order to uniquely identify the 
> > > specialization, but we don't, because that's not been implemented yet. 
> > > When that's fixed, we should print those cases as `MyType > > 1>{""}>` and `MyType{""}>`. This is necessary anyway, 
> > > because we can't in general assume that the resulting value is enough to 
> > > indicate what type CTAD will have selected.
> > > 
> > > We already handle this properly in some cases, but see this FIXMEs: 
> > > https://github.com/llvm/llvm-project/blob/6c2be3015e07f25912b8cd5b75214c532f568638/clang/lib/AST/TemplateBase.cpp#L433
> > > 
> > > See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that 
> > > the non-struct enum case is handled properly but the enum-in-struct case 
> > > is not).
> > > That's a separate bug. [...]
> > > 
> > > When a template parameter has a deduced class type, we should include 
> > > that type in the printed output in order to uniquely identify the 
> > > specialization, but we don't, because that's not been implemented yet. 
> > > When that's fixed, we should print those cases as `MyType > > 1>{""}>` and `MyType{""}>`. This is necessary anyway, 
> > > because we can't in general assume that the resulting value is enough to 
> > > indicate what type CTAD will have selected.
> > >
> > 
> > But it looks like a feature rather than a bug? String literals provided 
> > both type and value to emphasis a structural type's value for equivalence 
> > comparison. The reason of why `MyType<{""}>` and `MyType<"\0\0\0">` are 
> > different looks more obvious to me.
> > 
> > > See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that 
> > > the non-struct enum case is handled properly but the enum-in-struct case 
> > > is not).
> > 
> > I'm fine if a specific NTTP, `A`, is treated differently from `auto`. But 
> > the last case is similar to this https://godbolt.org/z/YcscTrchM Which I 
> > thought about printing something like `Y<{(E[]){97, 98}}>` :)
> That discussion looks OT... For now, not shrinking `"\0\0\0"` down to `""` 
> follows the existing logic, i.e., we are printing `{0, 0, 0}` even though 
> it's an array.
> 
Nvm, I did not realize that null characters cannot be safely escaped with just 
`\0` without looking at the characters that follow it. Dropping that case and 
fallback to print the integer sequence.



Comment at: clang/lib/AST/APValue.cpp:645
+
+  // Better than printing a two-digit sequence of 10 integers.
+  StringRef Ellipsis;

rsmith wrote:
> ...except that some callers want output that uniquely identifies the template 
> argument, and moreover some callers want output that is valid C++ code that 
> produces the same template-id.
> 
> It'd be better to do this behind a `PrintingPolicy` flag that the diagnostics 
> engine sets. But we'd want to turn that flag off during template type diffing.
Added `Policy.EntireContentsOfLargeArray`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

lichray wrote:
> rsmith wrote:
> > lichray wrote:
> > > rsmith wrote:
> > > > We should drop all trailing zeroes here, because array initialization 
> > > > from a string literal will reconstruct them.
> > > Are you sure? `MyType<{""}>` and `MyType<{"\0\0\0"}>` are different types.
> > That's a separate bug. `APValue`'s printing is not intended to identify the 
> > type of the result, only to identify the value in the case where we already 
> > know the type. Eg, we don't print a type suffix on a pretty-printed integer 
> > value. For the specific case of template parameters, it's the 
> > responsibility of the template argument printing code to uniquely identify 
> > the template argument.
> > 
> > When a template parameter has a deduced class type, we should include that 
> > type in the printed output in order to uniquely identify the 
> > specialization, but we don't, because that's not been implemented yet. When 
> > that's fixed, we should print those cases as `MyType{""}>` and 
> > `MyType{""}>`. This is necessary anyway, because we can't in 
> > general assume that the resulting value is enough to indicate what type 
> > CTAD will have selected.
> > 
> > We already handle this properly in some cases, but see this FIXMEs: 
> > https://github.com/llvm/llvm-project/blob/6c2be3015e07f25912b8cd5b75214c532f568638/clang/lib/AST/TemplateBase.cpp#L433
> > 
> > See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that 
> > the non-struct enum case is handled properly but the enum-in-struct case is 
> > not).
> > That's a separate bug. [...]
> > 
> > When a template parameter has a deduced class type, we should include that 
> > type in the printed output in order to uniquely identify the 
> > specialization, but we don't, because that's not been implemented yet. When 
> > that's fixed, we should print those cases as `MyType{""}>` and 
> > `MyType{""}>`. This is necessary anyway, because we can't in 
> > general assume that the resulting value is enough to indicate what type 
> > CTAD will have selected.
> >
> 
> But it looks like a feature rather than a bug? String literals provided both 
> type and value to emphasis a structural type's value for equivalence 
> comparison. The reason of why `MyType<{""}>` and `MyType<"\0\0\0">` are 
> different looks more obvious to me.
> 
> > See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that 
> > the non-struct enum case is handled properly but the enum-in-struct case is 
> > not).
> 
> I'm fine if a specific NTTP, `A`, is treated differently from `auto`. But the 
> last case is similar to this https://godbolt.org/z/YcscTrchM Which I thought 
> about printing something like `Y<{(E[]){97, 98}}>` :)
That discussion looks OT... For now, not shrinking `"\0\0\0"` down to `""` 
follows the existing logic, i.e., we are printing `{0, 0, 0}` even though it's 
an array.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

rsmith wrote:
> lichray wrote:
> > rsmith wrote:
> > > We should drop all trailing zeroes here, because array initialization 
> > > from a string literal will reconstruct them.
> > Are you sure? `MyType<{""}>` and `MyType<{"\0\0\0"}>` are different types.
> That's a separate bug. `APValue`'s printing is not intended to identify the 
> type of the result, only to identify the value in the case where we already 
> know the type. Eg, we don't print a type suffix on a pretty-printed integer 
> value. For the specific case of template parameters, it's the responsibility 
> of the template argument printing code to uniquely identify the template 
> argument.
> 
> When a template parameter has a deduced class type, we should include that 
> type in the printed output in order to uniquely identify the specialization, 
> but we don't, because that's not been implemented yet. When that's fixed, we 
> should print those cases as `MyType{""}>` and `MyType 4>{""}>`. This is necessary anyway, because we can't in general assume that 
> the resulting value is enough to indicate what type CTAD will have selected.
> 
> We already handle this properly in some cases, but see this FIXMEs: 
> https://github.com/llvm/llvm-project/blob/6c2be3015e07f25912b8cd5b75214c532f568638/clang/lib/AST/TemplateBase.cpp#L433
> 
> See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that the 
> non-struct enum case is handled properly but the enum-in-struct case is not).
> That's a separate bug. [...]
> 
> When a template parameter has a deduced class type, we should include that 
> type in the printed output in order to uniquely identify the specialization, 
> but we don't, because that's not been implemented yet. When that's fixed, we 
> should print those cases as `MyType{""}>` and `MyType 4>{""}>`. This is necessary anyway, because we can't in general assume that 
> the resulting value is enough to indicate what type CTAD will have selected.
>

But it looks like a feature rather than a bug? String literals provided both 
type and value to emphasis a structural type's value for equivalence 
comparison. The reason of why `MyType<{""}>` and `MyType<"\0\0\0">` are 
different looks more obvious to me.

> See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that the 
> non-struct enum case is handled properly but the enum-in-struct case is not).

I'm fine if a specific NTTP, `A`, is treated differently from `auto`. But the 
last case is similar to this https://godbolt.org/z/YcscTrchM Which I thought 
about printing something like `Y<{(E[]){97, 98}}>` :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

lichray wrote:
> rsmith wrote:
> > We should drop all trailing zeroes here, because array initialization from 
> > a string literal will reconstruct them.
> Are you sure? `MyType<{""}>` and `MyType<{"\0\0\0"}>` are different types.
That's a separate bug. `APValue`'s printing is not intended to identify the 
type of the result, only to identify the value in the case where we already 
know the type. Eg, we don't print a type suffix on a pretty-printed integer 
value. For the specific case of template parameters, it's the responsibility of 
the template argument printing code to uniquely identify the template argument.

When a template parameter has a deduced class type, we should include that type 
in the printed output in order to uniquely identify the specialization, but we 
don't, because that's not been implemented yet. When that's fixed, we should 
print those cases as `MyType{""}>` and `MyType{""}>`. 
This is necessary anyway, because we can't in general assume that the resulting 
value is enough to indicate what type CTAD will have selected.

We already handle this properly in some cases, but see this FIXMEs: 
https://github.com/llvm/llvm-project/blob/6c2be3015e07f25912b8cd5b75214c532f568638/clang/lib/AST/TemplateBase.cpp#L433

See also some related issues: https://godbolt.org/z/YhcdMYx6n (note that the 
non-struct enum case is handled properly but the enum-in-struct case is not).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/AST/APValue.cpp:628-629
 
+static bool TryPrintAsStringLiteral(raw_ostream , const ArrayType *ATy,
+const APValue *Data, size_t Size) {
+  if (Size == 0)

rsmith wrote:
> Is there anything you can factor out of `StringLiteral::outputString` and 
> reuse here? At least the single-character printing code seems like something 
> we should try to not overly duplicate.
The goals of the two routines are different. `StringLiteral::outputString` must 
output something that can parse back as a string literal, even it doesn't 
decode UTF-8 right now; the new routine in this patch doesn't have to -- it can 
give up anytime it wants.

I wish `switch` statements were more composable. But if you don't mind, I can 
add a function in `CharInfo.h` to test and get the C-style escaped char and 
retire the outmost `switch` statements in those two routines.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

rsmith wrote:
> We should drop all trailing zeroes here, because array initialization from a 
> string literal will reconstruct them.
Are you sure? `MyType<{""}>` and `MyType<{"\0\0\0"}>` are different types.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391744.
lichray added a comment.

Ensure the ellipses output is never shorter than the normal ones (will look at 
review comments later)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp

Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{"escape\0"}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\'\f\v"}>
+  new ASCII<"escape\\\t'\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more than[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII<"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{L"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, ...}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print even more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print many characters no more than[...]"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII;
+}
+
+void utf8()
+{
+  // CHECK{LITERAL}: ASCII<{u8""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u8"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{229, 165, 189, 239, 191, 189, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"print many characters no more than[...]"}>
+  new ASCII;
+}
+
+void utf16()
+{
+  // CHECK{LITERAL}: ASCII<{u""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{22909, 65533, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"print many characters no more 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/AST/APValue.cpp:628-629
 
+static bool TryPrintAsStringLiteral(raw_ostream , const ArrayType *ATy,
+const APValue *Data, size_t Size) {
+  if (Size == 0)

Is there anything you can factor out of `StringLiteral::outputString` and reuse 
here? At least the single-character printing code seems like something we 
should try to not overly duplicate.



Comment at: clang/lib/AST/APValue.cpp:637-639
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;

We should drop all trailing zeroes here, because array initialization from a 
string literal will reconstruct them.



Comment at: clang/lib/AST/APValue.cpp:641-643
+  constexpr size_t MaxN = 36;
+  char Buf[MaxN * 2 + 3] = {'"'}; // "At most 36 escaped chars" + \0
+  auto *pBuf = Buf + 1;

Prefer `llvm::SmallString` and `push_back`.



Comment at: clang/lib/AST/APValue.cpp:645
+
+  // Better than printing a two-digit sequence of 10 integers.
+  StringRef Ellipsis;

...except that some callers want output that uniquely identifies the template 
argument, and moreover some callers want output that is valid C++ code that 
produces the same template-id.

It'd be better to do this behind a `PrintingPolicy` flag that the diagnostics 
engine sets. But we'd want to turn that flag off during template type diffing.



Comment at: clang/lib/AST/APValue.cpp:902
 if (I == 10) {
   // Avoid printing out the entire contents of large arrays.
+  Out << "...}";

(The existing code is also doing elision here that will be inappropriate for 
some callers. If you add a `PrintingPolicy` to unambiguously print template 
arguments, it should disable this check too.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

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


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391718.
lichray added a comment.

Add EOL to source file


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp

Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{"escape\0"}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\'\f\v"}>
+  new ASCII<"escape\\\t'\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more t[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII<"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{L"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, ...}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print even more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print many characters no more t[...]"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII;
+}
+
+void utf8()
+{
+  // CHECK{LITERAL}: ASCII<{u8""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u8"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{229, 165, 189, 239, 191, 189, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"print many characters no more t[...]"}>
+  new ASCII;
+}
+
+void utf16()
+{
+  // CHECK{LITERAL}: ASCII<{u""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{22909, 65533, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"print many characters no more t[...]"}>
+  new ASCII;
+}
+
+void utf32()
+{
+  // CHECK{LITERAL}: ASCII<{U""}>
+  new ASCII;
+  // 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391717.
lichray added a comment.

- Add tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp
  clang/test/SemaTemplate/temp_arg_string_printing.cpp

Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/temp_arg_string_printing.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-print %s | FileCheck %s
+
+using size_t = __SIZE_TYPE__;
+static_assert(__has_builtin(__make_integer_seq));
+
+template  class idx_seq {};
+template  using make_idx_seq = __make_integer_seq;
+
+template 
+struct Str {
+  constexpr Str(CharT const ()[N]) : Str(s, make_idx_seq()) {}
+  CharT value[N];
+
+private:
+  template 
+  constexpr Str(CharT const ()[N], idx_seq) : value{s[I]...} {}
+};
+
+template  class ASCII {};
+
+void narrow() {
+  // CHECK{LITERAL}: ASCII<{""}>
+  new ASCII<"">;
+  // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}>
+  new ASCII<"the quick brown fox jumps">;
+  // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}>
+  new ASCII<"OVER THE LAZY DOG 0123456789">;
+  // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{"escape\0"}>
+  new ASCII<"escape\0">;
+  // CHECK{LITERAL}: ASCII<{"escape\r\n"}>
+  new ASCII<"escape\r\n">;
+  // CHECK{LITERAL}: ASCII<{"escape\\\t\'\f\v"}>
+  new ASCII<"escape\\\t'\f\v">;
+  // CHECK{LITERAL}: ASCII<{"escape\a\bc"}>
+  new ASCII<"escape\a\b\c">;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII<"not\x11">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abc">;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, ...}}>
+  new ASCII<"\x12\x14\x7f\x10\x01 abcd">;
+  // CHECK{LITERAL}: ASCII<{"print more characters as string"}>
+  new ASCII<"print more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print even more characters as string"}>
+  new ASCII<"print even more characters as string">;
+  // CHECK{LITERAL}: ASCII<{"print many characters no more t[...]"}>
+  new ASCII<"print many characters no more than a limit">;
+  // CHECK{LITERAL}: ASCII<{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII<"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0">;
+  // CHECK{LITERAL}: ASCII<{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n">;
+}
+
+void wide() {
+  // CHECK{LITERAL}: ASCII<{L""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{L"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, ...}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print even more characters as string"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"print many characters no more t[...]"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{L"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[...]"}>
+  new ASCII;
+}
+
+void utf8()
+{
+  // CHECK{LITERAL}: ASCII<{u8""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u8"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{229, 165, 189, 239, 191, 189, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u8"print many characters no more t[...]"}>
+  new ASCII;
+}
+
+void utf16()
+{
+  // CHECK{LITERAL}: ASCII<{u""}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}>
+  new ASCII?/)">;
+  // CHECK{LITERAL}: ASCII<{u"escape\0"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"escape\r\n"}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{{22909, 65533, 0}}>
+  new ASCII;
+  // CHECK{LITERAL}: ASCII<{u"print many characters no more t[...]"}>
+  new ASCII;
+}
+
+void utf32()
+{
+  // CHECK{LITERAL}: ASCII<{U""}>
+  new ASCII;
+  // CHECK{LITERAL}: 

[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391602.
lichray added a comment.

Restore deleted comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp

Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -625,6 +625,97 @@
   return V.convertToDouble();
 }
 
+static bool TryPrintAsStringLiteral(raw_ostream , const ArrayType *ATy,
+const APValue *Data, size_t Size) {
+  if (Size == 0)
+return false;
+
+  QualType Ty = ATy->getElementType();
+  if (!Ty->isAnyCharacterType())
+return false;
+
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;
+
+  constexpr size_t MaxN = 36;
+  char Buf[MaxN * 2 + 3] = {'"'}; // "At most 36 escaped chars" + \0
+  auto *pBuf = Buf + 1;
+
+  // Better than printing a two-digit sequence of 10 integers.
+  StringRef Ellipsis;
+  if (Size > MaxN) {
+Ellipsis = " [...]";
+Size = std::min(MaxN - Ellipsis.size(), Size);
+  }
+
+  auto writeEscape = [](char *Ptr, char Ch) {
+Ptr[0] = '\\';
+Ptr[1] = Ch;
+return Ptr + 2;
+  };
+
+  for (auto  : ArrayRef(Data, Size)) {
+auto Char64 = Val.getInt().getExtValue();
+if (Char64 > 0x7f)
+  return false; // Bye bye, see you in integers.
+switch (auto Ch = static_cast(Char64)) {
+default:
+  if (isPrintable(Ch)) {
+*pBuf++ = Ch;
+break;
+  }
+  return false;
+case '\\':
+case '\'': // The diagnostic message is 'quoted'
+  pBuf = writeEscape(pBuf, Ch);
+  break;
+case '\0':
+  pBuf = writeEscape(pBuf, '0');
+  break;
+case '\a':
+  pBuf = writeEscape(pBuf, 'a');
+  break;
+case '\b':
+  pBuf = writeEscape(pBuf, 'b');
+  break;
+case '\f':
+  pBuf = writeEscape(pBuf, 'f');
+  break;
+case '\n':
+  pBuf = writeEscape(pBuf, 'n');
+  break;
+case '\r':
+  pBuf = writeEscape(pBuf, 'r');
+  break;
+case '\t':
+  pBuf = writeEscape(pBuf, 't');
+  break;
+case '\v':
+  pBuf = writeEscape(pBuf, 'v');
+  break;
+}
+  }
+
+  if (!Ellipsis.empty()) {
+memcpy(pBuf, Ellipsis.data(), Ellipsis.size());
+pBuf += Ellipsis.size();
+  }
+  *pBuf++ = '"';
+
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())
+Out << 'U';
+
+  Out << StringRef(Buf, pBuf - Buf);
+  return true;
+}
+
 void APValue::printPretty(raw_ostream , const ASTContext ,
   QualType Ty) const {
   printPretty(Out, Ctx.getPrintingPolicy(), Ty, );
@@ -795,17 +886,24 @@
   }
   case APValue::Array: {
 const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
+unsigned N = getArrayInitializedElts();
+if (N != 0 &&
+TryPrintAsStringLiteral(Out, AT, (0), N))
+  return;
 QualType ElemTy = AT->getElementType();
 Out << '{';
-if (unsigned N = getArrayInitializedElts()) {
-  getArrayInitializedElt(0).printPretty(Out, Policy, ElemTy, Ctx);
-  for (unsigned I = 1; I != N; ++I) {
+unsigned I = 0;
+switch (N) {
+case 0:
+  for (; I != N; ++I) {
 Out << ", ";
 if (I == 10) {
   // Avoid printing out the entire contents of large arrays.
-  Out << "...";
-  break;
+  Out << "...}";
+  return;
 }
+LLVM_FALLTHROUGH;
+  default:
 getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray updated this revision to Diff 391600.
lichray added a comment.

Fix failed assertion


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp

Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -625,6 +625,97 @@
   return V.convertToDouble();
 }
 
+static bool TryPrintAsStringLiteral(raw_ostream , const ArrayType *ATy,
+const APValue *Data, size_t Size) {
+  if (Size == 0)
+return false;
+
+  QualType Ty = ATy->getElementType();
+  if (!Ty->isAnyCharacterType())
+return false;
+
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;
+
+  constexpr size_t MaxN = 36;
+  char Buf[MaxN * 2 + 3] = {'"'}; // "At most 36 escaped chars" + \0
+  auto *pBuf = Buf + 1;
+
+  // Better than printing a two-digit sequence of 10 integers.
+  StringRef Ellipsis;
+  if (Size > MaxN) {
+Ellipsis = " [...]";
+Size = std::min(MaxN - Ellipsis.size(), Size);
+  }
+
+  auto writeEscape = [](char *Ptr, char Ch) {
+Ptr[0] = '\\';
+Ptr[1] = Ch;
+return Ptr + 2;
+  };
+
+  for (auto  : ArrayRef(Data, Size)) {
+auto Char64 = Val.getInt().getExtValue();
+if (Char64 > 0x7f)
+  return false; // Bye bye, see you in integers.
+switch (auto Ch = static_cast(Char64)) {
+default:
+  if (isPrintable(Ch)) {
+*pBuf++ = Ch;
+break;
+  }
+  return false;
+case '\\':
+case '\'': // The diagnostic message is 'quoted'
+  pBuf = writeEscape(pBuf, Ch);
+  break;
+case '\0':
+  pBuf = writeEscape(pBuf, '0');
+  break;
+case '\a':
+  pBuf = writeEscape(pBuf, 'a');
+  break;
+case '\b':
+  pBuf = writeEscape(pBuf, 'b');
+  break;
+case '\f':
+  pBuf = writeEscape(pBuf, 'f');
+  break;
+case '\n':
+  pBuf = writeEscape(pBuf, 'n');
+  break;
+case '\r':
+  pBuf = writeEscape(pBuf, 'r');
+  break;
+case '\t':
+  pBuf = writeEscape(pBuf, 't');
+  break;
+case '\v':
+  pBuf = writeEscape(pBuf, 'v');
+  break;
+}
+  }
+
+  if (!Ellipsis.empty()) {
+memcpy(pBuf, Ellipsis.data(), Ellipsis.size());
+pBuf += Ellipsis.size();
+  }
+  *pBuf++ = '"';
+
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())
+Out << 'U';
+
+  Out << StringRef(Buf, pBuf - Buf);
+  return true;
+}
+
 void APValue::printPretty(raw_ostream , const ASTContext ,
   QualType Ty) const {
   printPretty(Out, Ctx.getPrintingPolicy(), Ty, );
@@ -795,17 +886,23 @@
   }
   case APValue::Array: {
 const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
+unsigned N = getArrayInitializedElts();
+if (N != 0 &&
+TryPrintAsStringLiteral(Out, AT, (0), N))
+  return;
 QualType ElemTy = AT->getElementType();
 Out << '{';
-if (unsigned N = getArrayInitializedElts()) {
-  getArrayInitializedElt(0).printPretty(Out, Policy, ElemTy, Ctx);
-  for (unsigned I = 1; I != N; ++I) {
+unsigned I = 0;
+switch (N) {
+case 0:
+  for (; I != N; ++I) {
 Out << ", ";
 if (I == 10) {
-  // Avoid printing out the entire contents of large arrays.
-  Out << "...";
-  break;
+  Out << "...}";
+  return;
 }
+LLVM_FALLTHROUGH;
+  default:
 getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115031: [AST] Print NTTP args as string-literals when possible

2021-12-03 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray created this revision.
lichray requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

C++20 NTTP (non-type template parameter) prints `MyType<{{116, 104, 105, 
115}}>` when the code is as simple as `MyType<"this">`. Of course, due to the 
need for an intermediate structural type to trigger CTAD, it'd be better to 
keep one layer of the braces. So this patch prints `MyType<{"this"}>`.

Currently, `StringLiteral` can handle this case nicely, but `StringLiteral` 
inside `APValue` code looks like a circular dependency. So, in this patch, I 
implemented a very cheap strategy to emit string literals in diagnostic message 
only when it's more readable and fall back to integer sequences. *Please tell 
me whether this approach is acceptable* before I write tests.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115031

Files:
  clang/lib/AST/APValue.cpp

Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -625,6 +625,97 @@
   return V.convertToDouble();
 }
 
+static bool TryPrintAsStringLiteral(raw_ostream , const ArrayType *ATy,
+const APValue *Data, size_t Size) {
+  if (Size == 0)
+return false;
+
+  QualType Ty = ATy->getElementType();
+  if (!Ty->isAnyCharacterType())
+return false;
+
+  // Nothing we can do about a sequence that is not null-terminated
+  if (!Data[--Size].getInt().isZero())
+return false;
+
+  constexpr size_t MaxN = 36;
+  char Buf[MaxN * 2 + 3] = {'"'}; // "At most 36 escaped chars" + \0
+  auto *pBuf = Buf + 1;
+
+  // Better than printing a two-digit sequence of 10 integers.
+  StringRef Ellipsis;
+  if (Size > MaxN) {
+Ellipsis = " [...]";
+Size = std::min(MaxN - Ellipsis.size(), Size);
+  }
+
+  auto writeEscape = [](char *Ptr, char Ch) {
+Ptr[0] = '\\';
+Ptr[1] = Ch;
+return Ptr + 2;
+  };
+
+  for (auto  : ArrayRef(Data, Size)) {
+auto Char64 = Val.getInt().getExtValue();
+if (Char64 > 0x7f)
+  return false; // Bye bye, see you in integers.
+switch (auto Ch = static_cast(Char64)) {
+default:
+  if (isPrintable(Ch)) {
+*pBuf++ = Ch;
+break;
+  }
+  return false;
+case '\\':
+case '\'': // The diagnostic message is 'quoted'
+  pBuf = writeEscape(pBuf, Ch);
+  break;
+case '\0':
+  pBuf = writeEscape(pBuf, '0');
+  break;
+case '\a':
+  pBuf = writeEscape(pBuf, 'a');
+  break;
+case '\b':
+  pBuf = writeEscape(pBuf, 'b');
+  break;
+case '\f':
+  pBuf = writeEscape(pBuf, 'f');
+  break;
+case '\n':
+  pBuf = writeEscape(pBuf, 'n');
+  break;
+case '\r':
+  pBuf = writeEscape(pBuf, 'r');
+  break;
+case '\t':
+  pBuf = writeEscape(pBuf, 't');
+  break;
+case '\v':
+  pBuf = writeEscape(pBuf, 'v');
+  break;
+}
+  }
+
+  if (!Ellipsis.empty()) {
+memcpy(pBuf, Ellipsis.data(), Ellipsis.size());
+pBuf += Ellipsis.size();
+  }
+  *pBuf++ = '"';
+
+  if (Ty->isWideCharType())
+Out << 'L';
+  else if (Ty->isChar8Type())
+Out << "u8";
+  else if (Ty->isChar16Type())
+Out << 'u';
+  else if (Ty->isChar32Type())
+Out << 'U';
+
+  Out << StringRef(Buf, pBuf - Buf);
+  return true;
+}
+
 void APValue::printPretty(raw_ostream , const ASTContext ,
   QualType Ty) const {
   printPretty(Out, Ctx.getPrintingPolicy(), Ty, );
@@ -795,17 +886,22 @@
   }
   case APValue::Array: {
 const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
+if (TryPrintAsStringLiteral(Out, AT, (0),
+getArrayInitializedElts()))
+  return;
 QualType ElemTy = AT->getElementType();
 Out << '{';
-if (unsigned N = getArrayInitializedElts()) {
-  getArrayInitializedElt(0).printPretty(Out, Policy, ElemTy, Ctx);
-  for (unsigned I = 1; I != N; ++I) {
+unsigned I = 0;
+switch (unsigned N = getArrayInitializedElts()) {
+case 0:
+  for (; I != N; ++I) {
 Out << ", ";
 if (I == 10) {
-  // Avoid printing out the entire contents of large arrays.
-  Out << "...";
-  break;
+  Out << "...}";
+  return;
 }
+LLVM_FALLTHROUGH;
+  default:
 getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits