[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-25 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Sorry for the late comments.




Comment at: clang/lib/Sema/SemaInit.cpp:167-177
 } else if (ParenExpr *PE = dyn_cast(E)) {
   E = PE->getSubExpr();
 } else if (UnaryOperator *UO = dyn_cast(E)) {
   assert(UO->getOpcode() == UO_Extension);
   E = UO->getSubExpr();
 } else if (GenericSelectionExpr *GSE = dyn_cast(E)) {
   E = GSE->getResultExpr();

The duplication between this and `IgnoreParensSingleStep` is a code smell; can 
we expose `IgnoreParensSingleStep` and call it from here?



Comment at: clang/lib/Sema/SemaInit.cpp:8511
+Expr *Init = Args[0];
+S.Diag(Init->getBeginLoc(), diag::ext_init_from_predefined) << Init;
+  }

We won't reach this case for `const char arr[] = {__func__};` because in that 
case `Args[0]` will be an `InitListExpr` instead. Right now we accept this with 
no warning in MS extensions mode:

```
void f() {
  const char c[] = {__func__};
}
```

We should perform this check in the handling of `SK_StringInit` instead, in 
order to properly address that case.

Also, this will only catch the case where the argument is an unparenthesized 
predefined expression. You'll need to do something like repeatedly calling 
`IgnoreParensSingleStep` looking for a `PredefinedExpr` to cope with things 
like:

```
void g() {
  const char c[] = (__func__);
  const char d[] = _Generic(0, int: __func__);
}
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-10 Thread Arthur Eubanks via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG878e590503df: Reland [clang] Make predefined expressions 
string literals under -fms-extensions (authored by aeubanks).

Changed prior to commit:
  https://reviews.llvm.org/D146764?vs=520204=521039#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp
  clang/test/SemaCXX/predefined-expr-msvc.cpp

Index: clang/test/SemaCXX/predefined-expr-msvc.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/predefined-expr-msvc.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify
+// RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -verify -fms-extensions
+
+// expected-no-diagnostics
+
+struct StringRef {
+  StringRef(const char *);
+};
+template 
+StringRef getTypeName() {
+  StringRef s = __func__;
+}
+
Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+ const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
+ const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
+ const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
+ const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+ const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only -verify
+
+//--- a.h
+
+// expected-no-diagnostics
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+// expected-warning@a.h:8 {{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+
+import A;
+
+void g() {
+f(); // expected-note {{in instantiation of function template specialization 'f' requested here}}
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -174,6 +174,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
@@ -8508,6 +8510,15 @@
 << Init->getSourceRange();
   }
 
+  if 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-09 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks reopened this revision.
aeubanks added a comment.
This revision is now accepted and ready to land.

the following crashes with this patch:

  struct StringRef {
StringRef(const char *);
  };
  template 
  StringRef getTypeName() {
StringRef s = __func__;
  }

`clang -cc1 -fms-extensions -std=c++17 -x c++ a.cpp -fsyntax-only`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-07 Thread Arthur Eubanks via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG856f384bf945: [clang] Make predefined expressions string 
literals under -fms-extensions (authored by aeubanks).

Changed prior to commit:
  https://reviews.llvm.org/D146764?vs=519613=520204#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+ const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
+ const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
+ const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
+ const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+ const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only -verify
+
+//--- a.h
+
+// expected-no-diagnostics
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+// expected-warning@a.h:8 {{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+
+import A;
+
+void g() {
+f(); // expected-note {{in instantiation of function template specialization 'f' requested here}}
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -174,6 +174,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
@@ -8501,6 +8503,15 @@
 << Init->getSourceRange();
   }
 
+  if (S.getLangOpts().MicrosoftExt && Args.size() == 1 &&
+  isa(Args[0]) && Entity.getType()->isArrayType()) {
+// Produce a Microsoft compatibility warning when initializing from a
+// predefined expression since MSVC treats predefined expressions as string
+// literals.
+Expr *Init = Args[0];
+S.Diag(Init->getBeginLoc(), diag::ext_init_from_predefined) << Init;
+  }
+
   // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope
   QualType 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-07 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added a comment.

added a release note


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

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

Presuming that the issues found by precommit CI were resolved (current failures 
are unrelated to your changes), this LGTM but still needs a release note.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-04 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 519613.
aeubanks added a comment.

only diagnose if we're initializing an array


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+ const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
+ const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
+ const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
+ const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+ const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only -verify
+
+//--- a.h
+
+// expected-no-diagnostics
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+// expected-warning@a.h:8 {{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+
+import A;
+
+void g() {
+f(); // expected-note {{in instantiation of function template specialization 'f' requested here}}
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -174,6 +174,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
@@ -8501,6 +8503,15 @@
 << Init->getSourceRange();
   }
 
+  if (S.getLangOpts().MicrosoftExt && Args.size() == 1 &&
+  isa(Args[0]) && Entity.getType()->isArrayType()) {
+// Produce a Microsoft compatibility warning when initializing from a
+// predefined expression since MSVC treats predefined expressions as string
+// literals.
+Expr *Init = Args[0];
+S.Diag(Init->getBeginLoc(), diag::ext_init_from_predefined) << Init;
+  }
+
   // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope
   QualType ETy = Entity.getType();
   bool HasGlobalAS = ETy.hasAddressSpace() &&
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3581,7 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Precommit CI found some related failures that need to be addressed, but the 
functional changes are all looking good to me. Be sure to also add a release 
note for the fix as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-03 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 519215.
aeubanks added a comment.

add -verify to module test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+ const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
+ const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
+ const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
+ const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+ const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only -verify
+
+//--- a.h
+
+// expected-no-diagnostics
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+// expected-warning@a.h:8 {{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+
+import A;
+
+void g() {
+f(); // expected-note {{in instantiation of function template specialization 'f' requested here}}
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
@@ -8500,6 +8502,15 @@
 << Init->getSourceRange();
   }
 
+  if (S.getLangOpts().MicrosoftExt && Args.size() == 1 &&
+  isa(Args[0])) {
+// Produce a Microsoft compatibility warning when initializing from a
+// predefined expression since MSVC treats predefined expressions as string
+// literals.
+Expr *Init = Args[0];
+S.Diag(Init->getBeginLoc(), diag::ext_init_from_predefined) << Init;
+  }
+
   // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope
   QualType ETy = Entity.getType();
   bool HasGlobalAS = ETy.hasAddressSpace() &&
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3580,7 +3580,8 @@
 }
   }
 
-  return 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D146764#4313905 , @aeubanks wrote:

> added the warning, not sure if this needs more tests for testing the 
> interaction between `-pedantic`, `-Wmicrosoft`, 
> `-Wmicrosoft-init-from-predefined` or if that's already assumed to work

That's generally assumed to work, really the only question is whether we want 
`Extension` (only warned in `-pedantic`) or `ExtWarn` (warned by default). I 
think most of our Microsoft extension warnings are `ExtWarn` and it seems 
defensible for this to be on by default, but it'd be nice to know just how 
chatty this is on real world code bases too. I have the sneaking suspicion this 
code pattern doesn't come up often enough for this to be "too chatty", but if 
we find it triggers on popular libraries we might want to consider dialing it 
back to just `Extension`.




Comment at: clang/test/Modules/predefined.cpp:6
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm 
-fms-extensions
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions 
-fsyntax-only
+

aeubanks wrote:
> aaron.ballman wrote:
> > Er, should we have a `-verify` on this as well as `// 
> > expected-no-diagnostics`?
> isn't that tested by the Sema test?
Not quite. The Sema test does test a lot of the functionality, but this is 
testing whether we import the AST node properly and can still use it, so it's 
testing a different code path for generating the AST nodes used for doing 
semantic checks.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-02 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added a comment.

added the warning, not sure if this needs more tests for testing the 
interaction between `-pedantic`, `-Wmicrosoft`, 
`-Wmicrosoft-init-from-predefined` or if that's already assumed to work




Comment at: clang/test/Modules/predefined.cpp:6
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm 
-fms-extensions
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions 
-fsyntax-only
+

aaron.ballman wrote:
> Er, should we have a `-verify` on this as well as `// 
> expected-no-diagnostics`?
isn't that tested by the Sema test?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-02 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 518887.
aeubanks added a comment.

add warning


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+ const char a[] = __FUNCTION__; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}}
+ const char b[] = __FUNCDNAME__; // expected-warning{{initializing an array from a '__FUNCDNAME__' predefined identifier is a Microsoft extension}}
+ const char c[] = __FUNCSIG__; // expected-warning{{initializing an array from a '__FUNCSIG__' predefined identifier is a Microsoft extension}}
+ const char d[] = __func__; // expected-warning{{initializing an array from a '__func__' predefined identifier is a Microsoft extension}}
+ const char e[] = __PRETTY_FUNCTION__; // expected-warning{{initializing an array from a '__PRETTY_FUNCTION__' predefined identifier is a Microsoft extension}}
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only
+
+//--- a.h
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+import A;
+
+void g() {
+f();
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
@@ -8500,6 +8502,15 @@
 << Init->getSourceRange();
   }
 
+  if (S.getLangOpts().MicrosoftExt && Args.size() == 1 &&
+  isa(Args[0])) {
+// Produce a Microsoft compatibility warning when initializing from a
+// predefined expression since MSVC treats predefined expressions as string
+// literals.
+Expr *Init = Args[0];
+S.Diag(Init->getBeginLoc(), diag::ext_init_from_predefined) << Init;
+  }
+
   // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope
   QualType ETy = Entity.getType();
   bool HasGlobalAS = ETy.hasAddressSpace() &&
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3580,7 +3580,8 @@
 }
   }
 
-  return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IK, LangOpts.MicrosoftExt,
+SL);
 }
 
 ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
Index: clang/lib/AST/Expr.cpp

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-02 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/test/Modules/predefined.cpp:6
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm 
-fms-extensions
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions 
-fsyntax-only
+

Er, should we have a `-verify` on this as well as `// expected-no-diagnostics`?



Comment at: clang/test/Sema/ms_predefined_expr.cpp:5-9
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;

Apologies for not noticing this earlier, but because this code isn't portable 
(for the standard predefined identifiers), I think we should also have a 
`-pedantic` test that ensures we get a diagnostic about accepting this code 
being a Microsoft extension.

I would recommend something along the lines of: `initializing an array from a 
'%0' predefined identifier is a Microsoft extension` put into a new warning 
group named `-Wmicrosoft-init-from-predefined` which is added to the 
`-Wmicrosoft` warning group.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-02 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 518777.
aeubanks added a comment.

add module test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Modules/predefined.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// expected-no-diagnostics
+
+void f() {
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;
+}
Index: clang/test/Modules/predefined.cpp
===
--- /dev/null
+++ clang/test/Modules/predefined.cpp
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -x c++ -std=c++20 -emit-module-interface a.h -o a.pcm -fms-extensions
+// RUN: %clang_cc1 -std=c++20 a.cpp -fmodule-file=A=a.pcm -fms-extensions -fsyntax-only
+
+//--- a.h
+
+export module A;
+
+export template 
+void f() {
+char a[] = __func__;
+}
+
+//--- a.cpp
+
+import A;
+
+void g() {
+f();
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3580,7 +3580,8 @@
 }
   }
 
-  return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IK, LangOpts.MicrosoftExt,
+SL);
 }
 
 ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -663,13 +663,14 @@
 }
 
 PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
-   StringLiteral *SL)
+   bool IsTransparent, StringLiteral *SL)
 : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
   PredefinedExprBits.Kind = IK;
   assert((getIdentKind() == IK) &&
  "IdentKind do not fit in PredefinedExprBitfields!");
   bool HasFunctionName = SL != nullptr;
   PredefinedExprBits.HasFunctionName = HasFunctionName;
+  PredefinedExprBits.IsTransparent = IsTransparent;
   PredefinedExprBits.Loc = L;
   if (HasFunctionName)
 setFunctionName(SL);
@@ -683,11 +684,11 @@
 
 PredefinedExpr *PredefinedExpr::Create(const ASTContext , SourceLocation L,
QualType FNTy, IdentKind IK,
-   StringLiteral *SL) {
+   bool IsTransparent, StringLiteral *SL) {
   bool HasFunctionName = SL != nullptr;
   void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
alignof(PredefinedExpr));
-  

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-02 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D146764#4310655 , @aeubanks wrote:

> In D146764#4310398 , @aaron.ballman 
> wrote:
>
>> I think you're missing changes in ASTReaderStmt.cpp and ASTWriterStmt.cpp, 
>> so serialization through modules or PCH won't work without that.
>
> done. how would this sort of change be tested?

Thanks! Typically with a test using modules or PCH, so something along these 
lines: 
https://github.com/llvm/llvm-project/blob/main/clang/test/Modules/cxx20-10-5-ex1.cpp
 and/or 
https://github.com/llvm/llvm-project/blob/main/clang/test/PCH/cxx-namespaces.cpp


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-01 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks marked an inline comment as done.
aeubanks added a comment.

In D146764#4310398 , @aaron.ballman 
wrote:

> I think you're missing changes in ASTReaderStmt.cpp and ASTWriterStmt.cpp, so 
> serialization through modules or PCH won't work without that.

done. how would this sort of change be tested?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-01 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 518548.
aeubanks added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// expected-no-diagnostics
+
+void f() {
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;
+}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -593,6 +593,7 @@
   bool HasFunctionName = E->getFunctionName() != nullptr;
   Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentKind()); // FIXME: stable encoding
+  Record.push_back(E->isTransparent());
   Record.AddSourceLocation(E->getLocation());
   if (HasFunctionName)
 Record.AddStmt(E->getFunctionName());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -582,6 +582,7 @@
   bool HasFunctionName = Record.readInt();
   E->PredefinedExprBits.HasFunctionName = HasFunctionName;
   E->PredefinedExprBits.Kind = Record.readInt();
+  E->PredefinedExprBits.IsTransparent = Record.readInt();
   E->setLocation(readSourceLocation());
   if (HasFunctionName)
 E->setFunctionName(cast(Record.readSubExpr()));
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3580,7 +3580,8 @@
 }
   }
 
-  return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IK, LangOpts.MicrosoftExt,
+SL);
 }
 
 ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -663,13 +663,14 @@
 }
 
 PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
-   StringLiteral *SL)
+   bool IsTransparent, StringLiteral *SL)
 : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
   PredefinedExprBits.Kind = IK;
   assert((getIdentKind() == IK) &&
  "IdentKind do not fit in PredefinedExprBitfields!");
   bool HasFunctionName = SL != nullptr;
   PredefinedExprBits.HasFunctionName = HasFunctionName;
+  PredefinedExprBits.IsTransparent = IsTransparent;
   PredefinedExprBits.Loc = L;
   if (HasFunctionName)
 setFunctionName(SL);
@@ -683,11 +684,11 @@
 
 PredefinedExpr *PredefinedExpr::Create(const ASTContext , SourceLocation L,
QualType FNTy, IdentKind IK,
-   StringLiteral *SL) {
+   bool IsTransparent, StringLiteral *SL) {
   bool HasFunctionName = SL != nullptr;
   void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
alignof(PredefinedExpr));
-  return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
+  return new (Mem) PredefinedExpr(L, FNTy, IK, IsTransparent, SL);
 }
 
 PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext ,
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -7068,7 +7068,8 @@
 return std::move(Err);
 
   return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType,
-E->getIdentKind(), ToFunctionName);
+

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

I think you're missing changes in ASTReaderStmt.cpp and ASTWriterStmt.cpp, so 
serialization through modules or PCH won't work without that.




Comment at: clang/include/clang/AST/Expr.h:1996
   PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
- StringLiteral *SL);
+ bool TreatAsStringLiteral, StringLiteral *SL);
 

I think we should keep `PredefinedExpr` general, so how about `IsTransparent` 
instead? Then we can add a comment above `Create()` that explains what 
`IsTransparent` does.

(This makes it easier for us to add predefined expressions that aren't string 
literals but are still transparently handled.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-05-01 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added a comment.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-04-19 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added a comment.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-04-13 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

aaron.ballman wrote:
> rsmith wrote:
> > aeubanks wrote:
> > > cor3ntin wrote:
> > > > aaron.ballman wrote:
> > > > > aeubanks wrote:
> > > > > > aaron.ballman wrote:
> > > > > > > This is incorrect -- these are still predefined expressions even 
> > > > > > > if they're a string literal. Otherwise, we lose AST fidelity and 
> > > > > > > things like the `predefinedExpr()` AST matcher don't work 
> > > > > > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> > > > > > >  and `-ast-print` will print the wrong thing 
> > > > > > > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> > > > > > how would you structure this? an almost identical `PredefinedExpr` 
> > > > > > class that also subclasses `StringLiteral`? or special case all the 
> > > > > > places that check for `StringLiteral` to also check for 
> > > > > > `PredefinedExpr` (the case I was mostly looking at was initializing 
> > > > > > a char array with predefined expressions but presumably there are 
> > > > > > more places that matter)
> > > > > We can't inherit from `StringLiteral` (it's a `final` class because 
> > > > > it has `TrailingObjects`), so that might be the only viable approach. 
> > > > > However, there's a fair number of places in the compiler where we 
> > > > > care if something is or isn't a `StringLiteral`, so I can see why 
> > > > > we'd want to avoid that if possible.
> > > > > 
> > > > > Oye, but it seems that even MSVC is not consistent with whether the 
> > > > > predefined expression is a string literal or not: 
> > > > > https://godbolt.org/z/jzY8cz79d
> > > > I think these should be plain old string literals, but for the purpose 
> > > > or AST matchers and such, maybe we could have a "predefined macro" bit, 
> > > > or even an additional object that stores the name.
> > > > Oye, but it seems that even MSVC is not consistent with whether the 
> > > > predefined expression is a string literal or not: 
> > > > https://godbolt.org/z/jzY8cz79d
> > > 
> > > the other predefined expressions work, that looks like a bug on MSVC's 
> > > part
> > > 
> > > > I think these should be plain old string literals, but for the purpose 
> > > > or AST matchers and such, maybe we could have a "predefined macro" bit, 
> > > > or even an additional object that stores the name.
> > > 
> > > what do you mean by "an additional object that stores the name"?
> > > 
> > > I started trying to add a bit to `StringLiteral` that signifies if it's 
> > > an MSVC predefined expression. being new to ast matchers, I'm having 
> > > trouble figuring out how to make a matcher that matches both 
> > > `PredefinedExpr` and some `StringLiteral`s but also behaves like a 
> > > `VariadicDynCastAllOfMatcher`.
> > > 
> > > something I noticed in one of the tests [1] is that there's a check
> > > ```
> > > predefinedExpr(hasType(asString("const char[4]")),
> > >  has(stringLiteral()))
> > > ```
> > > thinking about the `has(stringLiteral())`, if somebody wants to get the 
> > > literal for a predefined expr, presumably right now they're looking for a 
> > > string literal child, but if we directly match a string literal then that 
> > > would break? WDYT?
> > > 
> > > [1] 
> > > https://github.com/llvm/llvm-project/blob/75ca15fcbb2e1b3671e41f971a000c6d59f5e5ae/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp#L1064
> > I wonder if we could keep the representation as-is, but add an "is 
> > transparent" bit on `PredefinedExpr` that's set for string literal 
> > predefined expressions under `-fms-extensions`, and make `IgnoreParens` 
> > step over transparent `PredefinedExpr`s. That seems like it'd exactly match 
> > the MS behavior, which seems to allow (eg) `__func__` to appear anywhere a 
> > //parenthesized// string literal can appear.
> That seems like a good approach to me. We've got spare bits in 
> `PredefinedExprBitfields`, so this won't impact AST size, which is nice.
much much cleaner, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-04-13 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 513337.
aeubanks added a comment.

add comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// expected-no-diagnostics
+
+void f() {
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;
+}
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3582,7 +3582,8 @@
 }
   }
 
-  return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IK, LangOpts.MicrosoftExt,
+SL);
 }
 
 ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -663,13 +663,14 @@
 }
 
 PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
-   StringLiteral *SL)
+   bool TreatAsStringLiteral, StringLiteral *SL)
 : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
   PredefinedExprBits.Kind = IK;
   assert((getIdentKind() == IK) &&
  "IdentKind do not fit in PredefinedExprBitfields!");
   bool HasFunctionName = SL != nullptr;
   PredefinedExprBits.HasFunctionName = HasFunctionName;
+  PredefinedExprBits.TreatAsStringLiteral = TreatAsStringLiteral;
   PredefinedExprBits.Loc = L;
   if (HasFunctionName)
 setFunctionName(SL);
@@ -683,11 +684,12 @@
 
 PredefinedExpr *PredefinedExpr::Create(const ASTContext , SourceLocation L,
QualType FNTy, IdentKind IK,
+   bool TreatAsStringLiteral,
StringLiteral *SL) {
   bool HasFunctionName = SL != nullptr;
   void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
alignof(PredefinedExpr));
-  return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
+  return new (Mem) PredefinedExpr(L, FNTy, IK, TreatAsStringLiteral, SL);
 }
 
 PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext ,
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -7068,7 +7068,8 @@
 return std::move(Err);
 
   return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType,
-E->getIdentKind(), ToFunctionName);
+E->getIdentKind(), E->getTreatAsStringLiteral(),
+ToFunctionName);
 }
 
 ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -364,6 +364,10 @@
 /// for the predefined identifier.
 unsigned HasFunctionName : 1;
 
+/// True if this PredefinedExpr should be treated as a StringLiteral (for
+/// MSVC compatibility).
+unsigned TreatAsStringLiteral : 1;
+
 /// The location of this PredefinedExpr.
 SourceLocation Loc;
   };
Index: clang/include/clang/AST/IgnoreExpr.h
===
--- clang/include/clang/AST/IgnoreExpr.h
+++ clang/include/clang/AST/IgnoreExpr.h
@@ -166,6 +166,11 @@
   return CE->getChosenSubExpr();
   }
 
+  else if (auto *PE = dyn_cast(E)) {
+if (PE->getTreatAsStringLiteral())
+  return PE->getFunctionName();
+  }
+
   return E;
 }
 
Index: clang/include/clang/AST/Expr.h
===
--- 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-04-13 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks updated this revision to Diff 513335.
aeubanks added a comment.
Herald added a subscriber: martong.

use IgnoreParens instead


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/IgnoreExpr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/Sema/ms_predefined_expr.cpp

Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// expected-no-diagnostics
+
+void f() {
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;
+}
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -173,6 +173,8 @@
   E = GSE->getResultExpr();
 } else if (ChooseExpr *CE = dyn_cast(E)) {
   E = CE->getChosenSubExpr();
+} else if (PredefinedExpr *PE = dyn_cast(E)) {
+  E = PE->getFunctionName();
 } else {
   llvm_unreachable("unexpected expr in string literal init");
 }
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3582,7 +3582,8 @@
 }
   }
 
-  return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IK, LangOpts.MicrosoftExt,
+SL);
 }
 
 ExprResult Sema::BuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -663,13 +663,14 @@
 }
 
 PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
-   StringLiteral *SL)
+   bool TreatAsStringLiteral, StringLiteral *SL)
 : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
   PredefinedExprBits.Kind = IK;
   assert((getIdentKind() == IK) &&
  "IdentKind do not fit in PredefinedExprBitfields!");
   bool HasFunctionName = SL != nullptr;
   PredefinedExprBits.HasFunctionName = HasFunctionName;
+  PredefinedExprBits.TreatAsStringLiteral = TreatAsStringLiteral;
   PredefinedExprBits.Loc = L;
   if (HasFunctionName)
 setFunctionName(SL);
@@ -683,11 +684,12 @@
 
 PredefinedExpr *PredefinedExpr::Create(const ASTContext , SourceLocation L,
QualType FNTy, IdentKind IK,
+   bool TreatAsStringLiteral,
StringLiteral *SL) {
   bool HasFunctionName = SL != nullptr;
   void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
alignof(PredefinedExpr));
-  return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
+  return new (Mem) PredefinedExpr(L, FNTy, IK, TreatAsStringLiteral, SL);
 }
 
 PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext ,
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -7068,7 +7068,8 @@
 return std::move(Err);
 
   return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType,
-E->getIdentKind(), ToFunctionName);
+E->getIdentKind(), E->getTreatAsStringLiteral(),
+ToFunctionName);
 }
 
 ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -364,6 +364,8 @@
 /// for the predefined identifier.
 unsigned HasFunctionName : 1;
 
+unsigned TreatAsStringLiteral : 1;
+
 /// The location of this PredefinedExpr.
 SourceLocation Loc;
   };
Index: clang/include/clang/AST/IgnoreExpr.h
===
--- clang/include/clang/AST/IgnoreExpr.h
+++ clang/include/clang/AST/IgnoreExpr.h
@@ -166,6 +166,11 @@
   return CE->getChosenSubExpr();
   }
 
+  else if (auto *PE = dyn_cast(E)) {
+if (PE->getTreatAsStringLiteral())
+  return PE->getFunctionName();
+  }
+
   return E;
 }
 
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -1993,7 

[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

rsmith wrote:
> aeubanks wrote:
> > cor3ntin wrote:
> > > aaron.ballman wrote:
> > > > aeubanks wrote:
> > > > > aaron.ballman wrote:
> > > > > > This is incorrect -- these are still predefined expressions even if 
> > > > > > they're a string literal. Otherwise, we lose AST fidelity and 
> > > > > > things like the `predefinedExpr()` AST matcher don't work 
> > > > > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> > > > > >  and `-ast-print` will print the wrong thing 
> > > > > > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> > > > > how would you structure this? an almost identical `PredefinedExpr` 
> > > > > class that also subclasses `StringLiteral`? or special case all the 
> > > > > places that check for `StringLiteral` to also check for 
> > > > > `PredefinedExpr` (the case I was mostly looking at was initializing a 
> > > > > char array with predefined expressions but presumably there are more 
> > > > > places that matter)
> > > > We can't inherit from `StringLiteral` (it's a `final` class because it 
> > > > has `TrailingObjects`), so that might be the only viable approach. 
> > > > However, there's a fair number of places in the compiler where we care 
> > > > if something is or isn't a `StringLiteral`, so I can see why we'd want 
> > > > to avoid that if possible.
> > > > 
> > > > Oye, but it seems that even MSVC is not consistent with whether the 
> > > > predefined expression is a string literal or not: 
> > > > https://godbolt.org/z/jzY8cz79d
> > > I think these should be plain old string literals, but for the purpose or 
> > > AST matchers and such, maybe we could have a "predefined macro" bit, or 
> > > even an additional object that stores the name.
> > > Oye, but it seems that even MSVC is not consistent with whether the 
> > > predefined expression is a string literal or not: 
> > > https://godbolt.org/z/jzY8cz79d
> > 
> > the other predefined expressions work, that looks like a bug on MSVC's part
> > 
> > > I think these should be plain old string literals, but for the purpose or 
> > > AST matchers and such, maybe we could have a "predefined macro" bit, or 
> > > even an additional object that stores the name.
> > 
> > what do you mean by "an additional object that stores the name"?
> > 
> > I started trying to add a bit to `StringLiteral` that signifies if it's an 
> > MSVC predefined expression. being new to ast matchers, I'm having trouble 
> > figuring out how to make a matcher that matches both `PredefinedExpr` and 
> > some `StringLiteral`s but also behaves like a `VariadicDynCastAllOfMatcher`.
> > 
> > something I noticed in one of the tests [1] is that there's a check
> > ```
> > predefinedExpr(hasType(asString("const char[4]")),
> >  has(stringLiteral()))
> > ```
> > thinking about the `has(stringLiteral())`, if somebody wants to get the 
> > literal for a predefined expr, presumably right now they're looking for a 
> > string literal child, but if we directly match a string literal then that 
> > would break? WDYT?
> > 
> > [1] 
> > https://github.com/llvm/llvm-project/blob/75ca15fcbb2e1b3671e41f971a000c6d59f5e5ae/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp#L1064
> I wonder if we could keep the representation as-is, but add an "is 
> transparent" bit on `PredefinedExpr` that's set for string literal predefined 
> expressions under `-fms-extensions`, and make `IgnoreParens` step over 
> transparent `PredefinedExpr`s. That seems like it'd exactly match the MS 
> behavior, which seems to allow (eg) `__func__` to appear anywhere a 
> //parenthesized// string literal can appear.
That seems like a good approach to me. We've got spare bits in 
`PredefinedExprBitfields`, so this won't impact AST size, which is nice.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

aeubanks wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > aeubanks wrote:
> > > > aaron.ballman wrote:
> > > > > This is incorrect -- these are still predefined expressions even if 
> > > > > they're a string literal. Otherwise, we lose AST fidelity and things 
> > > > > like the `predefinedExpr()` AST matcher don't work 
> > > > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> > > > >  and `-ast-print` will print the wrong thing 
> > > > > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> > > > how would you structure this? an almost identical `PredefinedExpr` 
> > > > class that also subclasses `StringLiteral`? or special case all the 
> > > > places that check for `StringLiteral` to also check for 
> > > > `PredefinedExpr` (the case I was mostly looking at was initializing a 
> > > > char array with predefined expressions but presumably there are more 
> > > > places that matter)
> > > We can't inherit from `StringLiteral` (it's a `final` class because it 
> > > has `TrailingObjects`), so that might be the only viable approach. 
> > > However, there's a fair number of places in the compiler where we care if 
> > > something is or isn't a `StringLiteral`, so I can see why we'd want to 
> > > avoid that if possible.
> > > 
> > > Oye, but it seems that even MSVC is not consistent with whether the 
> > > predefined expression is a string literal or not: 
> > > https://godbolt.org/z/jzY8cz79d
> > I think these should be plain old string literals, but for the purpose or 
> > AST matchers and such, maybe we could have a "predefined macro" bit, or 
> > even an additional object that stores the name.
> > Oye, but it seems that even MSVC is not consistent with whether the 
> > predefined expression is a string literal or not: 
> > https://godbolt.org/z/jzY8cz79d
> 
> the other predefined expressions work, that looks like a bug on MSVC's part
> 
> > I think these should be plain old string literals, but for the purpose or 
> > AST matchers and such, maybe we could have a "predefined macro" bit, or 
> > even an additional object that stores the name.
> 
> what do you mean by "an additional object that stores the name"?
> 
> I started trying to add a bit to `StringLiteral` that signifies if it's an 
> MSVC predefined expression. being new to ast matchers, I'm having trouble 
> figuring out how to make a matcher that matches both `PredefinedExpr` and 
> some `StringLiteral`s but also behaves like a `VariadicDynCastAllOfMatcher`.
> 
> something I noticed in one of the tests [1] is that there's a check
> ```
> predefinedExpr(hasType(asString("const char[4]")),
>  has(stringLiteral()))
> ```
> thinking about the `has(stringLiteral())`, if somebody wants to get the 
> literal for a predefined expr, presumably right now they're looking for a 
> string literal child, but if we directly match a string literal then that 
> would break? WDYT?
> 
> [1] 
> https://github.com/llvm/llvm-project/blob/75ca15fcbb2e1b3671e41f971a000c6d59f5e5ae/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp#L1064
I wonder if we could keep the representation as-is, but add an "is transparent" 
bit on `PredefinedExpr` that's set for string literal predefined expressions 
under `-fms-extensions`, and make `IgnoreParens` step over transparent 
`PredefinedExpr`s. That seems like it'd exactly match the MS behavior, which 
seems to allow (eg) `__func__` to appear anywhere a //parenthesized// string 
literal can appear.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Arthur Eubanks (out until mid-April) via Phabricator via cfe-commits
aeubanks added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

cor3ntin wrote:
> aaron.ballman wrote:
> > aeubanks wrote:
> > > aaron.ballman wrote:
> > > > This is incorrect -- these are still predefined expressions even if 
> > > > they're a string literal. Otherwise, we lose AST fidelity and things 
> > > > like the `predefinedExpr()` AST matcher don't work 
> > > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> > > >  and `-ast-print` will print the wrong thing 
> > > > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> > > how would you structure this? an almost identical `PredefinedExpr` class 
> > > that also subclasses `StringLiteral`? or special case all the places that 
> > > check for `StringLiteral` to also check for `PredefinedExpr` (the case I 
> > > was mostly looking at was initializing a char array with predefined 
> > > expressions but presumably there are more places that matter)
> > We can't inherit from `StringLiteral` (it's a `final` class because it has 
> > `TrailingObjects`), so that might be the only viable approach. However, 
> > there's a fair number of places in the compiler where we care if something 
> > is or isn't a `StringLiteral`, so I can see why we'd want to avoid that if 
> > possible.
> > 
> > Oye, but it seems that even MSVC is not consistent with whether the 
> > predefined expression is a string literal or not: 
> > https://godbolt.org/z/jzY8cz79d
> I think these should be plain old string literals, but for the purpose or AST 
> matchers and such, maybe we could have a "predefined macro" bit, or even an 
> additional object that stores the name.
> Oye, but it seems that even MSVC is not consistent with whether the 
> predefined expression is a string literal or not: 
> https://godbolt.org/z/jzY8cz79d

the other predefined expressions work, that looks like a bug on MSVC's part

> I think these should be plain old string literals, but for the purpose or AST 
> matchers and such, maybe we could have a "predefined macro" bit, or even an 
> additional object that stores the name.

what do you mean by "an additional object that stores the name"?

I started trying to add a bit to `StringLiteral` that signifies if it's an MSVC 
predefined expression. being new to ast matchers, I'm having trouble figuring 
out how to make a matcher that matches both `PredefinedExpr` and some 
`StringLiteral`s but also behaves like a `VariadicDynCastAllOfMatcher`.

something I noticed in one of the tests [1] is that there's a check
```
predefinedExpr(hasType(asString("const char[4]")),
 has(stringLiteral()))
```
thinking about the `has(stringLiteral())`, if somebody wants to get the literal 
for a predefined expr, presumably right now they're looking for a string 
literal child, but if we directly match a string literal then that would break? 
WDYT?

[1] 
https://github.com/llvm/llvm-project/blob/75ca15fcbb2e1b3671e41f971a000c6d59f5e5ae/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp#L1064


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

aaron.ballman wrote:
> aeubanks wrote:
> > aaron.ballman wrote:
> > > This is incorrect -- these are still predefined expressions even if 
> > > they're a string literal. Otherwise, we lose AST fidelity and things like 
> > > the `predefinedExpr()` AST matcher don't work 
> > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> > >  and `-ast-print` will print the wrong thing 
> > > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> > how would you structure this? an almost identical `PredefinedExpr` class 
> > that also subclasses `StringLiteral`? or special case all the places that 
> > check for `StringLiteral` to also check for `PredefinedExpr` (the case I 
> > was mostly looking at was initializing a char array with predefined 
> > expressions but presumably there are more places that matter)
> We can't inherit from `StringLiteral` (it's a `final` class because it has 
> `TrailingObjects`), so that might be the only viable approach. However, 
> there's a fair number of places in the compiler where we care if something is 
> or isn't a `StringLiteral`, so I can see why we'd want to avoid that if 
> possible.
> 
> Oye, but it seems that even MSVC is not consistent with whether the 
> predefined expression is a string literal or not: 
> https://godbolt.org/z/jzY8cz79d
I think these should be plain old string literals, but for the purpose or AST 
matchers and such, maybe we could have a "predefined macro" bit, or even an 
additional object that stores the name.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

aeubanks wrote:
> aaron.ballman wrote:
> > This is incorrect -- these are still predefined expressions even if they're 
> > a string literal. Otherwise, we lose AST fidelity and things like the 
> > `predefinedExpr()` AST matcher don't work 
> > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
> >  and `-ast-print` will print the wrong thing 
> > (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
> how would you structure this? an almost identical `PredefinedExpr` class that 
> also subclasses `StringLiteral`? or special case all the places that check 
> for `StringLiteral` to also check for `PredefinedExpr` (the case I was mostly 
> looking at was initializing a char array with predefined expressions but 
> presumably there are more places that matter)
We can't inherit from `StringLiteral` (it's a `final` class because it has 
`TrailingObjects`), so that might be the only viable approach. However, there's 
a fair number of places in the compiler where we care if something is or isn't 
a `StringLiteral`, so I can see why we'd want to avoid that if possible.

Oye, but it seems that even MSVC is not consistent with whether the predefined 
expression is a string literal or not: https://godbolt.org/z/jzY8cz79d


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

aaron.ballman wrote:
> This is incorrect -- these are still predefined expressions even if they're a 
> string literal. Otherwise, we lose AST fidelity and things like the 
> `predefinedExpr()` AST matcher don't work 
> (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
>  and `-ast-print` will print the wrong thing 
> (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).
how would you structure this? an almost identical `PredefinedExpr` class that 
also subclasses `StringLiteral`? or special case all the places that check for 
`StringLiteral` to also check for `PredefinedExpr` (the case I was mostly 
looking at was initializing a char array with predefined expressions but 
presumably there are more places that matter)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

In D146764#4219278 , @hans wrote:

> +mstorsjo is this okay for mingw mode too?

I believe the current form of the patch is fine - i.e. disabled by default in 
mingw mode, but enabled if the extra MS language extensions are enabled. (I 
didn't check myself how those options map to `LangOpts.MicrosoftExt` but I 
presume it works as I described above.)




Comment at: clang/include/clang/Testing/TestClangConfig.h:61
 
-  bool hasDelayedTemplateParsing() const {
-return Target == "x86_64-pc-win32-msvc";
-  }
+  bool isWin32() const { return Target == "x86_64-pc-win32-msvc"; }
+

I'm not entirely sure of the use context of this function (only specific 
tests?), but mingw targets with a differen triple are win32 too. But then they 
could also be using an entirely different architecture than x86_64, so I guess 
this might be ok too if we're ready to tweak it when a need arises?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman requested changes to this revision.
aaron.ballman added a comment.
This revision now requires changes to proceed.

This should also have a release note, eventually.




Comment at: clang/lib/Sema/SemaExpr.cpp:3586-3591
+  // MSVC treats all predefined expressions as string literals rather than char
+  // arrays.
+  if (LangOpts.MicrosoftExt)
+return SL;
+
   return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);

This is incorrect -- these are still predefined expressions even if they're a 
string literal. Otherwise, we lose AST fidelity and things like the 
`predefinedExpr()` AST matcher don't work 
(https://github.com/llvm/llvm-project/blob/main/clang/include/clang/ASTMatchers/ASTMatchers.h#L2697),
 and `-ast-print` will print the wrong thing 
(https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/StmtPrinter.cpp#L1248).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-24 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a reviewer: mstorsjo.
hans added a comment.

+mstorsjo is this okay for mingw mode too?




Comment at: clang/lib/Sema/SemaExpr.cpp:3558
+return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
+  } else {
 // Pre-defined identifiers are of type char[x], where x is the length of

Since this becomes an "else after return" it could be dropped.



Comment at: clang/test/CodeGen/predefined-expr.c:4
+
+// ITANIUM: @__func__.plainFunction = private unnamed_addr constant [14 x i8] 
c"plainFunction\00"
+// ITANIUM: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant 
[25 x i8] c"void plainFunction(void)\00"

Both invocations use the Itanium abi, so the check prefix is a bit confusing. 
How about DEFAULT and MS?



Comment at: clang/test/Sema/ms_predefined_expr.cpp:4
+
+void f(void) {
+ const char a[] = __FUNCTION__;

ultra nit: the 'void' param makes this look like c code. Should it go in a .c 
file instead of .cpp?



Comment at: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp:1062
+  // Predefined expressions are string literals under Microsoft extensions.
+  if (GetParam().isWin32())
+return;

Could the same check be used in ASTImporterTest.cpp?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146764

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


[PATCH] D146764: [clang] Make predefined expressions string literals under -fms-extensions

2023-03-23 Thread Arthur Eubanks via Phabricator via cfe-commits
aeubanks created this revision.
Herald added a reviewer: shafik.
Herald added a project: All.
aeubanks requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

MSVC makes these string literals [1][2].

[1] https://godbolt.org/z/6vnTzbExx
[2] 
https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170

Fixes #114


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146764

Files:
  clang/include/clang/Testing/TestClangConfig.h
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/predefined-expr.c
  clang/test/Sema/ms_predefined_expr.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -1058,6 +1058,10 @@
 }
 
 TEST_P(ASTMatchersTest, PredefinedExpr) {
+  // Predefined expressions are string literals under Microsoft extensions.
+  if (GetParam().isWin32())
+return;
+
   // __func__ expands as StringLiteral("foo")
   EXPECT_TRUE(matches("void foo() { __func__; }",
   predefinedExpr(hasType(asString("const char[4]")),
Index: clang/unittests/AST/ASTImporterTest.cpp
===
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -509,6 +509,11 @@
 }
 
 TEST_P(ImportExpr, ImportPredefinedExpr) {
+  // Predefined expressions are string literals under Microsoft extensions.
+  if (std::find(GetParam().begin(), GetParam().end(), "-fms-compatibility") !=
+  GetParam().end())
+return;
+
   MatchVerifier Verifier;
   // __func__ expands as StringLiteral("declToImport")
   testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "",
Index: clang/test/Sema/ms_predefined_expr.cpp
===
--- /dev/null
+++ clang/test/Sema/ms_predefined_expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// expected-no-diagnostics
+
+void f(void) {
+ const char a[] = __FUNCTION__;
+ const char b[] = __FUNCDNAME__;
+ const char c[] = __FUNCSIG__;
+ const char d[] = __func__;
+ const char e[] = __PRETTY_FUNCTION__;
+}
Index: clang/test/CodeGen/predefined-expr.c
===
--- clang/test/CodeGen/predefined-expr.c
+++ clang/test/CodeGen/predefined-expr.c
@@ -1,16 +1,27 @@
-// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -fms-extensions %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
-
-// CHECK: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [25 x i8] c"void plainFunction(void)\00"
-// CHECK: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [26 x i8] c"void externFunction(void)\00"
-// CHECK: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [33 x i8] c"void privateExternFunction(void)\00"
-// CHECK: @__func__.__captured_stmt = private unnamed_addr constant [25 x i8] c"functionWithCapturedStmt\00"
-// CHECK: @__PRETTY_FUNCTION__.__captured_stmt = private unnamed_addr constant [36 x i8] c"void functionWithCapturedStmt(void)\00"
-// CHECK: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00"
-// CHECK: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [26 x i8] c"void staticFunction(void)\00"
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -fms-extensions %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s --check-prefix=MS
+
+// ITANIUM: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00"
+// ITANIUM: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [25 x i8] c"void plainFunction(void)\00"
+// ITANIUM: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00"
+// ITANIUM: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [26 x i8] c"void externFunction(void)\00"
+// ITANIUM: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00"
+// ITANIUM: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [33 x i8] c"void privateExternFunction(void)\00"
+// ITANIUM: @__func__.__captured_stmt = private unnamed_addr constant [25 x i8]