118334Speter//===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===// 2132718Skan// 3132718Skan// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 418334Speter// See https://llvm.org/LICENSE.txt for license information. 550397Sobrien// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 618334Speter// 7132718Skan//===----------------------------------------------------------------------===// 818334Speter 9132718Skan#include "clang/Tooling/Transformer/RewriteRule.h" 1018334Speter#include "clang/AST/ASTTypeTraits.h" 1118334Speter#include "clang/AST/Stmt.h" 1218334Speter#include "clang/ASTMatchers/ASTMatchFinder.h" 1318334Speter#include "clang/ASTMatchers/ASTMatchers.h" 14132718Skan#include "clang/Basic/SourceLocation.h" 1518334Speter#include "clang/Tooling/Transformer/SourceCode.h" 1618334Speter#include "llvm/ADT/StringRef.h" 1718334Speter#include "llvm/Support/Errc.h" 1818334Speter#include "llvm/Support/Error.h" 1918334Speter#include <map> 20132718Skan#include <string> 2118334Speter#include <utility> 2218334Speter#include <vector> 2318334Speter 2418334Speterusing namespace clang; 2550397Sobrienusing namespace transformer; 2618334Speter 2718334Speterusing ast_matchers::MatchFinder; 2850397Sobrienusing ast_matchers::internal::DynTypedMatcher; 29132718Skan 30132718Skanusing MatchResult = MatchFinder::MatchResult; 3118334Speter 3218334Speterconst char transformer::RootID[] = "___root___"; 3318334Speter 3418334Speterstatic Expected<SmallVector<transformer::Edit, 1>> 3550397SobrientranslateEdits(const MatchResult &Result, ArrayRef<ASTEdit> ASTEdits) { 3650397Sobrien SmallVector<transformer::Edit, 1> Edits; 3790075Sobrien for (const auto &E : ASTEdits) { 3890075Sobrien Expected<CharSourceRange> Range = E.TargetRange(Result); 39132718Skan if (!Range) 40132718Skan return Range.takeError(); 41132718Skan std::optional<CharSourceRange> EditRange = 4218334Speter tooling::getFileRangeForEdit(*Range, *Result.Context); 43132718Skan // FIXME: let user specify whether to treat this case as an error or ignore 44132718Skan // it as is currently done. This behavior is problematic in that it hides 45132718Skan // failures from bad ranges. Also, the behavior here differs from 46132718Skan // `flatten`. Here, we abort (without error), whereas flatten, if it hits an 47132718Skan // empty list, does not abort. As a result, `editList({A,B})` is not 48132718Skan // equivalent to `flatten(edit(A), edit(B))`. The former will abort if `A` 49117395Skan // produces a bad range, whereas the latter will simply ignore A. 50117395Skan if (!EditRange) 51117395Skan return SmallVector<Edit, 0>(); 52117395Skan transformer::Edit T; 53117395Skan T.Kind = E.Kind; 54117395Skan T.Range = *EditRange; 55117395Skan if (E.Replacement) { 56132718Skan auto Replacement = E.Replacement->eval(Result); 57132718Skan if (!Replacement) 58132718Skan return Replacement.takeError(); 59132718Skan T.Replacement = std::move(*Replacement); 60132718Skan } 61132718Skan if (E.Note) { 62132718Skan auto Note = E.Note->eval(Result); 63132718Skan if (!Note) 64132718Skan return Note.takeError(); 65132718Skan T.Note = std::move(*Note); 66132718Skan } 67132718Skan if (E.Metadata) { 68132718Skan auto Metadata = E.Metadata(Result); 69132718Skan if (!Metadata) 70132718Skan return Metadata.takeError(); 71132718Skan T.Metadata = std::move(*Metadata); 72132718Skan } 73132718Skan Edits.push_back(std::move(T)); 74117395Skan } 75132718Skan return Edits; 76132718Skan} 77117395Skan 78132718SkanEditGenerator transformer::editList(SmallVector<ASTEdit, 1> Edits) { 79132718Skan return [Edits = std::move(Edits)](const MatchResult &Result) { 80132718Skan return translateEdits(Result, Edits); 81117395Skan }; 82132718Skan} 83132718Skan 84132718SkanEditGenerator transformer::edit(ASTEdit Edit) { 85132718Skan return [Edit = std::move(Edit)](const MatchResult &Result) { 86132718Skan return translateEdits(Result, {Edit}); 87117395Skan }; 88132718Skan} 89132718Skan 90117395SkanEditGenerator transformer::noopEdit(RangeSelector Anchor) { 91132718Skan return [Anchor = std::move(Anchor)](const MatchResult &Result) 92132718Skan -> Expected<SmallVector<transformer::Edit, 1>> { 93132718Skan Expected<CharSourceRange> Range = Anchor(Result); 94132718Skan if (!Range) 95117395Skan return Range.takeError(); 96132718Skan // In case the range is inside a macro expansion, map the location back to a 97132718Skan // "real" source location. 98132718Skan SourceLocation Begin = 99132718Skan Result.SourceManager->getSpellingLoc(Range->getBegin()); 100132718Skan Edit E; 101132718Skan // Implicitly, leave `E.Replacement` as the empty string. 102132718Skan E.Kind = EditKind::Range; 103132718Skan E.Range = CharSourceRange::getCharRange(Begin, Begin); 104132718Skan return SmallVector<Edit, 1>{E}; 105132718Skan }; 106132718Skan} 107132718Skan 108132718SkanEditGenerator 109132718Skantransformer::flattenVector(SmallVector<EditGenerator, 2> Generators) { 110117395Skan if (Generators.size() == 1) 111132718Skan return std::move(Generators[0]); 112132718Skan return 113132718Skan [Gs = std::move(Generators)]( 11418334Speter const MatchResult &Result) -> llvm::Expected<SmallVector<Edit, 1>> { 11518334Speter SmallVector<Edit, 1> AllEdits; 116132718Skan for (const auto &G : Gs) { 11718334Speter llvm::Expected<SmallVector<Edit, 1>> Edits = G(Result); 11818334Speter if (!Edits) 11918334Speter return Edits.takeError(); 12018334Speter AllEdits.append(Edits->begin(), Edits->end()); 12118334Speter } 12218334Speter return AllEdits; 12318334Speter }; 124117395Skan} 125117395Skan 126117395SkanASTEdit transformer::changeTo(RangeSelector Target, TextGenerator Replacement) { 12718334Speter ASTEdit E; 128117395Skan E.TargetRange = std::move(Target); 129117395Skan E.Replacement = std::move(Replacement); 13018334Speter return E; 13118334Speter} 13250397Sobrien 13350397SobrienASTEdit transformer::note(RangeSelector Anchor, TextGenerator Note) { 13450397Sobrien ASTEdit E; 13550397Sobrien E.TargetRange = transformer::before(Anchor); 136132718Skan E.Note = std::move(Note); 137132718Skan return E; 13850397Sobrien} 13950397Sobrien 14050397Sobriennamespace { 14152284Sobrien/// A \c TextGenerator that always returns a fixed string. 14252284Sobrienclass SimpleTextGenerator : public MatchComputation<std::string> { 143132718Skan std::string S; 14452284Sobrien 14550397Sobrienpublic: 14650397Sobrien SimpleTextGenerator(std::string S) : S(std::move(S)) {} 14790075Sobrien llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &, 14850397Sobrien std::string *Result) const override { 14950397Sobrien Result->append(S); 15050397Sobrien return llvm::Error::success(); 15150397Sobrien } 15250397Sobrien std::string toString() const override { 15350397Sobrien return (llvm::Twine("text(\"") + S + "\")").str(); 15450397Sobrien } 15550397Sobrien}; 15650397Sobrien} // namespace 15750397Sobrien 15890075Sobrienstatic TextGenerator makeText(std::string S) { 15990075Sobrien return std::make_shared<SimpleTextGenerator>(std::move(S)); 16090075Sobrien} 16190075Sobrien 16290075SobrienASTEdit transformer::remove(RangeSelector S) { 16390075Sobrien return change(std::move(S), makeText("")); 16490075Sobrien} 16590075Sobrien 166132718Skanstatic std::string formatHeaderPath(StringRef Header, IncludeFormat Format) { 16750397Sobrien switch (Format) { 16890075Sobrien case transformer::IncludeFormat::Quoted: 16950397Sobrien return Header.str(); 17050397Sobrien case transformer::IncludeFormat::Angled: 171132718Skan return ("<" + Header + ">").str(); 172132718Skan } 17350397Sobrien llvm_unreachable("Unknown transformer::IncludeFormat enum"); 17450397Sobrien} 17550397Sobrien 17650397SobrienASTEdit transformer::addInclude(RangeSelector Target, StringRef Header, 17750397Sobrien IncludeFormat Format) { 17850397Sobrien ASTEdit E; 179132718Skan E.Kind = EditKind::AddInclude; 18018334Speter E.TargetRange = Target; 18150397Sobrien E.Replacement = makeText(formatHeaderPath(Header, Format)); 18218334Speter return E; 18350397Sobrien} 18450397Sobrien 18550397SobrienEditGenerator 18618334Spetertransformer::detail::makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits) { 187132718Skan return editList(std::move(Edits)); 188132718Skan} 189132718Skan 190132718SkanEditGenerator transformer::detail::makeEditGenerator(ASTEdit Edit) { 191132718Skan return edit(std::move(Edit)); 192132718Skan} 193132718Skan 19418334SpeterRewriteRule transformer::detail::makeRule(DynTypedMatcher M, 19550397Sobrien EditGenerator Edits) { 196132718Skan RewriteRule R; 19750397Sobrien R.Cases = {{std::move(M), std::move(Edits)}}; 19850397Sobrien return R; 19918334Speter} 20018334Speter 20150397SobrienRewriteRule transformer::makeRule(ast_matchers::internal::DynTypedMatcher M, 20250397Sobrien std::initializer_list<ASTEdit> Edits) { 20350397Sobrien return detail::makeRule(std::move(M), 20450397Sobrien detail::makeEditGenerator(std::move(Edits))); 20550397Sobrien} 206132718Skan 20718334Speternamespace { 20850397Sobrien 20990075Sobrien/// Unconditionally binds the given node set before trying `InnerMatcher` and 21050397Sobrien/// keeps the bound nodes on a successful match. 21150397Sobrientemplate <typename T> 21290075Sobrienclass BindingsMatcher : public ast_matchers::internal::MatcherInterface<T> { 213117395Skan ast_matchers::BoundNodes Nodes; 21418334Speter const ast_matchers::internal::Matcher<T> InnerMatcher; 21550397Sobrien 21650397Sobrienpublic: 21750397Sobrien explicit BindingsMatcher(ast_matchers::BoundNodes Nodes, 21850397Sobrien ast_matchers::internal::Matcher<T> InnerMatcher) 21950397Sobrien : Nodes(std::move(Nodes)), InnerMatcher(std::move(InnerMatcher)) {} 22050397Sobrien 22150397Sobrien bool matches( 22250397Sobrien const T &Node, ast_matchers::internal::ASTMatchFinder *Finder, 223117395Skan ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override { 224117395Skan ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); 22590075Sobrien for (const auto &N : Nodes.getMap()) 22650397Sobrien Result.setBinding(N.first, N.second); 22750397Sobrien if (InnerMatcher.matches(Node, Finder, &Result)) { 22850397Sobrien *Builder = std::move(Result); 22950397Sobrien return true; 23050397Sobrien } 23150397Sobrien return false; 23290075Sobrien } 23390075Sobrien}; 23490075Sobrien 23590075Sobrien/// Matches nodes of type T that have at least one descendant node for which the 23690075Sobrien/// given inner matcher matches. Will match for each descendant node that 237117395Skan/// matches. Based on ForEachDescendantMatcher, but takes a dynamic matcher, 23896263Sobrien/// instead of a static one, because it is used by RewriteRule, which carries 23996263Sobrien/// (only top-level) dynamic matchers. 24090075Sobrientemplate <typename T> 24190075Sobrienclass DynamicForEachDescendantMatcher 242117395Skan : public ast_matchers::internal::MatcherInterface<T> { 24390075Sobrien const DynTypedMatcher DescendantMatcher; 24450397Sobrien 24550397Sobrienpublic: 24650397Sobrien explicit DynamicForEachDescendantMatcher(DynTypedMatcher DescendantMatcher) 24790075Sobrien : DescendantMatcher(std::move(DescendantMatcher)) {} 24890075Sobrien 24990075Sobrien bool matches( 25090075Sobrien const T &Node, ast_matchers::internal::ASTMatchFinder *Finder, 25190075Sobrien ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override { 25290075Sobrien return Finder->matchesDescendantOf( 25390075Sobrien Node, this->DescendantMatcher, Builder, 25490075Sobrien ast_matchers::internal::ASTMatchFinder::BK_All); 25590075Sobrien } 25690075Sobrien}; 25790075Sobrien 25852284Sobrientemplate <typename T> 25950397Sobrienast_matchers::internal::Matcher<T> 26050397SobrienforEachDescendantDynamically(ast_matchers::BoundNodes Nodes, 26150397Sobrien DynTypedMatcher M) { 26250397Sobrien return ast_matchers::internal::makeMatcher(new BindingsMatcher<T>( 26350397Sobrien std::move(Nodes), 26450397Sobrien ast_matchers::internal::makeMatcher( 26550397Sobrien new DynamicForEachDescendantMatcher<T>(std::move(M))))); 26650397Sobrien} 26790075Sobrien 26850397Sobrienclass ApplyRuleCallback : public MatchFinder::MatchCallback { 26950397Sobrienpublic: 27050397Sobrien ApplyRuleCallback(RewriteRule Rule) : Rule(std::move(Rule)) {} 27150397Sobrien 272132718Skan template <typename T> 27350397Sobrien void registerMatchers(const ast_matchers::BoundNodes &Nodes, 27490075Sobrien MatchFinder *MF) { 27550397Sobrien for (auto &Matcher : transformer::detail::buildMatchers(Rule)) 27650397Sobrien MF->addMatcher(forEachDescendantDynamically<T>(Nodes, Matcher), this); 27718334Speter } 27818334Speter 27918334Speter void run(const MatchFinder::MatchResult &Result) override { 28018334Speter if (!Edits) 28118334Speter return; 28218334Speter size_t I = transformer::detail::findSelectedCase(Result, Rule); 28318334Speter auto Transformations = Rule.Cases[I].Edits(Result); 28418334Speter if (!Transformations) { 28518334Speter Edits = Transformations.takeError(); 28618334Speter return; 28718334Speter } 28818334Speter Edits->append(Transformations->begin(), Transformations->end()); 28918334Speter } 29018334Speter 29118334Speter RewriteRule Rule; 29218334Speter 29318334Speter // Initialize to a non-error state. 294132718Skan Expected<SmallVector<Edit, 1>> Edits = SmallVector<Edit, 1>(); 29518334Speter}; 29618334Speter} // namespace 29718334Speter 29818334Spetertemplate <typename T> 29918334Speterllvm::Expected<SmallVector<clang::transformer::Edit, 1>> 30018334SpeterrewriteDescendantsImpl(const T &Node, RewriteRule Rule, 30118334Speter const MatchResult &Result) { 30218334Speter ApplyRuleCallback Callback(std::move(Rule)); 30318334Speter MatchFinder Finder; 30418334Speter Callback.registerMatchers<T>(Result.Nodes, &Finder); 30518334Speter Finder.match(Node, *Result.Context); 30618334Speter return std::move(Callback.Edits); 30718334Speter} 30818334Speter 30950397Sobrienllvm::Expected<SmallVector<clang::transformer::Edit, 1>> 31050397Sobrientransformer::detail::rewriteDescendants(const Decl &Node, RewriteRule Rule, 31118334Speter const MatchResult &Result) { 312117395Skan return rewriteDescendantsImpl(Node, std::move(Rule), Result); 313117395Skan} 314117395Skan 31550397Sobrienllvm::Expected<SmallVector<clang::transformer::Edit, 1>> 316132718Skantransformer::detail::rewriteDescendants(const Stmt &Node, RewriteRule Rule, 317132718Skan const MatchResult &Result) { 318132718Skan return rewriteDescendantsImpl(Node, std::move(Rule), Result); 319132718Skan} 32050397Sobrien 321132718Skanllvm::Expected<SmallVector<clang::transformer::Edit, 1>> 322132718Skantransformer::detail::rewriteDescendants(const TypeLoc &Node, RewriteRule Rule, 323132718Skan const MatchResult &Result) { 32450397Sobrien return rewriteDescendantsImpl(Node, std::move(Rule), Result); 32550397Sobrien} 326117395Skan 327117395Skanllvm::Expected<SmallVector<clang::transformer::Edit, 1>> 328117395Skantransformer::detail::rewriteDescendants(const DynTypedNode &DNode, 329117395Skan RewriteRule Rule, 330117395Skan const MatchResult &Result) { 331117395Skan if (const auto *Node = DNode.get<Decl>()) 332117395Skan return rewriteDescendantsImpl(*Node, std::move(Rule), Result); 333117395Skan if (const auto *Node = DNode.get<Stmt>()) 334117395Skan return rewriteDescendantsImpl(*Node, std::move(Rule), Result); 335117395Skan if (const auto *Node = DNode.get<TypeLoc>()) 336117395Skan return rewriteDescendantsImpl(*Node, std::move(Rule), Result); 337117395Skan 33850397Sobrien return llvm::make_error<llvm::StringError>( 33950397Sobrien llvm::errc::invalid_argument, 34050397Sobrien "type unsupported for recursive rewriting, Kind=" + 34150397Sobrien DNode.getNodeKind().asStringRef()); 34250397Sobrien} 34350397Sobrien 34450397SobrienEditGenerator transformer::rewriteDescendants(std::string NodeId, 34550397Sobrien RewriteRule Rule) { 34650397Sobrien return [NodeId = std::move(NodeId), 34750397Sobrien Rule = std::move(Rule)](const MatchResult &Result) 34850397Sobrien -> llvm::Expected<SmallVector<clang::transformer::Edit, 1>> { 34950397Sobrien const ast_matchers::BoundNodes::IDToNodeMap &NodesMap = 35050397Sobrien Result.Nodes.getMap(); 35150397Sobrien auto It = NodesMap.find(NodeId); 35250397Sobrien if (It == NodesMap.end()) 35390075Sobrien return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument, 35450397Sobrien "ID not bound: " + NodeId); 35550397Sobrien return detail::rewriteDescendants(It->second, std::move(Rule), Result); 35650397Sobrien }; 35750397Sobrien} 35850397Sobrien 35950397Sobrienvoid transformer::addInclude(RewriteRuleBase &Rule, StringRef Header, 36050397Sobrien IncludeFormat Format) { 36150397Sobrien for (auto &Case : Rule.Cases) 36250397Sobrien Case.Edits = flatten(std::move(Case.Edits), addInclude(Header, Format)); 36350397Sobrien} 36450397Sobrien 36590075Sobrien#ifndef NDEBUG 36690075Sobrien// Filters for supported matcher kinds. FIXME: Explicitly list the allowed kinds 36790075Sobrien// (all node matcher types except for `QualType` and `Type`), rather than just 36890075Sobrien// banning `QualType` and `Type`. 369132718Skanstatic bool hasValidKind(const DynTypedMatcher &M) { 370132718Skan return !M.canConvertTo<QualType>(); 371132718Skan} 372132718Skan#endif 373117395Skan 37450397Sobrien// Binds each rule's matcher to a unique (and deterministic) tag based on 37550397Sobrien// `TagBase` and the id paired with the case. All of the returned matchers have 376132718Skan// their traversal kind explicitly set, either based on a pre-set kind or to the 377132718Skan// provided `DefaultTraversalKind`. 37850397Sobrienstatic std::vector<DynTypedMatcher> taggedMatchers( 37990075Sobrien StringRef TagBase, 38090075Sobrien const SmallVectorImpl<std::pair<size_t, RewriteRule::Case>> &Cases, 38190075Sobrien TraversalKind DefaultTraversalKind) { 38290075Sobrien std::vector<DynTypedMatcher> Matchers; 38350397Sobrien Matchers.reserve(Cases.size()); 38490075Sobrien for (const auto &Case : Cases) { 385132718Skan std::string Tag = (TagBase + Twine(Case.first)).str(); 386132718Skan // HACK: Many matchers are not bindable, so ensure that tryBind will work. 38750397Sobrien DynTypedMatcher BoundMatcher(Case.second.Matcher); 38850397Sobrien BoundMatcher.setAllowBind(true); 38990075Sobrien auto M = *BoundMatcher.tryBind(Tag); 390117395Skan Matchers.push_back(!M.getTraversalKind() 391117395Skan ? M.withTraversalKind(DefaultTraversalKind) 39290075Sobrien : std::move(M)); 393132718Skan } 394132718Skan return Matchers; 39590075Sobrien} 39690075Sobrien 39790075Sobrien// Simply gathers the contents of the various rules into a single rule. The 39890075Sobrien// actual work to combine these into an ordered choice is deferred to matcher 399132718Skan// registration. 400132718Skantemplate <> 40190075SobrienRewriteRuleWith<void> 40290075Sobrientransformer::applyFirst(ArrayRef<RewriteRuleWith<void>> Rules) { 40350397Sobrien RewriteRule R; 404132718Skan for (auto &Rule : Rules) 40550397Sobrien R.Cases.append(Rule.Cases.begin(), Rule.Cases.end()); 40690075Sobrien return R; 40750397Sobrien} 40890075Sobrien 40990075Sobrienstd::vector<DynTypedMatcher> 41090075Sobrientransformer::detail::buildMatchers(const RewriteRuleBase &Rule) { 41190075Sobrien // Map the cases into buckets of matchers -- one for each "root" AST kind, 41290075Sobrien // which guarantees that they can be combined in a single anyOf matcher. Each 41390075Sobrien // case is paired with an identifying number that is converted to a string id 41490075Sobrien // in `taggedMatchers`. 41590075Sobrien std::map<ASTNodeKind, 41650397Sobrien SmallVector<std::pair<size_t, RewriteRuleBase::Case>, 1>> 41718334Speter Buckets; 41850397Sobrien const SmallVectorImpl<RewriteRule::Case> &Cases = Rule.Cases; 41950397Sobrien for (int I = 0, N = Cases.size(); I < N; ++I) { 42050397Sobrien assert(hasValidKind(Cases[I].Matcher) && 42150397Sobrien "Matcher must be non-(Qual)Type node matcher"); 42250397Sobrien Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]); 42350397Sobrien } 42450397Sobrien 42550397Sobrien // Each anyOf explicitly controls the traversal kind. The anyOf itself is set 42650397Sobrien // to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to the kind 42750397Sobrien // of the branches. Then, each branch is either left as is, if the kind is 42850397Sobrien // already set, or explicitly set to `TK_AsIs`. We choose this setting because 42950397Sobrien // it is the default interpretation of matchers. 43050397Sobrien std::vector<DynTypedMatcher> Matchers; 43150397Sobrien for (const auto &Bucket : Buckets) { 43250397Sobrien DynTypedMatcher M = DynTypedMatcher::constructVariadic( 43350397Sobrien DynTypedMatcher::VO_AnyOf, Bucket.first, 434117395Skan taggedMatchers("Tag", Bucket.second, TK_AsIs)); 43550397Sobrien M.setAllowBind(true); 43650397Sobrien // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true. 43750397Sobrien Matchers.push_back(M.tryBind(RootID)->withTraversalKind(TK_AsIs)); 43850397Sobrien } 43990075Sobrien return Matchers; 440132718Skan} 44150397Sobrien 44250397SobrienDynTypedMatcher transformer::detail::buildMatcher(const RewriteRuleBase &Rule) { 44350397Sobrien std::vector<DynTypedMatcher> Ms = buildMatchers(Rule); 444132718Skan assert(Ms.size() == 1 && "Cases must have compatible matchers."); 44550397Sobrien return Ms[0]; 44650397Sobrien} 44750397Sobrien 44850397SobrienSourceLocation transformer::detail::getRuleMatchLoc(const MatchResult &Result) { 44950397Sobrien auto &NodesMap = Result.Nodes.getMap(); 45050397Sobrien auto Root = NodesMap.find(RootID); 45150397Sobrien assert(Root != NodesMap.end() && "Transformation failed: missing root node."); 452132718Skan std::optional<CharSourceRange> RootRange = tooling::getFileRangeForEdit( 45350397Sobrien CharSourceRange::getTokenRange(Root->second.getSourceRange()), 45450397Sobrien *Result.Context); 45550397Sobrien if (RootRange) 456132718Skan return RootRange->getBegin(); 45750397Sobrien // The match doesn't have a coherent range, so fall back to the expansion 458132718Skan // location as the "beginning" of the match. 45950397Sobrien return Result.SourceManager->getExpansionLoc( 46050397Sobrien Root->second.getSourceRange().getBegin()); 461132718Skan} 46250397Sobrien 46350397Sobrien// Finds the case that was "selected" -- that is, whose matcher triggered the 46450397Sobrien// `MatchResult`. 46550397Sobriensize_t transformer::detail::findSelectedCase(const MatchResult &Result, 46650397Sobrien const RewriteRuleBase &Rule) { 46752284Sobrien if (Rule.Cases.size() == 1) 46852284Sobrien return 0; 46952284Sobrien 470122180Skan auto &NodesMap = Result.Nodes.getMap(); 47152284Sobrien for (size_t i = 0, N = Rule.Cases.size(); i < N; ++i) { 47252284Sobrien std::string Tag = ("Tag" + Twine(i)).str(); 47352284Sobrien if (NodesMap.find(Tag) != NodesMap.end()) 47452284Sobrien return i; 47552284Sobrien } 47650397Sobrien llvm_unreachable("No tag found for this rule."); 47750397Sobrien} 47850397Sobrien