46 if (
const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
47 FoundDecl = CtorDecl->getParent();
48 else if (
const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
49 FoundDecl = DtorDecl->getParent();
66 : FoundDecl(FoundDecl), Context(Context) {}
68 std::vector<std::string> Find() {
71 if (
const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
72 addUSRsOfOverridenFunctions(MethodDecl);
73 for (
const auto &OverriddenMethod : OverriddenMethods) {
74 if (checkIfOverriddenFunctionAscends(OverriddenMethod))
77 addUSRsOfInstantiatedMethods(MethodDecl);
78 }
else if (
const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
79 handleCXXRecordDecl(RecordDecl);
80 }
else if (
const auto *TemplateDecl =
81 dyn_cast<ClassTemplateDecl>(FoundDecl)) {
82 handleClassTemplateDecl(TemplateDecl);
83 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(FoundDecl)) {
85 if (
const auto *FTD = FD->getPrimaryTemplate())
86 handleFunctionTemplateDecl(FTD);
87 }
else if (
const auto *FD = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
88 handleFunctionTemplateDecl(FD);
89 }
else if (
const auto *VTD = dyn_cast<VarTemplateDecl>(FoundDecl)) {
90 handleVarTemplateDecl(VTD);
91 }
else if (
const auto *VD =
92 dyn_cast<VarTemplateSpecializationDecl>(FoundDecl)) {
94 handleVarTemplateDecl(VD->getSpecializedTemplate());
95 }
else if (
const auto *VD = dyn_cast<VarDecl>(FoundDecl)) {
97 if (
const auto *VTD = VD->getDescribedVarTemplate())
98 handleVarTemplateDecl(VTD);
102 return std::vector<std::string>(USRSet.begin(), USRSet.end());
105 bool shouldVisitTemplateInstantiations()
const {
return true; }
107 bool VisitCXXMethodDecl(
const CXXMethodDecl *MethodDecl) {
108 if (MethodDecl->isVirtual())
109 OverriddenMethods.push_back(MethodDecl);
110 if (MethodDecl->getInstantiatedFromMemberFunction())
111 InstantiatedMethods.push_back(MethodDecl);
116 void handleCXXRecordDecl(
const CXXRecordDecl *RecordDecl) {
117 if (!RecordDecl->getDefinition()) {
121 RecordDecl = RecordDecl->getDefinition();
122 if (
const auto *ClassTemplateSpecDecl =
123 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl))
124 handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate());
125 addUSRsOfCtorDtors(RecordDecl);
128 void handleClassTemplateDecl(
const ClassTemplateDecl *TemplateDecl) {
129 for (
const auto *
Specialization : TemplateDecl->specializations())
132 TemplateDecl->getPartialSpecializations(PartialSpecs);
133 for (
const auto *Spec : PartialSpecs)
134 addUSRsOfCtorDtors(Spec);
135 addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl());
138 void handleFunctionTemplateDecl(
const FunctionTemplateDecl *FTD) {
141 for (
const auto *S : FTD->specializations())
145 void handleVarTemplateDecl(
const VarTemplateDecl *VTD) {
148 for (
const auto *Spec : VTD->specializations())
151 VTD->getPartialSpecializations(PartialSpecs);
152 for (
const auto *Spec : PartialSpecs)
156 void addUSRsOfCtorDtors(
const CXXRecordDecl *RD) {
157 const auto* RecordDecl = RD->getDefinition();
165 for (
const auto *CtorDecl : RecordDecl->ctors())
168 if (RecordDecl->hasUserDeclaredConstructor())
169 for (
const auto *
D : RecordDecl->decls())
170 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(
D))
171 if (
const auto *Ctor =
172 dyn_cast<CXXConstructorDecl>(FTD->getTemplatedDecl()))
179 void addUSRsOfOverridenFunctions(
const CXXMethodDecl *MethodDecl) {
182 for (
const auto &OverriddenMethod : MethodDecl->overridden_methods())
183 addUSRsOfOverridenFunctions(OverriddenMethod);
186 void addUSRsOfInstantiatedMethods(
const CXXMethodDecl *MethodDecl) {
191 if (
const auto *FT = MethodDecl->getInstantiatedFromMemberFunction())
193 for (
const auto *Method : InstantiatedMethods) {
195 Method->getInstantiatedFromMemberFunction())) != USRSet.end())
200 bool checkIfOverriddenFunctionAscends(
const CXXMethodDecl *MethodDecl) {
201 for (
const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
202 if (USRSet.find(
getUSRForDecl(OverriddenMethod)) != USRSet.end())
204 return checkIfOverriddenFunctionAscends(OverriddenMethod);
209 const Decl *FoundDecl;
211 std::set<std::string> USRSet;
212 std::vector<const CXXMethodDecl *> OverriddenMethods;
213 std::vector<const CXXMethodDecl *> InstantiatedMethods;
219 AdditionalUSRFinder Finder(ND, Context);
220 return Finder.Find();
227 std::vector<std::string> &SpellingNames,
228 std::vector<std::vector<std::string>> &USRList,
229 bool Force,
bool &ErrorOccurred)
230 : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
231 SpellingNames(SpellingNames), USRList(USRList), Force(Force),
232 ErrorOccurred(ErrorOccurred) {}
236 unsigned SymbolOffset,
const std::string &QualifiedName) {
241 ErrorOccurred =
true;
244 "SourceLocation in file %0 at offset %1 is invalid");
253 const NamedDecl *FoundDecl = QualifiedName.empty()
257 if (FoundDecl ==
nullptr) {
258 if (QualifiedName.empty()) {
262 "clang-rename could not find symbol (offset %0)");
263 Engine.
Report(Point, CouldNotFindSymbolAt) << SymbolOffset;
264 ErrorOccurred =
true;
269 SpellingNames.push_back(std::string());
270 USRList.push_back(std::vector<std::string>());
276 Engine.
Report(CouldNotFindSymbolNamed) << QualifiedName;
277 ErrorOccurred =
true;
282 SpellingNames.push_back(FoundDecl->getNameAsString());
283 AdditionalUSRFinder Finder(FoundDecl, Context);
284 USRList.push_back(Finder.Find());
288 void HandleTranslationUnit(ASTContext &Context)
override {
289 const SourceManager &SourceMgr = Context.getSourceManager();
290 for (
unsigned Offset : SymbolOffsets) {
291 if (!FindSymbol(Context, SourceMgr, Offset,
""))
294 for (
const std::string &QualifiedName : QualifiedNames) {
295 if (!FindSymbol(Context, SourceMgr, 0, QualifiedName))
302 std::vector<std::string> &SpellingNames;
303 std::vector<std::vector<std::string>> &USRList;
309 return std::make_unique<NamedDeclFindingConsumer>(
310 SymbolOffsets, QualifiedNames, SpellingNames, USRList, Force,
Defines the clang::ASTContext interface.
Defines the clang::FileManager interface and associated types.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::Preprocessor interface.
Methods for determining the USR of a symbol at a location in source code.
Provides an action to find all relevant USRs at a point.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
StringRef getName() const
The name of this FileEntry.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
A SourceLocation and its associated SourceManager.
This represents a decl that may have a name.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Diagnostic wrappers for TextAPI types for error reporting.