summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/Selection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/Selection.cpp')
-rw-r--r--clang-tools-extra/clangd/Selection.cpp31
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) {
OpenPOWER on IntegriCloud