Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.37 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. #include "clang/AST/ASTConsumer.h"
  4. #include "clang/AST/RecursiveASTVisitor.h"
  5. #include "clang/Frontend/CompilerInstance.h"
  6. #include "clang/Frontend/FrontendAction.h"
  7. #include "clang/Tooling/Tooling.h"
  8.  
  9. using namespace clang;
  10.  
  11. class FindNamedClassVisitor : public RecursiveASTVisitor<FindNamedClassVisitor>
  12. {
  13. public:
  14.     explicit FindNamedClassVisitor(ASTContext *) {}
  15.  
  16.     bool VisitCXXRecordDecl(CXXRecordDecl *Decl)
  17.     {
  18.         if (Decl->getQualifiedNameAsString() != "A")
  19.             return true;
  20.  
  21.         // For each method of A
  22.         for (const auto &M : Decl->methods())
  23.         {
  24.             assert(M->getAccess() == AS_public);
  25.  
  26.             // Check the visibility of the return type
  27.             const auto *C = M->getReturnType()->getAsCXXRecordDecl();
  28.             assert(C != nullptr);
  29.  
  30.             std::cout << C->getNameAsString()
  31.                       << ": Acc=" << AccToString(C->getAccess())
  32.                       << "; Visible=" << IsVisible(C) << std::endl;
  33.  
  34.             // just to be sure, check also the canonical decl
  35.             C = C->getCanonicalDecl();
  36.             std::cout << C->getNameAsString()
  37.                       << ": Acc=" << AccToString(C->getAccess())
  38.                       << "; Visible=" << IsVisible(C) << std::endl;
  39.         }
  40.         return true;
  41.     }
  42.  
  43. private:
  44.     bool IsVisible(const CXXRecordDecl *R) const
  45.     {
  46.         assert(R != nullptr);
  47.         // R is not public? return false
  48.         if (R->getAccess() != AS_public && R->getAccess() != AS_none)
  49.             return false;
  50.  
  51.         // if R is public (or AS_none), check that also the parent is public
  52.         const auto *Parent = R->getParent();
  53.         if (llvm::isa<CXXRecordDecl>(Parent))
  54.             return IsVisible(llvm::cast<CXXRecordDecl>(Parent));
  55.         return true;
  56.     }
  57.  
  58.     // return a printable version of an access specifier
  59.     std::string AccToString(AccessSpecifier A) const
  60.     {
  61.         switch (A)
  62.         {
  63.             case AccessSpecifier::AS_none:
  64.                 return "AS_none";
  65.             case AccessSpecifier::AS_public:
  66.                 return "AS_public";
  67.             case AccessSpecifier::AS_private:
  68.                 return "AS_private";
  69.             case AccessSpecifier::AS_protected:
  70.                 return "AS_protected";
  71.         }
  72.     }
  73. };
  74.  
  75. class FindNamedClassConsumer : public clang::ASTConsumer
  76. {
  77. public:
  78.     explicit FindNamedClassConsumer(ASTContext *Context) : Visitor(Context) {}
  79.  
  80.     virtual void HandleTranslationUnit(clang::ASTContext &Context)
  81.     {
  82.         Visitor.TraverseDecl(Context.getTranslationUnitDecl());
  83.     }
  84.  
  85. private:
  86.     FindNamedClassVisitor Visitor;
  87. };
  88.  
  89. class FindNamedClassAction : public clang::ASTFrontendAction
  90. {
  91. public:
  92.     virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
  93.         clang::CompilerInstance &Compiler, llvm::StringRef InFile)
  94.     {
  95.         return std::unique_ptr<clang::ASTConsumer>(
  96.             new FindNamedClassConsumer(&Compiler.getASTContext()));
  97.     }
  98. };
  99.  
  100. int main(int argc, char **argv)
  101. {
  102.     // Demo code
  103.     const char code[] = R"__(
  104. class A {
  105. private:
  106.  class B { public: class B2 {}; };
  107.  template<typename T> class C {};
  108.  
  109. public:
  110.  class D {};
  111.  
  112.  // ---
  113.  B getB();
  114.  B::B2 getB2();
  115.  C<int> getC();
  116.  D getD();
  117. };
  118.  
  119. )__";
  120.     clang::tooling::runToolOnCode(new FindNamedClassAction(), code);
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement