|
10 | 10 | #include "Logger.h" |
11 | 11 | #include "SourceCode.h" |
12 | 12 | #include "clang/AST/ASTTypeTraits.h" |
| 13 | +#include "clang/AST/Decl.h" |
13 | 14 | #include "clang/AST/DeclCXX.h" |
14 | 15 | #include "clang/AST/Expr.h" |
15 | 16 | #include "clang/AST/ExprCXX.h" |
@@ -594,13 +595,23 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> { |
594 | 595 | // Usually empty, but sometimes children cover tokens but shouldn't own them. |
595 | 596 | SourceRange earlySourceRange(const DynTypedNode &N) { |
596 | 597 | if (const Decl *D = N.get<Decl>()) { |
| 598 | + // We want constructor name to be claimed by TypeLoc not the constructor |
| 599 | + // itself. Similar for deduction guides, we rather want to select the |
| 600 | + // underlying TypeLoc. |
| 601 | + // FIXME: Unfortunately this doesn't work, even though RecursiveASTVisitor |
| 602 | + // traverses the underlying TypeLoc inside DeclarationName, it is null for |
| 603 | + // constructors. |
| 604 | + if (isa<CXXConstructorDecl>(D) || isa<CXXDeductionGuideDecl>(D)) |
| 605 | + return SourceRange(); |
| 606 | + // This will capture Field, Function, MSProperty, NonTypeTemplateParm and |
| 607 | + // VarDecls. We want the name in the declarator to be claimed by the decl |
| 608 | + // and not by any children. For example: |
597 | 609 | // void [[foo]](); |
598 | | - if (auto *FD = llvm::dyn_cast<FunctionDecl>(D)) |
599 | | - return FD->getNameInfo().getSourceRange(); |
600 | 610 | // int (*[[s]])(); |
601 | | - else if (auto *VD = llvm::dyn_cast<VarDecl>(D)) |
602 | | - return VD->getLocation(); |
603 | | - } else if (const auto* CCI = N.get<CXXCtorInitializer>()) { |
| 611 | + // struct X { int [[hash]] [32]; [[operator]] int();} |
| 612 | + if (const auto *DD = llvm::dyn_cast<DeclaratorDecl>(D)) |
| 613 | + return DD->getLocation(); |
| 614 | + } else if (const auto *CCI = N.get<CXXCtorInitializer>()) { |
604 | 615 | // : [[b_]](42) |
605 | 616 | return CCI->getMemberLocation(); |
606 | 617 | } |
|
0 commit comments