(
Loc.isInvalid())
48std::pair<clang::FileID, unsigned> FileIdAndOffset =
49FullLoc.getSpellingLoc().getDecomposedLoc();
50 return SM.getFileEntryForID(FileIdAndOffset.first) !=
nullptr;
55classUSRLocFindingASTVisitor
56:
publicRecursiveSymbolVisitor<USRLocFindingASTVisitor> {
58 explicitUSRLocFindingASTVisitor(
conststd::vector<std::string> &USRs,
60 constASTContext &Context)
61: RecursiveSymbolVisitor(Context.getSourceManager(),
62Context.getLangOpts()),
63USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
66 boolvisitSymbolOccurrence(
constNamedDecl *ND,
69assert(NameRanges.size() == 1 &&
70 "Multiple name pieces are not supported yet!");
71SourceLocation
Loc= NameRanges[0].getBegin();
72 constSourceManager &
SM= Context.getSourceManager();
74 if(
Loc.isMacroID())
76checkAndAddLocation(
Loc);
88 voidcheckAndAddLocation(SourceLocation
Loc) {
89 constSourceLocation BeginLoc =
Loc;
91BeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
94Context.getSourceManager(), Context.getLangOpts());
95 size_tOffset = TokenName.find(PrevName.getNamePieces()[0]);
99 if(Offset != StringRef::npos)
101BeginLoc.getLocWithOffset(Offset));
104 conststd::set<std::string> USRSet;
105 constSymbolName PrevName;
107 constASTContext &Context;
110SourceLocation StartLocationForType(TypeLoc TL) {
114NestedNameSpecifierLoc NestedNameSpecifier =
115ElaboratedTypeLoc.getQualifierLoc();
116 if(NestedNameSpecifier.getNestedNameSpecifier())
117 returnNestedNameSpecifier.getBeginLoc();
118TL = TL.getNextTypeLoc();
120 returnTL.getBeginLoc();
123SourceLocation EndLocationForType(TypeLoc TL) {
125 while(TL.getTypeLocClass() == TypeLoc::Elaborated ||
127TL = TL.getNextTypeLoc();
132 if(TL.getTypeLocClass() == TypeLoc::TemplateSpecialization) {
133 returnTL.castAs<TemplateSpecializationTypeLoc>()
135.getLocWithOffset(-1);
137 returnTL.getEndLoc();
140NestedNameSpecifier *GetNestedNameForType(TypeLoc TL) {
143TL = TL.getNextTypeLoc();
148 returnElaboratedTypeLoc.getQualifierLoc().getNestedNameSpecifier();
156classRenameLocFinder :
publicRecursiveASTVisitor<RenameLocFinder> {
159: USRSet(USRs.begin(), USRs.end()), Context(Context) {}
182 boolVisitNamedDecl(
constNamedDecl *Decl) {
184 if(llvm::isa<UsingDecl>(
Decl))
188 if(llvm::isa<CXXDestructorDecl>(
Decl))
191 if(
Decl->isImplicit())
194 if(isInUSRSet(
Decl)) {
197 if(
const auto* TAT = dyn_cast<TypeAliasTemplateDecl>(
Decl))
198 Decl= TAT->getTemplatedDecl();
200 autoStartLoc =
Decl->getLocation();
201 autoEndLoc = StartLoc;
202 if(IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
203RenameInfo Info = {StartLoc,
209RenameInfos.push_back(Info);
215 boolVisitMemberExpr(
constMemberExpr *Expr) {
216 constNamedDecl *
Decl= Expr->getFoundDecl();
217 autoStartLoc = Expr->getMemberLoc();
218 autoEndLoc = Expr->getMemberLoc();
219 if(isInUSRSet(Decl)) {
220RenameInfos.push_back({StartLoc, EndLoc,
229 boolVisitDesignatedInitExpr(
constDesignatedInitExpr *
E) {
230 for(
constDesignatedInitExpr::Designator &
D:
E->designators()) {
231 if(
D.isFieldDesignator()) {
232 if(
constFieldDecl *Decl =
D.getFieldDecl()) {
233 if(isInUSRSet(Decl)) {
234 autoStartLoc =
D.getFieldLoc();
235 autoEndLoc =
D.getFieldLoc();
236RenameInfos.push_back({StartLoc, EndLoc,
248 boolVisitCXXConstructorDecl(
constCXXConstructorDecl *CD) {
255 if(
constFieldDecl *FD =
Initializer->getMember()) {
256 if(isInUSRSet(FD)) {
258RenameInfos.push_back({
Loc,
Loc,
269 boolVisitDeclRefExpr(
constDeclRefExpr *Expr) {
270 constNamedDecl *
Decl= Expr->getFoundDecl();
273 if(
auto*UsingShadow = llvm::dyn_cast<UsingShadowDecl>(Decl)) {
274 Decl= UsingShadow->getTargetDecl();
277 autoStartLoc = Expr->getBeginLoc();
280SourceLocation EndLoc = Expr->hasExplicitTemplateArgs()
281? Expr->getLAngleLoc().getLocWithOffset(-1)
284 if(
const auto*MD = llvm::dyn_cast<CXXMethodDecl>(Decl)) {
285 if(isInUSRSet(MD)) {
289RenameInfos.push_back({EndLoc, EndLoc,
303 if(
const auto*
T= llvm::dyn_cast<EnumConstantDecl>(Decl)) {
306 if(!Expr->hasQualifier())
309 if(
const auto*ED =
310llvm::dyn_cast_or_null<EnumDecl>(getClosestAncestorDecl(*
T))) {
325EndLoc = Expr->getQualifierLoc().getEndLoc().getLocWithOffset(-1);
326assert(EndLoc.isValid() &&
327 "The enum constant should have prefix qualifers.");
329 if(isInUSRSet(Decl) &&
330IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
331RenameInfo Info = {StartLoc,
334getClosestAncestorDecl(*Expr),
335Expr->getQualifier(),
337RenameInfos.push_back(Info);
343 boolVisitUsingDecl(
constUsingDecl *Using) {
344 for(
const auto*UsingShadow :
Using->shadows()) {
345 if(isInUSRSet(UsingShadow->getTargetDecl())) {
346UsingDecls.push_back(Using);
353 boolVisitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
354 if(!NestedLoc.getNestedNameSpecifier()->getAsType())
357 if(
const auto*TargetDecl =
358getSupportedDeclFromTypeLoc(NestedLoc.getTypeLoc())) {
359 if(isInUSRSet(TargetDecl)) {
360RenameInfo Info = {NestedLoc.getBeginLoc(),
361EndLocationForType(NestedLoc.getTypeLoc()),
363getClosestAncestorDecl(NestedLoc),
364NestedLoc.getNestedNameSpecifier()->getPrefix(),
366RenameInfos.push_back(Info);
372 boolVisitTypeLoc(TypeLoc
Loc) {
373 autoParents = Context.getParents(
Loc);
374TypeLoc ParentTypeLoc;
375 if(!Parents.empty()) {
380 if(
const auto*NSL = Parents[0].get<NestedNameSpecifierLoc>()) {
381VisitNestedNameSpecifierLocations(*NSL);
385 if(
const auto*TL = Parents[0].get<TypeLoc>())
391 if(
const auto*TargetDecl = getSupportedDeclFromTypeLoc(
Loc)) {
392 if(isInUSRSet(TargetDecl)) {
403 if(!ParentTypeLoc.isNull() &&
404isInUSRSet(getSupportedDeclFromTypeLoc(ParentTypeLoc)))
407 autoStartLoc = StartLocationForType(
Loc);
408 autoEndLoc = EndLocationForType(
Loc);
409 if(IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
410RenameInfo Info = {StartLoc,
413getClosestAncestorDecl(
Loc),
414GetNestedNameForType(
Loc),
416RenameInfos.push_back(Info);
423 if(
const auto*TemplateSpecType =
424dyn_cast<TemplateSpecializationType>(
Loc.getType())) {
425TypeLoc TargetLoc =
Loc;
426 if(!ParentTypeLoc.isNull()) {
427 if(llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
428TargetLoc = ParentTypeLoc;
431 if(isInUSRSet(TemplateSpecType->getTemplateName().getAsTemplateDecl())) {
432TypeLoc TargetLoc =
Loc;
438 if(!ParentTypeLoc.isNull() &&
439llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
440TargetLoc = ParentTypeLoc;
442 autoStartLoc = StartLocationForType(TargetLoc);
443 autoEndLoc = EndLocationForType(TargetLoc);
444 if(IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
448TemplateSpecType->getTemplateName().getAsTemplateDecl(),
450GetNestedNameForType(TargetLoc),
452RenameInfos.push_back(Info);
460 conststd::vector<RenameInfo> &getRenameInfos()
const{
returnRenameInfos; }
463 conststd::vector<const UsingDecl *> &getUsingDecls()
const{
470 constNamedDecl *getSupportedDeclFromTypeLoc(TypeLoc
Loc) {
472 returnTT->getDecl();
473 if(
const auto*RD =
Loc.getType()->getAsCXXRecordDecl())
475 if(
const auto*ED =
476llvm::dyn_cast_or_null<EnumDecl>(
Loc.getType()->getAsTagDecl()))
482 template<
typenameASTNodeType>
483 const Decl*getClosestAncestorDecl(
constASTNodeType &
Node) {
484 autoParents = Context.getParents(
Node);
486 if(Parents.size() != 1)
488 if(ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(Parents[0].getNodeKind()))
489 returnParents[0].template get<Decl>();
490 returngetClosestAncestorDecl(Parents[0]);
495 constTypeLoc *getParentTypeLoc(TypeLoc
Loc)
const{
496 autoParents = Context.getParents(
Loc);
498 if(Parents.size() != 1)
500 returnParents[0].get<TypeLoc>();
504 boolisInUSRSet(
constDecl *Decl)
const{
508 returnllvm::is_contained(USRSet, USR);
511 conststd::set<std::string> USRSet;
513std::vector<RenameInfo> RenameInfos;
516std::vector<const UsingDecl *> UsingDecls;
524Visitor.TraverseDecl(
Decl);
525 returnVisitor.takeOccurrences();
528std::vector<tooling::AtomicChange>
539llvm::StringRef
Text) {
541llvm::Error Err = ReplaceChange.
replace(
544llvm::errs() <<
"Failed to add replacement to AtomicChange: " 545<< llvm::toString(std::move(Err)) <<
"\n";
551 for(
const auto&RenameInfo : Finder.getRenameInfos()) {
552std::string ReplacedName = NewName.str();
553 if(RenameInfo.IgnorePrefixQualifers) {
555 size_tLastColonPos = NewName.find_last_of(
':');
556 if(LastColonPos != std::string::npos)
557ReplacedName = std::string(NewName.substr(LastColonPos + 1));
559 if(RenameInfo.FromDecl && RenameInfo.Context) {
560 if(!llvm::isa<clang::TranslationUnitDecl>(
561RenameInfo.Context->getDeclContext())) {
563RenameInfo.Specifier, RenameInfo.Begin,
564RenameInfo.Context->getDeclContext(), RenameInfo.FromDecl,
565NewName.starts_with(
"::") ? NewName.str()
566: (
"::"+ NewName).str());
581 if(ActualName.starts_with(
"::") && !NewName.starts_with(
"::")) {
582ReplacedName =
"::"+ NewName.str();
587 if(NewName.starts_with(
"::") && NewName.substr(2) == ReplacedName)
588ReplacedName = NewName.str();
590Replace(RenameInfo.Begin, RenameInfo.End, ReplacedName);
595 for(
const auto*Using : Finder.getUsingDecls())
596Replace(Using->getBeginLoc(), Using->getEndLoc(),
"using "+ NewName.str());
Defines the clang::ASTContext interface.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
A wrapper class around RecursiveASTVisitor that visits each occurrences of a named symbol.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Methods for determining the USR of a symbol at a location in source code.
const NamedDecl * FromDecl
bool IgnorePrefixQualifers
const NestedNameSpecifier * Specifier
Provides functionality for finding all instances of a USR in a given AST.
SourceManager & getSourceManager()
const LangOptions & getLangOpts() const
static CharSourceRange getTokenRange(SourceRange R)
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
A SourceLocation and its associated SourceManager.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
The top declaration context.
ASTContext & getASTContext() const
@ 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.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4