Skip to content

Commit d5faa43

Browse files
author
v01dxyz
committed
tmp: Add test and replace ignore parens by getAsAdjusted
1 parent b6f0130 commit d5faa43

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

clang/lib/AST/Decl.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,13 +3880,7 @@ FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const {
38803880
if (!TSI)
38813881
return FunctionTypeLoc();
38823882

3883-
TypeLoc TL = TSI->getTypeLoc().IgnoreParens();
3884-
3885-
// ignore function type attributes
3886-
while (auto ATL = TL.getAs<AttributedTypeLoc>())
3887-
TL = ATL.getModifiedLoc();
3888-
3889-
return TL.getAs<FunctionTypeLoc>();
3883+
return TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>();
38903884
}
38913885

38923886
SourceRange FunctionDecl::getReturnTypeSourceRange() const {

clang/unittests/AST/AttrTest.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ TEST(Attr, AnnotateType) {
8686
struct S { int mem; };
8787
int [[clang::annotate_type("int")]]
8888
S::* [[clang::annotate_type("ptr_to_mem")]] ptr_to_member = &S::mem;
89+
90+
// Function Type Attributes
91+
__attribute__((noreturn)) int f_noreturn();
8992
)cpp");
9093

9194
{
@@ -153,6 +156,42 @@ TEST(Attr, AnnotateType) {
153156
EXPECT_EQ(IntTL.getType(), AST->getASTContext().IntTy);
154157
}
155158

159+
{
160+
const FunctionDecl *Func = getFunctionNode(AST.get(), "f_noreturn");
161+
const FunctionTypeLoc FTL = Func->getFunctionTypeLoc();
162+
const FunctionType *FT = FTL.getTypePtr();
163+
164+
EXPECT_TRUE(FT->getExtInfo().getNoReturn());
165+
}
166+
167+
// The following test verifies getFunctionTypeLoc returns a type
168+
// which takes into account the attribute (instead of only the nake
169+
// type).
170+
//
171+
// This is hard to do with C/C++ because it seems using a function
172+
// type attribute with a C/C++ -function declaration only results
173+
// with either:
174+
//
175+
// 1. It does NOT produce any AttributedType (for example it only
176+
// sets one flag of the FunctionType's ExtInfo, ie NoReturn).
177+
// 2. It produces an AttributedType with modified type and
178+
// equivalent type that are equal (for example, that's what
179+
// happens with Calling Convention attributes).
180+
//
181+
// Fortunately, ObjC has one specific function type attribute that
182+
// creates an AttributedType with different modified type and
183+
// equivalent type.
184+
auto AST_ObjC = buildASTFromCodeWithArgs(R"objc(
185+
__attribute__((ns_returns_retained)) id f();
186+
)objc", {"-fobjc-arc",}, "input.mm");
187+
{
188+
const FunctionDecl *f = getFunctionNode(AST_ObjC.get(), "f");
189+
const FunctionTypeLoc FTL = f->getFunctionTypeLoc();
190+
191+
const FunctionType *FT = FTL.getTypePtr();
192+
EXPECT_TRUE(FT->getExtInfo().getProducesResult());
193+
}
194+
156195
// Test type annotation on an `__auto_type` type in C mode.
157196
AST = buildASTFromCodeWithArgs(R"c(
158197
__auto_type [[clang::annotate_type("auto")]] auto_var = 1;
@@ -166,6 +205,7 @@ TEST(Attr, AnnotateType) {
166205
AutoTypeLoc AutoTL;
167206
AssertAnnotatedAs(Var->getTypeSourceInfo()->getTypeLoc(), "auto", AutoTL);
168207
}
208+
169209
}
170210

171211
TEST(Attr, RegularKeywordAttribute) {

0 commit comments

Comments
 (0)