autoloading visitor
This commit is contained in:
parent
ae5a3ce221
commit
f9f829c48e
@ -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; }
|
||||
|
82
lib/Interpreter/AutoloadingVisitor.cpp
Normal file
82
lib/Interpreter/AutoloadingVisitor.cpp
Normal file
@ -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
|
33
lib/Interpreter/AutoloadingVisitor.h
Normal file
33
lib/Interpreter/AutoloadingVisitor.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -9,6 +9,5 @@
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib/UserInterface/textinput)
|
||||
add_subdirectory(driver)
|
||||
add_subdirectory(fwd)
|
||||
endif()
|
||||
|
||||
|
@ -9,6 +9,6 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
DIRS := driver fwd
|
||||
DIRS := driver
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -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)
|
@ -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
|
@ -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>());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user