JMazurkiewicz updated this revision to Diff 523360.
JMazurkiewicz marked 2 inline comments as done.
JMazurkiewicz added a comment.

- Address comments (thanks for the review @aaron.ballman!),
- Remove `clang-format` changes (CI might fail),
- Add extra tests in `clang/test/Preprocessor/feature_tests.cpp`.


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

https://reviews.llvm.org/D150183

Files:
  clang/docs/LanguageExtensions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Expr.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Expr.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Preprocessor/feature_tests.c
  clang/test/Preprocessor/feature_tests.cpp
  clang/test/Sema/source_location.c
  clang/test/SemaCXX/source_location.cpp

Index: clang/test/SemaCXX/source_location.cpp
===================================================================
--- clang/test/SemaCXX/source_location.cpp
+++ clang/test/SemaCXX/source_location.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -verify %s
+// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -verify %s
 // expected-no-diagnostics
 
 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
@@ -86,6 +88,9 @@
 static_assert(is_same<decltype(__builtin_FILE()), const char *>);
 static_assert(is_same<decltype(__builtin_FILE_NAME()), const char *>);
 static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
+#ifdef MS
+static_assert(is_same<decltype(__builtin_FUNCSIG()), const char *>);
+#endif
 static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
 
 // test noexcept
@@ -94,6 +99,9 @@
 static_assert(noexcept(__builtin_FILE()));
 static_assert(noexcept(__builtin_FILE_NAME()));
 static_assert(noexcept(__builtin_FUNCTION()));
+#ifdef MS
+static_assert(noexcept(__builtin_FUNCSIG()));
+#endif
 static_assert(noexcept(__builtin_source_location()));
 
 //===----------------------------------------------------------------------===//
@@ -450,6 +458,57 @@
 
 } // namespace test_func
 
+//===----------------------------------------------------------------------===//
+//                            __builtin_FUNCSIG()
+//===----------------------------------------------------------------------===//
+
+#ifdef MS
+namespace test_funcsig {
+
+constexpr const char *test_funcsig_simple(const char *f = __builtin_FUNCSIG()) {
+  return f;
+}
+constexpr const char *get_funcsig() {
+  return __FUNCSIG__;
+}
+constexpr bool test_funcsig() {
+  return is_equal(__FUNCSIG__, test_funcsig_simple()) &&
+         !is_equal(get_funcsig(), test_funcsig_simple());
+}
+static_assert(test_funcsig());
+
+template <class T>
+constexpr Pair<const char*, const char*> test_funcsig_template(T, const char* f = __builtin_FUNCSIG()) {
+  return {f, __builtin_FUNCSIG()};
+}
+template <class T>
+void func_template_tests() {
+  constexpr auto P = test_funcsig_template(42);
+  static_assert(is_equal(P.first, __FUNCSIG__), "");
+  static_assert(!is_equal(P.second, __FUNCSIG__), "");
+}
+template void func_template_tests<int>();
+
+template <class = int, class T = const char*>
+struct TestCtor {
+  T funcsig = __builtin_FUNCSIG();
+  T ctor_funcsig;
+  TestCtor() = default;
+  template <class F = const char*>
+  constexpr TestCtor(int, F f = __builtin_FUNCSIG()) : ctor_funcsig(f) {}
+};
+void ctor_tests() {
+  constexpr TestCtor<> Template{42};
+  static_assert(is_equal(Template.funcsig, "__cdecl test_funcsig::TestCtor<>::TestCtor(int, F) [T = const char *, F = const char *]"));
+  static_assert(is_equal(Template.ctor_funcsig, __FUNCSIG__));
+}
+
+constexpr const char* global_funcsig = __builtin_FUNCSIG();
+static_assert(is_equal(global_funcsig, ""));
+
+} // namespace test_funcsig
+#endif
+
 //===----------------------------------------------------------------------===//
 //                            __builtin_COLUMN()
 //===----------------------------------------------------------------------===//
Index: clang/test/Sema/source_location.c
===================================================================
--- clang/test/Sema/source_location.c
+++ clang/test/Sema/source_location.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c90 -fconst-strings -DCONST_STRINGS -verify %s
 // RUN: %clang_cc1 -std=c90 -verify %s
+// RUN: %clang_cc1 -std=c90 -fms-extensions -DMS -fconst-strings -DCONST_STRINGS -verify %s
+// RUN: %clang_cc1 -std=c90 -fms-extensions -DMS -verify %s
 
 // expected-no-diagnostics
 
@@ -13,6 +15,9 @@
 #ifndef CONST_STRINGS
 char *const NCFILE = __builtin_FILE();
 char *const NCFUNC = __builtin_FUNCTION();
+#ifdef MS
+char *const NCFNSG = __builtin_FUNCSIG();
+#endif
 #endif
 
 #ifdef CONST_STRINGS
@@ -20,6 +25,9 @@
 _Static_assert(IsEqual(__builtin_FILE_NAME(), __FILE_NAME__), "");
 _Static_assert(__builtin_LINE() == __LINE__, "");
 _Static_assert(IsEqual("", __builtin_FUNCTION()), "");
+#ifdef MS
+_Static_assert(IsEqual("", __builtin_FUNCSIG()), "");
+#endif
 
 #line 42 "my_file.c"
 _Static_assert(__builtin_LINE() == 42, "");
@@ -30,5 +38,8 @@
 
 void foo(void) {
   _Static_assert(IsEqual(__builtin_FUNCTION(), "foo"), "");
+#ifdef MS
+  _Static_assert(IsEqual(__builtin_FUNCSIG(), "void __cdecl foo(void)"), "");
+#endif
 }
 #endif // CONST_STRINGS
Index: clang/test/Preprocessor/feature_tests.cpp
===================================================================
--- clang/test/Preprocessor/feature_tests.cpp
+++ clang/test/Preprocessor/feature_tests.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -verify -DVERIFY
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -fms-extensions -DMS -verify -DVERIFY
 
 #ifndef __has_feature
 #error Should have __has_feature
@@ -34,6 +35,14 @@
 #error Clang should have these
 #endif
 
+#ifdef MS
+#if !__has_builtin(__builtin_FUNCSIG)
+#error Clang should have this
+#endif
+#elif __has_builtin(__builtin_FUNCSIG)
+#error Clang should not have this without '-fms-extensions'
+#endif
+
 // This is a C-only builtin.
 #if __has_builtin(__builtin_types_compatible_p)
 #error Clang should not have this in C++ mode
Index: clang/test/Preprocessor/feature_tests.c
===================================================================
--- clang/test/Preprocessor/feature_tests.c
+++ clang/test/Preprocessor/feature_tests.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -target-cpu pentium4 -verify -DVERIFY
 // RUN: %clang_cc1 %s -E -triple=i686-apple-darwin9 -target-cpu pentium4
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -target-cpu pentium4 -fms-extensions -DMS -verify -DVERIFY
+// RUN: %clang_cc1 %s -E -triple=i686-apple-darwin9 -target-cpu pentium4 -fms-extensions -DMS
 #ifndef __has_feature
 #error Should have __has_feature
 #endif
@@ -31,6 +33,14 @@
 #error Clang should have these
 #endif
 
+#ifdef MS
+#if !__has_builtin(__builtin_FUNCSIG)
+#error Clang should have this
+#endif
+#elif __has_builtin(__builtin_FUNCSIG)
+#error Clang should not have this without '-fms-extensions'
+#endif
+
 // These are C++-only builtins.
 #if __has_builtin(__array_rank) || \
     __has_builtin(__underlying_type) || \
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -17181,7 +17181,8 @@
   switch (Kind) {
   case SourceLocExpr::File:
   case SourceLocExpr::FileName:
-  case SourceLocExpr::Function: {
+  case SourceLocExpr::Function:
+  case SourceLocExpr::FuncSig: {
     QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0);
     ResultTy =
         Context.getPointerType(ArrTy->getAsArrayTypeUnsafe()->getElementType());
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -792,6 +792,7 @@
 /// [GNU]   '__builtin_FILE' '(' ')'
 /// [CLANG] '__builtin_FILE_NAME' '(' ')'
 /// [GNU]   '__builtin_FUNCTION' '(' ')'
+/// [MS]    '__builtin_FUNCSIG' '(' ')'
 /// [GNU]   '__builtin_LINE' '(' ')'
 /// [CLANG] '__builtin_COLUMN' '(' ')'
 /// [GNU]   '__builtin_source_location' '(' ')'
@@ -1321,6 +1322,7 @@
   case tok::kw___builtin_FILE:
   case tok::kw___builtin_FILE_NAME:
   case tok::kw___builtin_FUNCTION:
+  case tok::kw___builtin_FUNCSIG:
   case tok::kw___builtin_LINE:
   case tok::kw___builtin_source_location:
     if (NotPrimaryExpression)
@@ -2547,6 +2549,7 @@
 /// [GNU]   '__builtin_FILE' '(' ')'
 /// [CLANG] '__builtin_FILE_NAME' '(' ')'
 /// [GNU]   '__builtin_FUNCTION' '(' ')'
+/// [MS]    '__builtin_FUNCSIG' '(' ')'
 /// [GNU]   '__builtin_LINE' '(' ')'
 /// [CLANG] '__builtin_COLUMN' '(' ')'
 /// [GNU]   '__builtin_source_location' '(' ')'
@@ -2783,6 +2786,7 @@
   case tok::kw___builtin_FILE:
   case tok::kw___builtin_FILE_NAME:
   case tok::kw___builtin_FUNCTION:
+  case tok::kw___builtin_FUNCSIG:
   case tok::kw___builtin_LINE:
   case tok::kw___builtin_source_location: {
     // Attempt to consume the r-paren.
@@ -2799,6 +2803,8 @@
         return SourceLocExpr::FileName;
       case tok::kw___builtin_FUNCTION:
         return SourceLocExpr::Function;
+      case tok::kw___builtin_FUNCSIG:
+        return SourceLocExpr::FuncSig;
       case tok::kw___builtin_LINE:
         return SourceLocExpr::Line;
       case tok::kw___builtin_COLUMN:
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -2247,6 +2247,8 @@
     return "__builtin_FILE_NAME";
   case Function:
     return "__builtin_FUNCTION";
+  case FuncSig:
+    return "__builtin_FUNCSIG";
   case Line:
     return "__builtin_LINE";
   case Column:
@@ -2297,11 +2299,14 @@
                                                  Ctx.getTargetInfo());
     return MakeStringLiteral(Path);
   }
-  case SourceLocExpr::Function: {
+  case SourceLocExpr::Function:
+  case SourceLocExpr::FuncSig: {
     const auto *CurDecl = dyn_cast<Decl>(Context);
+    const auto Kind = getIdentKind() == SourceLocExpr::Function
+                          ? PredefinedExpr::Function
+                          : PredefinedExpr::FuncSig;
     return MakeStringLiteral(
-        CurDecl ? PredefinedExpr::ComputeName(PredefinedExpr::Function, CurDecl)
-                : std::string(""));
+        CurDecl ? PredefinedExpr::ComputeName(Kind, CurDecl) : std::string(""));
   }
   case SourceLocExpr::Line:
   case SourceLocExpr::Column: {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6000,8 +6000,8 @@
   ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
                             TypeSourceInfo *TInfo, SourceLocation RPLoc);
 
-  // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(),
-  // __builtin_COLUMN(), __builtin_source_location()
+  // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FUNCSIG(),
+  // __builtin_FILE(), __builtin_COLUMN(), __builtin_source_location()
   ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind,
                                 SourceLocation BuiltinLoc,
                                 SourceLocation RPLoc);
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -438,6 +438,7 @@
 KEYWORD(__builtin_FILE              , KEYALL)
 KEYWORD(__builtin_FILE_NAME         , KEYALL)
 KEYWORD(__builtin_FUNCTION          , KEYALL)
+KEYWORD(__builtin_FUNCSIG           , KEYMS)
 KEYWORD(__builtin_LINE              , KEYALL)
 KEYWORD(__builtin_COLUMN            , KEYALL)
 KEYWORD(__builtin_source_location   , KEYCXX)
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4691,14 +4691,22 @@
 };
 
 /// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
-/// __builtin_FUNCTION(), __builtin_FILE(), __builtin_FILE_NAME(),
-/// or __builtin_source_location().
+/// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(),
+/// __builtin_FILE_NAME() or __builtin_source_location().
 class SourceLocExpr final : public Expr {
   SourceLocation BuiltinLoc, RParenLoc;
   DeclContext *ParentContext;
 
 public:
-  enum IdentKind { Function, File, FileName, Line, Column, SourceLocStruct };
+  enum IdentKind {
+    Function,
+    FuncSig,
+    File,
+    FileName,
+    Line,
+    Column,
+    SourceLocStruct
+  };
 
   SourceLocExpr(const ASTContext &Ctx, IdentKind Type, QualType ResultTy,
                 SourceLocation BLoc, SourceLocation RParenLoc,
@@ -4724,6 +4732,7 @@
     case File:
     case FileName:
     case Function:
+    case FuncSig:
     case SourceLocStruct:
       return false;
     case Line:
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@
   ``memcmp(&lhs, &rhs, sizeof(T)) == 0``.
 - Clang now ignores null directives outside of the include guard when deciding
   whether a file can be enabled for the multiple-include optimization.
+- Clang now support ``__builtin_FUNCSIG()`` which retruns the same information
+  as the ``__FUNCSIG__`` macro (available only with ``-fms-extensions`` flag).
+  This fixes (`#58951 <https://github.com/llvm/llvm-project/issues/58951>`_).
 
 New Compiler Flags
 ------------------
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -3711,7 +3711,7 @@
 
 Clang provides builtins to support C++ standard library implementation
 of ``std::source_location`` as specified in C++20.  With the exception
-of ``__builtin_COLUMN`` and ``__builtin_FILE_NAME``,
+of ``__builtin_COLUMN``, ``__builtin_FILE_NAME`` and ``__builtin_FUNCSIG``,
 these builtins are also implemented by GCC.
 
 **Syntax**:
@@ -3721,6 +3721,7 @@
   const char *__builtin_FILE();
   const char *__builtin_FILE_NAME(); // Clang only
   const char *__builtin_FUNCTION();
+  const char *__builtin_FUNCSIG(); // Microsoft
   unsigned    __builtin_LINE();
   unsigned    __builtin_COLUMN(); // Clang only
   const std::source_location::__impl *__builtin_source_location();
@@ -3750,11 +3751,12 @@
 
 **Description**:
 
-The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, ``__builtin_FILE`` and
-``__builtin_FILE_NAME`` return the values, at the "invocation point", for
-``__LINE__``, ``__FUNCTION__``, ``__FILE__`` and ``__FILE_NAME__`` respectively.
-``__builtin_COLUMN`` similarly returns the column,
-though there is no corresponding macro. These builtins are constant expressions.
+The builtins ``__builtin_LINE``, ``__builtin_FUNCTION``, ``__builtin_FUNCSIG``,
+``__builtin_FILE`` and ``__builtin_FILE_NAME`` return the values, at the
+"invocation point", for ``__LINE__``, ``__FUNCTION__``, ``__FUNCSIG__``,
+``__FILE__`` and ``__FILE_NAME__`` respectively. ``__builtin_COLUMN`` similarly
+returns the column, though there is no corresponding macro. These builtins are
+constant expressions.
 
 When the builtins appear as part of a default function argument the invocation
 point is the location of the caller. When the builtins appear as part of a
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to