[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] 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] 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] 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] 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] 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