diff --git a/clang/lib/Tooling/Transformer/Stencil.cpp b/clang/lib/Tooling/Transformer/Stencil.cpp --- a/clang/lib/Tooling/Transformer/Stencil.cpp +++ b/clang/lib/Tooling/Transformer/Stencil.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Expr.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/Transformer/SourceCode.h" #include "clang/Tooling/Transformer/SourceCodeBuilders.h" @@ -226,12 +227,14 @@ Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match, std::string *Result) { - auto Range = Data.Selector(Match); - if (!Range) - return Range.takeError(); - if (auto Err = tooling::validateEditRange(*Range, *Match.SourceManager)) + auto RawRange = Data.Selector(Match); + if (!RawRange) + return RawRange.takeError(); + CharSourceRange Range = Lexer::makeFileCharRange( + *RawRange, *Match.SourceManager, Match.Context->getLangOpts()); + if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager)) return Err; - *Result += tooling::getText(*Range, *Match.Context); + *Result += tooling::getText(Range, *Match.Context); return Error::success(); } diff --git a/clang/unittests/Tooling/StencilTest.cpp b/clang/unittests/Tooling/StencilTest.cpp --- a/clang/unittests/Tooling/StencilTest.cpp +++ b/clang/unittests/Tooling/StencilTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Transformer/Stencil.h" +#include "clang/AST/ASTTypeTraits.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/FixIt.h" #include "clang/Tooling/Tooling.h" @@ -373,6 +374,48 @@ testExpr(Id, "3;", run(SimpleFn), "Bound"); } +TEST_F(StencilTest, CatOfMacroRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO 3.77 + double foo(double d); + foo(MACRO);)cpp"; + + auto StmtMatch = + matchStmt(Snippet, callExpr(callee(functionDecl(hasName("foo"))), + argumentCountIs(1), + hasArgument(0, expr().bind("arg")))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("arg")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("MACRO")); +} + +TEST_F(StencilTest, CatOfMacroArgRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO(a, b) a + b + MACRO(2, 3);)cpp"; + + auto StmtMatch = + matchStmt(Snippet, binaryOperator(hasRHS(expr().bind("rhs")))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("rhs")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("3")); +} + +TEST_F(StencilTest, CatOfMacroArgSubRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO(a, b) a + b + int foo(int); + MACRO(2, foo(3));)cpp"; + + auto StmtMatch = matchStmt( + Snippet, binaryOperator(hasRHS(callExpr( + callee(functionDecl(hasName("foo"))), argumentCountIs(1), + hasArgument(0, expr().bind("arg")))))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("arg")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("3")); +} + TEST_F(StencilTest, CatOfInvalidRangeFails) { StringRef Snippet = R"cpp( #define MACRO (3.77)