diff options
Diffstat (limited to 'clang-tools-extra/clangd/Selection.cpp')
-rw-r--r-- | clang-tools-extra/clangd/Selection.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp index 77db371d47d..cbb83a1934d 100644 --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -63,10 +63,8 @@ private: std::vector<std::pair<unsigned, unsigned>> Ranges; // Always sorted. }; -// Dump a node for debugging. -// DynTypedNode::print() doesn't include the kind of node, which is useful. -void printNode(llvm::raw_ostream &OS, const DynTypedNode &N, - const PrintingPolicy &PP) { +// Show the type of a node for debugging. +void printNodeKind(llvm::raw_ostream &OS, const DynTypedNode &N) { if (const TypeLoc *TL = N.get<TypeLoc>()) { // TypeLoc is a hierarchy, but has only a single ASTNodeKind. // Synthesize the name from the Type subclass (except for QualifiedTypeLoc). @@ -77,14 +75,13 @@ void printNode(llvm::raw_ostream &OS, const DynTypedNode &N, } else { OS << N.getNodeKind().asStringRef(); } - OS << " "; - N.print(OS, PP); } std::string printNodeToString(const DynTypedNode &N, const PrintingPolicy &PP) { std::string S; llvm::raw_string_ostream OS(S); - printNode(OS, N, PP); + printNodeKind(OS, N); + OS << " "; return std::move(OS.str()); } @@ -155,6 +152,15 @@ public: pop(); return true; } + // QualifiedTypeLoc is handled strangely in RecursiveASTVisitor: the derived + // TraverseTypeLoc is not called for the inner UnqualTypeLoc. + // This means we'd never see 'int' in 'const int'! Work around that here. + // (The reason for the behavior is to avoid traversing the nested Type twice, + // but we ignore TraverseType anyway). + bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QX) { + return traverseNode<TypeLoc>( + &QX, [&] { return TraverseTypeLoc(QX.getUnqualifiedLoc()); }); + } // Uninteresting parts of the AST that don't have locations within them. bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; } bool TraverseType(QualType) { return true; } @@ -361,12 +367,21 @@ void SelectionTree::print(llvm::raw_ostream &OS, const SelectionTree::Node &N, : '.'); else OS.indent(Indent); - printNode(OS, N.ASTNode, PrintPolicy); + printNodeKind(OS, N.ASTNode); + OS << ' '; + N.ASTNode.print(OS, PrintPolicy); OS << "\n"; for (const Node *Child : N.Children) print(OS, *Child, Indent + 2); } +std::string SelectionTree::Node::kind() const { + std::string S; + llvm::raw_string_ostream OS(S); + printNodeKind(OS, ASTNode); + return std::move(OS.str()); +} + // Decide which selection emulates a "point" query in between characters. static std::pair<unsigned, unsigned> pointBounds(unsigned Offset, FileID FID, ASTContext &AST) { |