autoloading visitor

This commit is contained in:
manasij7479 2014-06-10 18:30:14 +05:30 committed by sftnight
parent ae5a3ce221
commit f9f829c48e
9 changed files with 138 additions and 202 deletions

View File

@ -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; }

View 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

View 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

View File

@ -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

View File

@ -9,6 +9,5 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib/UserInterface/textinput)
add_subdirectory(driver)
add_subdirectory(fwd)
endif()

View File

@ -9,6 +9,6 @@
##===----------------------------------------------------------------------===##
LEVEL := ../../..
DIRS := driver fwd
DIRS := driver
include $(LEVEL)/Makefile.common

View File

@ -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)

View File

@ -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

View File

@ -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>());
}