[PATCH] D93938: [clang-format] Fixed AfterEnum handling

2021-11-17 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Not trying to take over this patch, because I've got a ton of patches I need to 
be finishing up myself.

but I think the problematic code is in UnwrappedLineParser.cpp:1900

  if (FormatTok->Tok.getKind() == ClosingBraceKind) {
if (IsEnum && !Style.AllowShortEnumsOnASingleLine)
  addUnwrappedLine();
nextToken();
return !HasError;
  }

I'd change that if statement to

  if (FormatTok->Tok.getKind() == ClosingBraceKind) {
if (IsEnum && (!Style.AllowShortEnumsOnASingleLine || 
!BraceWrapping.AfterEnum))
addUnwrappedLine();
nextToken();
return !HasError;
  }

I haven't tried this code at all, just a gut feeling based on my experience 
fixing the extern block wrapping; hopefully it helps point you in the right 
direction.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93938

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


[PATCH] D93938: [clang-format] Fixed AfterEnum handling

2021-11-17 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D93938#2832825 , @Userbla wrote:

> I applied this fix locally to a branch based off llvm 11.x and the 
> `FormatTest.FormatsTypedefEnum` test now fails.

I'm running into this bug too.

  typedef enum Blah {
  One = 1,
  } Blah;

becomes

  typedef enum Blah
  {
  One = 1,
  } Blah;

with BraceWrapping.AfterEnum set to true or false, and 
AllowShortEnumsOnASingleLine set to false; but with 
AllowShortEnumsOnASingleLine set to true and BraceWrapping.AfterEnum set to 
true it works.

Only problem is, I never want short enums to be on a single line.



I feel like I ran into a similar bug when I contributed the patch to add 
BraceWrapping.AfterExternBlock; something else I don't recall off the top of my 
head, was messing with that setting too.

and the solution was to add an if statement around that call to 
addUnwrappedLine().


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93938

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


[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-11-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 387788.
MarcusJohnson91 added a comment.

Clang-FormatDiff.py; Still waiting for the UTFConvert patch to land first.


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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/ScanfFormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -24,6 +24,8 @@
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  printf("%l16s", "foo"); // expected-warning{{format specifies type 'char16_t *' but the argument has type 'const char *'}}
+  printf("%l32s", "foo"); // expected-warning{{format specifies type 'char32_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/Sema/format-strings-int-typedefs.c
===
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -10,18 +10,35 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
 
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'short')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'short *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+
   scanf("%jd", 0); // expected-warning {{format specifies type 'intmax_t *' (aka 'long long *')}}
   scanf("%ju", 0); // expected-warning {{format specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
   scanf("%zu", 0); // expected-warning {{format specifies type 'size_t *' (aka 'unsigned long *')}}
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
 
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
   // typedef size_t et al. to something crazy.
   typedef void *size_t;
Index: clang/lib/AST/ScanfFormatString.cpp
===
--- clang/lib/AST/ScanfFormatString.cpp
+++ clang/lib/AST/ScanfFormatString.cpp
@@ -261,6 +261,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
 case LengthModifier::AsShortLong:
   return ArgType::Invalid();
   }
@@ -302,6 +304,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case 

[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-08-01 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 363376.

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

https://reviews.llvm.org/D106755

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -8,6 +8,9 @@
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
+extern int vwprintf(const wchar_t *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -18,12 +21,23 @@
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
 
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
+
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,54 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp); // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf(L"%a", 1.0);
+  wscanf(L"%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // expected-warning {{not a string literal}}
+  // expected-note@-1{{treat the string as an argument to avoid this}}
 
   // PR13099
   printf(
 R"foobar(%)foobar"
 R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
 R"xyzzy()xyzzy");
+  wprintf(
+  LR"foobar(%)foobar"
+  LR"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
+  LR"xyzzy()xyzzy");
 
   printf(u8"this is %d test", 0); // ok
+  wprintf(L"this is %d test", 0); // ok
   printf(u8R"foo(
   \u1234\U0010fffe
   %d)foo" // expected-warning {{more '%' conversions than data arguments}}
   );
+  wprintf(LR"foo(
+  \u1234\U0010fffe
+  %d)foo" // expected-warning {{more '%' conversions than data 

[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-08-01 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 363374.

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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/ScanfFormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -24,6 +24,8 @@
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  printf("%l16s", "foo"); // expected-warning{{format specifies type 'char16_t *' but the argument has type 'const char *'}}
+  printf("%l32s", "foo"); // expected-warning{{format specifies type 'char32_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/Sema/format-strings-int-typedefs.c
===
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -10,18 +10,35 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
 
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'short')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'short *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+
   scanf("%jd", 0); // expected-warning {{format specifies type 'intmax_t *' (aka 'long long *')}}
   scanf("%ju", 0); // expected-warning {{format specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
   scanf("%zu", 0); // expected-warning {{format specifies type 'size_t *' (aka 'unsigned long *')}}
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
 
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
   // typedef size_t et al. to something crazy.
   typedef void *size_t;
Index: clang/lib/AST/ScanfFormatString.cpp
===
--- clang/lib/AST/ScanfFormatString.cpp
+++ clang/lib/AST/ScanfFormatString.cpp
@@ -261,6 +261,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
 case LengthModifier::AsShortLong:
   return ArgType::Invalid();
   }
@@ -302,6 +304,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
 case LengthModifier::AsShortLong:
   

[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-07-30 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 363245.
MarcusJohnson91 added a comment.

Rebased


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

https://reviews.llvm.org/D106755

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -8,6 +8,9 @@
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
+extern int vwprintf(const wchar_t *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -18,12 +21,23 @@
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
 
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
+
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,54 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp); // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf(L"%a", 1.0);
+  wscanf(L"%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // expected-warning {{not a string literal}}
+  // expected-note@-1{{treat the string as an argument to avoid this}}
 
   // PR13099
   printf(
 R"foobar(%)foobar"
 R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
 R"xyzzy()xyzzy");
+  wprintf(
+  LR"foobar(%)foobar"
+  LR"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
+  LR"xyzzy()xyzzy");
 
   printf(u8"this is %d test", 0); // ok
+  wprintf(L"this is %d test", 0); // ok
   printf(u8R"foo(
   \u1234\U0010fffe
   %d)foo" // expected-warning {{more '%' conversions than data arguments}}
   );
+  wprintf(LR"foo(
+  

[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-07-30 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 363244.
MarcusJohnson91 added a comment.

Rebased on Main


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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -24,6 +24,8 @@
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  printf("%l16s", "foo"); // expected-warning{{format specifies type 'char16_t *' but the argument has type 'const char *'}}
+  printf("%l32s", "foo"); // expected-warning{{format specifies type 'char32_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/Sema/format-strings-int-typedefs.c
===
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -10,18 +10,35 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
 
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'short')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'short *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+
   scanf("%jd", 0); // expected-warning {{format specifies type 'intmax_t *' (aka 'long long *')}}
   scanf("%ju", 0); // expected-warning {{format specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
   scanf("%zu", 0); // expected-warning {{format specifies type 'size_t *' (aka 'unsigned long *')}}
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
 
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
   // typedef size_t et al. to something crazy.
   typedef void *size_t;
Index: clang/lib/AST/FormatString.cpp
===
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -520,6 +520,12 @@
 case WCStrTy:
   Res = C.getPointerType(C.getWideCharType());
   break;
+case Char16Ty:
+  Res = C.getPointerType(C.getChar16Type());
+  break;
+case Char32Ty:
+  Res = C.getPointerType(C.getChar32Type());
+  break;
 case ObjCPointerTy:
   Res = C.ObjCBuiltinIdTy;
   break;
@@ -607,6 +613,10 @@
 return "m";
   case AsWide:
 return "w";
+  case AsUTF16:
+return "l16";
+  case AsUTF32:
+return "l32";
   case None:
 return "";
   }
@@ -860,6 +870,17 @@
 default:
   return false;
   }
+case LengthModifier::AsUTF16:
+case 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-30 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

There is only one function in ConvertUTFWrapper.cpp: convertUTF32ToUTF8String

idk wtf is going on, maybe the ammending the commit is breaking something?

the diff I see here is correct...

Maybe I should just make a new diff here entirely?


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

https://reviews.llvm.org/D106753

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


[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-30 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 363216.
MarcusJohnson91 added a comment.

It seems like this diff keeps getting reverted?

I've fixed all the issues mentioned, and the tests work now, everything is 
formatted correctly too.

I've set git up to do full context diffs, but it's not working?


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -25,6 +25,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x2E\xF5\x01\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
@@ -36,6 +47,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x00\x00\xfe\xff\x00\x01\xF5\x2E";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,60 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -123,6 +123,9 @@
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
 typedef enum {
   conversionOK,   /* conversion successful */
   sourceExhausted,/* partial character in source, but hit end */
@@ -278,6 +281,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+ * 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362923.

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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -25,6 +25,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x2E\xF5\x01\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
@@ -36,6 +47,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x00\x00\xfe\xff\x00\x01\xF5\x2E";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,60 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -123,6 +123,9 @@
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
 typedef enum {
   conversionOK,   /* conversion successful */
   sourceExhausted,/* partial character in source, but hit end */
@@ -278,6 +281,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+ * Converts a UTF32 string into a UTF8 std::string.
+ *
+ * \param [in] Src A buffer of UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef Src, 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362907.
MarcusJohnson91 added a comment.

Formatted the diff


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -25,6 +25,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x2E\xF5\x01\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
@@ -36,6 +47,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x00\x00\xfe\xff\x00\x01\xF5\x2E";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -89,6 +111,8 @@
   EXPECT_EQ(Expected, Result);
 }
 
+
+
 TEST(ConvertUTFTest, ConvertUTF8toWide) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,60 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -123,6 +123,9 @@
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
 typedef enum {
   conversionOK,   /* conversion successful */
   sourceExhausted,/* partial character in source, but hit end */
@@ -278,6 +281,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+ * 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362882.
MarcusJohnson91 added a comment.

The tests work on my machine now, turns out the Big endian one needs a BOM, 
pretty obvious in hindsight.


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -25,6 +25,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x2E\xF5\x01\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
@@ -36,6 +47,17 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is a crystal ball.
+  alignas(UTF32) static const char Src[] = "\x00\x00\xfe\xff\x00\x01\xF5\x2E";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xF0\x9F\x94\xAE");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -89,6 +111,8 @@
   EXPECT_EQ(Expected, Result);
 }
 
+
+
 TEST(ConvertUTFTest, ConvertUTF8toWide) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,60 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -123,6 +123,9 @@
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
 typedef enum {
   conversionOK,   /* conversion successful */
   sourceExhausted,/* partial character in source, but hit end */
@@ -278,6 +281,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-28 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

The problem seems to be in the conversion function expecting strings to be a 
multiple of 4 bytes, which doesn't hold up with the way ArrayRef stores things 
as char that is casted to char32_t, when using ASCII values like in the look of 
disapproval emoji, having an underscore in the middle.

But removing the assert and early return result in even more errors.

changing the input string to remove the underscore also fails, i'm out of ideas.


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

https://reviews.llvm.org/D106753

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


[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-28 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362511.

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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xA0\x0C\x00\x00_\xA0\x0C\x00\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\x00\x00\x0C\xA0_\x00\x00\x0C\xA0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,17 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,64 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 4)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -123,6 +123,9 @@
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
 typedef enum {
   conversionOK,   /* conversion successful */
   sourceExhausted,/* partial character in source, but hit end */
@@ -278,6 +281,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * 

[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-07-28 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362446.

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

https://reviews.llvm.org/D106755

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -8,6 +8,9 @@
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
+extern int vwprintf(const wchar_t *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -18,12 +21,23 @@
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
 
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
+
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,53 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'wchar_t **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'wchar_t **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp); // expected-warning{{format specifies type 'void **' but the argument has type 'wchar_t **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // expected-warning {{not a string literal}}
+  // expected-note@-1{{treat the string as an argument to avoid this}}
 
   // PR13099
   printf(
 R"foobar(%)foobar"
 R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
 R"xyzzy()xyzzy");
+  wprintf(
+  R"foobar(%)foobar"
+  R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
+  R"xyzzy()xyzzy");
 
   printf(u8"this is %d test", 0); // ok
+  wprintf(u8"this is %d test", 0); // ok
   printf(u8R"foo(
   \u1234\U0010fffe
   %d)foo" // expected-warning {{more '%' conversions than data arguments}}
   );
+  wprintf(u8R"foo(
+  \u1234\U0010fffe
+  %d)foo" // expected-warning {{more '%' conversions than data arguments}}

[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-07-28 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362444.
MarcusJohnson91 added a comment.

Added a couple tests


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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -24,6 +24,8 @@
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  printf("%l16s", "foo"); // expected-warning{{format specifies type 'char16_t *' but the argument has type 'const char *'}}
+  printf("%l32s", "foo"); // expected-warning{{format specifies type 'char32_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/Sema/format-strings-int-typedefs.c
===
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -10,8 +10,17 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
+  
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'short')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'short *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
   scanf("%jd", 0); // expected-warning {{format specifies type 'intmax_t *' (aka 'long long *')}}
   scanf("%ju", 0); // expected-warning {{format specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
@@ -19,8 +28,17 @@
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
 
 
   // typedef size_t et al. to something crazy.
Index: clang/lib/AST/FormatString.cpp
===
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -520,6 +520,12 @@
 case WCStrTy:
   Res = C.getPointerType(C.getWideCharType());
   break;
+case Char16Ty:
+  Res = C.getPointerType(C.getChar16Type());
+  break;
+case Char32Ty:
+  Res = C.getPointerType(C.getChar32Type());
+  break;
 case ObjCPointerTy:
   Res = C.ObjCBuiltinIdTy;
   break;
@@ -607,6 +613,10 @@
 return "m";
   case AsWide:
 return "w";
+  case AsUTF16:
+return "l16";
+  case AsUTF32:
+return "l32";
   case None:
 return "";
   }
@@ -860,6 +870,17 @@
 default:
   return false;
   }
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
+  switch (CS.getKind()) {
+  case ConversionSpecifier::cArg:
+  case 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-28 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362431.
MarcusJohnson91 added a comment.

Updated the tests


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xA0\x0C\x00\x00_\xA0\x0C\x00\x00";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\x00\x00\x0C\xA0_\x00\x00\x0C\xA0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,17 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,64 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 4)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -278,6 +278,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-27 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: llvm/lib/Support/ConvertUTFWrapper.cpp:176
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);

efriedma wrote:
> `SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1` seems like way too 
> much memory.
I copied that from the UTF16 code


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

https://reviews.llvm.org/D106753

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


[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-27 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 362198.
MarcusJohnson91 added a comment.

Dropped the UTF32 BOM stuff


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,17 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -141,6 +141,64 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 4)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string ) {
+  return convertUTF32ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+   Src.size() * sizeof(UTF32)),
+  Out);
+}
+
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
   assert(DstUTF16.empty());
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -278,6 +278,24 @@
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
 
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Anyone got any ideas what happened this time?


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

https://reviews.llvm.org/D106753

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 5 inline comments as done.
MarcusJohnson91 added inline comments.



Comment at: clang/lib/AST/Expr.cpp:1091
+  if (llvm::convertUTF32ToUTF8String(AR, Output)) {
+CString = new char[Output.size() + 1];
+memcpy(CString, Output.c_str(), Output.size());

efriedma wrote:
> This leaks memory.
> 
> This function should return either a StringRef to memory that's part of AST 
> object, or an std::string.
I've switched over to using getStringAsChar and doing the conversion there 
instead of in getStrDataAsChar, on the other patch. (just going through this 
review to see if I missed any feedback)



Comment at: clang/lib/AST/Type.cpp:1962
 
+bool Type::isType(const std::string TypeName) const {
+  QualType Desugar = this->getLocallyUnqualifiedSingleStepDesugaredType();

efriedma wrote:
> MarcusJohnson91 wrote:
> > aaron.ballman wrote:
> > > Oh, I see now that this is doing a name comparison against the type -- 
> > > that's not a good API in general because it's *really* hard to guess at 
> > > what the type will come out as textually. e.g., `class` and `struct` 
> > > keywords are interchangeable in C++, C sometimes gets confused with 
> > > `bool` vs `_Bool`, template arguments sometimes matter, nested name 
> > > specifiers, etc. Callers of this API will have to guess at these details 
> > > and the printing of the type may change over time (e.g., C may switch 
> > > from `_Bool` to `bool` and then code calling `isType("_Bool")` may react 
> > > poorly to the change).
> > > 
> > > I think we need to avoid this sort of API on `Type`.
> > I see your point, I reverted the behavior back to doing the desugaring in 
> > just isChar16Type and isChar32Type
> I'm not convinced we should be looking at sugar even in 
> isChar16Type/isChar32Type/isAnyCharacterType.  That seems like a great way to 
> end up with subtle bugs that only manifest when someone uses the wrong 
> typedef.
> 
> Where is the distinction between the value `(uint32_t)1` vs. `(char32_t)1` 
> relevant for C, anyway?
char32_t is a typedef, not a builtin type in C.

the underlying type is uint_least32_t, which is usually another typedef to int.

in order for char32_t to be accepted in C mode, we have to know that it is a 
string type and not just some random array, so I'm checking the sugar to see if 
char32_t appears in the typedef chain.




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

https://reviews.llvm.org/D103426

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


[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361539.
MarcusJohnson91 added a comment.

Clang-formatted the diff


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

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp

Index: clang/lib/AST/FormatString.cpp
===
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -520,6 +520,12 @@
 case WCStrTy:
   Res = C.getPointerType(C.getWideCharType());
   break;
+case Char16Ty:
+  Res = C.getPointerType(C.getChar16Type());
+  break;
+case Char32Ty:
+  Res = C.getPointerType(C.getChar32Type());
+  break;
 case ObjCPointerTy:
   Res = C.ObjCBuiltinIdTy;
   break;
@@ -607,6 +613,10 @@
 return "m";
   case AsWide:
 return "w";
+  case AsUTF16:
+return "l16";
+  case AsUTF32:
+return "l32";
   case None:
 return "";
   }
@@ -860,6 +870,17 @@
 default:
   return false;
   }
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
+  switch (CS.getKind()) {
+  case ConversionSpecifier::cArg:
+  case ConversionSpecifier::CArg:
+  case ConversionSpecifier::sArg:
+  case ConversionSpecifier::SArg:
+return true;
+  default:
+return false;
+  }
 case LengthModifier::AsWide:
   switch (CS.getKind()) {
 case ConversionSpecifier::cArg:
@@ -886,6 +907,8 @@
 case LengthModifier::AsSizeT:
 case LengthModifier::AsPtrDiff:
 case LengthModifier::AsLongDouble:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
   return true;
 case LengthModifier::AsAllocate:
 case LengthModifier::AsMAllocate:
@@ -997,6 +1020,12 @@
 } else if (Identifier->getName() == "ptrdiff_t") {
   LM.setKind(LengthModifier::AsPtrDiff);
   return true;
+} else if (Identifier->getName() == "char16_t") {
+  LM.setKind(LengthModifier::AsUTF16);
+  return true;
+} else if (Identifier->getName() == "char32_t") {
+  LM.setKind(LengthModifier::AsUTF32);
+  return true;
 }
 
 QualType T = Typedef->getUnderlyingType();
Index: clang/include/clang/AST/FormatString.h
===
--- clang/include/clang/AST/FormatString.h
+++ clang/include/clang/AST/FormatString.h
@@ -65,22 +65,24 @@
 public:
   enum Kind {
 None,
-AsChar,   // 'hh'
-AsShort,  // 'h'
-AsShortLong,  // 'hl' (OpenCL float/int vector element)
-AsLong,   // 'l'
-AsLongLong,   // 'll'
-AsQuad,   // 'q' (BSD, deprecated, for 64-bit integer types)
-AsIntMax, // 'j'
-AsSizeT,  // 'z'
-AsPtrDiff,// 't'
-AsInt32,  // 'I32' (MSVCRT, like __int32)
-AsInt3264,// 'I'   (MSVCRT, like __int3264 from MIDL)
-AsInt64,  // 'I64' (MSVCRT, like __int64)
-AsLongDouble, // 'L'
-AsAllocate,   // for '%as', GNU extension to C90 scanf
-AsMAllocate,  // for '%ms', GNU extension to scanf
-AsWide,   // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
+AsChar, // 'hh'
+AsShort,// 'h'
+AsShortLong,// 'hl' (OpenCL float/int vector element)
+AsLong, // 'l'
+AsLongLong, // 'll'
+AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
+AsIntMax,   // 'j'
+AsSizeT,// 'z'
+AsPtrDiff,  // 't'
+AsInt32,// 'I32' (MSVCRT, like __int32)
+AsInt3264,  // 'I'   (MSVCRT, like __int3264 from MIDL)
+AsInt64,// 'I64' (MSVCRT, like __int64)
+AsLongDouble,   // 'L'
+AsAllocate, // for '%as', GNU extension to C90 scanf
+AsMAllocate,// for '%ms', GNU extension to scanf
+AsUTF16,// for '%l16(c|s)', Clang extension
+AsUTF32,// for '%l32(c|s)', Clang extension
+AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
 AsWideChar = AsLong // for '%ls', only makes sense for printf
   };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361538.
MarcusJohnson91 added a comment.

Clang-formatted the diff.


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

https://reviews.llvm.org/D106755

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -3,11 +3,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++11 %s
 
 #include 
+#include 
 
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int wscanf(const wchar_t *restrict, ...);
+extern int wprintf(const wchar_t *restrict, ...);
+extern int vwprintf(const wchar_t *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -18,12 +22,23 @@
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
 
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
+
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,53 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'wchar_t **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'wchar_t **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp); // expected-warning{{format specifies type 'void **' but the argument has type 'wchar_t **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // expected-warning {{not a string literal}}
+  // expected-note@-1{{treat the string as an argument to avoid this}}
 
   // PR13099
   printf(
 R"foobar(%)foobar"
 R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
 R"xyzzy()xyzzy");
+  wprintf(
+  R"foobar(%)foobar"
+  R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
+  R"xyzzy()xyzzy");
 
   printf(u8"this is %d test", 0); // ok
+  wprintf(u8"this is %d test", 0); // ok
   printf(u8R"foo(
   \u1234\U0010fffe
  

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361535.
MarcusJohnson91 marked an inline comment as done.
MarcusJohnson91 added a comment.

Implemented the fixes mentioned and reformatted the patch


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,33 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, HasUTF32BOM) {
+  bool HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xff\xfe\x00\x00", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff ", 5));
+  EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff\x00asdf", 9));
+  EXPECT_TRUE(HasBOM);
+
+  HasBOM = hasUTF32ByteOrderMark(None);
+  EXPECT_FALSE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xfe", 1));
+  EXPECT_FALSE(HasBOM);
+}
+
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -83,6 +83,13 @@
(S[0] == '\xfe' && S[1] == '\xff')));
 }
 
+bool hasUTF32ByteOrderMark(ArrayRef S) {
+  return (
+  S.size() >= 4 &&
+  ((S[0] == '\x00' && S[1] == '\x00' && S[2] == '\xfe' && S[3] == '\xff') ||
+   (S[0] == '\xff' && S[1] == '\xfe' && S[2] == '\x00' && S[3] == '\x00')));
+}
+
 bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string ) {
   assert(Out.empty());
 
@@ -141,6 +148,64 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 4)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+

[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361534.
MarcusJohnson91 added a comment.
Herald added subscribers: llvm-commits, dexonsmith, hiraditya.
Herald added a project: LLVM.

Implemented the fixes mentioned and reformatted the patch


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

https://reviews.llvm.org/D106755

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,33 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, HasUTF32BOM) {
+  bool HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xff\xfe\x00\x00", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff ", 5));
+  EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff\x00asdf", 9));
+  EXPECT_TRUE(HasBOM);
+
+  HasBOM = hasUTF32ByteOrderMark(None);
+  EXPECT_FALSE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xfe", 1));
+  EXPECT_FALSE(HasBOM);
+}
+
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -83,6 +83,13 @@
(S[0] == '\xfe' && S[1] == '\xff')));
 }
 
+bool hasUTF32ByteOrderMark(ArrayRef S) {
+  return (
+  S.size() >= 4 &&
+  ((S[0] == '\x00' && S[1] == '\x00' && S[2] == '\xfe' && S[3] == '\xff') ||
+   (S[0] == '\xff' && S[1] == '\xfe' && S[2] == '\x00' && S[3] == '\x00')));
+}
+
 bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string ) {
   assert(Out.empty());
 
@@ -141,6 +148,64 @@
   Src.size() * sizeof(UTF16)), Out);
 }
 
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 4)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != 

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 3 inline comments as done.
MarcusJohnson91 added inline comments.



Comment at: llvm/lib/Support/ConvertUTFWrapper.cpp:168
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);

efriedma wrote:
> Wrong constant.
> 
> Is this really the function you want to be using from clang?  I don't really 
> understand why you'd want to handle byte order marks.
I don't really care about the BOM tbh, I just figured if I was in here, I 
should flesh out the UTF-32 interface.


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

https://reviews.llvm.org/D106753

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


[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

I don't understand why the build failed?

I've compiled it and ran all the tests with `time ninja check`


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

https://reviews.llvm.org/D106753

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


[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361487.
MarcusJohnson91 edited the summary of this revision.
MarcusJohnson91 added a comment.

Added tests


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
@@ -78,6 +100,33 @@
   EXPECT_FALSE(HasBOM);
 }
 
+TEST(ConvertUTFTest, HasUTF32BOM) {
+  bool HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xff\xfe\x00\x00", 4));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff ", 5));
+  EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\x00\x00\xfe\xff\x00asdf", 9));
+  EXPECT_TRUE(HasBOM);
+
+  HasBOM = hasUTF32ByteOrderMark(None);
+  EXPECT_FALSE(HasBOM);
+  HasBOM = hasUTF32ByteOrderMark(makeArrayRef("\xfe", 1));
+  EXPECT_FALSE(HasBOM);
+}
+
+TEST(ConvertUTFTest, UTF32WrappersForConvertUTF32ToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef SrcRef = makeArrayRef((const UTF32 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
   // Src is the look of disapproval.
   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -82,6 +82,12 @@
   ((S[0] == '\xff' && S[1] == '\xfe') ||
(S[0] == '\xfe' && S[1] == '\xff')));
 }
+  
+bool hasUTF32ByteOrderMark(ArrayRef S) {
+  return (S.size() >= 4 &&
+  ((S[0] == '\x00' && S[1] == '\x00' && S[2] == '\xfe' && S[3] == '\xff') ||
+   (S[0] == '\xff' && S[1] == '\xfe' && S[2] == '\x00' && S[3] == '\x00')));
+}
 
 bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string ) {
   assert(Out.empty());
@@ -140,6 +146,64 @@
   llvm::ArrayRef(reinterpret_cast(Src.data()),
   Src.size() * sizeof(UTF16)), Out);
 }
+  
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 2)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361485.
MarcusJohnson91 added a comment.

Added tests


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

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp
  llvm/unittests/Support/ConvertUTFTest.cpp

Index: llvm/unittests/Support/ConvertUTFTest.cpp
===
--- llvm/unittests/Support/ConvertUTFTest.cpp
+++ llvm/unittests/Support/ConvertUTFTest.cpp
@@ -36,6 +36,28 @@
   EXPECT_EQ(Expected, Result);
 }
 
+TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  alignas(UTF32) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF32ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
 TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
   // Src is the look of disapproval.
   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -140,6 +140,64 @@
   llvm::ArrayRef(reinterpret_cast(Src.data()),
   Src.size() * sizeof(UTF16)), Out);
 }
+  
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 2)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+  
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string )
+{
+  return convertUTF16ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+  Src.size() * sizeof(UTF32)), Out);
+}
 
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -122,6 +122,9 @@
 
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+  
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE  0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
 typedef enum {
   conversionOK,   /* conversion successful */
@@ -277,6 +280,24 @@
 * \returns true on success
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
+  
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+* Converts a UTF32 string into a UTF8 std::string.
+*
+* \param [in] Src A buffer of UTF-32 encoded text.
+* \param [out] Out Converted UTF-8 is stored here on success.
+* \returns true on success
+*/
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string );
 
 /**
  * Converts a UTF-8 string into a UTF-16 string with native endianness.

[PATCH] D106756: Added l16/l32 length modifiers for char16_t/char32_t

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
MarcusJohnson91 added reviewers: aaron.ballman, efriedma.
MarcusJohnson91 added a project: clang.
MarcusJohnson91 requested review of this revision.

Split from D103426 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106756

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/ScanfFormatString.cpp
  clang/test/Sema/format-strings-int-typedefs.c

Index: clang/test/Sema/format-strings-int-typedefs.c
===
--- clang/test/Sema/format-strings-int-typedefs.c
+++ clang/test/Sema/format-strings-int-typedefs.c
@@ -12,6 +12,10 @@
   printf("%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   printf("%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   printf("%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  printf("%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  printf("%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  printf("%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  printf("%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   printf("%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   printf("%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
   
@@ -21,6 +25,10 @@
   wprintf(L"%td", 42.0); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'int')}}
   wprintf(L"%lc", 42.0); // expected-warning {{format specifies type 'wint_t' (aka 'int')}}
   wprintf(L"%ls", 42.0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  wprintf(L"%l16c", 42.0); // expected-warning {{format specifies type 'char16_t' (aka 'int')}}
+  wprintf(L"%l16s", 42.0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wprintf(L"%l32c", 42.0); // expected-warning {{format specifies type 'char32_t' (aka 'int')}}
+  wprintf(L"%l32s", 42.0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   wprintf(L"%S", 42.0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   wprintf(L"%C", 42.0);  // expected-warning {{format specifies type 'wchar_t' (aka 'int')}}
 
@@ -30,6 +38,10 @@
   scanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   scanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  scanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  scanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  scanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   scanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   scanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   
@@ -39,6 +51,10 @@
   wscanf("%td", 0); // expected-warning {{format specifies type 'ptrdiff_t *' (aka 'int *')}}
   wscanf("%lc", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   wscanf("%ls", 0); // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
+  wscanf("%l16c", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l16s", 0); // expected-warning {{format specifies type 'char16_t *' (aka 'int *')}}
+  wscanf("%l32c", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
+  wscanf("%l32s", 0); // expected-warning {{format specifies type 'char32_t *' (aka 'int *')}}
   wscanf("%S",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
   wscanf("%C",  0);  // expected-warning {{format specifies type 'wchar_t *' (aka 'int *')}}
 
Index: clang/lib/AST/ScanfFormatString.cpp
===
--- clang/lib/AST/ScanfFormatString.cpp
+++ clang/lib/AST/ScanfFormatString.cpp
@@ -261,6 +261,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
 case LengthModifier::AsShortLong:
   return ArgType::Invalid();
   }
@@ -302,6 +304,8 @@
 case LengthModifier::AsInt32:
 case LengthModifier::AsInt3264:
 case LengthModifier::AsWide:
+case LengthModifier::AsUTF16:
+case LengthModifier::AsUTF32:
 case 

[PATCH] D106755: Extended format string checking to wprintf/wscanf

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
Herald added a subscriber: martong.
Herald added a reviewer: aaron.ballman.
MarcusJohnson91 requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Split from D103426 


https://reviews.llvm.org/D106755

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -7,7 +7,10 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const char *restrict, ...);
+extern int wprintf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int vwprintf(const char *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -17,13 +20,24 @@
 #else
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
+  
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
@@ -76,7 +90,7 @@
   va_start(ap,fmt);
   const char * const format = fmt;
   vprintf(format, ap); // no-warning
-
+  
   const char *format2 = fmt;
   vprintf(format2, ap); // expected-warning{{format string is not a string literal}}
 
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,53 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'wchar_t **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'wchar_t **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'wchar_t **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // expected-warning {{not a string literal}}
+  // expected-note@-1{{treat the string as an argument to avoid this}}
 
   // PR13099
   printf(
 R"foobar(%)foobar"
 R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
 R"xyzzy()xyzzy");
+  wprintf(
+R"foobar(%)foobar"
+

[PATCH] D106753: ConvertUTF: Created wrapper convertUTF32ToUTF8String

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
MarcusJohnson91 added a project: clang.
Herald added subscribers: dexonsmith, hiraditya.
MarcusJohnson91 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Split from D103426 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106753

Files:
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp

Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -140,6 +140,64 @@
   llvm::ArrayRef(reinterpret_cast(Src.data()),
   Src.size() * sizeof(UTF16)), Out);
 }
+  
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 2)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+  
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string )
+{
+  return convertUTF16ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+  Src.size() * sizeof(UTF32)), Out);
+}
 
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -122,6 +122,9 @@
 
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+  
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE  0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
 typedef enum {
   conversionOK,   /* conversion successful */
@@ -277,6 +280,24 @@
 * \returns true on success
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
+  
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+* Converts a UTF32 string into a UTF8 std::string.
+*
+* \param [in] Src A buffer of UTF-32 encoded text.
+* \param [out] Out Converted UTF-8 is stored here on success.
+* \returns true on success
+*/
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string );
 
 /**
  * Converts a UTF-8 string into a UTF-16 string with native endianness.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361466.
MarcusJohnson91 added a comment.

Full context diff after squashing all the commits together


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

https://reviews.llvm.org/D103426

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/FormatString.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/ScanfFormatString.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp

Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -140,6 +140,64 @@
   llvm::ArrayRef(reinterpret_cast(Src.data()),
   Src.size() * sizeof(UTF16)), Out);
 }
+  
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 2)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+  
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string )
+{
+  return convertUTF16ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+  Src.size() * sizeof(UTF32)), Out);
+}
 
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -122,6 +122,9 @@
 
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+  
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE  0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
 typedef enum {
   conversionOK,   /* conversion successful */
@@ -277,6 +280,24 @@
 * \returns true on success
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
+  
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+* Converts a UTF32 string into a UTF8 std::string.
+*
+* \param [in] Src A buffer of UTF-32 encoded text.
+* \param [out] Out 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361414.
MarcusJohnson91 added a comment.

Getting weird crashes all over the place in code I didn't touch, no idea what's 
going on


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

https://reviews.llvm.org/D103426

Files:
  clang/lib/AST/Expr.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp


Index: clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -782,8 +782,8 @@
   bool BoundsProvided = ArgIndex == DEPR_ONLY;
 
   if (!BoundsProvided) {
-// Currently we only handle (not wide) string literals. It is possible to 
do
-// better, either by looking at references to const variables, or by doing
+// Currently we only handle string literals. It is possible to do better
+// either by looking at references to const variables, or by doing
 // real flow analysis.
 auto FormatString =
 dyn_cast(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1068,7 +1068,7 @@
 }
 
 char *StringLiteral::getStrDataAsChar() {
-  std::string Output = "";
+  std::string Output;
   char *CString = nullptr;
   
   switch (getKind()) {
@@ -1078,21 +1078,18 @@
   return getTrailingObjects();
   break;
 case StringKind::UTF16: {
-  std::string Trail16 = "";
-  Trail16 = getTrailingObjects();
-  ArrayRef ArrayRef16(Trail16.c_str(), Trail16.length());
-  if (llvm::convertUTF16ToUTF8String(ArrayRef16, Output)) {
+  ArrayRef AR(getTrailingObjects(), getByteLength());
+  if (llvm::convertUTF16ToUTF8String(AR, Output)) {
 CString = new char[Output.size() + 1]; // +1 for terminating NULL
 return CString;
   }
   break;
 }
 case StringKind::UTF32: {
-  std::string Trail32 = "";
-  Trail32 = getTrailingObjects();
-  ArrayRef ArrayRef32(Trail32.c_str(), Trail32.length());
-  if (llvm::convertUTF32ToUTF8String(ArrayRef32, Output)) {
+  ArrayRef AR(getTrailingObjects(), getByteLength());
+  if (llvm::convertUTF32ToUTF8String(AR, Output)) {
 CString = new char[Output.size() + 1];
+memcpy(CString, Output.c_str(), Output.size());
 return CString;
   }
   break;
@@ -1100,6 +1097,7 @@
 case StringKind::Wide: {
   if (llvm::convertWideToUTF8(getStringAsWChar(), Output)) {
 CString = new char[Output.size() + 1];
+memcpy(CString, Output.c_str(), Output.size());
 return CString;
   }
   break;
@@ -1108,8 +1106,7 @@
 }
 
 const char *StringLiteral::getStrDataAsChar() const {
-  const char *ConstString = StringLiteral::getStrDataAsChar();
-  return ConstString;
+  return const_cast(getStrDataAsChar());
 }
 
 StringLiteral::StringLiteral(const ASTContext , StringRef Str,


Index: clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -782,8 +782,8 @@
   bool BoundsProvided = ArgIndex == DEPR_ONLY;
 
   if (!BoundsProvided) {
-// Currently we only handle (not wide) string literals. It is possible to do
-// better, either by looking at references to const variables, or by doing
+// Currently we only handle string literals. It is possible to do better
+// either by looking at references to const variables, or by doing
 // real flow analysis.
 auto FormatString =
 dyn_cast(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1068,7 +1068,7 @@
 }
 
 char *StringLiteral::getStrDataAsChar() {
-  std::string Output = "";
+  std::string Output;
   char *CString = nullptr;
   
   switch (getKind()) {
@@ -1078,21 +1078,18 @@
   return getTrailingObjects();
   break;
 case StringKind::UTF16: {
-  std::string Trail16 = "";
-  Trail16 = getTrailingObjects();
-  ArrayRef ArrayRef16(Trail16.c_str(), Trail16.length());
-  if (llvm::convertUTF16ToUTF8String(ArrayRef16, Output)) {
+  ArrayRef AR(getTrailingObjects(), getByteLength());
+  if (llvm::convertUTF16ToUTF8String(AR, Output)) {
 CString = new char[Output.size() + 1]; // +1 for terminating NULL
 return CString;
   }
   break;
 }
 case StringKind::UTF32: {
-  std::string Trail32 = "";
-  Trail32 = getTrailingObjects();
-  ArrayRef ArrayRef32(Trail32.c_str(), Trail32.length());
-   

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361410.
MarcusJohnson91 added a comment.

Rebased on main


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

https://reviews.llvm.org/D103426

Files:
  clang/lib/AST/OSLog.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp

Index: clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -785,28 +785,10 @@
 // Currently we only handle (not wide) string literals. It is possible to do
 // better, either by looking at references to const variables, or by doing
 // real flow analysis.
-std::string String;
 auto FormatString =
 dyn_cast(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
 
-StringLiteral::StringKind Kind = FormatString->getKind();
-
-if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-  String = FormatString->getStringAsChar();
-} else if (Kind == StringLiteral::UTF16) {
-  std::wstring_convert, char16_t> Convert;
-  std::u16string U16 = FormatString->getStringAsChar16();
-  String = Convert.to_bytes(U16);
-} else if (Kind == StringLiteral::UTF32) {
-  std::wstring_convert, char32_t> Convert;
-  std::u32string U32 = FormatString->getStringAsChar32();
-  String = Convert.to_bytes(U32);
-} else if (Kind == StringLiteral::Wide) {
-  std::wstring_convert, wchar_t> Convert;
-  std::wstring WChar = FormatString->getStringAsWChar();
-  String = Convert.to_bytes(WChar);
-}
-
+std::string String(FormatString->getStrDataAsChar());
 StringRef StrRef = StringRef(String);
 
 if (FormatString &&
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -622,25 +622,7 @@
 auto *FormatExpr = TheCall->getArg(FormatIndex)->IgnoreParenImpCasts();
 
 if (auto *Format = dyn_cast(FormatExpr)) {
-  StringLiteral::StringKind Kind = Format->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = Format->getStringAsChar();
-  } else if (Kind == StringLiteral::UTF16) {
-std::wstring_convert, char16_t> Convert;
-std::u16string U16 = Format->getStringAsChar16();
-String = Convert.to_bytes(U16);
-  } else if (Kind == StringLiteral::UTF32) {
-std::wstring_convert, char32_t> Convert;
-std::u32string U32 = Format->getStringAsChar32();
-String = Convert.to_bytes(U32);
-  } else if (Kind == StringLiteral::Wide) {
-std::wstring_convert, wchar_t> Convert;
-std::wstring WChar = Format->getStringAsWChar();
-String = Convert.to_bytes(WChar);
-  }
-  
+  std::string String(Format->getStrDataAsChar());
   StringRef FormatStrRef(String);
   
   EstimateSizeFormatHandler H(FormatStrRef);
@@ -7492,6 +7474,10 @@
 return FExpr->getString().drop_front(Offset);
   }
   
+  const char *getStrDataAsChar() const {
+return FExpr->getStrDataAsChar();
+  }
+  
   std::string getStringAsChar() const {
 return FExpr->getStringAsChar();
   }
@@ -9549,24 +9535,7 @@
 /*IsStringLocation*/ true, OrigFormatExpr->getSourceRange());
 return;
   }
-  StringLiteral::StringKind Kind = FExpr->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = FExpr->getStringAsChar();
-  } else if (Kind == StringLiteral::UTF16) {
-std::wstring_convert, char16_t> Convert;
-std::u16string U16 = FExpr->getStringAsChar16();
-String = Convert.to_bytes(U16);
-  } else if (Kind == StringLiteral::UTF32) {
-std::wstring_convert, char32_t> Convert;
-std::u32string U32 = FExpr->getStringAsChar32();
-String = Convert.to_bytes(U32);
-  } else if (Kind == StringLiteral::Wide) {
-std::wstring_convert, wchar_t> Convert;
-std::wstring WChar = FExpr->getStringAsWChar();
-String = Convert.to_bytes(WChar);
-  }
+  std::string String(FExpr->getStrDataAsChar());
   
   StringRef StrRef(String);
   const char *Str = StrRef.data();
@@ -9637,25 +9606,7 @@
   assert(T && "String literal not of constant array type!");
   size_t TypeSize = T->getSize().getZExtValue();
   
-  StringLiteral::StringKind Kind = FExpr->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = FExpr->getStringAsChar();
-  } else if (Kind == StringLiteral::UTF16) {
-std::u16string  U16 = FExpr->getStringAsChar16();
-std::wstring_convert, char16_t> Convert;
-String = Convert.to_bytes(U16);
-  } else if (Kind == StringLiteral::UTF32) {
-std::u32string U32 = 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: clang/lib/AST/TemplateBase.cpp:77-80
+  const Decl *D = nullptr;
+  if (T->isTypedefNameType()) {
+D = T->getAs()->getDecl();
+  }

aaron.ballman wrote:
> This approach seems fragile for getting access to an AST context. I think 
> `TemplateArgument::print()` should likely be given an `const ASTContext &` 
> parameter instead.
Just switched it out, D was only used for the LangOpts() call anyway, so I just 
did it directly where it's needed instead of creating a variable



Comment at: 
clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp:791-808
+
+StringLiteral::StringKind Kind = FormatString->getKind();
+
+if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
+  String = FormatString->getStringAsChar();
+} else if (Kind == StringLiteral::UTF16) {
+  std::wstring_convert, char16_t> 
Convert;

MarcusJohnson91 wrote:
> cor3ntin wrote:
> > I think this code is present in multiple places in your PR, could it be 
> > deduplicated?
> Yup, I've been working on that too; This was actually the first thing I 
> started with.
I've moved this code into StringLiteral::getStrDataAsChar(), so now it does the 
conversion if needed, and removed the big if/else chain in all the places it 
was used previously.

Oh, and I made StringLiteral::getStrDataAsChar() public in the StringLiteral 
and I forwarded it in FormatStringLiteral.


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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361409.
MarcusJohnson91 marked an inline comment as done.
MarcusJohnson91 added a comment.

#1: Moved a comment to the top, so it's brettier 

#2: Moved all the ugly StringLiteral conversion code to 
StringLiteral::getStrDataAsChar and forwarded that function to 
FormatStringLiteral::getStrDataAsChar


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

https://reviews.llvm.org/D103426

Files:
  clang/lib/AST/OSLog.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp

Index: clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -785,28 +785,10 @@
 // Currently we only handle (not wide) string literals. It is possible to do
 // better, either by looking at references to const variables, or by doing
 // real flow analysis.
-std::string String;
 auto FormatString =
 dyn_cast(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
 
-StringLiteral::StringKind Kind = FormatString->getKind();
-
-if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-  String = FormatString->getStringAsChar();
-} else if (Kind == StringLiteral::UTF16) {
-  std::wstring_convert, char16_t> Convert;
-  std::u16string U16 = FormatString->getStringAsChar16();
-  String = Convert.to_bytes(U16);
-} else if (Kind == StringLiteral::UTF32) {
-  std::wstring_convert, char32_t> Convert;
-  std::u32string U32 = FormatString->getStringAsChar32();
-  String = Convert.to_bytes(U32);
-} else if (Kind == StringLiteral::Wide) {
-  std::wstring_convert, wchar_t> Convert;
-  std::wstring WChar = FormatString->getStringAsWChar();
-  String = Convert.to_bytes(WChar);
-}
-
+std::string String(FormatString->getStrDataAsChar());
 StringRef StrRef = StringRef(String);
 
 if (FormatString &&
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -622,25 +622,7 @@
 auto *FormatExpr = TheCall->getArg(FormatIndex)->IgnoreParenImpCasts();
 
 if (auto *Format = dyn_cast(FormatExpr)) {
-  StringLiteral::StringKind Kind = Format->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = Format->getStringAsChar();
-  } else if (Kind == StringLiteral::UTF16) {
-std::wstring_convert, char16_t> Convert;
-std::u16string U16 = Format->getStringAsChar16();
-String = Convert.to_bytes(U16);
-  } else if (Kind == StringLiteral::UTF32) {
-std::wstring_convert, char32_t> Convert;
-std::u32string U32 = Format->getStringAsChar32();
-String = Convert.to_bytes(U32);
-  } else if (Kind == StringLiteral::Wide) {
-std::wstring_convert, wchar_t> Convert;
-std::wstring WChar = Format->getStringAsWChar();
-String = Convert.to_bytes(WChar);
-  }
-  
+  std::string String(Format->getStrDataAsChar());
   StringRef FormatStrRef(String);
   
   EstimateSizeFormatHandler H(FormatStrRef);
@@ -7481,6 +7463,10 @@
 return FExpr->getString().drop_front(Offset);
   }
   
+  const char *getStrDataAsChar() const {
+return FExpr->getStrDataAsChar();
+  }
+  
   std::string getStringAsChar() const {
 return FExpr->getStringAsChar();
   }
@@ -9538,24 +9524,7 @@
 /*IsStringLocation*/ true, OrigFormatExpr->getSourceRange());
 return;
   }
-  StringLiteral::StringKind Kind = FExpr->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = FExpr->getStringAsChar();
-  } else if (Kind == StringLiteral::UTF16) {
-std::wstring_convert, char16_t> Convert;
-std::u16string U16 = FExpr->getStringAsChar16();
-String = Convert.to_bytes(U16);
-  } else if (Kind == StringLiteral::UTF32) {
-std::wstring_convert, char32_t> Convert;
-std::u32string U32 = FExpr->getStringAsChar32();
-String = Convert.to_bytes(U32);
-  } else if (Kind == StringLiteral::Wide) {
-std::wstring_convert, wchar_t> Convert;
-std::wstring WChar = FExpr->getStringAsWChar();
-String = Convert.to_bytes(WChar);
-  }
+  std::string String(FExpr->getStrDataAsChar());
   
   StringRef StrRef(String);
   const char *Str = StrRef.data();
@@ -9626,25 +9595,7 @@
   assert(T && "String literal not of constant array type!");
   size_t TypeSize = T->getSize().getZExtValue();
   
-  StringLiteral::StringKind Kind = FExpr->getKind();
-  std::string String;
-  
-  if (Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) {
-String = FExpr->getStringAsChar();
-  } else if 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 361405.
MarcusJohnson91 marked an inline comment as done.
MarcusJohnson91 added a comment.

Just implemented the change Aaron requested in TemplateBase.cpp


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

https://reviews.llvm.org/D103426

Files:
  clang/lib/AST/TemplateBase.cpp


Index: clang/lib/AST/TemplateBase.cpp
===
--- clang/lib/AST/TemplateBase.cpp
+++ clang/lib/AST/TemplateBase.cpp
@@ -74,14 +74,7 @@
 
   if (Policy.MSVCFormatting)
 IncludeType = false;
-  
-  const Decl *D = nullptr;
-  if (T->isTypedefNameType()) {
-D = T->getAs()->getDecl();
-  }
 
-  
-
   if (T->isBooleanType()) {
 if (!Policy.MSVCFormatting)
   Out << (Val.getBoolValue() ? "true" : "false");
@@ -95,15 +88,15 @@
 Out << "(unsigned char)";
 }
 CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out);
-  } else if (D != nullptr && T->isAnyCharacterType(D->getLangOpts()) && 
!Policy.MSVCFormatting) {
+  } else if 
(T->isAnyCharacterType(T->getAs()->getDecl()->getLangOpts()) && 
!Policy.MSVCFormatting) {
 CharacterLiteral::CharacterKind Kind;
 if (T->isWideCharType())
   Kind = CharacterLiteral::Wide;
 else if (T->isChar8Type())
   Kind = CharacterLiteral::UTF8;
-else if (T->isChar16Type(D->getLangOpts()))
+else if 
(T->isChar16Type(T->getAs()->getDecl()->getLangOpts()))
   Kind = CharacterLiteral::UTF16;
-else if (T->isChar32Type(D->getLangOpts()))
+else if 
(T->isChar32Type(T->getAs()->getDecl()->getLangOpts()))
   Kind = CharacterLiteral::UTF32;
 else
   Kind = CharacterLiteral::Ascii;


Index: clang/lib/AST/TemplateBase.cpp
===
--- clang/lib/AST/TemplateBase.cpp
+++ clang/lib/AST/TemplateBase.cpp
@@ -74,14 +74,7 @@
 
   if (Policy.MSVCFormatting)
 IncludeType = false;
-  
-  const Decl *D = nullptr;
-  if (T->isTypedefNameType()) {
-D = T->getAs()->getDecl();
-  }
 
-  
-
   if (T->isBooleanType()) {
 if (!Policy.MSVCFormatting)
   Out << (Val.getBoolValue() ? "true" : "false");
@@ -95,15 +88,15 @@
 Out << "(unsigned char)";
 }
 CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out);
-  } else if (D != nullptr && T->isAnyCharacterType(D->getLangOpts()) && !Policy.MSVCFormatting) {
+  } else if (T->isAnyCharacterType(T->getAs()->getDecl()->getLangOpts()) && !Policy.MSVCFormatting) {
 CharacterLiteral::CharacterKind Kind;
 if (T->isWideCharType())
   Kind = CharacterLiteral::Wide;
 else if (T->isChar8Type())
   Kind = CharacterLiteral::UTF8;
-else if (T->isChar16Type(D->getLangOpts()))
+else if (T->isChar16Type(T->getAs()->getDecl()->getLangOpts()))
   Kind = CharacterLiteral::UTF16;
-else if (T->isChar32Type(D->getLangOpts()))
+else if (T->isChar32Type(T->getAs()->getDecl()->getLangOpts()))
   Kind = CharacterLiteral::UTF32;
 else
   Kind = CharacterLiteral::Ascii;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 359704.
MarcusJohnson91 added a comment.
Herald added subscribers: llvm-commits, dexonsmith, hiraditya.
Herald added a project: LLVM.

Few tweaks since last time, nothing big


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

https://reviews.llvm.org/D103426

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Sema/SemaChecking.cpp
  llvm/include/llvm/Support/ConvertUTF.h
  llvm/lib/Support/ConvertUTFWrapper.cpp

Index: llvm/lib/Support/ConvertUTFWrapper.cpp
===
--- llvm/lib/Support/ConvertUTFWrapper.cpp
+++ llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -140,6 +140,64 @@
   llvm::ArrayRef(reinterpret_cast(Src.data()),
   Src.size() * sizeof(UTF16)), Out);
 }
+  
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string ) {
+  assert(Out.empty());
+
+  // Error out on an uneven byte count.
+  if (SrcBytes.size() % 2)
+return false;
+
+  // Avoid OOB by returning early on empty input.
+  if (SrcBytes.empty())
+return true;
+
+  const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
+  const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
+
+  assert((uintptr_t)Src % sizeof(UTF32) == 0);
+
+  // Byteswap if necessary.
+  std::vector ByteSwapped;
+  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+  ByteSwapped[I] = llvm::ByteSwap_32(ByteSwapped[I]);
+Src = [0];
+SrcEnd = [ByteSwapped.size() - 1] + 1;
+  }
+
+  // Skip the BOM for conversion.
+  if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE)
+Src++;
+
+  // Just allocate enough space up front.  We'll shrink it later.  Allocate
+  // enough that we can fit a null terminator without reallocating.
+  Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+  UTF8 *Dst = reinterpret_cast([0]);
+  UTF8 *DstEnd = Dst + Out.size();
+
+  ConversionResult CR =
+  ConvertUTF32toUTF8(, SrcEnd, , DstEnd, strictConversion);
+  assert(CR != targetExhausted);
+
+  if (CR != conversionOK) {
+Out.clear();
+return false;
+  }
+
+  Out.resize(reinterpret_cast(Dst) - [0]);
+  Out.push_back(0);
+  Out.pop_back();
+  return true;
+}
+  
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string )
+{
+  return convertUTF16ToUTF8String(
+  llvm::ArrayRef(reinterpret_cast(Src.data()),
+  Src.size() * sizeof(UTF32)), Out);
+}
 
 bool convertUTF8ToUTF16String(StringRef SrcUTF8,
   SmallVectorImpl ) {
Index: llvm/include/llvm/Support/ConvertUTF.h
===
--- llvm/include/llvm/Support/ConvertUTF.h
+++ llvm/include/llvm/Support/ConvertUTF.h
@@ -122,6 +122,9 @@
 
 #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
 #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+  
+#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE  0xFEFF
+#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE
 
 typedef enum {
   conversionOK,   /* conversion successful */
@@ -277,6 +280,24 @@
 * \returns true on success
 */
 bool convertUTF16ToUTF8String(ArrayRef Src, std::string );
+  
+/**
+ * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string );
+
+/**
+* Converts a UTF32 string into a UTF8 std::string.
+*
+* \param [in] Src A buffer of UTF-32 encoded text.
+* \param [out] Out Converted UTF-8 is stored here on success.
+* \returns true on success
+*/
+bool convertUTF32ToUTF8String(ArrayRef Src, std::string );
 
 /**
  * Converts a UTF-8 string into a UTF-16 string with native endianness.
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -9575,15 +9575,15 @@
   
   // Emit a warning if the string literal is truncated and does not contain an
   // embedded null character.
-if (TypeSize < StrRef.size() &&
-StrRef.substr(0, TypeSize).find('\0') == StringRef::npos) {
-  CheckFormatHandler::EmitFormatDiagnostic(
-  S, inFunctionCall, Args[format_idx],
-  S.PDiag(diag::warn_printf_format_string_not_null_terminated),
-  FExpr->getBeginLoc(),
-  /*IsStringLocation=*/true, OrigFormatExpr->getSourceRange());
-  return;
-}
+  if (TypeSize < StrRef.size() &&
+  StrRef.substr(0, TypeSize).find('\0') == StringRef::npos) {
+CheckFormatHandler::EmitFormatDiagnostic(
+ S, 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-17 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 359590.

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

https://reviews.llvm.org/D103426

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp

Index: clang/lib/AST/Type.cpp
===
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -1962,18 +1962,6 @@
   return false;
 }
 
-bool Type::isType(const std::string TypeName) const {
-  QualType Desugar = this->getLocallyUnqualifiedSingleStepDesugaredType();
-  
-  
-  while (!Desugar->isCanonicalUnqualified()) {
-if (Desugar.getAsString() == TypeName) {
-  return true;
-}
-Desugar = Desugar->getLocallyUnqualifiedSingleStepDesugaredType();
-  }
-}
-
 bool Type::isChar8Type() const {
   if (const BuiltinType *BT = dyn_cast(CanonicalType))
 return BT->getKind() == BuiltinType::Char8;
@@ -1985,7 +1973,15 @@
 if (BT->getKind() == BuiltinType::Char16)
   return true;
   if (!LangOpts.CPlusPlus) {
-return isType("char16_t");
+QualType Desugar = this->getLocallyUnqualifiedSingleStepDesugaredType();
+
+
+while (!Desugar->isCanonicalUnqualified()) {
+  if (Desugar.getAsString() == "char16_t") {
+return true;
+  }
+  Desugar = Desugar->getLocallyUnqualifiedSingleStepDesugaredType();
+}
   }
   return false;
 }
@@ -1995,7 +1991,14 @@
 if (BT->getKind() == BuiltinType::Char32)
   return true;
   if (!LangOpts.CPlusPlus) {
-return isType("char32_t");
+QualType Desugar = this->getLocallyUnqualifiedSingleStepDesugaredType();
+
+while (!Desugar->isCanonicalUnqualified()) {
+  if (Desugar.getAsString() == "char32_t") {
+return true;
+  }
+  Desugar = Desugar->getLocallyUnqualifiedSingleStepDesugaredType();
+}
   }
   return false;
 }
Index: clang/lib/AST/PrintfFormatString.cpp
===
--- clang/lib/AST/PrintfFormatString.cpp
+++ clang/lib/AST/PrintfFormatString.cpp
@@ -643,6 +643,9 @@
  "const unichar *");
 return ArgType(ArgType::WCStrTy, "wchar_t *");
   }
+  if (LM.getKind() == LengthModifier::AsWide) {
+return ArgType(ArgType::WCStrTy, "wchar_t *");
+  }
   if (LM.getKind() == LengthModifier::AsUTF16)
 return ArgType(ArgType::Char16Ty, "char16_t *");
   if (LM.getKind() == LengthModifier::AsUTF32)
@@ -860,6 +863,9 @@
 LM.setKind(LengthModifier::AsLongDouble);
 break;
   
+  case BuiltinType::Char8:
+LM.setKind(LengthModifier::AsUTF8);
+  
   case BuiltinType::Char16:
 LM.setKind(LengthModifier::AsUTF16);
 break;
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1331,6 +1331,8 @@
  const LangOptions ,
  const TargetInfo , unsigned *StartToken,
  unsigned *StartTokenByteOffset) const {
+  assert((getKind() == StringLiteral::Ascii || getKind() == StringLiteral::UTF8) &&
+ "Only narrow string literals are currently supported");
   // Loop over all of the tokens in this string until we find the one that
   // contains the byte we're looking for.
   unsigned TokNo = 0;
Index: clang/include/clang/AST/Type.h
===
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1972,7 +1972,6 @@
   /// Determine whether this type is a scoped enumeration type.
   bool isScopedEnumeralType() const;
   bool isBooleanType() const;
-  bool isType(const std::string TypeName) const;
   bool isCharType() const;
   bool isChar8Type() const;
   bool isWideCharType() const;
Index: clang/include/clang/AST/FormatString.h
===
--- clang/include/clang/AST/FormatString.h
+++ clang/include/clang/AST/FormatString.h
@@ -80,8 +80,8 @@
 AsLongDouble, // 'L'
 AsAllocate,   // for '%as', GNU extension to C90 scanf
 AsMAllocate,  // for '%ms', GNU extension to scanf
-AsUTF16,  // for '%l16(c|s)', soon to be standardized
-AsUTF32,  // for '%l32(c|s)', soon to be standardized
+AsUTF16,  // for '%l16(c|s)', Clang extension
+AsUTF32,  // for '%l32(c|s)', Clang extension
 AsWide,   // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
 AsWideChar = AsLong // for '%ls', only makes sense for printf
   };
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -1850,21 +1850,18 @@
   std::u16string getStringAsChar16() const {
 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-07-17 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: clang/include/clang/AST/Expr.h:1846-1871
+  std::string getStringAsChar() const {
+assert(getCharByteWidth() == 1 &&
+   "This function is used in places that assume strings use char");
+return std::string(getTrailingObjects(), getTrailingObjects() 
+ getByteLength());
+  }
+  
+  std::u16string getStringAsChar16() const {

cor3ntin wrote:
> aaron.ballman wrote:
> > One potential issue to this is that in C++, these types are defined to be 
> > UTF-16 and UTF-32, whereas in C, that isn't always the case. Currently, 
> > Clang defines `__STDC_UTF_16__` and `__STDC_UTF_32__` on all targets, but 
> > we may need to add some sanity checks to catch if a target overrides that 
> > behavior. Currently, all the targets in Clang are keeping that promise, but 
> > I have no idea what shenanigans downstream users get up to and whether 
> > their targets remove the macro definition or define it to `0` instead of 
> > `1`.
> Is it possible that the host and target wchar_t have a different size here?
I've honestly been wondering how Clang handled that, in the codebase vs at 
runtime myself for a while.



Comment at: clang/include/clang/AST/FormatString.h:83
 AsMAllocate,  // for '%ms', GNU extension to scanf
+AsUTF16,  // for '%l16(c|s)', soon to be standardized
+AsUTF32,  // for '%l32(c|s)', soon to be standardized

aaron.ballman wrote:
> May want to drop the "soon to be standardized" given that the proposal hasn't 
> been seen by WG14 yet. I think it's fine to say "Clang extension", though. 
> More on the format specifier itself, below.
Done,

and here is the link to the document, I haven't heard any feedback?

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2761.pdf



Comment at: clang/include/clang/AST/Type.h:1975
   bool isBooleanType() const;
+  bool isType(const std::string TypeName) const;
   bool isCharType() const;

aaron.ballman wrote:
> It's not clear from the header file what this function actually *does*. 
> Presumably, everything that can be represented by a `Type` is a type, so I'd 
> assume this returns `true` always. Or should this be a static function?
Yeah, could choose a better name just not sure what.

It takes a type name as the argument, and then it desugars the type one step at 
a time, and if it finds a match it returns true.

so, let's say we're in C++, and someone typedef'd char8_t to String.

This function will say yes, String is compatible with char8_t for example.

it's mostly for C mode's typedef's of char16_t and char32_t



Comment at: clang/lib/AST/Expr.cpp:1197
  unsigned *StartTokenByteOffset) const {
-  assert((getKind() == StringLiteral::Ascii ||
-  getKind() == StringLiteral::UTF8) &&

aaron.ballman wrote:
> I don't see changes that make this assertion valid to remove -- have I missed 
> something?
Nope you didn't miss anything, I did.

this is a remnant from when I was trying to templatize all the format checking 
code instead of converting the format strings.

Restored the assert.



Comment at: clang/lib/AST/FormatString.cpp:235-240
+  if (LO.C2x && I + 1 != E && I[0] == '1' && I[1] == '6') {
+++I;
+++I;
+lmKind = LengthModifier::AsUTF16;
+break;
+  } else if (LO.C2x && I + 1 != E && I[0] == '3' && I[1] == '2') {

aaron.ballman wrote:
> I don't think this is a conforming extension to C -- lowercase length 
> modifiers and conversion specifiers are reserved for the standard, and 
> uppercase length modifiers and conversion specifiers are reserved for the 
> implementation. `l16` starts with a lowercase letter, so it's reserved for 
> the standard.
> 
> Note: WG14 has been considering extensions in a closely-related space 
> (integer types rather than string or character types) that you may be 
> interested in, if you're not already aware of it: 
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2511.pdf. This proposal was 
> not adopted, but did have strong sentiment for something along these lines.
Yeah, honestly not really sure what to do about the reservation, L is also used 
for wide characters and some integers too, and (U|u)(16|32) wasn't taken well 
by the community.



Comment at: clang/lib/AST/OSLog.cpp:212
+  } else if (Lit->isUTF16()) {
+std::wstring_convert, char16_t> Convert;
+std::u16string U16 = Lit->getStringAsChar16();

aaron.ballman wrote:
> MarcusJohnson91 wrote:
> > aaron.ballman wrote:
> > > cor3ntin wrote:
> > > > I'm not sure I have a better suggestion but `codecvt_utf8_utf16` is 
> > > > deprecated in C++17
> > > Good point -- this likely should be lifted into a common interface (as it 
> > > appears several times in the patch) and make use of the existing 

[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-06-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: clang/lib/AST/OSLog.cpp:212
+  } else if (Lit->isUTF16()) {
+std::wstring_convert, char16_t> Convert;
+std::u16string U16 = Lit->getStringAsChar16();

aaron.ballman wrote:
> cor3ntin wrote:
> > I'm not sure I have a better suggestion but `codecvt_utf8_utf16` is 
> > deprecated in C++17
> Good point -- this likely should be lifted into a common interface (as it 
> appears several times in the patch) and make use of the existing LLVM UTF 
> conversion functionality: 
> https://github.com/intel/llvm/blob/sycl/llvm/include/llvm/Support/ConvertUTF.h
The ConvertUTF version you linked contains `convertUTF32toUTF8String` but the 
one in LLVM does not, what's the process for updating this?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-06-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-06-09 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D103426#2807860 , @aaron.ballman 
wrote:

> In D103426#2807245 , 
> @MarcusJohnson91 wrote:
>
>> In D103426#2806391 , 
>> @aaron.ballman wrote:
>>
>>> Do you have a reference to the WG14 paper proposing these conversion 
>>> specifiers?
>>
>> I've previously written up the proposal, which you actually helped with 
>> (thank you for that), just submitted a request to Dan Plakosh to get a 
>> document number and submit it.
>
> Thanks! Once it's submitted and available on the committee webpage, can you 
> post a link to it in this review? That'd help assess whether the 
> implementation matches the proposal or not.

Absolutely :)

>> Maybe I was a bit optimistic, but I don't think l16 and l32 will be a hard 
>> sell, but maybe I'm naive haha
>
> There's never a shortage of surprises when it comes to standardization 
> efforts. :-D

lol, well I'm hopeful it'll be smooth sailing


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-06-09 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: clang/lib/AST/Type.cpp:1980-2002
+bool Type::isChar16Type(const LangOptions ) const {
   if (const auto *BT = dyn_cast(CanonicalType))
-return BT->getKind() == BuiltinType::Char16;
-  return false;
-}
-
-bool Type::isChar32Type() const {
-  if (const auto *BT = dyn_cast(CanonicalType))
-return BT->getKind() == BuiltinType::Char32;
-  return false;
-}
-
-/// Determine whether this type is any of the built-in character
-/// types.
-bool Type::isAnyCharacterType() const {
-  const auto *BT = dyn_cast(CanonicalType);
-  if (!BT) return false;
-  switch (BT->getKind()) {
-  default: return false;
-  case BuiltinType::Char_U:
-  case BuiltinType::UChar:
-  case BuiltinType::WChar_U:
-  case BuiltinType::Char8:
-  case BuiltinType::Char16:
-  case BuiltinType::Char32:
-  case BuiltinType::Char_S:
-  case BuiltinType::SChar:
-  case BuiltinType::WChar_S:
-return true;
+if (BT->getKind() == BuiltinType::Char16)
+  return true;
+  if (!LangOpts.CPlusPlus) {
+return isType("char16_t");
   }

aaron.ballman wrote:
> If I understand properly, one issue is that `char16_t` is defined by C to be 
> *the same type* as `uint_least16_t`, which itself is a typedef to some other 
> integer type. So we can't make `char16_t` be a distinct type in C, it has to 
> be a typedef to a typedef to an integer type.
> 
> One concern I have about the approach in this patch is that it makes the type 
> system a bit more convoluted. This type is *not* really a character type in 
> C, it's a typedef type that playacts as a character type. I think this is a 
> pretty fundamental change to the type system in the compiler in some ways 
> because this query is no longer about the canonical type but about the 
> semantics of how the type is expected to be used.
> 
> I'd definitely like to hear what @rsmith thinks of this approach.
I see your point, but I'm not sure how else we could get it through the type 
checking system without doing it this way?

I tried to be careful to only allow the actual character typedefs through by 
making sure char16_t or char32_t is in the typedef chain, and only in C mode.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-06-09 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D103426#2806391 , @aaron.ballman 
wrote:

> Do you have a reference to the WG14 paper proposing these conversion 
> specifiers?

I've previously written up the proposal, which you actually helped with (thank 
you for that), just submitted a request to Dan Plakosh to get a document number 
and submit it.

Maybe I was a bit optimistic, but I don't think l16 and l32 will be a hard 
sell, but maybe I'm naive haha


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103426

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


[PATCH] D103426: Clang: Extend format string checking to wprintf/wscanf

2021-05-31 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
MarcusJohnson91 created this object with visibility "All Users".
MarcusJohnson91 added a project: clang.
Herald added a subscriber: martong.
Herald added a reviewer: aaron.ballman.
MarcusJohnson91 requested review of this revision.
Herald added a project: clang-tools-extra.

Also added support for the `%l16(c|s)` and `%l32(c|s)` conversion specifier for 
char16_t and char32_t types in C and C++, which should soon be accepted by ISO 
WG14.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103426

Files:
  clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp
  clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/Type.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/FormatString.cpp
  clang/lib/AST/OSLog.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/ScanfFormatString.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Lex/LiteralSupport.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
  clang/test/Sema/format-strings-c90.c
  clang/test/Sema/format-strings-darwin.c
  clang/test/Sema/format-strings-int-typedefs.c
  clang/test/Sema/format-strings-ms.c
  clang/test/Sema/format-strings-non-iso.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/string-plus-char.c
  clang/test/SemaCXX/format-strings-0x.cpp
  clang/test/SemaCXX/format-strings.cpp

Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -7,7 +7,10 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const char *restrict, ...);
+extern int wprintf(const char *restrict, ...);
 extern int vprintf(const char *restrict, va_list);
+extern int vwprintf(const char *restrict, va_list);
 }
 
 void f(char **sp, float *fp) {
@@ -17,13 +20,24 @@
 #else
   // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
 #endif
+  
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'wchar_t **'}}
+#endif
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
 }
 
 void g() {
   printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
+  wprintf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
 }
 
 // Test that we properly handle format_idx on C++ members.
@@ -76,7 +90,7 @@
   va_start(ap,fmt);
   const char * const format = fmt;
   vprintf(format, ap); // no-warning
-
+  
   const char *format2 = fmt;
   vprintf(format2, ap); // expected-warning{{format string is not a string literal}}
 
Index: clang/test/SemaCXX/format-strings-0x.cpp
===
--- clang/test/SemaCXX/format-strings-0x.cpp
+++ clang/test/SemaCXX/format-strings-0x.cpp
@@ -3,33 +3,53 @@
 extern "C" {
 extern int scanf(const char *restrict, ...);
 extern int printf(const char *restrict, ...);
+extern int wscanf(const wchar_t *restrict, ...);
 }
 
 void f(char **sp, float *fp) {
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}
+  wscanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'wchar_t **'}}
 
   printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}
+  wprintf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'wchar_t **'}}
   scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}
+  wscanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'wchar_t **'}}
 
   printf("%a", 1.0);
   scanf("%afoobar", fp);
+  wprintf("%a", 1.0);
+  wscanf("%afoobar", fp);
   printf(nullptr);
   printf(*sp); // expected-warning {{not a string literal}}
   // expected-note@-1{{treat the string as an argument to avoid this}}
+  wprintf(*sp); // 

[PATCH] D88084: [clang-format] Changed default styles BraceWrappping bool table to directly use variables

2021-05-31 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

@MyDeveloperDay

This patch was merged upstream a long time ago, how do I close it here on 
Phabricator? thanks


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88084

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


[PATCH] D88084: [clang-format] Changed default styles BraceWrappping bool table to directly use variables

2020-09-22 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D88084#2287450 , @MyDeveloperDay 
wrote:

> I noticed the pre-merge tests failed!

Yeah I just noticed that too, not sure what's up but I'll check into it, and 
yeah that's a good idea about initializing some of these duplicate variables in 
the constructor.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88084

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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-09-22 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked an inline comment as not done.
MarcusJohnson91 added inline comments.



Comment at: clang/lib/Format/Format.cpp:586
 IO.mapOptional("SortIncludes", Style.SortIncludes);
 IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
 IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);

MyDeveloperDay wrote:
> I'm confused by this diff... the Review is closed, if you are proposing 
> changes please make a new review
I went ahead and made a new revision, thanks for the tip.

I've added you and Silvestre as reviewers.

AS for your question about the very last diff, I originally wanted to change as 
little as possible, but Silvestre getting confused and thinking my patch broke 
something motivated me to fix the confusion with the BraceWrapping table once 
and for all, so here we are.


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

https://reviews.llvm.org/D75791

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


[PATCH] D88084: [clang-format] Changed default styles BraceWrappping bool table to directly use variables

2020-09-22 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
MarcusJohnson91 added reviewers: MyDeveloperDay, sylvestre.ledru.
MarcusJohnson91 added a project: clang-format.
Herald added a project: clang.
MarcusJohnson91 requested review of this revision.

Which should make these defaults more immune to changes in the BraceWrapping 
enum.

using a table of values is just asking for trouble, and by doing it this way 
there's more confidence about the correctness of the default styles.

as @Silvestre.Ledru inadvertently pointed out.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88084

Files:
  clang/lib/Format/Format.cpp

Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -726,24 +726,25 @@
   if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
 return Style;
   FormatStyle Expanded = Style;
-  Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
-/*AfterClass=*/false,
-/*AfterControlStatement=*/FormatStyle::BWACS_Never,
-/*AfterEnum=*/false,
-/*AfterFunction=*/false,
-/*AfterNamespace=*/false,
-/*AfterObjCDeclaration=*/false,
-/*AfterStruct=*/false,
-/*AfterUnion=*/false,
-/*AfterExternBlock=*/false,
-/*BeforeCatch=*/false,
-/*BeforeElse=*/false,
-/*BeforeLambdaBody=*/false,
-/*BeforeWhile=*/false,
-/*IndentBraces=*/false,
-/*SplitEmptyFunction=*/true,
-/*SplitEmptyRecord=*/true,
-/*SplitEmptyNamespace=*/true};
+  Expanded.BraceWrapping.AfterCaseLabel = false;
+  Expanded.BraceWrapping.AfterClass = false;
+  Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
+  Expanded.BraceWrapping.AfterEnum = false;
+  Expanded.BraceWrapping.AfterFunction = false;
+  Expanded.BraceWrapping.AfterNamespace = false;
+  Expanded.BraceWrapping.AfterObjCDeclaration = false;
+  Expanded.BraceWrapping.AfterStruct = false;
+  Expanded.BraceWrapping.AfterUnion = false;
+  Expanded.BraceWrapping.AfterExternBlock = false;
+  Expanded.BraceWrapping.BeforeCatch = false;
+  Expanded.BraceWrapping.BeforeElse = false;
+  Expanded.BraceWrapping.BeforeLambdaBody = false;
+  Expanded.BraceWrapping.BeforeWhile = false;
+  Expanded.BraceWrapping.IndentBraces = false;
+  Expanded.BraceWrapping.SplitEmptyFunction = true;
+  Expanded.BraceWrapping.SplitEmptyRecord = true;
+  Expanded.BraceWrapping.SplitEmptyNamespace = true;
+  Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
   switch (Style.BreakBeforeBraces) {
   case FormatStyle::BS_Linux:
 Expanded.BraceWrapping.AfterClass = true;
@@ -797,25 +798,24 @@
 Expanded.BraceWrapping.BeforeLambdaBody = true;
 break;
   case FormatStyle::BS_GNU:
-Expanded.BraceWrapping = {
-/*AfterCaseLabel=*/true,
-/*AfterClass=*/true,
-/*AfterControlStatement=*/FormatStyle::BWACS_Always,
-/*AfterEnum=*/true,
-/*AfterFunction=*/true,
-/*AfterNamespace=*/true,
-/*AfterObjCDeclaration=*/true,
-/*AfterStruct=*/true,
-/*AfterUnion=*/true,
-/*AfterExternBlock=*/true,
-/*BeforeCatch=*/true,
-/*BeforeElse=*/true,
-/*BeforeLambdaBody=*/false,
-/*BeforeWhile=*/true,
-/*IndentBraces=*/true,
-/*SplitEmptyFunction=*/true,
-/*SplitEmptyRecord=*/true,
-/*SplitEmptyNamespace=*/true};
+Expanded.BraceWrapping.AfterCaseLabel = true;
+Expanded.BraceWrapping.AfterClass = true;
+Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
+Expanded.BraceWrapping.AfterEnum = true;
+Expanded.BraceWrapping.AfterFunction = true;
+Expanded.BraceWrapping.AfterNamespace = true;
+Expanded.BraceWrapping.AfterObjCDeclaration = true;
+Expanded.BraceWrapping.AfterStruct = true;
+Expanded.BraceWrapping.AfterUnion = true;
+Expanded.BraceWrapping.AfterExternBlock = true;
+Expanded.BraceWrapping.BeforeCatch = true;
+Expanded.BraceWrapping.BeforeElse = true;
+Expanded.BraceWrapping.BeforeLambdaBody = false;
+Expanded.BraceWrapping.BeforeWhile = true;
+Expanded.BraceWrapping.IndentBraces = true;
+Expanded.BraceWrapping.SplitEmptyFunction = true;
+Expanded.BraceWrapping.SplitEmptyRecord = true;
+Expanded.BraceWrapping.SplitEmptyNamespace = true;
 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
 break;
   case FormatStyle::BS_WebKit:
@@ -859,24 +859,24 @@
   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
   LLVMStyle.BreakBeforeTernaryOperators = 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-09-21 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

@sylvestre.ledru

After looking more closely at the issue, it seems you're having an issue with 
Mozilla's comment alignment option.

you want the comments to be aligned, and it appears Clang11 no longer has that 
option set for Mozilla's style is what you're saying?

How are you accessing Mozilla's style?

are you calling clang-format with `-style=mozilla`, or `-style=file` and you've 
got an implicit .clang-format somewhere?



No matter what the root cause, I still think it's a good idea to directly use 
the variables instead of messing around with an unwieldy bool table.

the bool table is just asking for trouble anytime BraceWrapping is expanded, or 
even reordered, so I'm glad that I just pushed that new patch here and 
hopefully it'll land soon.



as for completely cutting out the old AfterExternBlock option, I'd like to 
fully supersede it still, I just need a good name for wrapping the extern 
blocks opening curly brace, anybody got any ideas?


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

https://reviews.llvm.org/D75791

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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-09-21 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 293240.
MarcusJohnson91 edited the summary of this revision.

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

https://reviews.llvm.org/D75791

Files:
  clang/lib/Format/Format.cpp

Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -726,24 +726,25 @@
   if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
 return Style;
   FormatStyle Expanded = Style;
-  Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
-/*AfterClass=*/false,
-/*AfterControlStatement=*/FormatStyle::BWACS_Never,
-/*AfterEnum=*/false,
-/*AfterFunction=*/false,
-/*AfterNamespace=*/false,
-/*AfterObjCDeclaration=*/false,
-/*AfterStruct=*/false,
-/*AfterUnion=*/false,
-/*AfterExternBlock=*/false,
-/*BeforeCatch=*/false,
-/*BeforeElse=*/false,
-/*BeforeLambdaBody=*/false,
-/*BeforeWhile=*/false,
-/*IndentBraces=*/false,
-/*SplitEmptyFunction=*/true,
-/*SplitEmptyRecord=*/true,
-/*SplitEmptyNamespace=*/true};
+  Expanded.BraceWrapping.AfterCaseLabel = false;
+  Expanded.BraceWrapping.AfterClass = false;
+  Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
+  Expanded.BraceWrapping.AfterEnum = false;
+  Expanded.BraceWrapping.AfterFunction = false;
+  Expanded.BraceWrapping.AfterNamespace = false;
+  Expanded.BraceWrapping.AfterObjCDeclaration = false;
+  Expanded.BraceWrapping.AfterStruct = false;
+  Expanded.BraceWrapping.AfterUnion = false;
+  Expanded.BraceWrapping.AfterExternBlock = false;
+  Expanded.BraceWrapping.BeforeCatch = false;
+  Expanded.BraceWrapping.BeforeElse = false;
+  Expanded.BraceWrapping.BeforeLambdaBody = false;
+  Expanded.BraceWrapping.BeforeWhile = false;
+  Expanded.BraceWrapping.IndentBraces = false;
+  Expanded.BraceWrapping.SplitEmptyFunction = true;
+  Expanded.BraceWrapping.SplitEmptyRecord = true;
+  Expanded.BraceWrapping.SplitEmptyNamespace = true;
+  Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
   switch (Style.BreakBeforeBraces) {
   case FormatStyle::BS_Linux:
 Expanded.BraceWrapping.AfterClass = true;
@@ -797,25 +798,24 @@
 Expanded.BraceWrapping.BeforeLambdaBody = true;
 break;
   case FormatStyle::BS_GNU:
-Expanded.BraceWrapping = {
-/*AfterCaseLabel=*/true,
-/*AfterClass=*/true,
-/*AfterControlStatement=*/FormatStyle::BWACS_Always,
-/*AfterEnum=*/true,
-/*AfterFunction=*/true,
-/*AfterNamespace=*/true,
-/*AfterObjCDeclaration=*/true,
-/*AfterStruct=*/true,
-/*AfterUnion=*/true,
-/*AfterExternBlock=*/true,
-/*BeforeCatch=*/true,
-/*BeforeElse=*/true,
-/*BeforeLambdaBody=*/false,
-/*BeforeWhile=*/true,
-/*IndentBraces=*/true,
-/*SplitEmptyFunction=*/true,
-/*SplitEmptyRecord=*/true,
-/*SplitEmptyNamespace=*/true};
+Expanded.BraceWrapping.AfterCaseLabel = true;
+Expanded.BraceWrapping.AfterClass = true;
+Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
+Expanded.BraceWrapping.AfterEnum = true;
+Expanded.BraceWrapping.AfterFunction = true;
+Expanded.BraceWrapping.AfterNamespace = true;
+Expanded.BraceWrapping.AfterObjCDeclaration = true;
+Expanded.BraceWrapping.AfterStruct = true;
+Expanded.BraceWrapping.AfterUnion = true;
+Expanded.BraceWrapping.AfterExternBlock = true;
+Expanded.BraceWrapping.BeforeCatch = true;
+Expanded.BraceWrapping.BeforeElse = true;
+Expanded.BraceWrapping.BeforeLambdaBody = false;
+Expanded.BraceWrapping.BeforeWhile = true;
+Expanded.BraceWrapping.IndentBraces = true;
+Expanded.BraceWrapping.SplitEmptyFunction = true;
+Expanded.BraceWrapping.SplitEmptyRecord = true;
+Expanded.BraceWrapping.SplitEmptyNamespace = true;
 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
 break;
   case FormatStyle::BS_WebKit:
@@ -859,24 +859,24 @@
   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
   LLVMStyle.BreakBeforeTernaryOperators = true;
   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
-  LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
- /*AfterClass=*/false,
- /*AfterControlStatement=*/FormatStyle::BWACS_Never,
- /*AfterEnum=*/false,
- /*AfterFunction=*/false,
- 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-09-20 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#2283961 , @sylvestre.ledru 
wrote:

> Any chance this changes could have caused this regression 
> https://bugs.llvm.org/show_bug.cgi?id=47589 ?

I don't think so, but I can double check the style defaults for the various 
types, and make the code harder to mess up in a min, currently I'm working on 
Clang's libSema so it might take a few days.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D75791

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


[PATCH] D80214: [clang-format] Set of unit test to begin to validate that we don't change defaults

2020-05-20 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 accepted this revision.
MarcusJohnson91 added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80214



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-20 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#2044492 , @MyDeveloperDay 
wrote:

> If you want me to land this for you, I'd feel more comfortable landing it if:
>
> a) We can land D80214: [clang-format] Set of unit test to begin to validate 
> that we don't change defaults  first
>  b) The Mozilla team have tested the impact (they clang-format their entire 
> code base I think)


I'm ok with accepting commit access, and I agree lets get D80214: 
[clang-format] Set of unit test to begin to validate that we don't change 
defaults  in, and see if Mozilla, Microsoft, 
Google, etc  has any comments; I'm just not sure of who to ping.

Is there anything else that D80214: [clang-format] Set of unit test to begin to 
validate that we don't change defaults  needs? 
it looked pretty well fleshed out.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264916.
MarcusJohnson91 added a comment.

Format.h: indented the ``AfterExternBlock: true`` example code snippet with 4 
spaces like the Indent option so it's more visible and matches.

I think it's perfect now.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2539,6 +2539,43 @@
Style);
 }
 
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = true;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}",
+   Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -13716,6 +13753,18 @@
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
 
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+  FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,16 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+if (!Style.IndentExternBlock) {
+  if (Style.BraceWrapping.AfterExternBlock) {
+addUnwrappedLine();
+  }
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.IndentExternBlock ==
+ FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -234,6 +234,17 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits {
   static void enumeration(IO , FormatStyle::ReturnTypeBreakingStyle ) {
@@ -510,6 +521,7 @@
   

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264909.
MarcusJohnson91 added a comment.

Just fixed the formatting of the ReleaseNotes.rst file, the extern blocks were 
slightly askew, and it might've made it a bit confusing


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2539,6 +2539,43 @@
Style);
 }
 
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = true;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}",
+   Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -13716,6 +13753,18 @@
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
 
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+  FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,16 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+if (!Style.IndentExternBlock) {
+  if (Style.BraceWrapping.AfterExternBlock) {
+addUnwrappedLine();
+  }
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.IndentExternBlock ==
+ FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -234,6 +234,17 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits {
   static void enumeration(IO , FormatStyle::ReturnTypeBreakingStyle ) {
@@ -510,6 +521,7 @@
 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264911.
MarcusJohnson91 added a comment.

Made the IndentExternBlockStyle enum comments a bit clearer, and regenerated 
the .rst file


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2539,6 +2539,43 @@
Style);
 }
 
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = true;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}",
+   Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -13716,6 +13753,18 @@
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
 
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+  FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,16 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+if (!Style.IndentExternBlock) {
+  if (Style.BraceWrapping.AfterExternBlock) {
+addUnwrappedLine();
+  }
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.IndentExternBlock ==
+ FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -234,6 +234,17 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits {
   static void enumeration(IO , FormatStyle::ReturnTypeBreakingStyle ) {
@@ -510,6 +521,7 @@
 IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 5 inline comments as done.
MarcusJohnson91 added inline comments.



Comment at: clang/lib/Format/Format.cpp:812
  true,  true};
+  LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
   LLVMStyle.BreakAfterJavaFieldAnnotations = false;

MyDeveloperDay wrote:
> is this one correct? AfterExternBLock is false in this case correct? should 
> this be NoIndent?
Yes AfterExternBlock is set to false here, but IndentExternBlock is being set 
to IEBS_AfterExternBlock, so the code falls back to parsing it as if 
IndentExternBlock wasn't set, and AfterExternBlock was set.

so IEBS_AfterExternBlock works for both true and false values.

Setting it to NoIndent would change the codepath to the new one and it would 
lose the newline between `extern "C"` and `{` in the process.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#2043758 , @MyDeveloperDay 
wrote:

> Sorry to "go around the houses" but we'll get there in the end...I think we 
> are close


I think we're close too.

Your other comment was interesting, about testing the styles to make sure they 
haven't changed with these new options, that didn't occur to me.

I think it might be worth looking into.

I'm just not really sure how we could do such a thing, or if after the option 
is submitted if it'd really be worth it to have run because I don't really 
think this option will be further modified, but the original AfterExternBlock 
guy didn't think anyone would want to expand that either and as a result we had 
to work around some of the issues with his design so who can really tell what 
the future holds?


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264839.
MarcusJohnson91 added a comment.

Ok, I've removed the inherited ones, and also removed the times I was setting a 
style when there wasn't one before.

also I moved the `IEBS_AfterExternBlock` line to right underneath the 
`BraceWrapping.AfterExternBlock = true/false;` line so it's easier to see.

and reformatted ofc.

---

btw, in .BraceWrapping = {true, false); blocks, AfterExternBlock is the 9th 
option, I checked the BraceWrapping enum.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2539,6 +2539,43 @@
Style);
 }
 
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = true;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}",
+   Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -13716,6 +13753,18 @@
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
 
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+  FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,16 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+if (!Style.IndentExternBlock) {
+  if (Style.BraceWrapping.AfterExternBlock) {
+addUnwrappedLine();
+  }
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.IndentExternBlock ==
+ FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -234,6 +234,17 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 4 inline comments as done.
MarcusJohnson91 added inline comments.



Comment at: clang/lib/Format/Format.cpp:714
   case FormatStyle::BS_Mozilla:
+Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
 Expanded.BraceWrapping.AfterClass = true;

MyDeveloperDay wrote:
> I'm sorry but I feel these are changing the previous default which as I 
> understood would indent ONLY if Style.BraceWrapping.AfterExternBlock == true
> 
> I think in all cases other than GNU this was false, isn't that correct?
I chose IEBS_AfterExternBlock here, because it already uses the 
BraceWrapping.AfterExternBlock style, that way it will still use 
AfterExternBlock: true value a few lines lower.



Comment at: clang/lib/Format/Format.cpp:725
   case FormatStyle::BS_Stroustrup:
+Expanded.IndentExternBlock = FormatStyle::IEBS_NoIndent;
 Expanded.BraceWrapping.AfterFunction = true;

MyDeveloperDay wrote:
> I think you can remove this to avoid confusion that you are changing from the 
> default LLVM style
k, that makes sense; I figured nothing was specified so it should be set to no, 
but I can remove it also.



Comment at: clang/lib/Format/Format.cpp:731
   case FormatStyle::BS_Allman:
+Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
 Expanded.BraceWrapping.AfterCaseLabel = true;

MyDeveloperDay wrote:
> Isn't this changing the default?
Expanded.BraceWrapping.AfterExternBlock = true; is a few lines lower, so it 
will use that value.

Maybe I should move this option to right below 
`Expanded.BraceWrapping.AfterExternBlock = true;`?



Comment at: clang/lib/Format/Format.cpp:931
   GoogleStyle.IndentCaseLabels = true;
+  GoogleStyle.IndentExternBlock = FormatStyle::IEBS_NoIndent;
   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;

MyDeveloperDay wrote:
> everyone inherits from LLVM so no need for this it only makes people think 
> its different from the base style
ok, I can remove the inherited ones too.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

As for crashes, none of them seem relevant; I'm on MacOS, the windows ABI crash 
seems especially irrelevent.

opt crashed, there were no arguments, and abort() was called.

llvm-lto2 crashed, not-prevailing.ll.tmp1-3.bc was the cause

llvm-dwarfdump crashed, arguments: -debug-line 
/Users/Marcus/Source/External/LLVM_BUILD/test/Object/Output/invalid.test.tmp3

llvm-as crashed, arguments: 
/Users/Marcus/Source/External/LLVM/llvm/test/Assembler/datalayout-invalid-stack-natural-alignment.ll

llvm-mc crashed, arguments: -triple i386-pc-win32 -filetype=obj

llvm-readobj crashed, arguments: -r 
/Users/Marcus/Source/External/LLVM/llvm/test/Object/Inputs/invalid-bad-section-address.coff

llc crashed, arguments: -stop-before=nonexistent -o /dev/null


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264763.
MarcusJohnson91 added a comment.

Added the style initializers, moved IEBS_AfterExternBlock to be the first enum 
value so that it's zero, that way the bool logic works.

Regenerated the docs as well, and also clang-formatting the files I've touched.

I reran the tests before creating this diff and everything worked.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2539,6 +2539,43 @@
Style);
 }
 
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = true;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}",
+   Style);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}",
+   Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -13716,6 +13753,18 @@
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
 
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+  FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+  FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+  FormatStyle::IEBS_NoIndent);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,16 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+if (!Style.IndentExternBlock) {
+  if (Style.BraceWrapping.AfterExternBlock) {
+addUnwrappedLine();
+  }
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true,
+ /*AddLevel=*/Style.IndentExternBlock ==
+ FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -205,6 +205,17 @@
   }
 };
 
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
+
 template <>
 struct 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

I've initialized all styles to either AfterExternBlock, if there was a 
BraceWrapping block, or NoIndent if there wasn't.

re-running my tests locally.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

I've got the indenting to work manually now as well, the issue was you need to 
have `BreakBeforeBraces: Custom` in the inline style for it to pick up 
BraceWrapping.AfterExternBlock's value.

Now I'm working on the automated tests, thanks for the tip about initializing, 
I'll look into that.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264597.
MarcusJohnson91 added a comment.

Fixed the generation of ReleaseNotes.rst


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2538,6 +2538,39 @@
"}",
Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13715,6 +13748,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, FormatStyle::IEBS_NoIndent);
 
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1115,9 +1115,9 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -204,6 +204,18 @@
 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
   }
 };
+  
+template <>
+struct ScalarEnumerationTraits {
+  static void
+  enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
 
 template <>
 struct ScalarEnumerationTraits {
@@ -513,6 +525,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#2040665 , @MyDeveloperDay 
wrote:

>




> Something is not quite right here, this text isn't ending up in the 
> ClangFormatStyleOptions.rst

You're right, I didn't catch that before, turns out having a comment before the 
variable is required for dump_format_style.py to work.

I've fixed this, I'm still working on the tests, and I'll clang-format the 
files when it's all done.

> Please clang-format the patch, I'm also getting a crash when running the 
> tests, please make sure they pass.

I'm not sure why the tests crash, I know that when I manually test all the 
options for IndentExternBlock , and when testing IndentExternBlock: 
AfterExternBlock and setting BraceWrapping.AfterExternBlock, everything works.

i just get gibberish about loading the default LLVM style failed, and a 
nonsensical hex dump (0xFF 0xFE then a bunch of NULLs)

I honestly thought these crashes were unrelated.



> Please add yourself to the pre-merge testing project so your reviews get 
> checked before updating the patch
> 
>   https://reviews.llvm.org/project/view/78/

When I go there and click Watch it says:

> You Shall Not Pass: #pre-merge_beta_testing 
> 
>  You do not have permission to edit this object.
>  Users with the "Can Edit" capability:
>  Administrators can take this action.





As for my testing, I'm doing both manual and autmoated testing, automated with 
`ninja check all`

and manual testing with main.c:

  #ifdef __cplusplus

extern "C" {
#endif

  void blah1(void);

#ifdef __cplusplus
}
#endif

extern "C++" {

  void blah2(void) {
  int one = 1;
  }

}

and here's the command line:

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: true}" /Users/Marcus/Desktop/Test_Clang-Format.c

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: false}" /Users/Marcus/Desktop/Test_Clang-Format.c

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: Indent}" /Users/Marcus/Desktop/Test_Clang-Format.c

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: NoIndent}" /Users/Marcus/Desktop/Test_Clang-Format.c

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: AfterExternBlock, BraceWrapping: {AfterExternBlock: false}}" 
/Users/Marcus/Desktop/Test_Clang-Format.c

~/Source/External/LLVM_BUILD/bin/clang-format -i -style="{IndentWidth: 4, 
IndentExternBlock: AfterExternBlock, BraceWrapping: {AfterExternBlock: true}}" 
/Users/Marcus/Desktop/Test_Clang-Format.c

tho now that I'm manually testing it again (I really only used manual testing 
to make sure the options were accepted, to iterate more quickly), it looks like 
the AfterExternBlock: true option isn't working, but false is.

if thats true how didn't the automated tests catch it?


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-17 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#2040532 , @MyDeveloperDay 
wrote:

> LGTM


So what's the next step? I've never committed to LLVM before.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked an inline comment as done.
MarcusJohnson91 added a comment.

Removed the lowercase Noindent case, that was a last minute addition I thought 
might make it a tad easier to work with, but you're right I didn't even test 
it, and honestly adding that complexity is just pointless at best.

Removed.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264462.

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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2538,6 +2538,39 @@
"}",
Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13715,6 +13748,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, FormatStyle::IEBS_NoIndent);
 
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1115,9 +1115,9 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -204,6 +204,18 @@
 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
   }
 };
+  
+template <>
+struct ScalarEnumerationTraits {
+  static void
+  enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
 
 template <>
 struct ScalarEnumerationTraits {
@@ -513,6 +525,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -1004,7 +1004,7 @@
 ///   }
 /// \endcode
 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264439.
MarcusJohnson91 added a comment.

Removed forgotten comment from control logic of UnwrappedLineParser


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2538,6 +2538,39 @@
"}",
Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13715,6 +13748,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, FormatStyle::IEBS_NoIndent);
 
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1115,9 +1115,9 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -204,6 +204,19 @@
 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
   }
 };
+  
+template <>
+struct ScalarEnumerationTraits {
+  static void
+  enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "Noindent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
 
 template <>
 struct ScalarEnumerationTraits {
@@ -513,6 +526,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
Index: clang/include/clang/Format/Format.h

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 264438.
MarcusJohnson91 edited the summary of this revision.
MarcusJohnson91 added a comment.

Did everything you asked and did a littl bit of my own cleanup as well.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2538,6 +2538,39 @@
"}",
Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" { /*9*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo10();\n"
+   "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" { /*11*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo12();\n"
+   "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\"\n{ /*13*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo14();\n"
+   "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" { /*15*/\n}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo16();\n"
+   "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13715,6 +13748,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, FormatStyle::IEBS_NoIndent);
 
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1113,11 +1113,11 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.BraceWrapping.AfterExternBlock) { // Style.IndentExternBlock == FormatStyle::IEBS_AfterExternBlock && 
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -204,6 +204,19 @@
 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
   }
 };
+  
+template <>
+struct ScalarEnumerationTraits {
+  static void
+  enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "Noindent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
 
 template <>
 struct ScalarEnumerationTraits {
@@ -513,6 +526,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-05-16 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 3 inline comments as done.
MarcusJohnson91 added a comment.

I've fixed all of your comments as well as fixed the tests.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-04-19 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 258612.
MarcusJohnson91 edited the summary of this revision.

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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2509,10 +2509,43 @@
Style);
   verifyFormat("extern \"C\"\n"
"{\n"
-   "  int foo();\n"
+   "int foo();\n"
"}",
Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo1();\n"
+   "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo2();\n"
+   "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+   "  int foo3();\n"
+   "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo4();\n"
+   "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13262,6 +13295,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
   AllowShortIfStatementsOnASingleLine,
   FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle.IEBS_Indent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, FormatStyle::IEBS_NoIndent);
 
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1112,11 +1112,11 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.IndentExternBlock == FormatStyle::IEBS_AfterExternBlock && Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock == true ? true : false);
 } else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent ? true : false);
 }
 addUnwrappedLine();
 return;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -202,6 +202,18 @@
 IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
   }
 };
+  
+template <>
+struct ScalarEnumerationTraits {
+  static void
+  enumeration(IO , FormatStyle::IndentExternBlockStyle ) {
+IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
+IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
+IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
+IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
+  }
+};
 
 template <>
 struct ScalarEnumerationTraits {
@@ -494,6 +506,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-04-14 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

@MyDeveloperDay

> but I'm also constantly surprised by how many of the enumeration cases 
> started out as booleans only later to have to be converted to enums. The more 
> I think about this the more I think the problem can probably be dealt with 
> better by making it an enumeration. (even if you support true and false to 
> mean "indent" and "don't indent"

I FULLY support all new options being required to be enums from now on, bools 
cause a whole lotta trouble when they have to be changed.

I've rewritten my patch, it works when manually testing it, now I'm just 
working on the automated tests.

A brand new patch should be up by either tonight or tomorrow.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-04-03 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

I agree that changing formatting randomly isn't a good idea, and I think 
converting AfterExternBlock to an enum is the way to go, but I'm just not sure 
on how it should be implemented.

Ok, I've got an idea to deprecate the AfterExternBlock option and map it to a 
new option, I'm gonna start implementing it right now.


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

https://reviews.llvm.org/D75791



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


[PATCH] D33029: [clang-format] add option for dangling parenthesis

2020-03-31 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D33029#1946761 , @bbassi wrote:

> I don't think that's quite right. Then you will also have to have a 
> `AlignWithDanglingParenthesis` for cases when people still want closing 
> parenthesis on new line but want parameters as well as closing parenthesis to 
> be aligned with opening parenthesis. I think we need a separate option, 
> something like `BreakBeforeClosingBracket`.


I think that's the biggest problem with making changes to Clang-Format, every 
name does things that the name doesn't imply.

Here it's very similar to the bin packing options, in my case it's 
BraceWrapping.AfterExternBlock also indenting by default, making adding a 
IndentExternBlock a real pain.

I personally say fuck backwards compatibility when maintaining it requires ever 
more workarounds to fix an obviously flawed abstraction, but I'm just some dude 
and AFAIK the guys in charge support the status quo.


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

https://reviews.llvm.org/D33029



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 252730.
MarcusJohnson91 added a comment.

Implemented the suggestion to break the test strings down into smaller pieces


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2491,11 +2491,43 @@
Style);
   verifyFormat("extern \"C\"\n"
"{\n"
-   "  int foo();\n"
+   "int foo();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo();"
+   "\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "  int foo();"
+   "\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo();"
+   "\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo();"
+   "\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12660,6 +12692,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1114,11 +1114,9 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
 }
-addUnwrappedLine();
+parseBlock(/*MustBeDeclaration=*/true,
+/*AddLevel=*/Style.IndentExternBlock);
 return;
   }
 }
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -493,6 +493,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
@@ -801,6 +802,7 @@
   LLVMStyle.IndentGotoLabels = true;
   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
   LLVMStyle.IndentWrappedFunctionNames = false;
+  LLVMStyle.IndentExternBlock = false;
   LLVMStyle.IndentWidth = 2;
   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
@@ -888,6 +890,7 @@
   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
   GoogleStyle.IndentCaseLabels = true;
+  GoogleStyle.IndentExternBlock = false;
   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
   GoogleStyle.ObjCSpaceAfterProperty = false;
@@ -1023,6 +1026,7 @@
 ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
 ChromiumStyle.ContinuationIndentWidth = 8;
 ChromiumStyle.IndentWidth = 4;
+ChromiumStyle.IndentExternBlock = false;
 // See styleguide for import groups:
 // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order
 ChromiumStyle.JavaImportGroups = {
@@ -1072,6 +1076,7 @@
   MozillaStyle.Cpp11BracedListStyle = false;
   MozillaStyle.FixNamespaceComments = false;
   MozillaStyle.IndentCaseLabels = true;
+  

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-25 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked 2 inline comments as done.
MarcusJohnson91 added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:2497
Style);
 }
 

MyDeveloperDay wrote:
> my assumption is this test is using `Style.IndentExternBlock =false` correct?
> 
> This suggests the default was previously true not false
> 
> ```
> if (Style.BraceWrapping.AfterExternBlock) {
> if (Style.BraceWrapping.AfterExternBlock) {
>   addUnwrappedLine();
>   parseBlock(/*MustBeDeclaration=*/true);
> } else {
>   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
>}
> ```
> 
> This one test change alone, makes me see that it might be incorrect to set 
> the default Indent to false when AfterExternBlock is true.  (parseBlock 
> default parameter for AddLevel is true)
> 
> shouldn't the default value of `Style.IndentExternBlock = 
> Style.BraceWrapping.AfterExternBlock`?
> 
> (which is 100% why I don't like seeing tests changed).. this was buried in 
> your last changes to the tests and I didn't see it.)
> 
> So now we need to go back and take a look through the clang sources and see 
> what its doing by default, and tests what other default styles are doing 
> prior to this change and if they indent then I think by default we need to 
> indent.
> 
> If we run clang-format on the following code, we see an issues
> 
> https://github.com/llvm/llvm-project/blob/a974b33a10745b528c34f0accbd230b0a4e1fb87/clang/test/SemaCXX/linkage-spec.cpp
> 
> Whats great about this Fix (which is why it needs to go in) this test file 
> despite being part of LLVM its not actually formatted with the LLVM style ;-) 
> i.e. it will come out as
> 
> ```
> extern "C" {
> extern "C" void f(int);
> }
> 
> extern "C++" {
> extern "C++" int (int);
> float ();
> }
> ```
> 
> instead of 
> 
> ```
> extern "C" {
>   extern "C" void f(int);
> }
> 
> extern "C++" {
>   extern "C++" int& g(int);
>   float& g();
> }
> ```
> 
> Thats because they don't want a break after the "C" and before the { but they 
> do what the indent.
> 
> Conversely there is code in
> 
> https://github.com/llvm/llvm-project/blob/a974b33a10745b528c34f0accbd230b0a4e1fb87/llvm/utils/benchmark/test/donotoptimize_assembly_test.cc
> 
> This code IS more formatted than the the previous one (not 100% correct but 
> close enough) and so having the default to true would cause unnecessary churn 
> here.
> 
> Then of course there must be other projects that use BreakAfterExtern=true 
> and they would get the indentation and want to keep it, so the setting of the 
> default value of IndentExternBlock  needs to be dynamic if possible, don't 
> you think.
> 
> To be honest your change should support actually allowing this some of these 
> files to now support keeping its format correclty, which in my view is great! 
> but breaking the default styles is always hard, because we get complaints 
> that different versions of clang-format can cause huge waves of changes and 
> I've seen unless teams are all on the same version then the format can 
> flipflop between versions.
> 
> 
> 
Yes, this test is defaulting to IndentExternBlock = false, because when I was 
initially looking at examples of C code for Google's style, Micorosft, WebKit, 
LLVM, etc (all the built in styles) it appeared that LLVM does not indent their 
extern blocks.

As for linkage-spec.cpp, that file indents extern blocks, and 
donotoptimize_assembly_test.cc doesn't as you pointed out.

As for why I chose to default LLVM to indenting, I don't remember which files 
specifically gave me the impression that LLVM indents.



As for changing the default behavior, I agree It sucks, but I'm not sure how we 
could have this feature without changing the behavior.

Maybe I should just remove the default for LLVM, or maybe I shouldn't default 
to anything for any style period?



Comment at: clang/unittests/Format/FormatTest.cpp:2505
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int foo();\n}", Style);
+

MyDeveloperDay wrote:
> nit: these are a little easier to read when formatted as above
> 
> ```
> verifyFormat("extern \"C\" {\n"
>   "  int foo();\n"
>   "}", Style);
> ```
Yeah, it really tripped me up reading these string literals when they were cut 
up into multiple pieces but without commas between them, so that's why I wrote 
these this way.

I'm not against breaking them up, it was just initially confusing to me.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 252466.
MarcusJohnson91 marked 4 inline comments as done.
MarcusJohnson91 added a comment.

Implemented @MyDeveloperDay's suggestion to simplify the if/else statements.

Removed all the test changes except one:

That's because the BraceWrapping.AfterExternBlock option has been changed so 
that it no longer indents and wraps the brace; now it just wraps the brace, and 
the old version of the test expected indenting.

Also Rebased on Master, and made sure all the tests passed, including the new 
tests I wrote for this feature.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2491,11 +2491,35 @@
Style);
   verifyFormat("extern \"C\"\n"
"{\n"
-   "  int foo();\n"
+   "int foo();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int foo();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int foo();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint foo();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint foo();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12660,6 +12684,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1114,11 +1114,9 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
-  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
 }
-addUnwrappedLine();
+parseBlock(/*MustBeDeclaration=*/true,
+/*AddLevel=*/Style.IndentExternBlock);
 return;
   }
 }
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -493,6 +493,7 @@
 IO.mapOptional("IndentWidth", Style.IndentWidth);
 IO.mapOptional("IndentWrappedFunctionNames",
Style.IndentWrappedFunctionNames);
+IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
@@ -801,6 +802,7 @@
   LLVMStyle.IndentGotoLabels = true;
   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
   LLVMStyle.IndentWrappedFunctionNames = false;
+  LLVMStyle.IndentExternBlock = false;
   LLVMStyle.IndentWidth = 2;
   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
@@ -888,6 +890,7 @@
   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
   GoogleStyle.IndentCaseLabels = true;
+  GoogleStyle.IndentExternBlock = false;
   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
   GoogleStyle.ObjCSpaceAfterProperty = false;
@@ -1023,6 +1026,7 @@
 ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
 ChromiumStyle.ContinuationIndentWidth = 8;
 ChromiumStyle.IndentWidth = 4;
+ChromiumStyle.IndentExternBlock = false;
 // See styleguide for import groups:
 // 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 marked an inline comment as done.
MarcusJohnson91 added a comment.

Restored all the test function names to foo().


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-24 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:31
+class FormatTest
+: public ::testing::Test { // FormatTest is a Fixture, data is reused
 protected:

MyDeveloperDay wrote:
> is this comment necessary?
Removed the comment, it was just a note to myself that fell through the cracks



Comment at: clang/unittests/Format/FormatTest.cpp:2440
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
-  verifyFormat("extern \"C\" {}");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
+  verifyFormat("extern \"C\" { /*2.2*/\n}");

MyDeveloperDay wrote:
> why are you changing tests? where is the test that shows this works when a 
> comment isn't present?
These test comments were adds solely so I could see which part of the tests 
we're failing, because there's some repeats and it got confusing. Clang's tests 
would print the line which included the text, it was basically printf debugging 
without printf.

There is now just one minor change to the existing tests.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-23 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Rebased on Master again, recompiling and re-running all the tests.

I'll update this comment when it passes, or create a new diff if it doesn't but 
nothing had to be changed so it'll probably work.

@krasimir I noticed that you've been active recently, can you review my patch?

Not sure if tagging is considered rude, I figure that @MyDeveloperDay's 
notification fell off your radar.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-21 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 251846.
MarcusJohnson91 added a comment.

Rebased on master


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2460,14 +2460,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
   verifyFormat("extern \"C\" {}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2475,9 +2475,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2486,16 +2486,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
-   "  int foo();\n"
+  verifyFormat("extern \"C\"\n{}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12660,6 +12685,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1112,11 +1112,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == false) {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == true) {
+  

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-18 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Bump


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-14 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 250354.
MarcusJohnson91 added a comment.

Fixed Format.h comments, and rebased on master.

it's perfect on my end now.


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2460,14 +2460,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
   verifyFormat("extern \"C\" {}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2475,9 +2475,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2486,16 +2486,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
-   "  int foo();\n"
+  verifyFormat("extern \"C\"\n{}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12660,6 +12685,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1094,11 +1094,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == false) {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-12 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 249954.
MarcusJohnson91 added a comment.

Rebased


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2460,14 +2460,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
   verifyFormat("extern \"C\" {}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2475,9 +2475,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2486,16 +2486,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
-   "  int foo();\n"
+  verifyFormat("extern \"C\"\n{}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12660,6 +12685,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1094,11 +1094,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == false) {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == true) {
+  parseBlock(/*MustBeDeclaration=*/true, 

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-11 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 249838.
MarcusJohnson91 added a comment.

New squashed commit with all changes present


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2436,14 +2436,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
   verifyFormat("extern \"C\" {}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2451,9 +2451,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2462,16 +2462,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
-   "  int foo();\n"
+  verifyFormat("extern \"C\"\n{}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12636,6 +12661,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,11 +1085,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {
   addUnwrappedLine();
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == false) {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == true) {
+  

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-11 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#1917837 , @MyDeveloperDay 
wrote:

> your patch seems to be missing the other files


Which other files? I made a new commit and did the full context diff, now sure 
why it's only showing the documentation update.

I've never committed to Clang before, I don't know this process exactly.




Comment at: clang/lib/Format/UnwrappedLineParser.cpp:1088
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {

MyDeveloperDay wrote:
> something here looks abit odd? there is too much repetition around you 
> option, I think you doing something at the wrong level.
I agree that the parseBlock function is doing too much, but it's written that 
way to begin with.

The parseBlock function takes 3 parameters and has defaults for two of them, I 
just changed the value for those defaults on the IndentExternBlock == false 
versions to default to not indenting; that way the AfterExternBlock option only 
handles bracewrapping extern blocks, without indenting as well.


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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-07 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 248975.
MarcusJohnson91 added a comment.

Updated the release notes


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

https://reviews.llvm.org/D75791

Files:
  clang/docs/ReleaseNotes.rst


Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -200,6 +200,23 @@
 
 
 
+- Option ``IndentExternBlock`` has been added to optionally apply indenting 
inside extern "C" blocks.
+  
+  The ``BraceWrapping.AfterExternBlock`` option has been modified so it no 
longer indents when set to true, now it just wraps the braces around extern 
blocks.
+
+  .. code-block:: c++
+
+true: false:
+  #ifdef __cplusplus  #ifdef __cplusplus
+  extern "C" {extern "C" {
+  #endif  #endif
+  
+  void f(void);   void f(void);
+  
+  #ifdef __cplusplus  #ifdef __cplusplus
+  }   }
+  #endif  #endif
+
 - Option ``IndentCaseBlocks`` has been added to support treating the block
   following a switch case label as a scope block which gets indented itself.
   It helps avoid having the closing bracket align with the switch statement's


Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -200,6 +200,23 @@
 
 
 
+- Option ``IndentExternBlock`` has been added to optionally apply indenting inside extern "C" blocks.
+  
+  The ``BraceWrapping.AfterExternBlock`` option has been modified so it no longer indents when set to true, now it just wraps the braces around extern blocks.
+
+  .. code-block:: c++
+
+true: false:
+  #ifdef __cplusplus  #ifdef __cplusplus
+  extern "C" {extern "C" {
+  #endif  #endif
+  
+  void f(void);   void f(void);
+  
+  #ifdef __cplusplus  #ifdef __cplusplus
+  }   }
+  #endif  #endif
+
 - Option ``IndentCaseBlocks`` has been added to support treating the block
   following a switch case label as a scope block which gets indented itself.
   It helps avoid having the closing bracket align with the switch statement's
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-07 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 248974.
MarcusJohnson91 added a comment.

Removed the debugging comments I added to FormatTest.cpp


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

https://reviews.llvm.org/D75791

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2436,14 +2436,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
   verifyFormat("extern \"C\" {}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2451,9 +2451,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2462,20 +2462,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\" {}", Style);
-  verifyFormat("extern \"C\" {\n"
-   "  int foo();\n"
-   "}",
-   Style);
+  verifyFormat("extern \"C\"\n{}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
 
   Style.BraceWrapping.AfterExternBlock = false;
   verifyFormat("extern \"C\" {}", Style);
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12640,6 +12661,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,10 +1085,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  parseBlock(/*MustBeDeclaration=*/true);
-} else {
+if (Style.BraceWrapping.AfterExternBlock == true &&
+Style.IndentExternBlock == true) {
+  addUnwrappedLine();
+  parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == false) {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+} else if (Style.BraceWrapping.AfterExternBlock == false &&
+   Style.IndentExternBlock == true) {
+  

[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-07 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

In D75791#1911133 , @MyDeveloperDay 
wrote:

> you need documentation and release note changes too


The comments were only for testing, I'll remove them.

The tests had to change because the behavior has changed slightly.

In practice it should be the same because LLVMStyle.IndentExternBlock default 
is set to false, but previously the BraceWrapping.AfterExternBlock = true code 
would indent as well, and now the behavior of BraceWrapping.AfterExternBlock 
only effects the brace wrapping.

As for the release notes, which file should I edit for that, and also which 
version will this even end up in? probably 11 right, because 10 is in RC status 
right now?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D75791



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


[PATCH] D75791: [clang-format] Added new option IndentExternBlock

2020-03-06 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 created this revision.
MarcusJohnson91 added a reviewer: cfe-commits.
Herald added a project: clang.

and refactored the BraceWrapping.AfterExternBlock code so that it only deals 
with wrapping the brace after an extern block.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75791

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -27,7 +27,8 @@
 
 FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
 
-class FormatTest : public ::testing::Test {
+class FormatTest
+: public ::testing::Test { // FormatTest is a Fixture, data is reused
 protected:
   enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck };
 
@@ -2436,14 +2437,14 @@
 }
 
 TEST_F(FormatTest, FormatsExternC) {
-  verifyFormat("extern \"C\" {\nint a;");
-  verifyFormat("extern \"C\" {}");
+  verifyFormat("extern \"C\" {\nint a; /*2.1*/");
+  verifyFormat("extern \"C\" { /*2.2*/\n}");
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_1();\n"
"}");
-  verifyFormat("extern \"C\" int foo() {}");
-  verifyFormat("extern \"C\" int foo();");
-  verifyFormat("extern \"C\" int foo() {\n"
+  verifyFormat("extern \"C\" int FormatsExternC_2() {}");
+  verifyFormat("extern \"C\" int FormatsExternC_3();");
+  verifyFormat("extern \"C\" int FormatsExternC_4() {\n"
"  int i = 42;\n"
"  return i;\n"
"}");
@@ -2451,9 +2452,9 @@
   FormatStyle Style = getLLVMStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
-  verifyFormat("extern \"C\" int foo() {}", Style);
-  verifyFormat("extern \"C\" int foo();", Style);
-  verifyFormat("extern \"C\" int foo()\n"
+  verifyFormat("extern \"C\" int FormatsExternC_5() {}", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_6();", Style);
+  verifyFormat("extern \"C\" int FormatsExternC_7()\n"
"{\n"
"  int i = 42;\n"
"  return i;\n"
@@ -2462,20 +2463,41 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\" {}", Style);
-  verifyFormat("extern \"C\" {\n"
-   "  int foo();\n"
-   "}",
-   Style);
+  verifyFormat("extern \"C\"\n{ /*2.2*/\n}", Style);
+  verifyFormat("extern \"C\"\n{\nint FormatsExternC_8();\n}", Style);
 
   Style.BraceWrapping.AfterExternBlock = false;
-  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" { /*2.3*/\n}", Style);
   verifyFormat("extern \"C\" {\n"
-   "int foo();\n"
+   "int FormatsExternC_9();\n"
"}",
Style);
 }
 
+TEST_F(FormatTest, FormatsExternBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" { /*1.1*/\n}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_1();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = true;
+  verifyFormat("extern \"C\" { /*1.2*/\n}", Style);
+  verifyFormat("extern \"C\" {\n  int FormatsExternBlock_2();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" { /*1.3*/\n}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_3();\n}", Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = false;
+  verifyFormat("extern \"C\" { /*1.4*/\n}", Style);
+  verifyFormat("extern \"C\" {\nint FormatsExternBlock_4();\n}", Style);
+}
+
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
   verifyFormat("asm(\"nop\" ::: \"memory\");");
@@ -12640,6 +12662,7 @@
   CHECK_PARSE_BOOL(IndentCaseBlocks);
   CHECK_PARSE_BOOL(IndentGotoLabels);
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(IndentExternBlock);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,10 +1085,21 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock) {
-  parseBlock(/*MustBeDeclaration=*/true);
-} 

[PATCH] D75410: [clang-format] Fixed BraceWrapping.AfterExternBlock

2020-03-03 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 abandoned this revision.
MarcusJohnson91 added a comment.

I'm moving the intended change to a new clang-format option instead of 
modifying an established one.


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

https://reviews.llvm.org/D75410



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


[PATCH] D75410: [clang-format] Fixed BraceWrapping.AfterExternBlock

2020-03-01 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 247524.
MarcusJohnson91 added a comment.

Full Context Diff (I think?)


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

https://reviews.llvm.org/D75410

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2462,14 +2462,18 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
"  int foo();\n"
"}",
Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo();\n"
+   "}",
+   Style);
 }
 
 TEST_F(FormatTest, FormatsInlineASM) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1086,7 +1086,6 @@
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
 if (Style.BraceWrapping.AfterExternBlock) {
-  addUnwrappedLine();
   parseBlock(/*MustBeDeclaration=*/true);
 } else {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -977,6 +977,29 @@
 ///   } catch () {
 ///   }
 /// \endcode
+/// \code
+///  true:
+/// #ifdef __cplusplus
+/// extern "C" {
+/// #endif
+///
+/// void f(void);
+///
+/// #ifdef __cplusplus
+/// }
+/// #endif
+///
+/// false:
+/// #ifdef __cplusplus
+/// extern "C" {
+/// #endif
+///
+/// void f(void);
+///
+/// #ifdef __cplusplus
+/// }
+/// #endif
+/// \endcode
 bool BeforeCatch;
 /// Wrap before ``else``.
 /// \code
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -935,6 +935,28 @@
   extern "C" {
   int foo();
   }
+  
+  true:
+  #ifdef __cplusplus
+  extern "C" {
+  #endif
+  
+  void f(void);
+  
+  #ifdef __cplusplus
+  }
+  #endif
+  
+  false:
+  #ifdef __cplusplus
+  extern "C" {
+  #endif
+  
+  void f(void);
+  
+  #ifdef __cplusplus
+  }
+  #endif
 
   * ``bool BeforeCatch`` Wrap before ``catch``.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75410: [Clang-Format] Fixed BraceWrapping.AfterExternBlock

2020-02-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 247462.
MarcusJohnson91 added a comment.

Rewrote the AfterExternBlock code to rely on just that clang-format option and 
remove the ExternNamespace check.

Fixed the tests as well.

and clang-formatted everything


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

https://reviews.llvm.org/D75410

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2462,14 +2462,18 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
"  int foo();\n"
"}",
Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo();\n"
+   "}",
+   Style);
 }
 
 TEST_F(FormatTest, FormatsInlineASM) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,13 +1085,8 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock &&
-Style.BraceWrapping.AfterNamespace) {
-  addUnwrappedLine();
+if (Style.BraceWrapping.AfterExternBlock) {
   parseBlock(/*MustBeDeclaration=*/true);
-} else if (Style.BraceWrapping.AfterExternBlock &&
-   Style.BraceWrapping.AfterNamespace == false) {
-  parseBlock(/*MustBeDeclaration=*/false);
 } else {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
 }


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2462,14 +2462,18 @@
 
   Style.BraceWrapping.AfterExternBlock = true;
   Style.BraceWrapping.SplitEmptyRecord = false;
-  verifyFormat("extern \"C\"\n"
-   "{}",
-   Style);
-  verifyFormat("extern \"C\"\n"
-   "{\n"
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
"  int foo();\n"
"}",
Style);
+
+  Style.BraceWrapping.AfterExternBlock = false;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+   "int foo();\n"
+   "}",
+   Style);
 }
 
 TEST_F(FormatTest, FormatsInlineASM) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,13 +1085,8 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock &&
-Style.BraceWrapping.AfterNamespace) {
-  addUnwrappedLine();
+if (Style.BraceWrapping.AfterExternBlock) {
   parseBlock(/*MustBeDeclaration=*/true);
-} else if (Style.BraceWrapping.AfterExternBlock &&
-   Style.BraceWrapping.AfterNamespace == false) {
-  parseBlock(/*MustBeDeclaration=*/false);
 } else {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75410: Fixed Extern Block Indentation in libFormat

2020-02-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 updated this revision to Diff 247457.
MarcusJohnson91 added a comment.

Clang-Formatted UnwrappedLineParser.cpp


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

https://reviews.llvm.org/D75410

Files:
  clang/lib/Format/UnwrappedLineParser.cpp


Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,10 +1085,12 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock && 
Style.BraceWrapping.AfterNamespace) {
+if (Style.BraceWrapping.AfterExternBlock &&
+Style.BraceWrapping.AfterNamespace) {
   addUnwrappedLine();
   parseBlock(/*MustBeDeclaration=*/true);
-} else if (Style.BraceWrapping.AfterExternBlock && 
Style.BraceWrapping.AfterNamespace == false) {
+} else if (Style.BraceWrapping.AfterExternBlock &&
+   Style.BraceWrapping.AfterNamespace == false) {
   parseBlock(/*MustBeDeclaration=*/false);
 } else {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);


Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1085,10 +1085,12 @@
 if (FormatTok->Tok.is(tok::string_literal)) {
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-if (Style.BraceWrapping.AfterExternBlock && Style.BraceWrapping.AfterNamespace) {
+if (Style.BraceWrapping.AfterExternBlock &&
+Style.BraceWrapping.AfterNamespace) {
   addUnwrappedLine();
   parseBlock(/*MustBeDeclaration=*/true);
-} else if (Style.BraceWrapping.AfterExternBlock && Style.BraceWrapping.AfterNamespace == false) {
+} else if (Style.BraceWrapping.AfterExternBlock &&
+   Style.BraceWrapping.AfterNamespace == false) {
   parseBlock(/*MustBeDeclaration=*/false);
 } else {
   parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75410: Fixed Extern Block Indentation in libFormat

2020-02-29 Thread Marcus Johnson via Phabricator via cfe-commits
MarcusJohnson91 added a comment.

Not sure why it failed to compile, it compiles just fine on my machine...

I'm gonna re-pull from master and see if it works.


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

https://reviews.llvm.org/D75410



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


  1   2   >