Skip to content

Commit cf12f37

Browse files
committed
[clang] Turn invented Exprs' source locations in __builtin_dump_struct to empty
This reflects the comment in llvm#71366 (comment). 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.
1 parent 89ecb80 commit cf12f37

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,33 @@ TEST(InlayHints, RestrictRange) {
17241724
ElementsAre(labelIs(": int"), labelIs(": char")));
17251725
}
17261726

1727+
TEST(ParameterHints, PseudoObjectExpr) {
1728+
Annotations Code(R"cpp(
1729+
struct S {
1730+
__declspec(property(get=GetX, put=PutX)) int x[];
1731+
int GetX(int y, int z) { return 42 + y; }
1732+
void PutX(int y) { x = $one[[y]]; } // FIXME: Undesired `x = y: y` for this ill-formed expression.
1733+
};
1734+
1735+
int printf(const char *Format, ...);
1736+
1737+
int main() {
1738+
S s;
1739+
__builtin_dump_struct(&s, printf); // Not `Format: __builtin_dump_struct()`
1740+
printf($Param[["Hello, %d"]], 42); // Normal calls are not affected.
1741+
return s.x[ $two[[1]] ][ $three[[2]] ]; // `x[y: 1][z: 2]`
1742+
}
1743+
)cpp");
1744+
auto TU = TestTU::withCode(Code.code());
1745+
TU.ExtraArgs.push_back("-fms-extensions");
1746+
auto AST = TU.build();
1747+
EXPECT_THAT(inlayHints(AST, std::nullopt),
1748+
ElementsAre(HintMatcher(ExpectedHint{"y: ", "one"}, Code),
1749+
HintMatcher(ExpectedHint{"Format: ", "Param"}, Code),
1750+
HintMatcher(ExpectedHint{"y: ", "two"}, Code),
1751+
HintMatcher(ExpectedHint{"z: ", "three"}, Code)));
1752+
}
1753+
17271754
TEST(ParameterHints, ArgPacksAndConstructors) {
17281755
assertParameterHints(
17291756
R"cpp(

clang/lib/Sema/SemaChecking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,13 @@ namespace {
454454
struct BuiltinDumpStructGenerator {
455455
Sema &S;
456456
CallExpr *TheCall;
457-
SourceLocation Loc = TheCall->getBeginLoc();
457+
SourceLocation Loc;
458458
SmallVector<Expr *, 32> Actions;
459459
DiagnosticErrorTrap ErrorTracker;
460460
PrintingPolicy Policy;
461461

462462
BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
463-
: S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
463+
: S(S), TheCall(TheCall), Loc(), ErrorTracker(S.getDiagnostics()),
464464
Policy(S.Context.getPrintingPolicy()) {
465465
Policy.AnonymousTagLocations = false;
466466
}
@@ -491,7 +491,7 @@ struct BuiltinDumpStructGenerator {
491491
// Register a note to explain why we're performing the call.
492492
Sema::CodeSynthesisContext Ctx;
493493
Ctx.Kind = Sema::CodeSynthesisContext::BuildingBuiltinDumpStructCall;
494-
Ctx.PointOfInstantiation = Loc;
494+
Ctx.PointOfInstantiation = TheCall->getBeginLoc();
495495
Ctx.CallArgs = Args.data();
496496
Ctx.NumCallArgs = Args.size();
497497
S.pushCodeSynthesisContext(Ctx);

0 commit comments

Comments
 (0)