11#ifndef AstDumper_hpp
22#define AstDumper_hpp
33
4+ #define ENABLE_TYPEVISITOR
5+ #define ENABLE_BUILTINTYPE
6+
47#include < format>
58#include < stack>
69#include < ranges>
710#include < numeric>
811#include < clang/AST/ASTConsumer.h>
912#include < clang/AST/TypeLoc.h>
1013#include < clang/AST/Type.h>
14+ #include < clang/AST/TypeVisitor.h>
1115#include < clang/AST/RecursiveASTVisitor.h>
1216#include < clang/AST/ASTTypeTraits.h>
1317#include < llvm/Support/raw_ostream.h>
18+ #include < clang/AST/PrettyPrinter.h>
1419
1520#include " clang_utility_1.hpp"
1621#include " TreeFormatter.hpp"
1722
23+ class AstDumper ;
24+
25+ class DumpTypeVisitor : public clang ::TypeVisitor<DumpTypeVisitor> {
26+ public:
27+ DumpTypeVisitor (AstDumper* dumper) : dumper_(dumper) {}
28+ AstDumper* dumper_;
29+ void VisitType (const clang::Type* type);
30+ #ifdef ENABLE_BUILTINTYPE
31+ void VisitBuiltinType (const clang::BuiltinType* type);
32+ #endif
33+ };
34+
1835class AstDumper : public clang ::RecursiveASTVisitor<AstDumper> {
1936public:
2037
38+ friend class DumpTypeVisitor ;
39+
2140 /*
2241 Types
2342 */
@@ -39,6 +58,16 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
3958 std::size_t stmtCount;
4059 std::size_t typeCount;
4160 std::size_t typeLocCount;
61+ std::size_t conceptRefCount;
62+ std::size_t cxxBaseSpecCount;
63+ std::size_t ctorInitCount;
64+ std::size_t lambdaCaptureCount;
65+ std::size_t nestedNameSpecCount;
66+ std::size_t nestedNameSpecLocCount;
67+ std::size_t tempArgCount;
68+ std::size_t tempArgLocCount;
69+ std::size_t tempNameCount;
70+ std::size_t objcProtocolLocCount;
4271 };
4372
4473 /*
@@ -71,6 +100,16 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
71100 stats.stmtCount = stmtCount_;
72101 stats.typeCount = typeCount_;
73102 stats.typeLocCount = typeLocCount_;
103+ stats.conceptRefCount = conceptRefCount_;
104+ stats.cxxBaseSpecCount = cxxBaseSpecCount_;
105+ stats.ctorInitCount = ctorInitCount_;
106+ stats.lambdaCaptureCount = lambdaCaptureCount_;
107+ stats.nestedNameSpecCount = nestedNameSpecCount_;
108+ stats.nestedNameSpecLocCount = nestedNameSpecLocCount_;
109+ stats.tempArgCount = tempArgCount_;
110+ stats.tempArgLocCount = tempArgLocCount_;
111+ stats.tempNameCount = tempNameCount_;
112+ stats.objcProtocolLocCount = objcProtocolLocCount_;
74113 }
75114
76115 /*
@@ -181,29 +220,6 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
181220 return ret;
182221 }
183222
184- template <class Node , class IsNull , class TraverseNode >
185- bool traverseImpl3 (Node node, IsNull isNull, TraverseNode traverseNode,
186- const std::string& label = {}) {
187- if (isNull (node)) {
188- return true ;
189- }
190- BigInt nodeId = makeNodeId ();
191- logf (1 , " TraverseImpl entered {} {}\n " , nodeId, label);
192- // Note: The DynTypedNode is not really used for anything currently.
193- nodeStack_.emplace_back (nodeId, getCurLevel () + 1 ,
194- clang::DynTypedNode::create (node));
195- treeFormatter_.down ();
196- bool ret = traverseNode (node);
197- if (auto numChildren = treeFormatter_.getCurChildNo ();
198- numChildren < 0 ) {
199- logf (1 , " no visited nodes\n " );
200- }
201- treeFormatter_.up ();
202- nodeStack_.pop_back ();
203- logf (1 , " TraverseImpl exited {} {}\n " , nodeId, label);
204- return ret;
205- }
206-
207223 template <class Node , class IsNull , class TraverseNode , class VisitNode >
208224 bool traverseImpl3a (Node node, IsNull isNull, TraverseNode traverseNode,
209225 VisitNode visitNode, const std::string& label = {}) {
@@ -231,10 +247,7 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
231247 /*
232248 The following are not currently handled:
233249 TraverseSynOrSemInitListExpr
234- TraverseObjCProtocolLoc
235- TraverseConceptReference
236250 TraverseTemplateInstantiations (overloaded)
237- TraverseOMPClause
238251 TraverseConceptRequirement
239252 */
240253
@@ -276,6 +289,7 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
276289
277290 bool TraverseLambdaCapture (clang::LambdaExpr *lambda,
278291 const clang::LambdaCapture *capture, clang::Expr *init) {
292+ xVisitLambdaCapture (capture);
279293 if (lambda->isInitCapture (capture)) {
280294 if (!TraverseDecl (capture->getCapturedVar ())) {
281295 return false ;
@@ -302,18 +316,20 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
302316 " NestedNameSpecifierLoc" );
303317 }
304318
305- #if 0
306- // Ignore ObjCProcotolLoc nodes.
307319 bool TraverseObjCProtocolLoc (clang::ObjCProtocolLoc loc) {
320+ // NOTE/FIXME: This should probably actually do something.
321+ // Effectively, ignore ObjCProcotolLoc nodes.
322+ ++objcProtocolLocCount_;
308323 return true ;
309324 }
310- #endif
311325
312326#if 0
313327 // NOTE: This will not compile since Base::TraverseOMPClause is private.
314328 bool TraverseOMPClause(clang::OMPClause* node) {
315- return traverseImpl1(node,
316- [this](auto node){return Base::TraverseOMPClause(node);});
329+ return traverseImpl1a(node,
330+ [this](auto node){return Base::TraverseOMPClause(node);},
331+ [this](auto node){return xVisitOMPClause(node);},
332+ "OMPClause");
317333 }
318334#endif
319335
@@ -348,14 +364,12 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
348364 " TemplateName" );
349365 }
350366
351- // Note: The QualType case is handled differently, since this
352- // results in one of the VisitType family of methods being called
353- // that takes a Type* instead of a QualType.
354367 bool TraverseType (clang::QualType qualType) {
355- return traverseImpl3 (qualType,
368+ return traverseImpl3a (qualType,
356369 [this ](auto qualType){return qualType.isNull ();},
357370 [this ](auto qualType){return Base::TraverseType (qualType);},
358- " Type" );
371+ [this ](auto qualType){return xVisitType (qualType.getTypePtr ());},
372+ " QualType" );
359373 }
360374
361375 bool TraverseTypeLoc (clang::TypeLoc typeLoc) {
@@ -383,18 +397,21 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
383397
384398 bool xVisitConceptReference (clang::ConceptReference* cr) {
385399 ++visitCount_;
400+ ++conceptRefCount_;
386401 treeFormatter_.addNode (makeDesc (" ConceptReference" ));
387402 return true ;
388403 }
389404
390405 bool xVisitCXXBaseSpecifier (clang::CXXBaseSpecifier loc) {
391406 ++visitCount_;
407+ ++cxxBaseSpecCount_;
392408 treeFormatter_.addNode (makeDesc (" CXXBaseSpecifier" ));
393409 return true ;
394410 }
395411
396412 bool xVisitConstructorInitializer (clang::CXXCtorInitializer* init) {
397413 ++visitCount_;
414+ ++ctorInitCount_;
398415 treeFormatter_.addNode (makeDesc (" CXXCtorInitializer" ));
399416 return true ;
400417 }
@@ -415,8 +432,9 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
415432 }
416433
417434 // ???
418- bool VisitLambdaCapture (const clang::LambdaCapture *capture) {
435+ bool xVisitLambdaCapture (const clang::LambdaCapture *capture) {
419436 ++visitCount_;
437+ ++lambdaCaptureCount_;
420438 std::string desc = makeDesc (" LambdaCapture" );
421439 logf (1 , " {}" , desc);
422440 treeFormatter_.addNode (desc);
@@ -425,6 +443,7 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
425443
426444 bool xVisitNestedNameSpecifier (clang::NestedNameSpecifier* nns) {
427445 ++visitCount_;
446+ ++nestedNameSpecCount_;
428447 std::string desc = makeDesc (" NestedNameSpecifier" );
429448 logf (1 , " {}" , desc);
430449 treeFormatter_.addNode (desc);
@@ -433,15 +452,25 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
433452
434453 bool xVisitNestedNameSpecifierLoc (clang::NestedNameSpecifierLoc loc) {
435454 ++visitCount_;
455+ ++nestedNameSpecLocCount_;
436456 std::string desc = makeDesc (" NestedNameSpecifierLoc" );
437457 logf (1 , " {}" , desc);
438458 treeFormatter_.addNode (desc);
439459 return true ;
440460 }
441461
442- // ObjCProtocolLoc
462+ #if 0
463+ // NOTE: This is not currently used.
464+ bool xVisitObjCProtocolLoc(clang::ObjCProtocolLoc loc) {
465+ return true;
466+ }
467+ #endif
443468
444- // OMPClause
469+ bool xVisitOMPClause (clang::OMPClause* node) {
470+ ++visitCount_;
471+ assert (node);
472+ return true ;
473+ }
445474
446475 bool xVisitStmt (clang::Stmt* stmt) {
447476 ++visitCount_;
@@ -456,6 +485,7 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
456485
457486 bool xVisitTemplateArgument (clang::TemplateArgument arg) {
458487 ++visitCount_;
488+ ++tempArgCount_;
459489 std::string desc = makeDesc (" TemplateArgument" );
460490 logf (1 , " {}" , desc);
461491 treeFormatter_.addNode (desc);
@@ -464,6 +494,7 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
464494
465495 bool xVisitTemplateArgumentLoc (clang::TemplateArgumentLoc loc) {
466496 ++visitCount_;
497+ ++tempArgLocCount_;
467498 std::string desc = makeDesc (" TemplateArgumentLoc" );
468499 logf (1 , " {}" , desc);
469500 treeFormatter_.addNode (desc);
@@ -472,12 +503,15 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
472503
473504 bool xVisitTemplateName (clang::TemplateName name) {
474505 ++visitCount_;
506+ ++tempNameCount_;
475507 std::string desc = makeDesc (" TemplateName" );
476508 logf (1 , " {}" , desc);
477509 treeFormatter_.addNode (desc);
478510 return true ;
479511 }
480512
513+ #ifndef ENABLE_TYPEVISITOR
514+
481515 bool VisitType (clang::Type* type) {
482516 ++visitCount_;
483517 ++typeCount_;
@@ -490,6 +524,19 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
490524 return true ;
491525 }
492526
527+ #else
528+
529+ bool xVisitType (const clang::Type* type) {
530+ DumpTypeVisitor visitor (this );
531+ visitor.Visit (type);
532+ ++visitCount_;
533+ ++typeCount_;
534+ assert (type);
535+ return true ;
536+ }
537+
538+ #endif
539+
493540 bool xVisitTypeLoc (clang::TypeLoc typeLoc) {
494541 ++visitCount_;
495542 ++typeLocCount_;
@@ -502,14 +549,6 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
502549 return true ;
503550 }
504551
505- #if 0
506- bool VisitComment(clang::comments::Comment* comment) {
507- ++visitCount_;
508- treeFormatter_.addNode("comments::Comment");
509- return true;
510- }
511- #endif
512-
513552private:
514553
515554 /* ***********************************************************\
@@ -529,7 +568,41 @@ class AstDumper : public clang::RecursiveASTVisitor<AstDumper> {
529568 BigInt stmtCount_ = 0 ;
530569 BigInt typeCount_ = 0 ;
531570 BigInt typeLocCount_ = 0 ;
571+ std::size_t conceptRefCount_ = 0 ;
572+ std::size_t cxxBaseSpecCount_ = 0 ;
573+ std::size_t ctorInitCount_ = 0 ;
574+ std::size_t lambdaCaptureCount_ = 0 ;
575+ std::size_t nestedNameSpecCount_ = 0 ;
576+ std::size_t nestedNameSpecLocCount_ = 0 ;
577+ std::size_t tempArgCount_ = 0 ;
578+ std::size_t tempArgLocCount_ = 0 ;
579+ std::size_t tempNameCount_ = 0 ;
580+ std::size_t objcProtocolLocCount_ = 0 ;
581+
532582 bool doTemplateInstantiations_;
533583};
534584
585+ inline void DumpTypeVisitor::VisitType (const clang::Type* type)
586+ {
587+ TreeFormatter<llvm::raw_ostream>& treeFormatter_ = dumper_->treeFormatter_ ;
588+ std::string name = type->getTypeClassName ();
589+ std::string desc = dumper_->makeDesc (std::format (" type {}Type" ,
590+ type->getTypeClassName ()));
591+ dumper_->logf (1 , " {}" , desc);
592+ dumper_->treeFormatter_ .addNode (desc);
593+ }
594+
595+ #ifdef ENABLE_BUILTINTYPE
596+ inline void DumpTypeVisitor::VisitBuiltinType (const clang::BuiltinType* type)
597+ {
598+ clang::PrintingPolicy printPolicy (*dumper_->langOpts_ );
599+ TreeFormatter<llvm::raw_ostream>& treeFormatter_ = dumper_->treeFormatter_ ;
600+ std::string name = type->getTypeClassName ();
601+ std::string desc = dumper_->makeDesc (std::format (" type {}Type {}" ,
602+ type->getTypeClassName (), std::string (type->getName (printPolicy))));
603+ dumper_->logf (1 , " {}" , desc);
604+ dumper_->treeFormatter_ .addNode (desc);
605+ }
606+ #endif
607+
535608#endif
0 commit comments