39 if (
const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
40 FoundDecl = CtorDecl->getParent();
41 else if (
const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
42 FoundDecl = DtorDecl->getParent();
59 : FoundDecl(FoundDecl), Context(Context) {}
61 std::vector<std::string> Find() {
64 if (
const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
65 addUSRsOfOverridenFunctions(MethodDecl);
66 for (
const auto &OverriddenMethod : OverriddenMethods) {
67 if (checkIfOverriddenFunctionAscends(OverriddenMethod))
70 addUSRsOfInstantiatedMethods(MethodDecl);
71 }
else if (
const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
72 handleCXXRecordDecl(RecordDecl);
73 }
else if (
const auto *TemplateDecl =
74 dyn_cast<ClassTemplateDecl>(FoundDecl)) {
75 handleClassTemplateDecl(TemplateDecl);
76 }
else if (
const auto *FD = dyn_cast<FunctionDecl>(FoundDecl)) {
78 if (
const auto *FTD = FD->getPrimaryTemplate())
79 handleFunctionTemplateDecl(FTD);
80 }
else if (
const auto *FD = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
81 handleFunctionTemplateDecl(FD);
82 }
else if (
const auto *VTD = dyn_cast<VarTemplateDecl>(FoundDecl)) {
83 handleVarTemplateDecl(VTD);
84 }
else if (
const auto *VD =
85 dyn_cast<VarTemplateSpecializationDecl>(FoundDecl)) {
87 handleVarTemplateDecl(VD->getSpecializedTemplate());
88 }
else if (
const auto *VD = dyn_cast<VarDecl>(FoundDecl)) {
90 if (
const auto *VTD = VD->getDescribedVarTemplate())
91 handleVarTemplateDecl(VTD);
95 return std::vector<std::string>(USRSet.begin(), USRSet.end());
98 bool shouldVisitTemplateInstantiations()
const {
return true; }
100 bool VisitCXXMethodDecl(
const CXXMethodDecl *MethodDecl) {
101 if (MethodDecl->isVirtual())
102 OverriddenMethods.push_back(MethodDecl);
103 if (MethodDecl->getInstantiatedFromMemberFunction())
104 InstantiatedMethods.push_back(MethodDecl);
109 void handleCXXRecordDecl(
const CXXRecordDecl *RecordDecl) {
110 if (!RecordDecl->getDefinition()) {
114 RecordDecl = RecordDecl->getDefinition();
115 if (
const auto *ClassTemplateSpecDecl =
116 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl))
117 handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate());
118 addUSRsOfCtorDtors(RecordDecl);
121 void handleClassTemplateDecl(
const ClassTemplateDecl *TemplateDecl) {
122 for (
const auto *
Specialization : TemplateDecl->specializations())
124 SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
125 TemplateDecl->getPartialSpecializations(PartialSpecs);
126 for (
const auto *Spec : PartialSpecs)
127 addUSRsOfCtorDtors(Spec);
128 addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl());
131 void handleFunctionTemplateDecl(
const FunctionTemplateDecl *FTD) {
134 for (
const auto *S : FTD->specializations())
138 void handleVarTemplateDecl(
const VarTemplateDecl *VTD) {
141 for (
const auto *Spec : VTD->specializations())
143 SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
144 VTD->getPartialSpecializations(PartialSpecs);
145 for (
const auto *Spec : PartialSpecs)
149 void addUSRsOfCtorDtors(
const CXXRecordDecl *RD) {
150 const auto* RecordDecl = RD->getDefinition();
158 for (
const auto *CtorDecl : RecordDecl->ctors())
161 if (RecordDecl->hasUserDeclaredConstructor())
162 for (
const auto *D : RecordDecl->decls())
163 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
164 if (
const auto *Ctor =
165 dyn_cast<CXXConstructorDecl>(FTD->getTemplatedDecl()))
172 void addUSRsOfOverridenFunctions(
const CXXMethodDecl *MethodDecl) {
175 for (
const auto &OverriddenMethod : MethodDecl->overridden_methods())
176 addUSRsOfOverridenFunctions(OverriddenMethod);
179 void addUSRsOfInstantiatedMethods(
const CXXMethodDecl *MethodDecl) {
184 if (
const auto *FT = MethodDecl->getInstantiatedFromMemberFunction())
186 for (
const auto *
Method : InstantiatedMethods) {
188 Method->getInstantiatedFromMemberFunction())) != USRSet.end())
193 bool checkIfOverriddenFunctionAscends(
const CXXMethodDecl *MethodDecl) {
194 for (
const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
195 if (USRSet.find(
getUSRForDecl(OverriddenMethod)) != USRSet.end())
197 return checkIfOverriddenFunctionAscends(OverriddenMethod);
202 const Decl *FoundDecl;
204 std::set<std::string> USRSet;
205 std::vector<const CXXMethodDecl *> OverriddenMethods;
206 std::vector<const CXXMethodDecl *> InstantiatedMethods;
212 AdditionalUSRFinder Finder(ND, Context);
213 return Finder.Find();
220 std::vector<std::string> &SpellingNames,
221 std::vector<std::vector<std::string>> &USRList,
222 bool Force,
bool &ErrorOccurred)
223 : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
224 SpellingNames(SpellingNames), USRList(USRList), Force(Force),
225 ErrorOccurred(ErrorOccurred) {}
229 unsigned SymbolOffset,
const std::string &QualifiedName) {
231 const FileID MainFileID = SourceMgr.getMainFileID();
233 if (SymbolOffset >= SourceMgr.getFileIDSize(MainFileID)) {
234 ErrorOccurred =
true;
237 "SourceLocation in file %0 at offset %1 is invalid");
239 << SourceMgr.getFileEntryRefForID(MainFileID)->getName()
244 const SourceLocation Point = SourceMgr.getLocForStartOfFile(MainFileID)
246 const NamedDecl *FoundDecl = QualifiedName.empty()
250 if (FoundDecl ==
nullptr) {
251 if (QualifiedName.empty()) {
255 "clang-rename could not find symbol (offset %0)");
256 Engine.
Report(Point, CouldNotFindSymbolAt) << SymbolOffset;
257 ErrorOccurred =
true;
262 SpellingNames.push_back(std::string());
263 USRList.push_back(std::vector<std::string>());
269 Engine.
Report(CouldNotFindSymbolNamed) << QualifiedName;
270 ErrorOccurred =
true;
276 AdditionalUSRFinder Finder(FoundDecl, Context);
277 USRList.push_back(Finder.Find());
281 void HandleTranslationUnit(ASTContext &Context)
override {
283 for (
unsigned Offset : SymbolOffsets) {
284 if (!FindSymbol(Context, SourceMgr, Offset,
""))
287 for (
const std::string &QualifiedName : QualifiedNames) {
288 if (!FindSymbol(Context, SourceMgr, 0, QualifiedName))
293 ArrayRef<unsigned> SymbolOffsets;
294 ArrayRef<std::string> QualifiedNames;
295 std::vector<std::string> &SpellingNames;
296 std::vector<std::vector<std::string>> &USRList;
302 return std::make_unique<NamedDeclFindingConsumer>(
303 SymbolOffsets, QualifiedNames, SpellingNames, USRList, Force,
Defines the clang::ASTContext 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.
SourceManager & getSourceManager()
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.
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.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
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.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
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.