https://github.com/upsj updated https://github.com/llvm/llvm-project/pull/177442
>From 0b997c6786c68aa29278d27900ce1ecd2e09bb32 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel <[email protected]> Date: Thu, 22 Jan 2026 20:20:45 +0100 Subject: [PATCH 1/3] format files --- clang/lib/Tooling/Transformer/RangeSelector.cpp | 3 +-- clang/unittests/Tooling/RangeSelectorTest.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp index 68b16f91652fb..8ba065f98864e 100644 --- a/clang/lib/Tooling/Transformer/RangeSelector.cpp +++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp @@ -405,8 +405,7 @@ RangeSelector transformer::constructExprArgs(std::string ID) { namespace { // Returns the range of the elements of the initializer list. Includes all // source between the braces. -CharSourceRange getElementsRange(const MatchResult &, - const InitListExpr &E) { +CharSourceRange getElementsRange(const MatchResult &, const InitListExpr &E) { return CharSourceRange::getCharRange(E.getLBraceLoc().getLocWithOffset(1), E.getRBraceLoc()); } diff --git a/clang/unittests/Tooling/RangeSelectorTest.cpp b/clang/unittests/Tooling/RangeSelectorTest.cpp index 9e83fa1dc92ff..543902bcafeab 100644 --- a/clang/unittests/Tooling/RangeSelectorTest.cpp +++ b/clang/unittests/Tooling/RangeSelectorTest.cpp @@ -173,7 +173,7 @@ TEST(RangeSelectorTest, AfterOp) { )cc"; StringRef Call = "call"; TestMatch Match = matchCode(Code, callExpr().bind(Call)); - const auto* E = Match.Result.Nodes.getNodeAs<Expr>(Call); + const auto *E = Match.Result.Nodes.getNodeAs<Expr>(Call); assert(E != nullptr); const SourceRange Range = E->getSourceRange(); // The end token, a right paren, is one character wide, so advance by one, >From 6c2dbd6cbf7df3998c6121d9902cb77e1310c217 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel <[email protected]> Date: Thu, 22 Jan 2026 20:22:37 +0100 Subject: [PATCH 2/3] [clang] add transformer range selector for spelled ranges This supports transformer-based text replacements inside macro definitions using the new spelled(...) function as well as retrieving names of declarations inside macro definitions using the existing name(...) function --- .../clang/Tooling/Transformer/RangeSelector.h | 5 ++ .../lib/Tooling/Transformer/RangeSelector.cpp | 23 +++++++++ clang/unittests/Tooling/RangeSelectorTest.cpp | 48 +++++++++++++++---- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h b/clang/include/clang/Tooling/Transformer/RangeSelector.h index c76a5106edd65..24cdc9133b5f3 100644 --- a/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h @@ -111,6 +111,11 @@ RangeSelector elseBranch(std::string ID); /// source), if `S` is an expansion, and `S` itself, otherwise. Corresponds to /// `SourceManager::getExpansionRange`. RangeSelector expansion(RangeSelector S); + +/// Selects the spelling range of `S` if it is spelled inside a macro +/// definition, and `S` itself, otherwise. Corresponds to calling +/// `SourceManager::getSpellingLoc` on both endpoints. +RangeSelector spelled(RangeSelector S); } // namespace transformer } // namespace clang diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp index 8ba065f98864e..9e40620e1f91d 100644 --- a/clang/lib/Tooling/Transformer/RangeSelector.cpp +++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp @@ -257,6 +257,8 @@ RangeSelector transformer::name(std::string ID) { if (!D->getDeclName().isIdentifier()) return missingPropertyError(ID, "name", "identifier"); SourceLocation L = D->getLocation(); + // the name may be spelled in a macro + L = Result.SourceManager->getSpellingLoc(L); auto R = CharSourceRange::getTokenRange(L, L); // Verify that the range covers exactly the name. // FIXME: extend this code to support cases like `operator +` or @@ -436,3 +438,24 @@ RangeSelector transformer::expansion(RangeSelector S) { return Result.SourceManager->getExpansionRange(*SRange); }; } + +RangeSelector transformer::spelled(RangeSelector S) { + return [S](const MatchResult &Result) -> Expected<CharSourceRange> { + Expected<CharSourceRange> SRange = S(Result); + if (!SRange) + return SRange.takeError(); + if (!SRange->isTokenRange()) { + return invalidArgumentError("spelled: only supports token ranges"); + } + const auto &SM = *Result.SourceManager; + const auto B = SRange->getBegin(); + const auto E = SRange->getEnd(); + if (SM.getFileID(B) != SM.getFileID(E)) { + return invalidArgumentError( + "spelled: range crosses file/macro boundaries"); + } + return CharSourceRange( + SourceRange(SM.getSpellingLoc(B), SM.getSpellingLoc(E)), + SRange->isTokenRange()); + }; +} diff --git a/clang/unittests/Tooling/RangeSelectorTest.cpp b/clang/unittests/Tooling/RangeSelectorTest.cpp index 543902bcafeab..7fd71177dfc03 100644 --- a/clang/unittests/Tooling/RangeSelectorTest.cpp +++ b/clang/unittests/Tooling/RangeSelectorTest.cpp @@ -583,19 +583,14 @@ TEST(RangeSelectorTest, NameOpDeclInMacroArg) { EXPECT_THAT_EXPECTED(select(name(ID), Match), HasValue("x")); } -TEST(RangeSelectorTest, NameOpDeclInMacroBodyError) { +TEST(RangeSelectorTest, NameSpelledInMacro) { StringRef Code = R"cc( - #define MACRO int x; - MACRO + #define NAME foo; + int NAME; )cc"; const char *ID = "id"; TestMatch Match = matchCode(Code, varDecl().bind(ID)); - EXPECT_THAT_EXPECTED( - name(ID)(Match.Result), - Failed<StringError>(testing::Property( - &StringError::getMessage, - AllOf(HasSubstr("range selected by name(node id="), - HasSubstr("' is different from decl name 'x'"))))); + EXPECT_THAT_EXPECTED(select(name(ID), Match), HasValue("foo")); } TEST(RangeSelectorTest, CallArgsOp) { @@ -924,6 +919,41 @@ TEST(RangeSelectorTest, ExpansionOpPartial) { HasValue("BADDECL(x * x)")); } +TEST(RangeSelectorTest, SpelledFullyInMacro) { + StringRef Code = R"cc( + #define MACRO int i; + MACRO + )cc"; + const char *ID = "id"; + TestMatch Match = matchCode(Code, varDecl().bind(ID)); + EXPECT_THAT_EXPECTED(select(spelled(node(ID)), Match), HasValue("int i")); +} + +TEST(RangeSelectorTest, SpelledWithArgumentInMacro) { + StringRef Code = R"cc( + #define MACRO(T) void foo(T t); + MACRO(int) + )cc"; + const char *ID = "id"; + TestMatch Match = matchCode(Code, functionDecl().bind(ID)); + EXPECT_THAT_EXPECTED(select(spelled(node(ID)), Match), + HasValue("void foo(T t)")); +} + +TEST(RangeSelectorTest, SpelledPartiallyInMacro) { + StringRef Code = R"cc( + #define MACRO(T) foo(T t); int i; + void MACRO(int); + )cc"; + const char *ID = "id"; + TestMatch Match = matchCode(Code, functionDecl().bind(ID)); + EXPECT_THAT_EXPECTED( + select(spelled(node(ID)), Match), + Failed<StringError>(testing::Property( + &StringError::getMessage, + HasSubstr("spelled: range crosses file/macro boundaries")))); +} + TEST(RangeSelectorTest, IfBoundOpBound) { StringRef Code = R"cc( int f() { >From 93fdc614c2940054ae07c51a299783b696c6d2a3 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel <[email protected]> Date: Fri, 23 Jan 2026 17:14:43 +0100 Subject: [PATCH 3/3] [clang] less restrictive spelled(...) selector --- clang/lib/Tooling/Transformer/RangeSelector.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp index 9e40620e1f91d..6e5d12a500bac 100644 --- a/clang/lib/Tooling/Transformer/RangeSelector.cpp +++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp @@ -444,16 +444,9 @@ RangeSelector transformer::spelled(RangeSelector S) { Expected<CharSourceRange> SRange = S(Result); if (!SRange) return SRange.takeError(); - if (!SRange->isTokenRange()) { - return invalidArgumentError("spelled: only supports token ranges"); - } const auto &SM = *Result.SourceManager; const auto B = SRange->getBegin(); const auto E = SRange->getEnd(); - if (SM.getFileID(B) != SM.getFileID(E)) { - return invalidArgumentError( - "spelled: range crosses file/macro boundaries"); - } return CharSourceRange( SourceRange(SM.getSpellingLoc(B), SM.getSpellingLoc(E)), SRange->isTokenRange()); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
