Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FunctionDecl::getFunctionTypeLoc: ignore function type attributes #118420

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

v01dXYZ
Copy link
Contributor

@v01dXYZ v01dXYZ commented Dec 3, 2024

Related to #118290.

Copy link

github-actions bot commented Dec 3, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@v01dXYZ v01dXYZ force-pushed the clang-func-decl-get-func-type-loc-when-func-attributes branch from c7e93d1 to b6f0130 Compare December 3, 2024 04:20

TypeLoc TL = TSI->getTypeLoc().IgnoreParens();

// ignore function type attributes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there other sugars we need to ignore? e.g., a ParenType via:

void (foo)(int f) {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. But to implement it in its updated form, I mimicked getAsAdjusted. So currently, it supports ParenType and AttributedType. I think I should add MacroQualifiedType for example.


// ignore function type attributes
while (auto ATL = TL.getAs<AttributedTypeLoc>())
TL = ATL.getModifiedLoc();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't THINK we want this? We want to keep around the 'type' as modified by the attributed type (so if it is no_return, we want to make sure we have a noreturn function type for example). So I would think we would want the Equivalent type here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad I've made this error. I'll start by adding your example as a test.

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needs tests here, plus perhaps a release note if this is something externally visible.

@v01dXYZ
Copy link
Contributor Author

v01dXYZ commented Dec 12, 2024

I've got to squash and reword the commits. Also, I'll add a line to the release stating now FunctionDecl getFunctionTypeLoc/getReturrnLoc now supports AnnotatedTypes.

@v01dXYZ v01dXYZ marked this pull request as ready for review December 16, 2024 14:26
@llvmbot llvmbot added clang Clang issues not falling into any other category clang-tools-extra clangd clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 16, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 16, 2024

@llvm/pr-subscribers-clang

Author: Robert Dazi (v01dXYZ)

Changes

Related to #118290.


Full diff: https://github.com/llvm/llvm-project/pull/118420.diff

3 Files Affected:

  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+8-6)
  • (modified) clang/lib/AST/Decl.cpp (+19-2)
  • (modified) clang/unittests/AST/AttrTest.cpp (+78)
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index 77d78b8777fe30..030e4995777060 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) {
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 741e908cf9bc56..dcc2240c599b9c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3876,8 +3876,25 @@ 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();
+  FunctionTypeLoc FTL;
+
+  while (!(FTL = TL.getAs<FunctionTypeLoc>())) {
+    if (const auto PTL = TL.getAs<ParenTypeLoc>())
+      TL = PTL.getInnerLoc();
+    else if (const auto ATL = TL.getAs<AttributedTypeLoc>())
+      TL = ATL.getEquivalentTypeLoc();
+    else if (const auto MQTL = TL.getAs<MacroQualifiedTypeLoc>())
+      TL = MQTL.getInnerLoc();
+    else
+      break;
+  }
+
+  return FTL;
 }
 
 SourceRange FunctionDecl::getReturnTypeSourceRange() const {
diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp
index 46c3f5729021ec..3be362895b77e8 100644
--- a/clang/unittests/AST/AttrTest.cpp
+++ b/clang/unittests/AST/AttrTest.cpp
@@ -86,6 +86,23 @@ 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();
+    __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");
 
   {
@@ -153,6 +170,67 @@ 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->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);
+  }
+
+  {
+    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).
+  //
+  // 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, 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).
+  //
+  // 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", "-fsyntax-only", "-fobjc-runtime=macosx-10.7"},
+      "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;

@llvmbot
Copy link
Member

llvmbot commented Dec 16, 2024

@llvm/pr-subscribers-clang-tools-extra

Author: Robert Dazi (v01dXYZ)

Changes

Related to #118290.


Full diff: https://github.com/llvm/llvm-project/pull/118420.diff

3 Files Affected:

  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+8-6)
  • (modified) clang/lib/AST/Decl.cpp (+19-2)
  • (modified) clang/unittests/AST/AttrTest.cpp (+78)
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index 77d78b8777fe30..030e4995777060 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) {
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 741e908cf9bc56..dcc2240c599b9c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3876,8 +3876,25 @@ 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();
+  FunctionTypeLoc FTL;
+
+  while (!(FTL = TL.getAs<FunctionTypeLoc>())) {
+    if (const auto PTL = TL.getAs<ParenTypeLoc>())
+      TL = PTL.getInnerLoc();
+    else if (const auto ATL = TL.getAs<AttributedTypeLoc>())
+      TL = ATL.getEquivalentTypeLoc();
+    else if (const auto MQTL = TL.getAs<MacroQualifiedTypeLoc>())
+      TL = MQTL.getInnerLoc();
+    else
+      break;
+  }
+
+  return FTL;
 }
 
 SourceRange FunctionDecl::getReturnTypeSourceRange() const {
diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp
index 46c3f5729021ec..3be362895b77e8 100644
--- a/clang/unittests/AST/AttrTest.cpp
+++ b/clang/unittests/AST/AttrTest.cpp
@@ -86,6 +86,23 @@ 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();
+    __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");
 
   {
@@ -153,6 +170,67 @@ 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->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);
+  }
+
+  {
+    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).
+  //
+  // 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, 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).
+  //
+  // 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", "-fsyntax-only", "-fobjc-runtime=macosx-10.7"},
+      "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;

@llvmbot
Copy link
Member

llvmbot commented Dec 16, 2024

@llvm/pr-subscribers-clangd

Author: Robert Dazi (v01dXYZ)

Changes

Related to #118290.


Full diff: https://github.com/llvm/llvm-project/pull/118420.diff

3 Files Affected:

  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+8-6)
  • (modified) clang/lib/AST/Decl.cpp (+19-2)
  • (modified) clang/unittests/AST/AttrTest.cpp (+78)
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index 77d78b8777fe30..030e4995777060 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) {
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 741e908cf9bc56..dcc2240c599b9c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3876,8 +3876,25 @@ 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();
+  FunctionTypeLoc FTL;
+
+  while (!(FTL = TL.getAs<FunctionTypeLoc>())) {
+    if (const auto PTL = TL.getAs<ParenTypeLoc>())
+      TL = PTL.getInnerLoc();
+    else if (const auto ATL = TL.getAs<AttributedTypeLoc>())
+      TL = ATL.getEquivalentTypeLoc();
+    else if (const auto MQTL = TL.getAs<MacroQualifiedTypeLoc>())
+      TL = MQTL.getInnerLoc();
+    else
+      break;
+  }
+
+  return FTL;
 }
 
 SourceRange FunctionDecl::getReturnTypeSourceRange() const {
diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp
index 46c3f5729021ec..3be362895b77e8 100644
--- a/clang/unittests/AST/AttrTest.cpp
+++ b/clang/unittests/AST/AttrTest.cpp
@@ -86,6 +86,23 @@ 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();
+    __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");
 
   {
@@ -153,6 +170,67 @@ 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->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);
+  }
+
+  {
+    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).
+  //
+  // 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, 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).
+  //
+  // 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", "-fsyntax-only", "-fobjc-runtime=macosx-10.7"},
+      "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;

@HighCommander4
Copy link
Collaborator

Clangd changes LGTM

@v01dXYZ
Copy link
Contributor Author

v01dXYZ commented Dec 16, 2024

Reminder to myself: the documentation comment for getFunctionTypeLoc maybe needs to be modified to indicate support for annotated function.

The comment doesn't seem to need any modifications (actually this patch makes the function behaves closer to the comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category clang-tools-extra clangd
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants