https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/67592
>From 55b67a58ef8b9856e5f0a8f535b8617f59711dec Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 27 Sep 2023 11:59:04 -0700 Subject: [PATCH 01/12] Fix value of __FUNCTION__ and __func__ in MSVC mode. --- clang/lib/AST/Expr.cpp | 9 ++- clang/lib/AST/TypePrinter.cpp | 21 +++++- clang/test/Analysis/eval-predefined-exprs.cpp | 4 +- .../CodeGenCXX/mangle-nttp-anon-union.cpp | 2 +- clang/test/CodeGenCXX/predefined-expr.cpp | 18 ----- clang/test/SemaCXX/source_location.cpp | 72 +++++++++++++++++++ 6 files changed, 99 insertions(+), 27 deletions(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index af82ca0784af41..49f3495c090f19 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -773,8 +773,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { const auto &LO = Context.getLangOpts(); - if (((IK == Func || IK == Function) && !LO.MicrosoftExt) || - (IK == LFunction && LO.MicrosoftExt)) + if (((IK == Function || IK == Func) && !LO.MicrosoftExt) || + ((IK == LFunction || IK == Func) && LO.MicrosoftExt)) return FD->getNameAsString(); SmallString<256> Name; @@ -804,7 +804,10 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { PrintingPolicy Policy(LO); PrettyCallbacks PrettyCB(LO); Policy.Callbacks = &PrettyCB; - Policy.UseClassForTemplateArgument = LO.MicrosoftExt; + if (IK == Function && LO.MicrosoftExt) { + Policy.UseClassForTemplateArgument = LO.MicrosoftExt; + Policy.MSVCFormatting = LO.MicrosoftExt; + } std::string Proto; llvm::raw_string_ostream POut(Proto); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 3771a29f26b173..8a7cf85cdf126b 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2195,6 +2195,7 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, llvm::SmallVector<TemplateArgument, 8> OrigArgs; for (const TA &A : Args) OrigArgs.push_back(getArgument(A)); + while (!Args.empty() && getArgument(Args.back()).getIsDefaulted()) Args = Args.drop_back(); } @@ -2218,10 +2219,24 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, } else { if (!FirstArg) OS << Comma; - if (Policy.UseClassForTemplateArgument && - Argument.getKind() == TemplateArgument::Type) - OS << "class "; + if (Policy.MSVCFormatting && Policy.UseClassForTemplateArgument && + Argument.getKind() == TemplateArgument::Type && + !Argument.getAsType()->isBuiltinType()) { + const Type *Ty = Argument.getAsType().getTypePtr(); + const char *kw; + if (Ty->isStructureType()) + kw = "struct "; + else if (Ty->isClassType()) + kw = "class "; + else if (Ty->isUnionType()) + kw = "union "; + else if (Ty->isEnumeralType()) + kw = "enum "; + else + llvm_unreachable("argument type not expected"); + OS << kw; + } // Tries to print the argument with location info if exists. printArgument(Arg, Policy, ArgOS, TemplateParameterList::shouldIncludeTypeForArgument( diff --git a/clang/test/Analysis/eval-predefined-exprs.cpp b/clang/test/Analysis/eval-predefined-exprs.cpp index 7be441eb5bad94..a6bac5ee9d486d 100644 --- a/clang/test/Analysis/eval-predefined-exprs.cpp +++ b/clang/test/Analysis/eval-predefined-exprs.cpp @@ -56,7 +56,7 @@ struct A { clang_analyzer_dump(__FUNCTION__); clang_analyzer_dump(__PRETTY_FUNCTION__); #ifdef ANALYZER_MS - // expected-warning@-4 {{&Element{"A::A",0 S64b,char}}} + // expected-warning@-4 {{&Element{"A",0 S64b,char}}} // expected-warning@-4 {{&Element{"A::A",0 S64b,char}}} #else // expected-warning@-7 {{&Element{"A",0 S64b,char}}} @@ -80,7 +80,7 @@ struct A { clang_analyzer_dump(__FUNCTION__); clang_analyzer_dump(__PRETTY_FUNCTION__); #ifdef ANALYZER_MS - // expected-warning@-4 {{&Element{"A::~A",0 S64b,char}}} + // expected-warning@-4 {{&Element{"~A",0 S64b,char}}} // expected-warning@-4 {{&Element{"A::~A",0 S64b,char}}} #else // expected-warning@-7 {{&Element{"~A",0 S64b,char}}} diff --git a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp index 78fa7c378c88d5..1982a3eeb94129 100644 --- a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp +++ b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s -// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | llvm-cxxfilt -n | FileCheck %s --check-prefix DEMANGLED +// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | llvm-cxxfilt -n | FileCheck %s template<typename T> struct wrapper1 { diff --git a/clang/test/CodeGenCXX/predefined-expr.cpp b/clang/test/CodeGenCXX/predefined-expr.cpp index af76e0538a9ec9..7f4863aa2066cf 100644 --- a/clang/test/CodeGenCXX/predefined-expr.cpp +++ b/clang/test/CodeGenCXX/predefined-expr.cpp @@ -5,8 +5,6 @@ // CHECK-DAG: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00" // CHECK-DAG: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00" -// CHECK-DAG: private unnamed_addr constant [43 x i8] c"TestClass<class UnitTestNative>::TestClass\00" -// CHECK-DAG: private unnamed_addr constant [10 x i8] c"TestClass\00" // CHECK-DAG: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00" // CHECK-DAG: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00" // CHECK-DAG: private unnamed_addr constant [103 x i8] c"static void ClassWithTemplateTemplateParam<char>::staticMember() [T = char, Param = NS::ClassTemplate]\00" @@ -458,21 +456,6 @@ class SpecializedClassTemplate<int> } }; - -template <class T> -class TestClass { -public: - TestClass() { - const char* expected = "TestClass<class UnitTestNative>::TestClass"; - if (strcmp(expected,__FUNCTION__)==0) - printf("PASSED\n"); - else - printf("FAILED %s\n",__FUNCTION__); - } -}; - -class UnitTestNative {}; - int main() { ClassInAnonymousNamespace anonymousNamespace; anonymousNamespace.anonymousNamespaceFunction(); @@ -553,7 +536,6 @@ int main() { SpecializedClassTemplate<char> sct2; sct2.memberFunctionTemplate('0', 0.0); - TestClass<UnitTestNative> t; return 0; } diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index d4d4c8fa650e1a..043e67164cf1ef 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -423,10 +423,17 @@ constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) { constexpr const char *get_function() { return __func__; } +#ifdef MS constexpr bool test_function() { + return !is_equal(__func__, test_func_simple()) && + !is_equal(get_function(), test_func_simple()); +} +#else + constexpr bool test_function() { return is_equal(__func__, test_func_simple()) && !is_equal(get_function(), test_func_simple()); } +#endif static_assert(test_function()); template <class T, class U = SL> @@ -463,8 +470,73 @@ void ctor_tests() { constexpr SL global_sl = SL::current(); static_assert(is_equal(global_sl.function(), "")); +template <class T> +class TestBI { +public: + TestBI() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI")); + static_assert(is_equal(__func__, "TestBI")); +#else + static_assert(is_equal(__func__, "TestBI")); + static_assert(is_equal(__func__, "TestBI")); +#endif + } +}; + +template <class T> +class TestClass { +public: + TestClass() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestClass<class test_func::C>::TestClass")); + static_assert(is_equal(__func__, "TestClass")); +#else + static_assert(is_equal(__func__, "TestClass")); + static_assert(is_equal(__func__, "TestClass")); +#endif + } +}; + +template <class T> +class TestStruct { +public: + TestStruct() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestStruct<struct test_func::S>::TestStruct")); + static_assert(is_equal(__func__, "TestStruct")); +#else + static_assert(is_equal(__func__, "TestStruct")); + static_assert(is_equal(__func__, "TestStruct")); +#endif + } +}; + +template <class T> +class TestEnum { +public: + TestEnum() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestEnum<enum test_func::E>::TestEnum")); + static_assert(is_equal(__func__, "TestEnum")); +#else + static_assert(is_equal(__func__, "TestEnum")); + static_assert(is_equal(__func__, "TestEnum")); +#endif + } +}; + + class C {}; +struct S {}; +enum E {}; + +test_func::TestBI<int> t1; +test_func::TestClass<C> t2; +test_func::TestStruct<S> t3; +test_func::TestEnum<E> t4; } // namespace test_func + //===----------------------------------------------------------------------===// // __builtin_FUNCSIG() //===----------------------------------------------------------------------===// >From 3bb28808e98d37de55a7bf2a2bdc524f7219bb18 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 27 Sep 2023 12:03:33 -0700 Subject: [PATCH 02/12] Fix format. --- clang/test/SemaCXX/source_location.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 043e67164cf1ef..815eed121637ad 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -526,7 +526,7 @@ class TestEnum { } }; - class C {}; +class C {}; struct S {}; enum E {}; >From 3ea6fa5703e6f3d387c87d8c544fceea439f4ee7 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 27 Sep 2023 12:38:50 -0700 Subject: [PATCH 03/12] Add undefined field. --- clang/include/clang/AST/PrettyPrinter.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index cee3cce7729c30..17d4e1a326d31c 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -76,8 +76,8 @@ struct PrintingPolicy { SuppressImplicitBase(false), FullyQualifiedName(false), PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false), - CleanUglifiedParameters(false), EntireContentsOfLargeArray(true), - UseEnumerators(true) {} + UseClassForTemplateArgument(false), CleanUglifiedParameters(false), + EntireContentsOfLargeArray(true), UseEnumerators(true) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -291,6 +291,10 @@ struct PrintingPolicy { /// parameters. unsigned AlwaysIncludeTypeForTemplateArgument : 1; + // Prints "class" keyword before type template arguments. This is used when + // printing a function via the _FUNCTION__ or __func__ macro in MSVC mode. + unsigned UseClassForTemplateArgument : 1; + /// Whether to strip underscores when printing reserved parameter names. /// e.g. std::vector<class _Tp> becomes std::vector<class Tp>. /// This only affects parameter names, and so describes a compatible API. >From dbcf81cf9e91e9b14470d9e18ac1dec2b3f6dfca Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Fri, 29 Sep 2023 10:51:51 -0700 Subject: [PATCH 04/12] Fixed a few issues. --- clang/lib/AST/Expr.cpp | 12 +++++++++--- clang/lib/AST/TypePrinter.cpp | 2 +- clang/test/SemaCXX/source_location.cpp | 12 ++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 4eef890154e87b..4157f8cf96dbbe 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -773,8 +773,9 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { const auto &LO = Context.getLangOpts(); - if (((IK == Function || IK == Func) && !LO.MicrosoftExt) || - ((IK == LFunction || IK == Func) && LO.MicrosoftExt)) + if (IK == Func || IK == Function && !LO.MicrosoftExt) + return FD->getNameAsString(); + if (IK == LFunction && LO.MicrosoftExt) return FD->getNameAsString(); SmallString<256> Name; @@ -804,7 +805,6 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { Policy.Callbacks = &PrettyCB; if (IK == Function && LO.MicrosoftExt) { Policy.UseClassForTemplateArgument = LO.MicrosoftExt; - Policy.MSVCFormatting = LO.MicrosoftExt; } std::string Proto; llvm::raw_string_ostream POut(Proto); @@ -832,6 +832,12 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { FD->printQualifiedName(POut, Policy); + if (IK == Function) { + POut.flush(); + Out << Proto; + return std::string(Name); + } + POut << "("; if (FT) { for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) { diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 8a7cf85cdf126b..83b73a67af4a4a 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2220,7 +2220,7 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, if (!FirstArg) OS << Comma; - if (Policy.MSVCFormatting && Policy.UseClassForTemplateArgument && + if (Policy.UseClassForTemplateArgument && Argument.getKind() == TemplateArgument::Type && !Argument.getAsType()->isBuiltinType()) { const Type *Ty = Argument.getAsType().getTypePtr(); diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 29ce9c1697835d..d2b4856c1e8302 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -721,8 +721,16 @@ constexpr bool test_in_func() { static_assert(is_equal(b.a.f, "test_func_passed.cpp")); static_assert(is_equal(b.a.f2, "test_func_passed.cpp")); static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp")); +#ifdef MS + static_assert(is_equal(b.a.func, "test_out_of_line_init::test_in_func")); +#else static_assert(is_equal(b.a.func, "test_in_func")); +#endif +#ifdef MS + static_assert(is_equal(b.a.func2, "test_out_of_line_init::test_in_func")); +#else static_assert(is_equal(b.a.func2, "test_in_func")); +#endif static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()")); return true; } @@ -749,7 +757,11 @@ constexpr InInit II; static_assert(II.l == 5200, ""); static_assert(is_equal(II.f, "in_init.cpp")); +#ifdef MS +static_assert(is_equal(II.func, "test_global_scope::InInit::InInit")); +#else static_assert(is_equal(II.func, "InInit")); +#endif #line 5400 struct AggInit { >From e6708c0af2f81e734c39a0e38742d8f8f1f166f8 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Sat, 30 Sep 2023 09:03:29 -0700 Subject: [PATCH 05/12] Fix LIT test literals.cpp. --- clang/test/AST/Interp/literals.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index ceda59405ea910..a4af7ab29a91cd 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1046,7 +1046,7 @@ namespace PredefinedExprs { static_assert(strings_match(__FUNCSIG__, "void __cdecl PredefinedExprs::foo(void)"), ""); static_assert(strings_match(L__FUNCSIG__, L"void __cdecl PredefinedExprs::foo(void)"), ""); static_assert(strings_match(L__FUNCTION__, L"foo"), ""); - static_assert(strings_match(__FUNCTION__, "foo"), ""); + static_assert(strings_match(__FUNCTION__, "PredefinedExprs::foo"), ""); static_assert(strings_match(__func__, "foo"), ""); static_assert(strings_match(__PRETTY_FUNCTION__, "void PredefinedExprs::foo()"), ""); } @@ -1058,9 +1058,9 @@ namespace PredefinedExprs { // expected-warning {{result unused}} return __FUNCTION__[index]; } - static_assert(heh(0) == 'h', ""); - static_assert(heh(1) == 'e', ""); - static_assert(heh(2) == 'h', ""); + static_assert(heh(0) == 'P', ""); + static_assert(heh(1) == 'r', ""); + static_assert(heh(2) == 'e', ""); #endif } >From 473ff2b127bf22138ef6be4a74c16dca190c383d Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Sat, 30 Sep 2023 10:36:53 -0700 Subject: [PATCH 06/12] Reverted LIT Test. --- clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp index 1982a3eeb94129..4fd4a51bc3ee18 100644 --- a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp +++ b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s -// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | llvm-cxxfilt -n | FileCheck %s +// RUN: %clang_cc1 -std=c++20 -fclang-abi-compat=latest -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -std=c++20 -fclang-abi-compat=latest -emit-llvm %s -o - -triple=x86_64-linux-gnu | llvm-cxxfilt -n | FileCheck %s --check-prefix DEMANGLED template<typename T> struct wrapper1 { >From 39c795ba37565c44235d5d615aabb0add84cc748 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 2 Oct 2023 08:49:19 -0700 Subject: [PATCH 07/12] Added release note as requested by reviewer. --- clang/docs/ReleaseNotes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 68172d5317a13b..7b03e9a341e9ac 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -266,6 +266,7 @@ Bug Fixes in This Version (`#64836 <https://github.com/llvm/llvm-project/issues/64836>`_) - Clang now allows an ``_Atomic`` qualified integer in a switch statement. Fixes (`#65557 <https://github.com/llvm/llvm-project/issues/65557>`_) +- Fix value of predefined macro ``__FUNCTION__`` to match MSVC's value. Fixes (`#66114 <https://github.com/llvm/llvm-project/issues/66114>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >From d64c4caf5a6534077158a096c3d88e8859baa462 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 2 Oct 2023 13:37:19 -0700 Subject: [PATCH 08/12] Addressed review comments. --- clang/docs/ReleaseNotes.rst | 3 ++- clang/include/clang/AST/PrettyPrinter.h | 8 ++++---- clang/lib/AST/Expr.cpp | 2 +- clang/lib/AST/TypePrinter.cpp | 27 ++++++++----------------- clang/test/SemaCXX/source_location.cpp | 6 +++--- 5 files changed, 18 insertions(+), 28 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7b03e9a341e9ac..c805f2073f0038 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -266,7 +266,8 @@ Bug Fixes in This Version (`#64836 <https://github.com/llvm/llvm-project/issues/64836>`_) - Clang now allows an ``_Atomic`` qualified integer in a switch statement. Fixes (`#65557 <https://github.com/llvm/llvm-project/issues/65557>`_) -- Fix value of predefined macro ``__FUNCTION__`` to match MSVC's value. Fixes (`#66114 <https://github.com/llvm/llvm-project/issues/66114>`_) +- Fix value of predefined macro ``__FUNCTION__`` to match MSVC's value. Fixes + (`#66114 <https://github.com/llvm/llvm-project/issues/66114>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 17d4e1a326d31c..f1216b4fd9861b 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -76,7 +76,7 @@ struct PrintingPolicy { SuppressImplicitBase(false), FullyQualifiedName(false), PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false), - UseClassForTemplateArgument(false), CleanUglifiedParameters(false), + ForcePrintingAsElaboratedType(false), CleanUglifiedParameters(false), EntireContentsOfLargeArray(true), UseEnumerators(true) {} /// Adjust this printing policy for cases where it's known that we're @@ -291,9 +291,9 @@ struct PrintingPolicy { /// parameters. unsigned AlwaysIncludeTypeForTemplateArgument : 1; - // Prints "class" keyword before type template arguments. This is used when - // printing a function via the _FUNCTION__ or __func__ macro in MSVC mode. - unsigned UseClassForTemplateArgument : 1; + // Whether to print the type as an elaborated type. This is used when + // printing a function via the _FUNCTION__ macro in MSVC mode. + unsigned ForcePrintingAsElaboratedType : 1; /// Whether to strip underscores when printing reserved parameter names. /// e.g. std::vector<class _Tp> becomes std::vector<class Tp>. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 4157f8cf96dbbe..dd95b12c3a5952 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -804,7 +804,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { PrettyCallbacks PrettyCB(Context.getLangOpts()); Policy.Callbacks = &PrettyCB; if (IK == Function && LO.MicrosoftExt) { - Policy.UseClassForTemplateArgument = LO.MicrosoftExt; + Policy.ForcePrintingAsElaboratedType = LO.MicrosoftExt; } std::string Proto; llvm::raw_string_ostream POut(Proto); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 83b73a67af4a4a..ee0159c1a020e1 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2220,27 +2220,16 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, if (!FirstArg) OS << Comma; - if (Policy.UseClassForTemplateArgument && + if (Policy.ForcePrintingAsElaboratedType && Argument.getKind() == TemplateArgument::Type && - !Argument.getAsType()->isBuiltinType()) { - const Type *Ty = Argument.getAsType().getTypePtr(); - const char *kw; - if (Ty->isStructureType()) - kw = "struct "; - else if (Ty->isClassType()) - kw = "class "; - else if (Ty->isUnionType()) - kw = "union "; - else if (Ty->isEnumeralType()) - kw = "enum "; - else - llvm_unreachable("argument type not expected"); - OS << kw; + !Argument.getAsType()->isBuiltinType()) + OS << Argument.getAsType().getAsString().data(); + else { } - // Tries to print the argument with location info if exists. - printArgument(Arg, Policy, ArgOS, - TemplateParameterList::shouldIncludeTypeForArgument( - Policy, TPL, ParmIndex)); + // Tries to print the argument with location info if exists. + printArgument(Arg, Policy, ArgOS, + TemplateParameterList::shouldIncludeTypeForArgument( + Policy, TPL, ParmIndex)); } StringRef ArgString = ArgOS.str(); diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index d2b4856c1e8302..7c70aec84903a9 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -478,7 +478,7 @@ class TestBI { static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI")); static_assert(is_equal(__func__, "TestBI")); #else - static_assert(is_equal(__func__, "TestBI")); + static_assert(is_equal(__FUNCTION__, "TestBI")); static_assert(is_equal(__func__, "TestBI")); #endif } @@ -492,7 +492,7 @@ class TestClass { static_assert(is_equal(__FUNCTION__, "test_func::TestClass<class test_func::C>::TestClass")); static_assert(is_equal(__func__, "TestClass")); #else - static_assert(is_equal(__func__, "TestClass")); + static_assert(is_equal(__FUNCTION__, "TestClass")); static_assert(is_equal(__func__, "TestClass")); #endif } @@ -520,7 +520,7 @@ class TestEnum { static_assert(is_equal(__FUNCTION__, "test_func::TestEnum<enum test_func::E>::TestEnum")); static_assert(is_equal(__func__, "TestEnum")); #else - static_assert(is_equal(__func__, "TestEnum")); + static_assert(is_equal(__FUNCTION__, "TestEnum")); static_assert(is_equal(__func__, "TestEnum")); #endif } >From 45f78db1f47d8b22caecd983bc7e7161bcc15c16 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 3 Oct 2023 10:58:00 -0700 Subject: [PATCH 09/12] Addressed review comments. --- clang/include/clang/AST/Expr.h | 3 +- clang/lib/AST/Expr.cpp | 20 +++++++++----- clang/lib/AST/TypePrinter.cpp | 3 +- clang/lib/Sema/SemaExpr.cpp | 6 +++- clang/test/SemaCXX/source_location.cpp | 38 +++++++------------------- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 1c717b520dd87c..530a2d92e666c2 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2058,7 +2058,8 @@ class PredefinedExpr final return getIdentKindName(getIdentKind()); } - static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl); + static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl, + bool ForceElaboratedPrinting = false); SourceLocation getBeginLoc() const { return getLocation(); } SourceLocation getEndLoc() const { return getLocation(); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index dd95b12c3a5952..1979cdf6796357 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -724,7 +724,8 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) { // FIXME: Maybe this should use DeclPrinter with a special "print predefined // expr" policy instead. -std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { +std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl, + bool ForceElaboratedPrinting) { ASTContext &Context = CurrentDecl->getASTContext(); if (IK == PredefinedExpr::FuncDName) { @@ -773,10 +774,16 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { const auto &LO = Context.getLangOpts(); - if (IK == Func || IK == Function && !LO.MicrosoftExt) - return FD->getNameAsString(); - if (IK == LFunction && LO.MicrosoftExt) - return FD->getNameAsString(); + if (ForceElaboratedPrinting) { + if ((IK == Func || IK == Function) && !LO.MicrosoftExt) + return FD->getNameAsString(); + if (IK == LFunction && LO.MicrosoftExt) + return FD->getNameAsString(); + } else { + if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual && + IK != FuncSig && IK != LFuncSig) + return FD->getNameAsString(); + } SmallString<256> Name; llvm::raw_svector_ostream Out(Name); @@ -803,9 +810,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { PrintingPolicy Policy(Context.getLangOpts()); PrettyCallbacks PrettyCB(Context.getLangOpts()); Policy.Callbacks = &PrettyCB; - if (IK == Function && LO.MicrosoftExt) { + if (IK == Function && ForceElaboratedPrinting) Policy.ForcePrintingAsElaboratedType = LO.MicrosoftExt; - } std::string Proto; llvm::raw_string_ostream POut(Proto); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index ee0159c1a020e1..ac420bca3e4b02 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2224,8 +2224,7 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, Argument.getKind() == TemplateArgument::Type && !Argument.getAsType()->isBuiltinType()) OS << Argument.getAsType().getAsString().data(); - else { - } + else // Tries to print the argument with location info if exists. printArgument(Arg, Policy, ArgOS, TemplateParameterList::shouldIncludeTypeForArgument( diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 92496b03ecabe5..b77c49aa013e32 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3727,7 +3727,11 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - auto Str = PredefinedExpr::ComputeName(IK, currentDecl); + bool ForceElaboratedPrinting = false; + if (IK == PredefinedExpr::IdentKind::Function && getLangOpts().MicrosoftExt) + ForceElaboratedPrinting = true; + auto Str = + PredefinedExpr::ComputeName(IK, currentDecl, ForceElaboratedPrinting); unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 7c70aec84903a9..2e38a8e0bebf2b 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -423,17 +423,10 @@ constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) { constexpr const char *get_function() { return __func__; } -#ifdef MS constexpr bool test_function() { - return !is_equal(__func__, test_func_simple()) && - !is_equal(get_function(), test_func_simple()); -} -#else - constexpr bool test_function() { return is_equal(__func__, test_func_simple()) && !is_equal(get_function(), test_func_simple()); } -#endif static_assert(test_function()); template <class T, class U = SL> @@ -475,11 +468,11 @@ class TestBI { public: TestBI() { #ifdef MS - static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI")); - static_assert(is_equal(__func__, "TestBI")); + static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI")); + static_assert(is_equal(__func__, "TestBI")); #else - static_assert(is_equal(__FUNCTION__, "TestBI")); - static_assert(is_equal(__func__, "TestBI")); + static_assert(is_equal(__FUNCTION__, "TestBI")); + static_assert(is_equal(__func__, "TestBI")); #endif } }; @@ -506,7 +499,7 @@ class TestStruct { static_assert(is_equal(__FUNCTION__, "test_func::TestStruct<struct test_func::S>::TestStruct")); static_assert(is_equal(__func__, "TestStruct")); #else - static_assert(is_equal(__func__, "TestStruct")); + static_assert(is_equal(__FUNCTION__, "TestStruct")); static_assert(is_equal(__func__, "TestStruct")); #endif } @@ -530,12 +523,13 @@ class C {}; struct S {}; enum E {}; -test_func::TestBI<int> t1; -test_func::TestClass<C> t2; -test_func::TestStruct<S> t3; -test_func::TestEnum<E> t4; + } // namespace test_func +test_func::TestBI<int> t1; +test_func::TestClass<test_func::C> t2; +test_func::TestStruct<test_func::S> t3; +test_func::TestEnum<test_func::E> t4; //===----------------------------------------------------------------------===// // __builtin_FUNCSIG() @@ -721,16 +715,8 @@ constexpr bool test_in_func() { static_assert(is_equal(b.a.f, "test_func_passed.cpp")); static_assert(is_equal(b.a.f2, "test_func_passed.cpp")); static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp")); -#ifdef MS - static_assert(is_equal(b.a.func, "test_out_of_line_init::test_in_func")); -#else static_assert(is_equal(b.a.func, "test_in_func")); -#endif -#ifdef MS - static_assert(is_equal(b.a.func2, "test_out_of_line_init::test_in_func")); -#else static_assert(is_equal(b.a.func2, "test_in_func")); -#endif static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()")); return true; } @@ -757,11 +743,7 @@ constexpr InInit II; static_assert(II.l == 5200, ""); static_assert(is_equal(II.f, "in_init.cpp")); -#ifdef MS -static_assert(is_equal(II.func, "test_global_scope::InInit::InInit")); -#else static_assert(is_equal(II.func, "InInit")); -#endif #line 5400 struct AggInit { >From 998bc11f0e2e252a1c711ffc21d58c7df864f8dd Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 3 Oct 2023 11:01:51 -0700 Subject: [PATCH 10/12] Cleaned up RN file. --- clang/docs/ReleaseNotes.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d2ab32e52e17ba..4d6479c0147d73 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -281,7 +281,6 @@ Bug Fixes in This Version Fixes (`#67603 <https://github.com/llvm/llvm-project/issues/67603>`_) - Fixes a crash caused by a multidimensional array being captured by a lambda (`#67722 <https://github.com/llvm/llvm-project/issues/67722>`_). ->>>>>>> e271bc1be7ea5b160f70cff28d7d50e03b7a6ca8 Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >From a564cdabd9be9e99f457d7143f71ea3dd5a7eb27 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 4 Oct 2023 05:10:52 -0700 Subject: [PATCH 11/12] Fix format in RN. --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4d6479c0147d73..9b6bc160fa9310 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -274,7 +274,7 @@ Bug Fixes in This Version (`#62945 <https://github.com/llvm/llvm-project/issues/62945>`_) - Clang now allows an ``_Atomic`` qualified integer in a switch statement. Fixes (`#65557 <https://github.com/llvm/llvm-project/issues/65557>`_) -- Fix value of predefined macro ``__FUNCTION__`` to match MSVC's value. Fixes +- Fix value of predefined macro ``__FUNCTION__`` to match MSVC's value. Fixes (`#66114 <https://github.com/llvm/llvm-project/issues/66114>`_) - Fixes crash when trying to obtain the common sugared type of `decltype(instantiation-dependent-expr)`. >From a6100a3a6bc4918c093ae1bb82e5b4075cc87dbf Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 13 Feb 2024 06:45:13 -0800 Subject: [PATCH 12/12] Fixed merge errors. --- clang/docs/ReleaseNotes.rst | 1 - clang/lib/AST/Expr.cpp | 14 -------------- clang/lib/AST/TypePrinter.cpp | 1 - 3 files changed, 16 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bd803c30cfbaf0..dd790236e03bb7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -175,7 +175,6 @@ Bug Fixes in This Version - Clang now doesn't produce false-positive warning `-Wconstant-logical-operand` for logical operators in C23. Fixes (`#64356 <https://github.com/llvm/llvm-project/issues/64356>`_). ->>>>>>> upstream/main Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b68afa330ba0cc..211997f730dab3 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -714,25 +714,11 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, return std::string(Out.str()); } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { -<<<<<<< HEAD - const auto &LO = Context.getLangOpts(); - if (ForceElaboratedPrinting) { - if ((IK == Func || IK == Function) && !LO.MicrosoftExt) - return FD->getNameAsString(); - if (IK == LFunction && LO.MicrosoftExt) - return FD->getNameAsString(); - } else { - if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual && - IK != FuncSig && IK != LFuncSig) - return FD->getNameAsString(); - } -======= if (IK != PredefinedIdentKind::PrettyFunction && IK != PredefinedIdentKind::PrettyFunctionNoVirtual && IK != PredefinedIdentKind::FuncSig && IK != PredefinedIdentKind::LFuncSig) return FD->getNameAsString(); ->>>>>>> upstream/main SmallString<256> Name; llvm::raw_svector_ostream Out(Name); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index e44a5df7a9fae6..aeda0da4223b6b 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2237,7 +2237,6 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, llvm::SmallVector<TemplateArgument, 8> OrigArgs; for (const TA &A : Args) OrigArgs.push_back(getArgument(A)); - while (!Args.empty() && getArgument(Args.back()).getIsDefaulted()) Args = Args.drop_back(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits