[clang] [clang-tools-extra] [clang] Turn invented Exprs' source locations in __builtin_dump_struct to empty (PR #72750)

via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 18 05:37:25 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangd

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

This reflects the comment in https://github.com/llvm/llvm-project/pull/71366#issuecomment-1817271492.

As that PR suggests, the invented CallExpr's source location previously pointed to the beginning of the `__builtin_dump_struct`. These spurious AST nodes confused clangd while displaying parameter inlay hints.

This patch takes another approach to address the same issue, by turning the location for each _argument_ within an invented call to printf to empty, (maybe) at the risk of breaking the invariant for CallExpr -- The source location for an argument could be invalid from now on.

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


2 Files Affected:

- (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+27) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+3-3) 


``````````diff
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index 20c1cdd985dbc01..47af261fad850e8 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1724,6 +1724,33 @@ TEST(InlayHints, RestrictRange) {
               ElementsAre(labelIs(": int"), labelIs(": char")));
 }
 
+TEST(ParameterHints, PseudoObjectExpr) {
+  Annotations Code(R"cpp(
+    struct S {
+      __declspec(property(get=GetX, put=PutX)) int x[];
+      int GetX(int y, int z) { return 42 + y; }
+      void PutX(int y) { x = $one[[y]]; } // FIXME: Undesired `x = y: y` for this ill-formed expression.
+    };
+
+    int printf(const char *Format, ...);
+
+    int main() {
+      S s;
+      __builtin_dump_struct(&s, printf); // Not `Format: __builtin_dump_struct()`
+      printf($Param[["Hello, %d"]], 42); // Normal calls are not affected.
+      return s.x[ $two[[1]] ][ $three[[2]] ]; // `x[y: 1][z: 2]`
+    }
+  )cpp");
+  auto TU = TestTU::withCode(Code.code());
+  TU.ExtraArgs.push_back("-fms-extensions");
+  auto AST = TU.build();
+  EXPECT_THAT(inlayHints(AST, std::nullopt),
+              ElementsAre(HintMatcher(ExpectedHint{"y: ", "one"}, Code),
+                          HintMatcher(ExpectedHint{"Format: ", "Param"}, Code),
+                          HintMatcher(ExpectedHint{"y: ", "two"}, Code),
+                          HintMatcher(ExpectedHint{"z: ", "three"}, Code)));
+}
+
 TEST(ParameterHints, ArgPacksAndConstructors) {
   assertParameterHints(
       R"cpp(
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ae588db02bbe722..5d348bd712dd104 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -454,13 +454,13 @@ namespace {
 struct BuiltinDumpStructGenerator {
   Sema &S;
   CallExpr *TheCall;
-  SourceLocation Loc = TheCall->getBeginLoc();
+  SourceLocation Loc;
   SmallVector<Expr *, 32> Actions;
   DiagnosticErrorTrap ErrorTracker;
   PrintingPolicy Policy;
 
   BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
-      : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
+      : S(S), TheCall(TheCall), Loc(), ErrorTracker(S.getDiagnostics()),
         Policy(S.Context.getPrintingPolicy()) {
     Policy.AnonymousTagLocations = false;
   }
@@ -491,7 +491,7 @@ struct BuiltinDumpStructGenerator {
     // Register a note to explain why we're performing the call.
     Sema::CodeSynthesisContext Ctx;
     Ctx.Kind = Sema::CodeSynthesisContext::BuildingBuiltinDumpStructCall;
-    Ctx.PointOfInstantiation = Loc;
+    Ctx.PointOfInstantiation = TheCall->getBeginLoc();
     Ctx.CallArgs = Args.data();
     Ctx.NumCallArgs = Args.size();
     S.pushCodeSynthesisContext(Ctx);

``````````

</details>


https://github.com/llvm/llvm-project/pull/72750


More information about the cfe-commits mailing list