summaryrefslogtreecommitdiff
path: root/lib/Tooling/Refactoring
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Tooling/Refactoring')
-rw-r--r--lib/Tooling/Refactoring/ASTSelectionRequirements.cpp2
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp2
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.cpp8
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.h51
-rw-r--r--lib/Tooling/Refactoring/RangeSelector.cpp296
-rw-r--r--lib/Tooling/Refactoring/RefactoringActions.cpp4
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp4
-rw-r--r--lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp2
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFindingAction.cpp6
-rw-r--r--lib/Tooling/Refactoring/SourceCode.cpp31
-rw-r--r--lib/Tooling/Refactoring/Stencil.cpp175
-rw-r--r--lib/Tooling/Refactoring/Transformer.cpp263
12 files changed, 18 insertions, 826 deletions
diff --git a/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp b/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
index 14fc66a979ae5..7dfd3988d9041 100644
--- a/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
+++ b/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
@@ -35,7 +35,7 @@ Expected<CodeRangeASTSelection> CodeRangeASTSelectionRequirement::evaluate(
if (!ASTSelection)
return ASTSelection.takeError();
std::unique_ptr<SelectedASTNode> StoredSelection =
- llvm::make_unique<SelectedASTNode>(std::move(*ASTSelection));
+ std::make_unique<SelectedASTNode>(std::move(*ASTSelection));
Optional<CodeRangeASTSelection> CodeRange = CodeRangeASTSelection::create(
Context.getSelectionRange(), *StoredSelection);
if (!CodeRange)
diff --git a/lib/Tooling/Refactoring/Extract/Extract.cpp b/lib/Tooling/Refactoring/Extract/Extract.cpp
index f5b94a462103f..402b561090524 100644
--- a/lib/Tooling/Refactoring/Extract/Extract.cpp
+++ b/lib/Tooling/Refactoring/Extract/Extract.cpp
@@ -13,12 +13,12 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/Refactoring/Extract/Extract.h"
-#include "SourceExtraction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring/Extract/SourceExtraction.h"
namespace clang {
namespace tooling {
diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
index 533c373e35c45..5d57ecf90a96d 100644
--- a/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
+++ b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SourceExtraction.h"
+#include "clang/Tooling/Refactoring/Extract/SourceExtraction.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
@@ -40,8 +40,12 @@ bool isSemicolonRequiredAfter(const Stmt *S) {
return isSemicolonRequiredAfter(CXXFor->getBody());
if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(S))
return isSemicolonRequiredAfter(ObjCFor->getBody());
+ if(const auto *Switch = dyn_cast<SwitchStmt>(S))
+ return isSemicolonRequiredAfter(Switch->getBody());
+ if(const auto *Case = dyn_cast<SwitchCase>(S))
+ return isSemicolonRequiredAfter(Case->getSubStmt());
switch (S->getStmtClass()) {
- case Stmt::SwitchStmtClass:
+ case Stmt::DeclStmtClass:
case Stmt::CXXTryStmtClass:
case Stmt::ObjCAtSynchronizedStmtClass:
case Stmt::ObjCAutoreleasePoolStmtClass:
diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.h b/lib/Tooling/Refactoring/Extract/SourceExtraction.h
deleted file mode 100644
index 545eb6c1a11c2..0000000000000
--- a/lib/Tooling/Refactoring/Extract/SourceExtraction.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===--- SourceExtraction.cpp - Clang refactoring library -----------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
-#define LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
-
-#include "clang/Basic/LLVM.h"
-
-namespace clang {
-
-class LangOptions;
-class SourceManager;
-class SourceRange;
-class Stmt;
-
-namespace tooling {
-
-/// Determines which semicolons should be inserted during extraction.
-class ExtractionSemicolonPolicy {
-public:
- bool isNeededInExtractedFunction() const {
- return IsNeededInExtractedFunction;
- }
-
- bool isNeededInOriginalFunction() const { return IsNeededInOriginalFunction; }
-
- /// Returns the semicolon insertion policy that is needed for extraction of
- /// the given statement from the given source range.
- static ExtractionSemicolonPolicy compute(const Stmt *S,
- SourceRange &ExtractedRange,
- const SourceManager &SM,
- const LangOptions &LangOpts);
-
-private:
- ExtractionSemicolonPolicy(bool IsNeededInExtractedFunction,
- bool IsNeededInOriginalFunction)
- : IsNeededInExtractedFunction(IsNeededInExtractedFunction),
- IsNeededInOriginalFunction(IsNeededInOriginalFunction) {}
- bool IsNeededInExtractedFunction;
- bool IsNeededInOriginalFunction;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H
diff --git a/lib/Tooling/Refactoring/RangeSelector.cpp b/lib/Tooling/Refactoring/RangeSelector.cpp
deleted file mode 100644
index 768c02e2277b3..0000000000000
--- a/lib/Tooling/Refactoring/RangeSelector.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-//===--- RangeSelector.cpp - RangeSelector implementations ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/Refactoring/RangeSelector.h"
-#include "clang/AST/Expr.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Tooling/Refactoring/SourceCode.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-#include <string>
-#include <utility>
-#include <vector>
-
-using namespace clang;
-using namespace tooling;
-
-using ast_matchers::MatchFinder;
-using ast_type_traits::ASTNodeKind;
-using ast_type_traits::DynTypedNode;
-using llvm::Error;
-using llvm::StringError;
-
-using MatchResult = MatchFinder::MatchResult;
-
-static Error invalidArgumentError(Twine Message) {
- return llvm::make_error<StringError>(llvm::errc::invalid_argument, Message);
-}
-
-static Error typeError(StringRef ID, const ASTNodeKind &Kind) {
- return invalidArgumentError("mismatched type (node id=" + ID +
- " kind=" + Kind.asStringRef() + ")");
-}
-
-static Error typeError(StringRef ID, const ASTNodeKind &Kind,
- Twine ExpectedType) {
- return invalidArgumentError("mismatched type: expected one of " +
- ExpectedType + " (node id=" + ID +
- " kind=" + Kind.asStringRef() + ")");
-}
-
-static Error missingPropertyError(StringRef ID, Twine Description,
- StringRef Property) {
- return invalidArgumentError(Description + " requires property '" + Property +
- "' (node id=" + ID + ")");
-}
-
-static Expected<DynTypedNode> getNode(const ast_matchers::BoundNodes &Nodes,
- StringRef ID) {
- auto &NodesMap = Nodes.getMap();
- auto It = NodesMap.find(ID);
- if (It == NodesMap.end())
- return invalidArgumentError("ID not bound: " + ID);
- return It->second;
-}
-
-// FIXME: handling of macros should be configurable.
-static SourceLocation findPreviousTokenStart(SourceLocation Start,
- const SourceManager &SM,
- const LangOptions &LangOpts) {
- if (Start.isInvalid() || Start.isMacroID())
- return SourceLocation();
-
- SourceLocation BeforeStart = Start.getLocWithOffset(-1);
- if (BeforeStart.isInvalid() || BeforeStart.isMacroID())
- return SourceLocation();
-
- return Lexer::GetBeginningOfToken(BeforeStart, SM, LangOpts);
-}
-
-// Finds the start location of the previous token of kind \p TK.
-// FIXME: handling of macros should be configurable.
-static SourceLocation findPreviousTokenKind(SourceLocation Start,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- tok::TokenKind TK) {
- while (true) {
- SourceLocation L = findPreviousTokenStart(Start, SM, LangOpts);
- if (L.isInvalid() || L.isMacroID())
- return SourceLocation();
-
- Token T;
- if (Lexer::getRawToken(L, T, SM, LangOpts, /*IgnoreWhiteSpace=*/true))
- return SourceLocation();
-
- if (T.is(TK))
- return T.getLocation();
-
- Start = L;
- }
-}
-
-static SourceLocation findOpenParen(const CallExpr &E, const SourceManager &SM,
- const LangOptions &LangOpts) {
- SourceLocation EndLoc =
- E.getNumArgs() == 0 ? E.getRParenLoc() : E.getArg(0)->getBeginLoc();
- return findPreviousTokenKind(EndLoc, SM, LangOpts, tok::TokenKind::l_paren);
-}
-
-RangeSelector tooling::before(RangeSelector Selector) {
- return [Selector](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<CharSourceRange> SelectedRange = Selector(Result);
- if (!SelectedRange)
- return SelectedRange.takeError();
- return CharSourceRange::getCharRange(SelectedRange->getBegin());
- };
-}
-
-RangeSelector tooling::after(RangeSelector Selector) {
- return [Selector](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<CharSourceRange> SelectedRange = Selector(Result);
- if (!SelectedRange)
- return SelectedRange.takeError();
- if (SelectedRange->isCharRange())
- return CharSourceRange::getCharRange(SelectedRange->getEnd());
- return CharSourceRange::getCharRange(Lexer::getLocForEndOfToken(
- SelectedRange->getEnd(), 0, Result.Context->getSourceManager(),
- Result.Context->getLangOpts()));
- };
-}
-
-RangeSelector tooling::node(std::string ID) {
- return [ID](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<DynTypedNode> Node = getNode(Result.Nodes, ID);
- if (!Node)
- return Node.takeError();
- return Node->get<Stmt>() != nullptr && Node->get<Expr>() == nullptr
- ? getExtendedRange(*Node, tok::TokenKind::semi, *Result.Context)
- : CharSourceRange::getTokenRange(Node->getSourceRange());
- };
-}
-
-RangeSelector tooling::statement(std::string ID) {
- return [ID](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<DynTypedNode> Node = getNode(Result.Nodes, ID);
- if (!Node)
- return Node.takeError();
- return getExtendedRange(*Node, tok::TokenKind::semi, *Result.Context);
- };
-}
-
-RangeSelector tooling::range(RangeSelector Begin, RangeSelector End) {
- return [Begin, End](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<CharSourceRange> BeginRange = Begin(Result);
- if (!BeginRange)
- return BeginRange.takeError();
- Expected<CharSourceRange> EndRange = End(Result);
- if (!EndRange)
- return EndRange.takeError();
- SourceLocation B = BeginRange->getBegin();
- SourceLocation E = EndRange->getEnd();
- // Note: we are precluding the possibility of sub-token ranges in the case
- // that EndRange is a token range.
- if (Result.SourceManager->isBeforeInTranslationUnit(E, B)) {
- return invalidArgumentError("Bad range: out of order");
- }
- return CharSourceRange(SourceRange(B, E), EndRange->isTokenRange());
- };
-}
-
-RangeSelector tooling::range(std::string BeginID, std::string EndID) {
- return tooling::range(node(std::move(BeginID)), node(std::move(EndID)));
-}
-
-RangeSelector tooling::member(std::string ID) {
- return [ID](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<DynTypedNode> Node = getNode(Result.Nodes, ID);
- if (!Node)
- return Node.takeError();
- if (auto *M = Node->get<clang::MemberExpr>())
- return CharSourceRange::getTokenRange(
- M->getMemberNameInfo().getSourceRange());
- return typeError(ID, Node->getNodeKind(), "MemberExpr");
- };
-}
-
-RangeSelector tooling::name(std::string ID) {
- return [ID](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<DynTypedNode> N = getNode(Result.Nodes, ID);
- if (!N)
- return N.takeError();
- auto &Node = *N;
- if (const auto *D = Node.get<NamedDecl>()) {
- if (!D->getDeclName().isIdentifier())
- return missingPropertyError(ID, "name", "identifier");
- SourceLocation L = D->getLocation();
- auto R = CharSourceRange::getTokenRange(L, L);
- // Verify that the range covers exactly the name.
- // FIXME: extend this code to support cases like `operator +` or
- // `foo<int>` for which this range will be too short. Doing so will
- // require subcasing `NamedDecl`, because it doesn't provide virtual
- // access to the \c DeclarationNameInfo.
- if (getText(R, *Result.Context) != D->getName())
- return CharSourceRange();
- return R;
- }
- if (const auto *E = Node.get<DeclRefExpr>()) {
- if (!E->getNameInfo().getName().isIdentifier())
- return missingPropertyError(ID, "name", "identifier");
- SourceLocation L = E->getLocation();
- return CharSourceRange::getTokenRange(L, L);
- }
- if (const auto *I = Node.get<CXXCtorInitializer>()) {
- if (!I->isMemberInitializer() && I->isWritten())
- return missingPropertyError(ID, "name", "explicit member initializer");
- SourceLocation L = I->getMemberLocation();
- return CharSourceRange::getTokenRange(L, L);
- }
- return typeError(ID, Node.getNodeKind(),
- "DeclRefExpr, NamedDecl, CXXCtorInitializer");
- };
-}
-
-namespace {
-// Creates a selector from a range-selection function \p Func, which selects a
-// range that is relative to a bound node id. \c T is the node type expected by
-// \p Func.
-template <typename T, CharSourceRange (*Func)(const MatchResult &, const T &)>
-class RelativeSelector {
- std::string ID;
-
-public:
- RelativeSelector(std::string ID) : ID(std::move(ID)) {}
-
- Expected<CharSourceRange> operator()(const MatchResult &Result) {
- Expected<DynTypedNode> N = getNode(Result.Nodes, ID);
- if (!N)
- return N.takeError();
- if (const auto *Arg = N->get<T>())
- return Func(Result, *Arg);
- return typeError(ID, N->getNodeKind());
- }
-};
-} // namespace
-
-// FIXME: Change the following functions from being in an anonymous namespace
-// to static functions, after the minimum Visual C++ has _MSC_VER >= 1915
-// (equivalent to Visual Studio 2017 v15.8 or higher). Using the anonymous
-// namespace works around a bug in earlier versions.
-namespace {
-// Returns the range of the statements (all source between the braces).
-CharSourceRange getStatementsRange(const MatchResult &,
- const CompoundStmt &CS) {
- return CharSourceRange::getCharRange(CS.getLBracLoc().getLocWithOffset(1),
- CS.getRBracLoc());
-}
-} // namespace
-
-RangeSelector tooling::statements(std::string ID) {
- return RelativeSelector<CompoundStmt, getStatementsRange>(std::move(ID));
-}
-
-namespace {
-// Returns the range of the source between the call's parentheses.
-CharSourceRange getCallArgumentsRange(const MatchResult &Result,
- const CallExpr &CE) {
- return CharSourceRange::getCharRange(
- findOpenParen(CE, *Result.SourceManager, Result.Context->getLangOpts())
- .getLocWithOffset(1),
- CE.getRParenLoc());
-}
-} // namespace
-
-RangeSelector tooling::callArgs(std::string ID) {
- return RelativeSelector<CallExpr, getCallArgumentsRange>(std::move(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) {
- return CharSourceRange::getCharRange(E.getLBraceLoc().getLocWithOffset(1),
- E.getRBraceLoc());
-}
-} // namespace
-
-RangeSelector tooling::initListElements(std::string ID) {
- return RelativeSelector<InitListExpr, getElementsRange>(std::move(ID));
-}
-
-RangeSelector tooling::expansion(RangeSelector S) {
- return [S](const MatchResult &Result) -> Expected<CharSourceRange> {
- Expected<CharSourceRange> SRange = S(Result);
- if (!SRange)
- return SRange.takeError();
- return Result.SourceManager->getExpansionRange(*SRange);
- };
-}
diff --git a/lib/Tooling/Refactoring/RefactoringActions.cpp b/lib/Tooling/Refactoring/RefactoringActions.cpp
index 1a3833243ab4c..7ac723f67c047 100644
--- a/lib/Tooling/Refactoring/RefactoringActions.cpp
+++ b/lib/Tooling/Refactoring/RefactoringActions.cpp
@@ -98,8 +98,8 @@ public:
std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions() {
std::vector<std::unique_ptr<RefactoringAction>> Actions;
- Actions.push_back(llvm::make_unique<LocalRename>());
- Actions.push_back(llvm::make_unique<ExtractRefactoring>());
+ Actions.push_back(std::make_unique<LocalRename>());
+ Actions.push_back(std::make_unique<ExtractRefactoring>());
return Actions;
}
diff --git a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
index 1649513a077a2..b0634912e3fc3 100644
--- a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -266,12 +266,12 @@ private:
};
std::unique_ptr<ASTConsumer> RenamingAction::newASTConsumer() {
- return llvm::make_unique<RenamingASTConsumer>(NewNames, PrevNames, USRList,
+ return std::make_unique<RenamingASTConsumer>(NewNames, PrevNames, USRList,
FileToReplaces, PrintLocations);
}
std::unique_ptr<ASTConsumer> QualifiedRenamingAction::newASTConsumer() {
- return llvm::make_unique<USRSymbolRenamer>(NewNames, USRList, FileToReplaces);
+ return std::make_unique<USRSymbolRenamer>(NewNames, USRList, FileToReplaces);
}
} // end namespace tooling
diff --git a/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp b/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
index 8cc1ffaf44820..9e69d37e81add 100644
--- a/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
+++ b/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
@@ -25,7 +25,7 @@ SymbolOccurrence::SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,
Locations[0], Locations[0].getLocWithOffset(NamePieces[0].size()));
return;
}
- MultipleRanges = llvm::make_unique<SourceRange[]>(Locations.size());
+ MultipleRanges = std::make_unique<SourceRange[]>(Locations.size());
RangeOrNumRanges.setBegin(
SourceLocation::getFromRawEncoding(Locations.size()));
for (const auto &Loc : llvm::enumerate(Locations)) {
diff --git a/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
index 54c6f3e734b15..e26248f50c298 100644
--- a/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -102,6 +102,10 @@ public:
private:
void handleCXXRecordDecl(const CXXRecordDecl *RecordDecl) {
+ if (!RecordDecl->getDefinition()) {
+ USRSet.insert(getUSRForDecl(RecordDecl));
+ return;
+ }
RecordDecl = RecordDecl->getDefinition();
if (const auto *ClassTemplateSpecDecl =
dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl))
@@ -264,7 +268,7 @@ private:
};
std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() {
- return llvm::make_unique<NamedDeclFindingConsumer>(
+ return std::make_unique<NamedDeclFindingConsumer>(
SymbolOffsets, QualifiedNames, SpellingNames, USRList, Force,
ErrorOccurred);
}
diff --git a/lib/Tooling/Refactoring/SourceCode.cpp b/lib/Tooling/Refactoring/SourceCode.cpp
deleted file mode 100644
index 3a97e178bbd4b..0000000000000
--- a/lib/Tooling/Refactoring/SourceCode.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===--- SourceCode.cpp - Source code manipulation routines -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides functions that simplify extraction of source code.
-//
-//===----------------------------------------------------------------------===//
-#include "clang/Tooling/Refactoring/SourceCode.h"
-#include "clang/Lex/Lexer.h"
-
-using namespace clang;
-
-StringRef clang::tooling::getText(CharSourceRange Range,
- const ASTContext &Context) {
- return Lexer::getSourceText(Range, Context.getSourceManager(),
- Context.getLangOpts());
-}
-
-CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range,
- tok::TokenKind Next,
- ASTContext &Context) {
- Optional<Token> Tok = Lexer::findNextToken(
- Range.getEnd(), Context.getSourceManager(), Context.getLangOpts());
- if (!Tok || !Tok->is(Next))
- return Range;
- return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
-}
diff --git a/lib/Tooling/Refactoring/Stencil.cpp b/lib/Tooling/Refactoring/Stencil.cpp
deleted file mode 100644
index 09eca21c3cef1..0000000000000
--- a/lib/Tooling/Refactoring/Stencil.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-//===--- Stencil.cpp - Stencil implementation -------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/Refactoring/Stencil.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/Expr.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Tooling/Refactoring/SourceCode.h"
-#include "llvm/Support/Errc.h"
-#include <atomic>
-#include <memory>
-#include <string>
-
-using namespace clang;
-using namespace tooling;
-
-using ast_matchers::MatchFinder;
-using llvm::Error;
-
-// A down_cast function to safely down cast a StencilPartInterface to a subclass
-// D. Returns nullptr if P is not an instance of D.
-template <typename D> const D *down_cast(const StencilPartInterface *P) {
- if (P == nullptr || D::typeId() != P->typeId())
- return nullptr;
- return static_cast<const D *>(P);
-}
-
-static llvm::Expected<ast_type_traits::DynTypedNode>
-getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
- auto &NodesMap = Nodes.getMap();
- auto It = NodesMap.find(Id);
- if (It == NodesMap.end())
- return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
- "Id not bound: " + Id);
- return It->second;
-}
-
-namespace {
-// An arbitrary fragment of code within a stencil.
-struct RawTextData {
- explicit RawTextData(std::string T) : Text(std::move(T)) {}
- std::string Text;
-};
-
-// A debugging operation to dump the AST for a particular (bound) AST node.
-struct DebugPrintNodeOpData {
- explicit DebugPrintNodeOpData(std::string S) : Id(std::move(S)) {}
- std::string Id;
-};
-
-// The fragment of code corresponding to the selected range.
-struct SelectorOpData {
- explicit SelectorOpData(RangeSelector S) : Selector(std::move(S)) {}
- RangeSelector Selector;
-};
-} // namespace
-
-bool isEqualData(const RawTextData &A, const RawTextData &B) {
- return A.Text == B.Text;
-}
-
-bool isEqualData(const DebugPrintNodeOpData &A, const DebugPrintNodeOpData &B) {
- return A.Id == B.Id;
-}
-
-// Equality is not (yet) defined for \c RangeSelector.
-bool isEqualData(const SelectorOpData &, const SelectorOpData &) { return false; }
-
-// The `evalData()` overloads evaluate the given stencil data to a string, given
-// the match result, and append it to `Result`. We define an overload for each
-// type of stencil data.
-
-Error evalData(const RawTextData &Data, const MatchFinder::MatchResult &,
- std::string *Result) {
- Result->append(Data.Text);
- return Error::success();
-}
-
-Error evalData(const DebugPrintNodeOpData &Data,
- const MatchFinder::MatchResult &Match, std::string *Result) {
- std::string Output;
- llvm::raw_string_ostream Os(Output);
- auto NodeOrErr = getNode(Match.Nodes, Data.Id);
- if (auto Err = NodeOrErr.takeError())
- return Err;
- NodeOrErr->print(Os, PrintingPolicy(Match.Context->getLangOpts()));
- *Result += Os.str();
- return Error::success();
-}
-
-Error evalData(const SelectorOpData &Data, const MatchFinder::MatchResult &Match,
- std::string *Result) {
- auto Range = Data.Selector(Match);
- if (!Range)
- return Range.takeError();
- *Result += getText(*Range, *Match.Context);
- return Error::success();
-}
-
-template <typename T>
-class StencilPartImpl : public StencilPartInterface {
- T Data;
-
-public:
- template <typename... Ps>
- explicit StencilPartImpl(Ps &&... Args)
- : StencilPartInterface(StencilPartImpl::typeId()),
- Data(std::forward<Ps>(Args)...) {}
-
- // Generates a unique identifier for this class (specifically, one per
- // instantiation of the template).
- static const void* typeId() {
- static bool b;
- return &b;
- }
-
- Error eval(const MatchFinder::MatchResult &Match,
- std::string *Result) const override {
- return evalData(Data, Match, Result);
- }
-
- bool isEqual(const StencilPartInterface &Other) const override {
- if (const auto *OtherPtr = down_cast<StencilPartImpl>(&Other))
- return isEqualData(Data, OtherPtr->Data);
- return false;
- }
-};
-
-namespace {
-using RawText = StencilPartImpl<RawTextData>;
-using DebugPrintNodeOp = StencilPartImpl<DebugPrintNodeOpData>;
-using SelectorOp = StencilPartImpl<SelectorOpData>;
-} // namespace
-
-StencilPart Stencil::wrap(StringRef Text) {
- return stencil::text(Text);
-}
-
-StencilPart Stencil::wrap(RangeSelector Selector) {
- return stencil::selection(std::move(Selector));
-}
-
-void Stencil::append(Stencil OtherStencil) {
- for (auto &Part : OtherStencil.Parts)
- Parts.push_back(std::move(Part));
-}
-
-llvm::Expected<std::string>
-Stencil::eval(const MatchFinder::MatchResult &Match) const {
- std::string Result;
- for (const auto &Part : Parts)
- if (auto Err = Part.eval(Match, &Result))
- return std::move(Err);
- return Result;
-}
-
-StencilPart stencil::text(StringRef Text) {
- return StencilPart(std::make_shared<RawText>(Text));
-}
-
-StencilPart stencil::selection(RangeSelector Selector) {
- return StencilPart(std::make_shared<SelectorOp>(std::move(Selector)));
-}
-
-StencilPart stencil::dPrint(StringRef Id) {
- return StencilPart(std::make_shared<DebugPrintNodeOp>(Id));
-}
diff --git a/lib/Tooling/Refactoring/Transformer.cpp b/lib/Tooling/Refactoring/Transformer.cpp
deleted file mode 100644
index 8e6fe6c7a940d..0000000000000
--- a/lib/Tooling/Refactoring/Transformer.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-//===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/Refactoring/Transformer.h"
-#include "clang/AST/Expr.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Tooling/Refactoring/AtomicChange.h"
-#include "clang/Tooling/Refactoring/SourceCode.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-#include <deque>
-#include <string>
-#include <utility>
-#include <vector>
-
-using namespace clang;
-using namespace tooling;
-
-using ast_matchers::MatchFinder;
-using ast_matchers::internal::DynTypedMatcher;
-using ast_type_traits::ASTNodeKind;
-using ast_type_traits::DynTypedNode;
-using llvm::Error;
-using llvm::StringError;
-
-using MatchResult = MatchFinder::MatchResult;
-
-// Did the text at this location originate in a macro definition (aka. body)?
-// For example,
-//
-// #define NESTED(x) x
-// #define MACRO(y) { int y = NESTED(3); }
-// if (true) MACRO(foo)
-//
-// The if statement expands to
-//
-// if (true) { int foo = 3; }
-// ^ ^
-// Loc1 Loc2
-//
-// For SourceManager SM, SM.isMacroArgExpansion(Loc1) and
-// SM.isMacroArgExpansion(Loc2) are both true, but isOriginMacroBody(sm, Loc1)
-// is false, because "foo" originated in the source file (as an argument to a
-// macro), whereas isOriginMacroBody(SM, Loc2) is true, because "3" originated
-// in the definition of MACRO.
-static bool isOriginMacroBody(const clang::SourceManager &SM,
- clang::SourceLocation Loc) {
- while (Loc.isMacroID()) {
- if (SM.isMacroBodyExpansion(Loc))
- return true;
- // Otherwise, it must be in an argument, so we continue searching up the
- // invocation stack. getImmediateMacroCallerLoc() gives the location of the
- // argument text, inside the call text.
- Loc = SM.getImmediateMacroCallerLoc(Loc);
- }
- return false;
-}
-
-Expected<SmallVector<tooling::detail::Transformation, 1>>
-tooling::detail::translateEdits(const MatchResult &Result,
- llvm::ArrayRef<ASTEdit> Edits) {
- SmallVector<tooling::detail::Transformation, 1> Transformations;
- for (const auto &Edit : Edits) {
- Expected<CharSourceRange> Range = Edit.TargetRange(Result);
- if (!Range)
- return Range.takeError();
- if (Range->isInvalid() ||
- isOriginMacroBody(*Result.SourceManager, Range->getBegin()))
- return SmallVector<Transformation, 0>();
- auto Replacement = Edit.Replacement(Result);
- if (!Replacement)
- return Replacement.takeError();
- tooling::detail::Transformation T;
- T.Range = *Range;
- T.Replacement = std::move(*Replacement);
- Transformations.push_back(std::move(T));
- }
- return Transformations;
-}
-
-ASTEdit tooling::change(RangeSelector S, TextGenerator Replacement) {
- ASTEdit E;
- E.TargetRange = std::move(S);
- E.Replacement = std::move(Replacement);
- return E;
-}
-
-RewriteRule tooling::makeRule(DynTypedMatcher M, SmallVector<ASTEdit, 1> Edits,
- TextGenerator Explanation) {
- return RewriteRule{{RewriteRule::Case{
- std::move(M), std::move(Edits), std::move(Explanation), {}}}};
-}
-
-void tooling::addInclude(RewriteRule &Rule, StringRef Header,
- IncludeFormat Format) {
- for (auto &Case : Rule.Cases)
- Case.AddedIncludes.emplace_back(Header.str(), Format);
-}
-
-// Determines whether A is a base type of B in the class hierarchy, including
-// the implicit relationship of Type and QualType.
-static bool isBaseOf(ASTNodeKind A, ASTNodeKind B) {
- static auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();
- static auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();
- /// Mimic the implicit conversions of Matcher<>.
- /// - From Matcher<Type> to Matcher<QualType>
- /// - From Matcher<Base> to Matcher<Derived>
- return (A.isSame(TypeKind) && B.isSame(QualKind)) || A.isBaseOf(B);
-}
-
-// Try to find a common kind to which all of the rule's matchers can be
-// converted.
-static ASTNodeKind
-findCommonKind(const SmallVectorImpl<RewriteRule::Case> &Cases) {
- assert(!Cases.empty() && "Rule must have at least one case.");
- ASTNodeKind JoinKind = Cases[0].Matcher.getSupportedKind();
- // Find a (least) Kind K, for which M.canConvertTo(K) holds, for all matchers
- // M in Rules.
- for (const auto &Case : Cases) {
- auto K = Case.Matcher.getSupportedKind();
- if (isBaseOf(JoinKind, K)) {
- JoinKind = K;
- continue;
- }
- if (K.isSame(JoinKind) || isBaseOf(K, JoinKind))
- // JoinKind is already the lowest.
- continue;
- // K and JoinKind are unrelated -- there is no least common kind.
- return ASTNodeKind();
- }
- return JoinKind;
-}
-
-// Binds each rule's matcher to a unique (and deterministic) tag based on
-// `TagBase`.
-static std::vector<DynTypedMatcher>
-taggedMatchers(StringRef TagBase,
- const SmallVectorImpl<RewriteRule::Case> &Cases) {
- std::vector<DynTypedMatcher> Matchers;
- Matchers.reserve(Cases.size());
- size_t count = 0;
- for (const auto &Case : Cases) {
- std::string Tag = (TagBase + Twine(count)).str();
- ++count;
- auto M = Case.Matcher.tryBind(Tag);
- assert(M && "RewriteRule matchers should be bindable.");
- Matchers.push_back(*std::move(M));
- }
- return Matchers;
-}
-
-// Simply gathers the contents of the various rules into a single rule. The
-// actual work to combine these into an ordered choice is deferred to matcher
-// registration.
-RewriteRule tooling::applyFirst(ArrayRef<RewriteRule> Rules) {
- RewriteRule R;
- for (auto &Rule : Rules)
- R.Cases.append(Rule.Cases.begin(), Rule.Cases.end());
- return R;
-}
-
-static DynTypedMatcher joinCaseMatchers(const RewriteRule &Rule) {
- assert(!Rule.Cases.empty() && "Rule must have at least one case.");
- if (Rule.Cases.size() == 1)
- return Rule.Cases[0].Matcher;
-
- auto CommonKind = findCommonKind(Rule.Cases);
- assert(!CommonKind.isNone() && "Cases must have compatible matchers.");
- return DynTypedMatcher::constructVariadic(
- DynTypedMatcher::VO_AnyOf, CommonKind, taggedMatchers("Tag", Rule.Cases));
-}
-
-DynTypedMatcher tooling::detail::buildMatcher(const RewriteRule &Rule) {
- DynTypedMatcher M = joinCaseMatchers(Rule);
- M.setAllowBind(true);
- // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true.
- return *M.tryBind(RewriteRule::RootID);
-}
-
-// Finds the case that was "selected" -- that is, whose matcher triggered the
-// `MatchResult`.
-const RewriteRule::Case &
-tooling::detail::findSelectedCase(const MatchResult &Result,
- const RewriteRule &Rule) {
- if (Rule.Cases.size() == 1)
- return Rule.Cases[0];
-
- auto &NodesMap = Result.Nodes.getMap();
- for (size_t i = 0, N = Rule.Cases.size(); i < N; ++i) {
- std::string Tag = ("Tag" + Twine(i)).str();
- if (NodesMap.find(Tag) != NodesMap.end())
- return Rule.Cases[i];
- }
- llvm_unreachable("No tag found for this rule.");
-}
-
-constexpr llvm::StringLiteral RewriteRule::RootID;
-
-void Transformer::registerMatchers(MatchFinder *MatchFinder) {
- MatchFinder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
-}
-
-void Transformer::run(const MatchResult &Result) {
- if (Result.Context->getDiagnostics().hasErrorOccurred())
- return;
-
- // Verify the existence and validity of the AST node that roots this rule.
- auto &NodesMap = Result.Nodes.getMap();
- auto Root = NodesMap.find(RewriteRule::RootID);
- assert(Root != NodesMap.end() && "Transformation failed: missing root node.");
- SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
- Root->second.getSourceRange().getBegin());
- assert(RootLoc.isValid() && "Invalid location for Root node of match.");
-
- RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, Rule);
- auto Transformations = tooling::detail::translateEdits(Result, Case.Edits);
- if (!Transformations) {
- Consumer(Transformations.takeError());
- return;
- }
-
- if (Transformations->empty()) {
- // No rewrite applied (but no error encountered either).
- RootLoc.print(llvm::errs() << "note: skipping match at loc ",
- *Result.SourceManager);
- llvm::errs() << "\n";
- return;
- }
-
- // Record the results in the AtomicChange.
- AtomicChange AC(*Result.SourceManager, RootLoc);
- for (const auto &T : *Transformations) {
- if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
- Consumer(std::move(Err));
- return;
- }
- }
-
- for (const auto &I : Case.AddedIncludes) {
- auto &Header = I.first;
- switch (I.second) {
- case IncludeFormat::Quoted:
- AC.addHeader(Header);
- break;
- case IncludeFormat::Angled:
- AC.addHeader((llvm::Twine("<") + Header + ">").str());
- break;
- }
- }
-
- Consumer(std::move(AC));
-}