10b57cec5SDimitry Andric //===--- USRFindingAction.cpp - Clang refactoring library -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Provides an action to find USR for the symbol at <offset>, as well as
110b57cec5SDimitry Andric /// all additional USRs.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric #include "clang/Tooling/Refactoring/Rename/USRFindingAction.h"
160b57cec5SDimitry Andric #include "clang/AST/AST.h"
170b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h"
180b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
190b57cec5SDimitry Andric #include "clang/AST/Decl.h"
200b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
210b57cec5SDimitry Andric #include "clang/Basic/FileManager.h"
220b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
230b57cec5SDimitry Andric #include "clang/Frontend/FrontendAction.h"
240b57cec5SDimitry Andric #include "clang/Lex/Lexer.h"
250b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
260b57cec5SDimitry Andric #include "clang/Tooling/CommonOptionsParser.h"
270b57cec5SDimitry Andric #include "clang/Tooling/Refactoring.h"
280b57cec5SDimitry Andric #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
290b57cec5SDimitry Andric #include "clang/Tooling/Tooling.h"
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric #include <algorithm>
320b57cec5SDimitry Andric #include <set>
330b57cec5SDimitry Andric #include <string>
340b57cec5SDimitry Andric #include <vector>
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric namespace clang {
390b57cec5SDimitry Andric namespace tooling {
400b57cec5SDimitry Andric
getCanonicalSymbolDeclaration(const NamedDecl * FoundDecl)410b57cec5SDimitry Andric const NamedDecl *getCanonicalSymbolDeclaration(const NamedDecl *FoundDecl) {
42480093f4SDimitry Andric if (!FoundDecl)
43480093f4SDimitry Andric return nullptr;
440b57cec5SDimitry Andric // If FoundDecl is a constructor or destructor, we want to instead take
450b57cec5SDimitry Andric // the Decl of the corresponding class.
460b57cec5SDimitry Andric if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
470b57cec5SDimitry Andric FoundDecl = CtorDecl->getParent();
480b57cec5SDimitry Andric else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
490b57cec5SDimitry Andric FoundDecl = DtorDecl->getParent();
500b57cec5SDimitry Andric // FIXME: (Alex L): Canonicalize implicit template instantions, just like
510b57cec5SDimitry Andric // the indexer does it.
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric // Note: please update the declaration's doc comment every time the
540b57cec5SDimitry Andric // canonicalization rules are changed.
550b57cec5SDimitry Andric return FoundDecl;
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric namespace {
590b57cec5SDimitry Andric // NamedDeclFindingConsumer should delegate finding USRs of given Decl to
600b57cec5SDimitry Andric // AdditionalUSRFinder. AdditionalUSRFinder adds USRs of ctor and dtor if given
610b57cec5SDimitry Andric // Decl refers to class and adds USRs of all overridden methods if Decl refers
620b57cec5SDimitry Andric // to virtual method.
630b57cec5SDimitry Andric class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
640b57cec5SDimitry Andric public:
AdditionalUSRFinder(const Decl * FoundDecl,ASTContext & Context)650b57cec5SDimitry Andric AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
660b57cec5SDimitry Andric : FoundDecl(FoundDecl), Context(Context) {}
670b57cec5SDimitry Andric
Find()680b57cec5SDimitry Andric std::vector<std::string> Find() {
690b57cec5SDimitry Andric // Fill OverriddenMethods and PartialSpecs storages.
70480093f4SDimitry Andric TraverseAST(Context);
710b57cec5SDimitry Andric if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
720b57cec5SDimitry Andric addUSRsOfOverridenFunctions(MethodDecl);
730b57cec5SDimitry Andric for (const auto &OverriddenMethod : OverriddenMethods) {
740b57cec5SDimitry Andric if (checkIfOverriddenFunctionAscends(OverriddenMethod))
750b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(OverriddenMethod));
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric addUSRsOfInstantiatedMethods(MethodDecl);
780b57cec5SDimitry Andric } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
790b57cec5SDimitry Andric handleCXXRecordDecl(RecordDecl);
800b57cec5SDimitry Andric } else if (const auto *TemplateDecl =
810b57cec5SDimitry Andric dyn_cast<ClassTemplateDecl>(FoundDecl)) {
820b57cec5SDimitry Andric handleClassTemplateDecl(TemplateDecl);
83e8d8bef9SDimitry Andric } else if (const auto *FD = dyn_cast<FunctionDecl>(FoundDecl)) {
84e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(FD));
85e8d8bef9SDimitry Andric if (const auto *FTD = FD->getPrimaryTemplate())
86e8d8bef9SDimitry Andric handleFunctionTemplateDecl(FTD);
87e8d8bef9SDimitry Andric } else if (const auto *FD = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
88e8d8bef9SDimitry Andric handleFunctionTemplateDecl(FD);
89e8d8bef9SDimitry Andric } else if (const auto *VTD = dyn_cast<VarTemplateDecl>(FoundDecl)) {
90e8d8bef9SDimitry Andric handleVarTemplateDecl(VTD);
91e8d8bef9SDimitry Andric } else if (const auto *VD =
92e8d8bef9SDimitry Andric dyn_cast<VarTemplateSpecializationDecl>(FoundDecl)) {
93e8d8bef9SDimitry Andric // FIXME: figure out why FoundDecl can be a VarTemplateSpecializationDecl.
94e8d8bef9SDimitry Andric handleVarTemplateDecl(VD->getSpecializedTemplate());
95e8d8bef9SDimitry Andric } else if (const auto *VD = dyn_cast<VarDecl>(FoundDecl)) {
96e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(VD));
97e8d8bef9SDimitry Andric if (const auto *VTD = VD->getDescribedVarTemplate())
98e8d8bef9SDimitry Andric handleVarTemplateDecl(VTD);
990b57cec5SDimitry Andric } else {
1000b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(FoundDecl));
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric return std::vector<std::string>(USRSet.begin(), USRSet.end());
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric
shouldVisitTemplateInstantiations() const1050b57cec5SDimitry Andric bool shouldVisitTemplateInstantiations() const { return true; }
1060b57cec5SDimitry Andric
VisitCXXMethodDecl(const CXXMethodDecl * MethodDecl)1070b57cec5SDimitry Andric bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
1080b57cec5SDimitry Andric if (MethodDecl->isVirtual())
1090b57cec5SDimitry Andric OverriddenMethods.push_back(MethodDecl);
1100b57cec5SDimitry Andric if (MethodDecl->getInstantiatedFromMemberFunction())
1110b57cec5SDimitry Andric InstantiatedMethods.push_back(MethodDecl);
1120b57cec5SDimitry Andric return true;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric private:
handleCXXRecordDecl(const CXXRecordDecl * RecordDecl)1160b57cec5SDimitry Andric void handleCXXRecordDecl(const CXXRecordDecl *RecordDecl) {
117a7dea167SDimitry Andric if (!RecordDecl->getDefinition()) {
118a7dea167SDimitry Andric USRSet.insert(getUSRForDecl(RecordDecl));
119a7dea167SDimitry Andric return;
120a7dea167SDimitry Andric }
1210b57cec5SDimitry Andric RecordDecl = RecordDecl->getDefinition();
1220b57cec5SDimitry Andric if (const auto *ClassTemplateSpecDecl =
1230b57cec5SDimitry Andric dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl))
1240b57cec5SDimitry Andric handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate());
1250b57cec5SDimitry Andric addUSRsOfCtorDtors(RecordDecl);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric
handleClassTemplateDecl(const ClassTemplateDecl * TemplateDecl)1280b57cec5SDimitry Andric void handleClassTemplateDecl(const ClassTemplateDecl *TemplateDecl) {
1290b57cec5SDimitry Andric for (const auto *Specialization : TemplateDecl->specializations())
1300b57cec5SDimitry Andric addUSRsOfCtorDtors(Specialization);
131e8d8bef9SDimitry Andric SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
132e8d8bef9SDimitry Andric TemplateDecl->getPartialSpecializations(PartialSpecs);
133e8d8bef9SDimitry Andric for (const auto *Spec : PartialSpecs)
134e8d8bef9SDimitry Andric addUSRsOfCtorDtors(Spec);
1350b57cec5SDimitry Andric addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl());
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric
handleFunctionTemplateDecl(const FunctionTemplateDecl * FTD)138e8d8bef9SDimitry Andric void handleFunctionTemplateDecl(const FunctionTemplateDecl *FTD) {
139e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(FTD));
140e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(FTD->getTemplatedDecl()));
141e8d8bef9SDimitry Andric for (const auto *S : FTD->specializations())
142e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(S));
143e8d8bef9SDimitry Andric }
144e8d8bef9SDimitry Andric
handleVarTemplateDecl(const VarTemplateDecl * VTD)145e8d8bef9SDimitry Andric void handleVarTemplateDecl(const VarTemplateDecl *VTD) {
146e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(VTD));
147e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(VTD->getTemplatedDecl()));
14881ad6265SDimitry Andric for (const auto *Spec : VTD->specializations())
149e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(Spec));
150e8d8bef9SDimitry Andric SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
151e8d8bef9SDimitry Andric VTD->getPartialSpecializations(PartialSpecs);
15281ad6265SDimitry Andric for (const auto *Spec : PartialSpecs)
153e8d8bef9SDimitry Andric USRSet.insert(getUSRForDecl(Spec));
154e8d8bef9SDimitry Andric }
155e8d8bef9SDimitry Andric
addUSRsOfCtorDtors(const CXXRecordDecl * RD)1565ffd83dbSDimitry Andric void addUSRsOfCtorDtors(const CXXRecordDecl *RD) {
1575ffd83dbSDimitry Andric const auto* RecordDecl = RD->getDefinition();
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric // Skip if the CXXRecordDecl doesn't have definition.
1605ffd83dbSDimitry Andric if (!RecordDecl) {
1615ffd83dbSDimitry Andric USRSet.insert(getUSRForDecl(RD));
1620b57cec5SDimitry Andric return;
1635ffd83dbSDimitry Andric }
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric for (const auto *CtorDecl : RecordDecl->ctors())
1660b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(CtorDecl));
1675ffd83dbSDimitry Andric // Add template constructor decls, they are not in ctors() unfortunately.
1685ffd83dbSDimitry Andric if (RecordDecl->hasUserDeclaredConstructor())
1695ffd83dbSDimitry Andric for (const auto *D : RecordDecl->decls())
1705ffd83dbSDimitry Andric if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1715ffd83dbSDimitry Andric if (const auto *Ctor =
1725ffd83dbSDimitry Andric dyn_cast<CXXConstructorDecl>(FTD->getTemplatedDecl()))
1735ffd83dbSDimitry Andric USRSet.insert(getUSRForDecl(Ctor));
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(RecordDecl->getDestructor()));
1760b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(RecordDecl));
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric
addUSRsOfOverridenFunctions(const CXXMethodDecl * MethodDecl)1790b57cec5SDimitry Andric void addUSRsOfOverridenFunctions(const CXXMethodDecl *MethodDecl) {
1800b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(MethodDecl));
1810b57cec5SDimitry Andric // Recursively visit each OverridenMethod.
1820b57cec5SDimitry Andric for (const auto &OverriddenMethod : MethodDecl->overridden_methods())
1830b57cec5SDimitry Andric addUSRsOfOverridenFunctions(OverriddenMethod);
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric
addUSRsOfInstantiatedMethods(const CXXMethodDecl * MethodDecl)1860b57cec5SDimitry Andric void addUSRsOfInstantiatedMethods(const CXXMethodDecl *MethodDecl) {
1870b57cec5SDimitry Andric // For renaming a class template method, all references of the instantiated
1880b57cec5SDimitry Andric // member methods should be renamed too, so add USRs of the instantiated
1890b57cec5SDimitry Andric // methods to the USR set.
1900b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(MethodDecl));
1910b57cec5SDimitry Andric if (const auto *FT = MethodDecl->getInstantiatedFromMemberFunction())
1920b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(FT));
1930b57cec5SDimitry Andric for (const auto *Method : InstantiatedMethods) {
1940b57cec5SDimitry Andric if (USRSet.find(getUSRForDecl(
1950b57cec5SDimitry Andric Method->getInstantiatedFromMemberFunction())) != USRSet.end())
1960b57cec5SDimitry Andric USRSet.insert(getUSRForDecl(Method));
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric
checkIfOverriddenFunctionAscends(const CXXMethodDecl * MethodDecl)2000b57cec5SDimitry Andric bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl) {
2010b57cec5SDimitry Andric for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
2020b57cec5SDimitry Andric if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
2030b57cec5SDimitry Andric return true;
2040b57cec5SDimitry Andric return checkIfOverriddenFunctionAscends(OverriddenMethod);
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric return false;
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric const Decl *FoundDecl;
2100b57cec5SDimitry Andric ASTContext &Context;
2110b57cec5SDimitry Andric std::set<std::string> USRSet;
2120b57cec5SDimitry Andric std::vector<const CXXMethodDecl *> OverriddenMethods;
2130b57cec5SDimitry Andric std::vector<const CXXMethodDecl *> InstantiatedMethods;
2140b57cec5SDimitry Andric };
2150b57cec5SDimitry Andric } // namespace
2160b57cec5SDimitry Andric
getUSRsForDeclaration(const NamedDecl * ND,ASTContext & Context)2170b57cec5SDimitry Andric std::vector<std::string> getUSRsForDeclaration(const NamedDecl *ND,
2180b57cec5SDimitry Andric ASTContext &Context) {
2190b57cec5SDimitry Andric AdditionalUSRFinder Finder(ND, Context);
2200b57cec5SDimitry Andric return Finder.Find();
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andric class NamedDeclFindingConsumer : public ASTConsumer {
2240b57cec5SDimitry Andric public:
NamedDeclFindingConsumer(ArrayRef<unsigned> SymbolOffsets,ArrayRef<std::string> QualifiedNames,std::vector<std::string> & SpellingNames,std::vector<std::vector<std::string>> & USRList,bool Force,bool & ErrorOccurred)2250b57cec5SDimitry Andric NamedDeclFindingConsumer(ArrayRef<unsigned> SymbolOffsets,
2260b57cec5SDimitry Andric ArrayRef<std::string> QualifiedNames,
2270b57cec5SDimitry Andric std::vector<std::string> &SpellingNames,
2280b57cec5SDimitry Andric std::vector<std::vector<std::string>> &USRList,
2290b57cec5SDimitry Andric bool Force, bool &ErrorOccurred)
2300b57cec5SDimitry Andric : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
2310b57cec5SDimitry Andric SpellingNames(SpellingNames), USRList(USRList), Force(Force),
2320b57cec5SDimitry Andric ErrorOccurred(ErrorOccurred) {}
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric private:
FindSymbol(ASTContext & Context,const SourceManager & SourceMgr,unsigned SymbolOffset,const std::string & QualifiedName)2350b57cec5SDimitry Andric bool FindSymbol(ASTContext &Context, const SourceManager &SourceMgr,
2360b57cec5SDimitry Andric unsigned SymbolOffset, const std::string &QualifiedName) {
2370b57cec5SDimitry Andric DiagnosticsEngine &Engine = Context.getDiagnostics();
2380b57cec5SDimitry Andric const FileID MainFileID = SourceMgr.getMainFileID();
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric if (SymbolOffset >= SourceMgr.getFileIDSize(MainFileID)) {
2410b57cec5SDimitry Andric ErrorOccurred = true;
2420b57cec5SDimitry Andric unsigned InvalidOffset = Engine.getCustomDiagID(
2430b57cec5SDimitry Andric DiagnosticsEngine::Error,
2440b57cec5SDimitry Andric "SourceLocation in file %0 at offset %1 is invalid");
2450b57cec5SDimitry Andric Engine.Report(SourceLocation(), InvalidOffset)
246*5f757f3fSDimitry Andric << SourceMgr.getFileEntryRefForID(MainFileID)->getName()
247*5f757f3fSDimitry Andric << SymbolOffset;
2480b57cec5SDimitry Andric return false;
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric const SourceLocation Point = SourceMgr.getLocForStartOfFile(MainFileID)
2520b57cec5SDimitry Andric .getLocWithOffset(SymbolOffset);
2530b57cec5SDimitry Andric const NamedDecl *FoundDecl = QualifiedName.empty()
2540b57cec5SDimitry Andric ? getNamedDeclAt(Context, Point)
2550b57cec5SDimitry Andric : getNamedDeclFor(Context, QualifiedName);
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric if (FoundDecl == nullptr) {
2580b57cec5SDimitry Andric if (QualifiedName.empty()) {
2590b57cec5SDimitry Andric FullSourceLoc FullLoc(Point, SourceMgr);
2600b57cec5SDimitry Andric unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID(
2610b57cec5SDimitry Andric DiagnosticsEngine::Error,
2620b57cec5SDimitry Andric "clang-rename could not find symbol (offset %0)");
2630b57cec5SDimitry Andric Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset;
2640b57cec5SDimitry Andric ErrorOccurred = true;
2650b57cec5SDimitry Andric return false;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric if (Force) {
2690b57cec5SDimitry Andric SpellingNames.push_back(std::string());
2700b57cec5SDimitry Andric USRList.push_back(std::vector<std::string>());
2710b57cec5SDimitry Andric return true;
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric unsigned CouldNotFindSymbolNamed = Engine.getCustomDiagID(
2750b57cec5SDimitry Andric DiagnosticsEngine::Error, "clang-rename could not find symbol %0");
2760b57cec5SDimitry Andric Engine.Report(CouldNotFindSymbolNamed) << QualifiedName;
2770b57cec5SDimitry Andric ErrorOccurred = true;
2780b57cec5SDimitry Andric return false;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric FoundDecl = getCanonicalSymbolDeclaration(FoundDecl);
2820b57cec5SDimitry Andric SpellingNames.push_back(FoundDecl->getNameAsString());
2830b57cec5SDimitry Andric AdditionalUSRFinder Finder(FoundDecl, Context);
2840b57cec5SDimitry Andric USRList.push_back(Finder.Find());
2850b57cec5SDimitry Andric return true;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
HandleTranslationUnit(ASTContext & Context)2880b57cec5SDimitry Andric void HandleTranslationUnit(ASTContext &Context) override {
2890b57cec5SDimitry Andric const SourceManager &SourceMgr = Context.getSourceManager();
2900b57cec5SDimitry Andric for (unsigned Offset : SymbolOffsets) {
2910b57cec5SDimitry Andric if (!FindSymbol(Context, SourceMgr, Offset, ""))
2920b57cec5SDimitry Andric return;
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric for (const std::string &QualifiedName : QualifiedNames) {
2950b57cec5SDimitry Andric if (!FindSymbol(Context, SourceMgr, 0, QualifiedName))
2960b57cec5SDimitry Andric return;
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric ArrayRef<unsigned> SymbolOffsets;
3010b57cec5SDimitry Andric ArrayRef<std::string> QualifiedNames;
3020b57cec5SDimitry Andric std::vector<std::string> &SpellingNames;
3030b57cec5SDimitry Andric std::vector<std::vector<std::string>> &USRList;
3040b57cec5SDimitry Andric bool Force;
3050b57cec5SDimitry Andric bool &ErrorOccurred;
3060b57cec5SDimitry Andric };
3070b57cec5SDimitry Andric
newASTConsumer()3080b57cec5SDimitry Andric std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() {
309a7dea167SDimitry Andric return std::make_unique<NamedDeclFindingConsumer>(
3100b57cec5SDimitry Andric SymbolOffsets, QualifiedNames, SpellingNames, USRList, Force,
3110b57cec5SDimitry Andric ErrorOccurred);
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric } // end namespace tooling
3150b57cec5SDimitry Andric } // end namespace clang
316