https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/118420
>From b6f013097c0003e37800ad13b420e50e3c84511b Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Tue, 3 Dec 2024 04:52:33 +0100 Subject: [PATCH 1/8] FunctionDecl::getFunctionTypeLoc: ignore function type attributes --- clang/lib/AST/Decl.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 741e908cf9bc5..7df66b3bb7e14 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3876,8 +3876,17 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { const TypeSourceInfo *TSI = getTypeSourceInfo(); - return TSI ? TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>() - : FunctionTypeLoc(); + + if (!TSI) + return FunctionTypeLoc(); + + TypeLoc TL = TSI->getTypeLoc().IgnoreParens(); + + // ignore function type attributes + while (auto ATL = TL.getAs<AttributedTypeLoc>()) + TL = ATL.getModifiedLoc(); + + return TL.getAs<FunctionTypeLoc>(); } SourceRange FunctionDecl::getReturnTypeSourceRange() const { >From d5faa43a7e9c27d9493b9a171fe4d283952a5103 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Sun, 8 Dec 2024 02:16:44 +0100 Subject: [PATCH 2/8] tmp: Add test and replace ignore parens by getAsAdjusted --- clang/lib/AST/Decl.cpp | 8 +------ clang/unittests/AST/AttrTest.cpp | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 7df66b3bb7e14..2ec5f5753427d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3880,13 +3880,7 @@ FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { if (!TSI) return FunctionTypeLoc(); - TypeLoc TL = TSI->getTypeLoc().IgnoreParens(); - - // ignore function type attributes - while (auto ATL = TL.getAs<AttributedTypeLoc>()) - TL = ATL.getModifiedLoc(); - - return TL.getAs<FunctionTypeLoc>(); + return TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>(); } SourceRange FunctionDecl::getReturnTypeSourceRange() const { diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 46c3f5729021e..6cf879c401251 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -86,6 +86,9 @@ TEST(Attr, AnnotateType) { struct S { int mem; }; int [[clang::annotate_type("int")]] S::* [[clang::annotate_type("ptr_to_mem")]] ptr_to_member = &S::mem; + + // Function Type Attributes + __attribute__((noreturn)) int f_noreturn(); )cpp"); { @@ -153,6 +156,42 @@ TEST(Attr, AnnotateType) { EXPECT_EQ(IntTL.getType(), AST->getASTContext().IntTy); } + { + const FunctionDecl *Func = getFunctionNode(AST.get(), "f_noreturn"); + const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); + const FunctionType *FT = FTL.getTypePtr(); + + EXPECT_TRUE(FT->getExtInfo().getNoReturn()); + } + + // The following test verifies getFunctionTypeLoc returns a type + // which takes into account the attribute (instead of only the nake + // type). + // + // This is hard to do with C/C++ because it seems using a function + // type attribute with a C/C++ -function declaration only results + // with either: + // + // 1. It does NOT produce any AttributedType (for example it only + // sets one flag of the FunctionType's ExtInfo, ie NoReturn). + // 2. It produces an AttributedType with modified type and + // equivalent type that are equal (for example, that's what + // happens with Calling Convention attributes). + // + // Fortunately, ObjC has one specific function type attribute that + // creates an AttributedType with different modified type and + // equivalent type. + auto AST_ObjC = buildASTFromCodeWithArgs(R"objc( + __attribute__((ns_returns_retained)) id f(); + )objc", {"-fobjc-arc",}, "input.mm"); + { + const FunctionDecl *f = getFunctionNode(AST_ObjC.get(), "f"); + const FunctionTypeLoc FTL = f->getFunctionTypeLoc(); + + const FunctionType *FT = FTL.getTypePtr(); + EXPECT_TRUE(FT->getExtInfo().getProducesResult()); + } + // Test type annotation on an `__auto_type` type in C mode. AST = buildASTFromCodeWithArgs(R"c( __auto_type [[clang::annotate_type("auto")]] auto_var = 1; @@ -166,6 +205,7 @@ TEST(Attr, AnnotateType) { AutoTypeLoc AutoTL; AssertAnnotatedAs(Var->getTypeSourceInfo()->getTypeLoc(), "auto", AutoTL); } + } TEST(Attr, RegularKeywordAttribute) { >From 7e647b98756f64fbcaccba808dae2abaf9bdb2d1 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Sun, 8 Dec 2024 02:55:33 +0100 Subject: [PATCH 3/8] tmp: getAsAdjusted use getModifiedLoc, replace the loop by a custom one --- clang/lib/AST/Decl.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 2ec5f5753427d..110ef70562c72 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3880,7 +3880,19 @@ FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { if (!TSI) return FunctionTypeLoc(); - return TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>(); + TypeLoc TL = TSI->getTypeLoc(); + FunctionTypeLoc FTL; + + while (!(FTL = TL.getAs<FunctionTypeLoc>())) { + if (auto PTL = TL.getAs<ParenTypeLoc>()) + TL = PTL.getInnerLoc(); + else if (auto ATL = TL.getAs<AttributedTypeLoc>()) + TL = ATL.getEquivalentTypeLoc(); + else + break; + } + + return FTL; } SourceRange FunctionDecl::getReturnTypeSourceRange() const { >From 21af94db316b2e827eeff04880e53f933c22c806 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Sun, 8 Dec 2024 03:00:32 +0100 Subject: [PATCH 4/8] tmp: fix test --- clang/unittests/AST/AttrTest.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 6cf879c401251..9fc1a294529b0 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -181,9 +181,12 @@ TEST(Attr, AnnotateType) { // Fortunately, ObjC has one specific function type attribute that // creates an AttributedType with different modified type and // equivalent type. - auto AST_ObjC = buildASTFromCodeWithArgs(R"objc( + auto AST_ObjC = buildASTFromCodeWithArgs( + R"objc( __attribute__((ns_returns_retained)) id f(); - )objc", {"-fobjc-arc",}, "input.mm"); + )objc", + {"-fobjc-arc", "-fsyntax-only", "-fobjc-runtime=macosx-10.7"}, + "input.mm"); { const FunctionDecl *f = getFunctionNode(AST_ObjC.get(), "f"); const FunctionTypeLoc FTL = f->getFunctionTypeLoc(); @@ -205,7 +208,6 @@ TEST(Attr, AnnotateType) { AutoTypeLoc AutoTL; AssertAnnotatedAs(Var->getTypeSourceInfo()->getTypeLoc(), "auto", AutoTL); } - } TEST(Attr, RegularKeywordAttribute) { >From f125b5e91a3c9fdd11077fe6acd4044128e6c2a3 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Wed, 11 Dec 2024 14:32:26 +0100 Subject: [PATCH 5/8] tmp: fix typos, add tests --- clang/unittests/AST/AttrTest.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 9fc1a294529b0..6ba07d01c4096 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -89,6 +89,7 @@ TEST(Attr, AnnotateType) { // Function Type Attributes __attribute__((noreturn)) int f_noreturn(); + __attribute__((preserve_most)) int f_cc_preserve_most(); )cpp"); { @@ -161,7 +162,15 @@ TEST(Attr, AnnotateType) { const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); const FunctionType *FT = FTL.getTypePtr(); - EXPECT_TRUE(FT->getExtInfo().getNoReturn()); + EXPECT_TRUE(FT->getNoReturnAttr()); + } + + { + const FunctionDecl *Func = getFunctionNode(AST.get(), "f_cc_preserve_most"); + const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); + const FunctionType *FT = FTL.getTypePtr(); + + EXPECT_TRUE(FT->getCallConv() == CC_PreserveMost); } // The following test verifies getFunctionTypeLoc returns a type @@ -169,7 +178,7 @@ TEST(Attr, AnnotateType) { // type). // // This is hard to do with C/C++ because it seems using a function - // type attribute with a C/C++ -function declaration only results + // type attribute with a C/C++ function declaration only results // with either: // // 1. It does NOT produce any AttributedType (for example it only >From 6d749da8e531cdf3336717e39a2ddbb13233070f Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Wed, 11 Dec 2024 17:11:41 +0100 Subject: [PATCH 6/8] Fix clangd test --- .../clangd/unittests/InlayHintTests.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 77d78b8777fe3..030e499577706 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1577,19 +1577,21 @@ TEST(TypeHints, Aliased) { } TEST(TypeHints, CallingConvention) { - // Check that we don't crash for lambdas without a FunctionTypeLoc + // Check that we don't crash for lambdas with an annotation // https://github.com/clangd/clangd/issues/2223 - std::string Code = R"cpp( + Annotations Source(R"cpp( void test() { - []() __cdecl {}; + []($lambda[[)]]__cdecl {}; } - )cpp"; - TestTU TU = TestTU::withCode(Code); + )cpp"); + TestTU TU = TestTU::withCode(Source.code()); TU.ExtraArgs.push_back("--target=x86_64-w64-mingw32"); TU.PredefineMacros = true; // for the __cdecl auto AST = TU.build(); - EXPECT_THAT(hintsOfKind(AST, InlayHintKind::Type), IsEmpty()); + EXPECT_THAT( + hintsOfKind(AST, InlayHintKind::Type), + ElementsAre(HintMatcher(ExpectedHint{"-> void", "lambda"}, Source))); } TEST(TypeHints, Decltype) { >From 3d18b0868193e56eef1b97ca67a59a55953ebd86 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Fri, 13 Dec 2024 01:35:26 +0100 Subject: [PATCH 7/8] Support MacroQualifiedTypeLoc, fix typos --- clang/lib/AST/Decl.cpp | 6 ++++-- clang/unittests/AST/AttrTest.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 110ef70562c72..dcc2240c599b9 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3884,10 +3884,12 @@ FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { FunctionTypeLoc FTL; while (!(FTL = TL.getAs<FunctionTypeLoc>())) { - if (auto PTL = TL.getAs<ParenTypeLoc>()) + if (const auto PTL = TL.getAs<ParenTypeLoc>()) TL = PTL.getInnerLoc(); - else if (auto ATL = TL.getAs<AttributedTypeLoc>()) + else if (const auto ATL = TL.getAs<AttributedTypeLoc>()) TL = ATL.getEquivalentTypeLoc(); + else if (const auto MQTL = TL.getAs<MacroQualifiedTypeLoc>()) + TL = MQTL.getInnerLoc(); else break; } diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 6ba07d01c4096..eb3cf0a64d774 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -90,6 +90,19 @@ TEST(Attr, AnnotateType) { // Function Type Attributes __attribute__((noreturn)) int f_noreturn(); __attribute__((preserve_most)) int f_cc_preserve_most(); + + #define PRESERVE_MOST __attribute__((preserve_most)) + PRESERVE_MOST int f_macro_attribue(); + + int (__attribute__((preserve_most)) f_paren_attribute)(); + + int ( + PRESERVE_MOST + ( + __attribute__((warn_unused_result)) + (f_w_paren_and_attr) + ) + ) (); )cpp"); { @@ -173,6 +186,19 @@ TEST(Attr, AnnotateType) { EXPECT_TRUE(FT->getCallConv() == CC_PreserveMost); } + { + for(auto should_have_func_type_loc: { + "f_macro_attribue", + "f_paren_attribute", + "f_w_paren_and_attr", + }) { + llvm::errs() << "O: " << should_have_func_type_loc << "\n"; + const FunctionDecl *Func = getFunctionNode(AST.get(), should_have_func_type_loc); + + EXPECT_TRUE(Func->getFunctionTypeLoc()); + } + } + // The following test verifies getFunctionTypeLoc returns a type // which takes into account the attribute (instead of only the nake // type). @@ -182,7 +208,7 @@ TEST(Attr, AnnotateType) { // with either: // // 1. It does NOT produce any AttributedType (for example it only - // sets one flag of the FunctionType's ExtInfo, ie NoReturn). + // sets one flag of the FunctionType's ExtInfo, e.g. NoReturn). // 2. It produces an AttributedType with modified type and // equivalent type that are equal (for example, that's what // happens with Calling Convention attributes). >From 94079e1922cbb14fe2d4f292de1582f31c9e6958 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Fri, 13 Dec 2024 05:20:47 +0100 Subject: [PATCH 8/8] fmt --- clang/unittests/AST/AttrTest.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index eb3cf0a64d774..3be362895b77e 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -187,13 +187,14 @@ TEST(Attr, AnnotateType) { } { - for(auto should_have_func_type_loc: { - "f_macro_attribue", - "f_paren_attribute", - "f_w_paren_and_attr", - }) { + for (auto should_have_func_type_loc : { + "f_macro_attribue", + "f_paren_attribute", + "f_w_paren_and_attr", + }) { llvm::errs() << "O: " << should_have_func_type_loc << "\n"; - const FunctionDecl *Func = getFunctionNode(AST.get(), should_have_func_type_loc); + const FunctionDecl *Func = + getFunctionNode(AST.get(), should_have_func_type_loc); EXPECT_TRUE(Func->getFunctionTypeLoc()); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits