[clang] FunctionDecl::getFunctionTypeLoc: ignore function type attributes (PR #118420)
Robert Dazi via cfe-commits
cfe-commits at lists.llvm.org
Sat Dec 7 19:15:05 PST 2024
https://github.com/v01dXYZ updated https://github.com/llvm/llvm-project/pull/118420
>From b6f013097c0003e37800ad13b420e50e3c84511b Mon Sep 17 00:00:00 2001
From: v01dxyz <v01dxyz at v01d.xyz>
Date: Tue, 3 Dec 2024 04:52:33 +0100
Subject: [PATCH 1/4] 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 741e908cf9bc56..7df66b3bb7e14d 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 <v01dxyz at v01d.xyz>
Date: Sun, 8 Dec 2024 02:16:44 +0100
Subject: [PATCH 2/4] 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 7df66b3bb7e14d..2ec5f5753427de 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 46c3f5729021ec..6cf879c4012510 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 <v01dxyz at v01d.xyz>
Date: Sun, 8 Dec 2024 02:55:33 +0100
Subject: [PATCH 3/4] 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 2ec5f5753427de..110ef70562c72d 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 <v01dxyz at v01d.xyz>
Date: Sun, 8 Dec 2024 03:00:32 +0100
Subject: [PATCH 4/4] 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 6cf879c4012510..9fc1a294529b0b 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) {
More information about the cfe-commits
mailing list