@@ -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
171211TEST (Attr, RegularKeywordAttribute) {
0 commit comments