From f9f829c48e380604b13906514131b7b5aa620f21 Mon Sep 17 00:00:00 2001 From: manasij7479 <manasij7479@gmail.com> Date: Tue, 10 Jun 2014 18:30:14 +0530 Subject: [PATCH] autoloading visitor --- include/cling/Interpreter/Interpreter.h | 3 + lib/Interpreter/AutoloadingVisitor.cpp | 82 +++++++++++++ lib/Interpreter/AutoloadingVisitor.h | 33 +++++ lib/Interpreter/Interpreter.cpp | 19 +++ tools/CMakeLists.txt | 1 - tools/Makefile | 2 +- tools/fwd/CMakeLists.txt | 20 --- tools/fwd/Makefile | 25 ---- tools/fwd/main.cpp | 155 ------------------------ 9 files changed, 138 insertions(+), 202 deletions(-) create mode 100644 lib/Interpreter/AutoloadingVisitor.cpp create mode 100644 lib/Interpreter/AutoloadingVisitor.h delete mode 100644 tools/fwd/CMakeLists.txt delete mode 100644 tools/fwd/Makefile delete mode 100644 tools/fwd/main.cpp diff --git a/include/cling/Interpreter/Interpreter.h b/include/cling/Interpreter/Interpreter.h index 78c13afe..03edf12e 100644 --- a/include/cling/Interpreter/Interpreter.h +++ b/include/cling/Interpreter/Interpreter.h @@ -614,6 +614,9 @@ namespace cling { /// void AddAtExitFunc(void (*Func) (void*), void* Arg); + + void GenerateAutoloadingMap(llvm::StringRef inFile,llvm::StringRef outFile); + friend class runtime::internal::LifetimeHandler; // FIXME: workaround until JIT supports exceptions static jmp_buf*& getNullDerefJump() { return m_JumpBuf; } diff --git a/lib/Interpreter/AutoloadingVisitor.cpp b/lib/Interpreter/AutoloadingVisitor.cpp new file mode 100644 index 00000000..c9e9de00 --- /dev/null +++ b/lib/Interpreter/AutoloadingVisitor.cpp @@ -0,0 +1,82 @@ +#include "AutoloadingVisitor.h" +namespace cling { + bool AutoloadingVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration) { + if(Declaration->getName().startswith("_") + || Declaration->getName().size() == 0 + /*|| //TODO: Find a way to avoid templates here*/) + return true; + + std::vector<NamespacePrinterRAII> scope; + clang::DeclContext* c=Declaration->getEnclosingNamespaceContext(); + while(c->isNamespace()) { + clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c); + scope.emplace_back(n->getNameAsString()); + c=c->getParent(); + } + + llvm::outs() << "\n" << Declaration->getKindName() + << " __attribute__((annotate(\"" + << m_InFile << "\"))) " + << Declaration->getName() << ";\n"; + return true; + } + bool AutoloadingVisitor::VisitFunctionDecl(clang::FunctionDecl* Declaration) { + + if(Declaration->getName().startswith("_") + || Declaration->getName().size() == 0 + || Declaration->isCXXClassMember() + || !Declaration->hasBody()) + return true; + + std::vector<NamespacePrinterRAII> scope; + clang::DeclContext* c = Declaration->getEnclosingNamespaceContext(); + while(c->isNamespace()) { + clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c); + scope.emplace_back(n->getNameAsString()); + c=c->getParent(); + } + + llvm::outs() << "\n" << Declaration->getReturnType().getAsString() + << " " << Declaration->getName() << " () " + << "__attribute__((annotate(\"" + << m_InFile << "\")));\n"; + + //TODO: arg list, not sure if necessary + + return true; + } + + bool AutoloadingVisitor::VisitClassTemplateDecl + (clang::ClassTemplateDecl* Declaration) { + if(Declaration->getName().startswith("_") + || Declaration->getName().size() == 0) + return true; + + std::vector<NamespacePrinterRAII> scope; + clang::DeclContext* c= + Declaration->getTemplatedDecl()->getEnclosingNamespaceContext(); + while(c->isNamespace()) { + clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c); + scope.emplace_back(n->getNameAsString()); + c=c->getParent(); + } + + llvm::outs()<<"template <"; + clang::TemplateParameterList* tl=Declaration->getTemplateParameters(); + for(auto it=tl->begin();it!=tl->end();++it) { + if(llvm::isa<clang::NonTypeTemplateParmDecl>(*it)) { + clang::NonTypeTemplateParmDecl* td=llvm::cast<clang::NonTypeTemplateParmDecl>(*it); + llvm::outs() << td->getType().getAsString(); + } + else llvm::outs() << "typename"; + llvm::outs()<<" " << (*it)->getName(); + if((it+1) != tl->end()) + llvm::outs() << ", "; + } + llvm::outs()<<"> class __attribute__((annotate(\"" + << m_InFile << "\"))) " + << Declaration->getName() << ";\n"; + + return true; + } +} // end namespace cling diff --git a/lib/Interpreter/AutoloadingVisitor.h b/lib/Interpreter/AutoloadingVisitor.h new file mode 100644 index 00000000..07192679 --- /dev/null +++ b/lib/Interpreter/AutoloadingVisitor.h @@ -0,0 +1,33 @@ +#ifndef CLING_AUTOLOADING_VISITOR_H +#define CLING_AUTOLOADING_VISITOR_H +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" + +namespace cling { + class NamespacePrinterRAII { + public: + NamespacePrinterRAII(std::string name) { + llvm::outs()<< "namespace " <<name<<" {\n"; + } + ~NamespacePrinterRAII() { + llvm::outs()<<"\n}\n"; + } + }; + + class AutoloadingVisitor + :public clang::RecursiveASTVisitor<AutoloadingVisitor> { + public: + AutoloadingVisitor(llvm::StringRef InFile,llvm::StringRef OutFile) + :m_InFile(InFile),m_OutFile(OutFile){} + bool VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration); + bool VisitFunctionDecl(clang::FunctionDecl* Declaration); + bool VisitClassTemplateDecl(clang::ClassTemplateDecl* Declaration); + + private: + llvm::StringRef m_InFile; + llvm::StringRef m_OutFile; + }; +}//end namespace cling + +#endif diff --git a/lib/Interpreter/Interpreter.cpp b/lib/Interpreter/Interpreter.cpp index 4af98c2c..c60db3c1 100644 --- a/lib/Interpreter/Interpreter.cpp +++ b/lib/Interpreter/Interpreter.cpp @@ -13,6 +13,7 @@ #include "DynamicLookup.h" #include "IncrementalExecutor.h" #include "IncrementalParser.h" +#include "AutoloadingVisitor.h" #include "cling/Interpreter/CIFactory.h" #include "cling/Interpreter/ClangInternalState.h" @@ -1186,4 +1187,22 @@ namespace cling { void Interpreter::AddAtExitFunc(void (*Func) (void*), void* Arg) { m_Executor->AddAtExitFunc(Func, Arg, getLastTransaction()); } + + void Interpreter::GenerateAutoloadingMap(llvm::StringRef inFile, + llvm::StringRef outFile) { + cling::Transaction* T; + this->declare(std::string("#include \"") + std::string(inFile) + "\"", &T); + for(auto dcit=T->decls_begin(); dcit!=T->decls_end(); ++dcit) { + Transaction::DelayCallInfo& dci = *dcit; + + for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) { + clang::Decl* decl = *dit; + auto visitor = new AutoloadingVisitor(inFile,outFile); + visitor->TraverseDecl(decl); + delete visitor; + } + + } + return; + } } // namespace cling diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index a1b1c057..961db625 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -9,6 +9,5 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib/UserInterface/textinput) add_subdirectory(driver) - add_subdirectory(fwd) endif() diff --git a/tools/Makefile b/tools/Makefile index e816d2a1..f5afba7e 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -9,6 +9,6 @@ ##===----------------------------------------------------------------------===## LEVEL := ../../.. -DIRS := driver fwd +DIRS := driver include $(LEVEL)/Makefile.common diff --git a/tools/fwd/CMakeLists.txt b/tools/fwd/CMakeLists.txt deleted file mode 100644 index bf6fb7d1..00000000 --- a/tools/fwd/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Support - Option - ) - -add_clang_executable(fwd - main.cpp - ) - -target_link_libraries(fwd - clangAST - clangASTMatchers - clangBasic - clangFrontend - clangTooling - clangDriver - ) - -install(TARGETS fwd - RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/tools/fwd/Makefile b/tools/fwd/Makefile deleted file mode 100644 index 233436ce..00000000 --- a/tools/fwd/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -##===-------- tools/toolTemplate/Makefile ------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../../../clang - -TOOLNAME = fwd -NO_INSTALL = 1 - -# No plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(CLANG_LEVEL)/../../Makefile.config -LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option -USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \ - clangRewriteFrontend.a clangRewriteCore.a \ - clangParse.a clangSema.a clangAnalysis.a \ - clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a - -include $(CLANG_LEVEL)/Makefile diff --git a/tools/fwd/main.cpp b/tools/fwd/main.cpp deleted file mode 100644 index c9eb17a0..00000000 --- a/tools/fwd/main.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "clang/Frontend/FrontendActions.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/Support/CommandLine.h" - -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclTemplate.h" - - -using namespace clang::tooling; -using namespace llvm; - -// Apply a custom category to all command-line options so that they are the -// only ones displayed. -static cl::OptionCategory FwdCategory("fwd options"); - -// CommonOptionsParser declares HelpMessage with a description of the common -// command-line options related to the compilation database and input files. -// It's nice to have this help message in all tools. -static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); - -// A help message for this specific tool can be added afterwards. -static cl::extrahelp MoreHelp("\nMore help text..."); - -class NamespacePrinterRAII { -public: - NamespacePrinterRAII(std::string name) { - llvm::outs()<< "namespace " <<name<<" {\n"; - } - ~NamespacePrinterRAII() { - llvm::outs()<<"\n}\n"; - } -}; - -class FindNamedClassVisitor - :public clang::RecursiveASTVisitor<FindNamedClassVisitor> { -public: - FindNamedClassVisitor(llvm::StringRef InFile):m_File(InFile){} - bool VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration) { - - if(Declaration->getName().startswith("_") - || Declaration->getName().size()==0 - /*|| //TODO: Find a way to avoid templates here*/) - return true; - - std::vector<NamespacePrinterRAII> scope; - clang::DeclContext* c=Declaration->getEnclosingNamespaceContext(); - while(c->isNamespace()) { - clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c); - scope.emplace_back(n->getNameAsString()); - c=c->getParent(); - } - - llvm::outs() << "\n" << Declaration->getKindName() - << " __attribute__((annotate(\"" - << m_File << "\"))) " - << Declaration->getName() << ";\n"; - return true; - } - bool VisitFunctionDecl(clang::FunctionDecl* Declaration) { - - if(Declaration->getName().startswith("_") - || Declaration->getName().size()==0 - || Declaration->isCXXClassMember() - || !Declaration->hasBody()) - return true; - - std::vector<NamespacePrinterRAII> scope; - clang::DeclContext* c=Declaration->getEnclosingNamespaceContext(); - while(c->isNamespace()) { - clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c); - scope.emplace_back(n->getNameAsString()); - c=c->getParent(); - } - - llvm::outs() << "\n" << Declaration->getReturnType().getAsString() - << " " << Declaration->getName() << " () " - << "__attribute__((annotate(\"" - << m_File << "\")));\n"; - - //TODO: arg list, not sure if necessary - - return true; - } - - bool VisitClassTemplateDecl(clang::ClassTemplateDecl* Declaration) { - - if(Declaration->getName().startswith("_") - || Declaration->getName().size()==0) - return true; - - std::vector<NamespacePrinterRAII> scope; - clang::DeclContext* c=Declaration->getTemplatedDecl()->getEnclosingNamespaceContext(); - while(c->isNamespace()) { - clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c); - scope.emplace_back(n->getNameAsString()); - c=c->getParent(); - } - - llvm::outs()<<"template <"; - clang::TemplateParameterList* tl=Declaration->getTemplateParameters(); - for(auto it=tl->begin();it!=tl->end();++it) { - if(llvm::isa<clang::NonTypeTemplateParmDecl>(*it)) { - clang::NonTypeTemplateParmDecl* td=llvm::cast<clang::NonTypeTemplateParmDecl>(*it); - llvm::outs()<<td->getType().getAsString(); - } - else llvm::outs()<<"typename"; - llvm::outs()<<" "<<(*it)->getName(); - if((it+1)!=tl->end()) - llvm::outs()<<", "; - } - llvm::outs()<<"> class __attribute__((annotate(\"" - << m_File << "\"))) " - << Declaration->getName() << ";\n"; - - return true; - } - -private: - llvm::StringRef m_File; -}; - -class FindNamedClassConsumer : public clang::ASTConsumer { -public: - FindNamedClassConsumer(llvm::StringRef InFile):Visitor(InFile){} - virtual void HandleTranslationUnit(clang::ASTContext &Context) { - // Traversing the translation unit decl via a RecursiveASTVisitor - // will visit all nodes in the AST. - Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - } -private: - // A RecursiveASTVisitor implementation. - FindNamedClassVisitor Visitor; -}; - - -class FindNamedClassAction : public clang::ASTFrontendAction { -public: - virtual clang::ASTConsumer *CreateASTConsumer( - clang::CompilerInstance &Compiler, llvm::StringRef InFile) { - return new FindNamedClassConsumer(InFile); - } -}; - - -int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, FwdCategory); - ClangTool Tool(OptionsParser.getCompilations(), - OptionsParser.getSourcePathList()); - - return Tool.run(newFrontendActionFactory<FindNamedClassAction>()); -}