[clang-tools-extra] r366698 - [clangd] Add dlog()s for SelectionTree, enabling -debug-only=SelectionTree.cpp

2019-07-22 Thread Sam McCall via cfe-commits
Author: sammccall
Date: Mon Jul 22 08:55:53 2019
New Revision: 366698

URL: http://llvm.org/viewvc/llvm-project?rev=366698=rev
Log:
[clangd] Add dlog()s for SelectionTree, enabling -debug-only=SelectionTree.cpp

Summary:
SelectionTree is a RecursiveASTVisitor which processes getSourceRange() for
every node. This is a lot of surface area with the AST, as getSourceRange()
is specialized for *many* node types.
And the resulting SelectionTree depends on the source ranges of many
visited nodes, and the order of traversal.

Put together, this means we really need a traversal log to debug when we
get an unexpected SelectionTree. I've built this ad-hoc a few times, now
it's time to check it in.

Example output:
```
D[14:07:44.184] Computing selection for 

D[14:07:44.184]  push: VarDecl const auto x = 42
D[14:07:44.184]   claimRange: 
D[14:07:44.184]   push: NestedNameSpecifierLoc (empty NestedNameSpecifierLoc)
D[14:07:44.184]   pop: NestedNameSpecifierLoc (empty NestedNameSpecifierLoc)
D[14:07:44.184]   push: QualifiedTypeLoc const auto
D[14:07:44.184]   pop: QualifiedTypeLoc const auto
D[14:07:44.184]claimRange: 
D[14:07:44.184]hit selection: 

D[14:07:44.184]   skip: IntegerLiteral 42
D[14:07:44.184]skipped range = 

D[14:07:44.184]  pop: VarDecl const auto x = 42
D[14:07:44.184]   claimRange: 
D[14:07:44.184]  skip: VarDecl int y = 43
D[14:07:44.184]   skipped range = 

D[14:07:44.184] Built selection tree
TranslationUnitDecl
  VarDecl const auto x = 42
 .QualifiedTypeLoc const auto

```

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65073

Modified:
clang-tools-extra/trunk/clangd/Selection.cpp
clang-tools-extra/trunk/clangd/Selection.h

Modified: clang-tools-extra/trunk/clangd/Selection.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Selection.cpp?rev=366698=366697=366698=diff
==
--- clang-tools-extra/trunk/clangd/Selection.cpp (original)
+++ clang-tools-extra/trunk/clangd/Selection.cpp Mon Jul 22 08:55:53 2019
@@ -8,15 +8,19 @@
 
 #include "Selection.h"
 #include "ClangdUnit.h"
+#include "Logger.h"
 #include "SourceCode.h"
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -59,6 +63,31 @@ private:
   std::vector> 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 , const DynTypedNode ,
+   const PrintingPolicy ) {
+  if (const TypeLoc *TL = N.get()) {
+// TypeLoc is a hierarchy, but has only a single ASTNodeKind.
+// Synthesize the name from the Type subclass (except for 
QualifiedTypeLoc).
+if (TL->getTypeLocClass() == TypeLoc::Qualified)
+  OS << "QualifiedTypeLoc";
+else
+  OS << TL->getType()->getTypeClassName() << "TypeLoc";
+  } else {
+OS << N.getNodeKind().asStringRef();
+  }
+  OS << " ";
+  N.print(OS, PP);
+}
+
+std::string printNodeToString(const DynTypedNode , const PrintingPolicy ) 
{
+  std::string S;
+  llvm::raw_string_ostream OS(S);
+  printNode(OS, N, PP);
+  return std::move(OS.str());
+}
+
 // We find the selection by visiting written nodes in the AST, looking for 
nodes
 // that intersect with the selected character range.
 //
@@ -71,9 +100,9 @@ class SelectionVisitor : public Recursiv
 public:
   // Runs the visitor to gather selected nodes and their ancestors.
   // If there is any selection, the root (TUDecl) is the first node.
-  static std::deque collect(ASTContext , unsigned Begin,
-  unsigned End, FileID File) {
-SelectionVisitor V(AST, Begin, End, File);
+  static std::deque collect(ASTContext , const PrintingPolicy ,
+  unsigned Begin, unsigned End, FileID File) {
+SelectionVisitor V(AST, PP, Begin, End, File);
 V.TraverseAST(AST);
 assert(V.Stack.size() == 1 && "Unpaired push/pop?");
 assert(V.Stack.top() == ());
@@ -114,9 +143,12 @@ public:
   }
   // Stmt is the same, but this form allows the data recursion optimization.
   bool dataTraverseStmtPre(Stmt *X) {
-if (!X || canSafelySkipNode(X->getSourceRange()))
+if (!X)
+  return false;
+auto N = DynTypedNode::create(*X);
+if (canSafelySkipNode(N))
   return false;
-push(DynTypedNode::create(*X));
+push(std::move(N));
 return true;
   }
   bool dataTraverseStmtPost(Stmt *X) {
@@ -130,10 +162,10 @@ public:
 private:
   using Base = RecursiveASTVisitor;
 
-  

r366698 - [clangd] Add dlog()s for SelectionTree, enabling -debug-only=SelectionTree.cpp

2019-07-22 Thread Sam McCall via cfe-commits
Author: sammccall
Date: Mon Jul 22 08:55:53 2019
New Revision: 366698

URL: http://llvm.org/viewvc/llvm-project?rev=366698=rev
Log:
[clangd] Add dlog()s for SelectionTree, enabling -debug-only=SelectionTree.cpp

Summary:
SelectionTree is a RecursiveASTVisitor which processes getSourceRange() for
every node. This is a lot of surface area with the AST, as getSourceRange()
is specialized for *many* node types.
And the resulting SelectionTree depends on the source ranges of many
visited nodes, and the order of traversal.

Put together, this means we really need a traversal log to debug when we
get an unexpected SelectionTree. I've built this ad-hoc a few times, now
it's time to check it in.

Example output:
```
D[14:07:44.184] Computing selection for 

D[14:07:44.184]  push: VarDecl const auto x = 42
D[14:07:44.184]   claimRange: 
D[14:07:44.184]   push: NestedNameSpecifierLoc (empty NestedNameSpecifierLoc)
D[14:07:44.184]   pop: NestedNameSpecifierLoc (empty NestedNameSpecifierLoc)
D[14:07:44.184]   push: QualifiedTypeLoc const auto
D[14:07:44.184]   pop: QualifiedTypeLoc const auto
D[14:07:44.184]claimRange: 
D[14:07:44.184]hit selection: 

D[14:07:44.184]   skip: IntegerLiteral 42
D[14:07:44.184]skipped range = 

D[14:07:44.184]  pop: VarDecl const auto x = 42
D[14:07:44.184]   claimRange: 
D[14:07:44.184]  skip: VarDecl int y = 43
D[14:07:44.184]   skipped range = 

D[14:07:44.184] Built selection tree
TranslationUnitDecl
  VarDecl const auto x = 42
 .QualifiedTypeLoc const auto

```

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65073

Modified:
cfe/trunk/lib/AST/ASTTypeTraits.cpp

Modified: cfe/trunk/lib/AST/ASTTypeTraits.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTTypeTraits.cpp?rev=366698=366697=366698=diff
==
--- cfe/trunk/lib/AST/ASTTypeTraits.cpp (original)
+++ cfe/trunk/lib/AST/ASTTypeTraits.cpp Mon Jul 22 08:55:53 2019
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/NestedNameSpecifier.h"
 
 namespace clang {
 namespace ast_type_traits {
@@ -129,9 +130,12 @@ void DynTypedNode::print(llvm::raw_ostre
 TN->print(OS, PP);
   else if (const NestedNameSpecifier *NNS = get())
 NNS->print(OS, PP);
-  else if (const NestedNameSpecifierLoc *NNSL = get())
-NNSL->getNestedNameSpecifier()->print(OS, PP);
-  else if (const QualType *QT = get())
+  else if (const NestedNameSpecifierLoc *NNSL = get()) 
{
+if (const NestedNameSpecifier *NNS = NNSL->getNestedNameSpecifier())
+  NNS->print(OS, PP);
+else
+  OS << "(empty NestedNameSpecifierLoc)";
+  } else if (const QualType *QT = get())
 QT->print(OS, PP);
   else if (const TypeLoc *TL = get())
 TL->getType().print(OS, PP);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits