diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/AnnotateFunctions/AnnotateFunctions.cpp | 88 | ||||
-rw-r--r-- | examples/AnnotateFunctions/CMakeLists.txt | 11 | ||||
-rw-r--r-- | examples/CMakeLists.txt | 11 | ||||
-rw-r--r-- | examples/PrintFunctionNames/CMakeLists.txt | 21 | ||||
-rw-r--r-- | examples/PrintFunctionNames/PrintFunctionNames.cpp | 124 | ||||
-rw-r--r-- | examples/PrintFunctionNames/PrintFunctionNames.exports | 0 | ||||
-rw-r--r-- | examples/PrintFunctionNames/README.txt | 16 | ||||
-rw-r--r-- | examples/analyzer-plugin/CMakeLists.txt | 11 | ||||
-rw-r--r-- | examples/analyzer-plugin/MainCallChecker.cpp | 54 | ||||
-rw-r--r-- | examples/analyzer-plugin/SampleAnalyzerPlugin.exports | 2 | ||||
-rw-r--r-- | examples/clang-interpreter/CMakeLists.txt | 93 | ||||
-rw-r--r-- | examples/clang-interpreter/README.txt | 20 | ||||
-rw-r--r-- | examples/clang-interpreter/Test.cxx | 34 | ||||
-rw-r--r-- | examples/clang-interpreter/main.cpp | 222 |
14 files changed, 0 insertions, 707 deletions
diff --git a/examples/AnnotateFunctions/AnnotateFunctions.cpp b/examples/AnnotateFunctions/AnnotateFunctions.cpp deleted file mode 100644 index 375f18f8e09a..000000000000 --- a/examples/AnnotateFunctions/AnnotateFunctions.cpp +++ /dev/null @@ -1,88 +0,0 @@ -//===- AnnotateFunctions.cpp ----------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Example clang plugin which adds an annotation to every function in -// translation units that start with #pragma enable_annotate. -// -//===----------------------------------------------------------------------===// - -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/LexDiagnostic.h" -using namespace clang; - -namespace { - -static bool EnableAnnotate = false; -static bool HandledDecl = false; - -class AnnotateFunctionsConsumer : public ASTConsumer { -public: - bool HandleTopLevelDecl(DeclGroupRef DG) override { - HandledDecl = true; - if (!EnableAnnotate) - return true; - for (auto D : DG) - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - FD->addAttr(AnnotateAttr::CreateImplicit(FD->getASTContext(), - "example_annotation")); - return true; - } -}; - -class AnnotateFunctionsAction : public PluginASTAction { -public: - std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef) override { - return llvm::make_unique<AnnotateFunctionsConsumer>(); - } - - bool ParseArgs(const CompilerInstance &CI, - const std::vector<std::string> &args) override { - return true; - } - - PluginASTAction::ActionType getActionType() override { - return AddBeforeMainAction; - } -}; - -class PragmaAnnotateHandler : public PragmaHandler { -public: - PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { } - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &PragmaTok) override { - - Token Tok; - PP.LexUnexpandedToken(Tok); - if (Tok.isNot(tok::eod)) - PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; - - if (HandledDecl) { - DiagnosticsEngine &D = PP.getDiagnostics(); - unsigned ID = D.getCustomDiagID( - DiagnosticsEngine::Error, - "#pragma enable_annotate not allowed after declarations"); - D.Report(PragmaTok.getLocation(), ID); - } - - EnableAnnotate = true; - } -}; - -} - -static FrontendPluginRegistry::Add<AnnotateFunctionsAction> -X("annotate-fns", "annotate functions"); - -static PragmaHandlerRegistry::Add<PragmaAnnotateHandler> -Y("enable_annotate","enable annotation"); diff --git a/examples/AnnotateFunctions/CMakeLists.txt b/examples/AnnotateFunctions/CMakeLists.txt deleted file mode 100644 index 44b6317e72af..000000000000 --- a/examples/AnnotateFunctions/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_llvm_library(AnnotateFunctions MODULE AnnotateFunctions.cpp PLUGIN_TOOL clang) - -if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(AnnotateFunctions PRIVATE - clangAST - clangBasic - clangFrontend - clangLex - LLVMSupport - ) -endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 8c2654840a98..000000000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -if(NOT CLANG_BUILD_EXAMPLES) - set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON) - set(EXCLUDE_FROM_ALL ON) -endif() - -if(CLANG_ENABLE_STATIC_ANALYZER) -add_subdirectory(analyzer-plugin) -endif() -add_subdirectory(clang-interpreter) -add_subdirectory(PrintFunctionNames) -add_subdirectory(AnnotateFunctions) diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt deleted file mode 100644 index 68c6f76dff05..000000000000 --- a/examples/PrintFunctionNames/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# If we don't need RTTI or EH, there's no reason to export anything -# from the plugin. -if( NOT MSVC ) # MSVC mangles symbols differently, and - # PrintFunctionNames.export contains C++ symbols. - if( NOT LLVM_REQUIRES_RTTI ) - if( NOT LLVM_REQUIRES_EH ) - set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/PrintFunctionNames.exports) - endif() - endif() -endif() - -add_llvm_library(PrintFunctionNames MODULE PrintFunctionNames.cpp PLUGIN_TOOL clang) - -if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(PrintFunctionNames PRIVATE - clangAST - clangBasic - clangFrontend - LLVMSupport - ) -endif() diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp deleted file mode 100644 index 9f6d495caec7..000000000000 --- a/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//===- PrintFunctionNames.cpp ---------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Example clang plugin which simply prints the names of all the top-level decls -// in the input file. -// -//===----------------------------------------------------------------------===// - -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Sema/Sema.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -namespace { - -class PrintFunctionsConsumer : public ASTConsumer { - CompilerInstance &Instance; - std::set<std::string> ParsedTemplates; - -public: - PrintFunctionsConsumer(CompilerInstance &Instance, - std::set<std::string> ParsedTemplates) - : Instance(Instance), ParsedTemplates(ParsedTemplates) {} - - bool HandleTopLevelDecl(DeclGroupRef DG) override { - for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) { - const Decl *D = *i; - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n"; - } - - return true; - } - - void HandleTranslationUnit(ASTContext& context) override { - if (!Instance.getLangOpts().DelayedTemplateParsing) - return; - - // This demonstrates how to force instantiation of some templates in - // -fdelayed-template-parsing mode. (Note: Doing this unconditionally for - // all templates is similar to not using -fdelayed-template-parsig in the - // first place.) - // The advantage of doing this in HandleTranslationUnit() is that all - // codegen (when using -add-plugin) is completely finished and this can't - // affect the compiler output. - struct Visitor : public RecursiveASTVisitor<Visitor> { - const std::set<std::string> &ParsedTemplates; - Visitor(const std::set<std::string> &ParsedTemplates) - : ParsedTemplates(ParsedTemplates) {} - bool VisitFunctionDecl(FunctionDecl *FD) { - if (FD->isLateTemplateParsed() && - ParsedTemplates.count(FD->getNameAsString())) - LateParsedDecls.insert(FD); - return true; - } - - std::set<FunctionDecl*> LateParsedDecls; - } v(ParsedTemplates); - v.TraverseDecl(context.getTranslationUnitDecl()); - clang::Sema &sema = Instance.getSema(); - for (const FunctionDecl *FD : v.LateParsedDecls) { - clang::LateParsedTemplate &LPT = - *sema.LateParsedTemplateMap.find(FD)->second; - sema.LateTemplateParser(sema.OpaqueParser, LPT); - llvm::errs() << "late-parsed-decl: \"" << FD->getNameAsString() << "\"\n"; - } - } -}; - -class PrintFunctionNamesAction : public PluginASTAction { - std::set<std::string> ParsedTemplates; -protected: - std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef) override { - return llvm::make_unique<PrintFunctionsConsumer>(CI, ParsedTemplates); - } - - bool ParseArgs(const CompilerInstance &CI, - const std::vector<std::string> &args) override { - for (unsigned i = 0, e = args.size(); i != e; ++i) { - llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n"; - - // Example error handling. - DiagnosticsEngine &D = CI.getDiagnostics(); - if (args[i] == "-an-error") { - unsigned DiagID = D.getCustomDiagID(DiagnosticsEngine::Error, - "invalid argument '%0'"); - D.Report(DiagID) << args[i]; - return false; - } else if (args[i] == "-parse-template") { - if (i + 1 >= e) { - D.Report(D.getCustomDiagID(DiagnosticsEngine::Error, - "missing -parse-template argument")); - return false; - } - ++i; - ParsedTemplates.insert(args[i]); - } - } - if (!args.empty() && args[0] == "help") - PrintHelp(llvm::errs()); - - return true; - } - void PrintHelp(llvm::raw_ostream& ros) { - ros << "Help for PrintFunctionNames plugin goes here\n"; - } - -}; - -} - -static FrontendPluginRegistry::Add<PrintFunctionNamesAction> -X("print-fns", "print function names"); diff --git a/examples/PrintFunctionNames/PrintFunctionNames.exports b/examples/PrintFunctionNames/PrintFunctionNames.exports deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/examples/PrintFunctionNames/PrintFunctionNames.exports +++ /dev/null diff --git a/examples/PrintFunctionNames/README.txt b/examples/PrintFunctionNames/README.txt deleted file mode 100644 index 23ab5f0b04fa..000000000000 --- a/examples/PrintFunctionNames/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -This is a simple example demonstrating how to use clang's facility for -providing AST consumers using a plugin. - -Build the plugin by running `make` in this directory. - -Once the plugin is built, you can run it using: --- -Linux: -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.so -plugin print-fns some-input-file.c -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.so -plugin print-fns -plugin-arg-print-fns help -plugin-arg-print-fns --example-argument some-input-file.c -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.so -plugin print-fns -plugin-arg-print-fns -an-error some-input-file.c - -Mac: -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.dylib -plugin print-fns some-input-file.c -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.dylib -plugin print-fns -plugin-arg-print-fns help -plugin-arg-print-fns --example-argument some-input-file.c -$ clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.dylib -plugin print-fns -plugin-arg-print-fns -an-error some-input-file.c diff --git a/examples/analyzer-plugin/CMakeLists.txt b/examples/analyzer-plugin/CMakeLists.txt deleted file mode 100644 index 7c7b2aec1988..000000000000 --- a/examples/analyzer-plugin/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/SampleAnalyzerPlugin.exports) -add_llvm_library(SampleAnalyzerPlugin MODULE MainCallChecker.cpp PLUGIN_TOOL clang) - -if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(SampleAnalyzerPlugin PRIVATE - clangAnalysis - clangAST - clangStaticAnalyzerCore - LLVMSupport - ) -endif() diff --git a/examples/analyzer-plugin/MainCallChecker.cpp b/examples/analyzer-plugin/MainCallChecker.cpp deleted file mode 100644 index 77316d696de3..000000000000 --- a/examples/analyzer-plugin/MainCallChecker.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" - -using namespace clang; -using namespace ento; - -namespace { -class MainCallChecker : public Checker < check::PreStmt<CallExpr> > { - mutable std::unique_ptr<BugType> BT; - -public: - void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; -}; -} // end anonymous namespace - -void MainCallChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - const Expr *Callee = CE->getCallee(); - const FunctionDecl *FD = C.getSVal(Callee).getAsFunctionDecl(); - - if (!FD) - return; - - // Get the name of the callee. - IdentifierInfo *II = FD->getIdentifier(); - if (!II) // if no identifier, not a simple C function - return; - - if (II->isStr("main")) { - ExplodedNode *N = C.generateErrorNode(); - if (!N) - return; - - if (!BT) - BT.reset(new BugType(this, "call to main", "example analyzer plugin")); - - std::unique_ptr<BugReport> report = - llvm::make_unique<BugReport>(*BT, BT->getName(), N); - report->addRange(Callee->getSourceRange()); - C.emitReport(std::move(report)); - } -} - -// Register plugin! -extern "C" -void clang_registerCheckers (CheckerRegistry ®istry) { - registry.addChecker<MainCallChecker>( - "example.MainCallChecker", "Disallows calls to functions called main", - ""); -} - -extern "C" -const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING; diff --git a/examples/analyzer-plugin/SampleAnalyzerPlugin.exports b/examples/analyzer-plugin/SampleAnalyzerPlugin.exports deleted file mode 100644 index 8d9ff882cfb1..000000000000 --- a/examples/analyzer-plugin/SampleAnalyzerPlugin.exports +++ /dev/null @@ -1,2 +0,0 @@ -clang_registerCheckers -clang_analyzerAPIVersionString diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt deleted file mode 100644 index b69a82e0541b..000000000000 --- a/examples/clang-interpreter/CMakeLists.txt +++ /dev/null @@ -1,93 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Core - ExecutionEngine - MC - MCJIT - Object - OrcJit - Option - RuntimeDyld - Support - native - ) - -add_clang_executable(clang-interpreter - main.cpp - ) - -add_dependencies(clang-interpreter - clang-headers - ) - -target_link_libraries(clang-interpreter - PRIVATE - clangBasic - clangCodeGen - clangDriver - clangFrontend - clangSerialization - ) - -export_executable_symbols(clang-interpreter) - -if (MSVC) - # Is this a CMake bug that even with export_executable_symbols, Windows - # needs to explictly export the type_info vtable - set_property(TARGET clang-interpreter - APPEND_STRING PROPERTY LINK_FLAGS " /EXPORT:??_7type_info@@6B@") -endif() - -function(clang_enable_exceptions TARGET) - # Really have to jump through hoops to enable exception handling independent - # of how LLVM is being built. - if (NOT LLVM_REQUIRES_EH AND NOT LLVM_REQUIRES_RTTI) - if (MSVC) - # /EHs to allow throwing from extern "C" - set(excptnExceptions_ON "/D _HAS_EXCEPTIONS=1 /EHs /wd4714") - set(excptnExceptions_OFF "/D _HAS_EXCEPTIONS=0 /EHs-c-") - set(excptnRTTI_ON "/GR") - set(excptnRTTI_OFF "/GR-") - set(excptnEHRTTIRegEx "(/EHs(-c-?)|_HAS_EXCEPTIONS=(0|1))") - else() - set(excptnExceptions_ON "-fexceptions") - set(excptnExceptions_OFF "-fno-exceptions") - set(excptnRTTI_ON "-frtti") - set(excptnRTTI_OFF "-fno-rtti") - set(excptnEHRTTIRegEx "-f(exceptions|no-exceptions)") - endif() - if (LLVM_REQUIRES_EH) - set(excptnExceptions_DFLT ${excptnExceptions_ON}) - else() - set(excptnExceptions_DFLT ${excptnExceptions_OFF}) - endif() - if (LLVM_REQUIRES_RTTI) - set(excptnRTTI_DFLT ${excptnRTTI_ON}) - else() - set(excptnRTTI_DFLT ${excptnRTTI_OFF}) - endif() - - # Strip the exception & rtti flags from the target - get_property(addedFlags TARGET ${TARGET} PROPERTY COMPILE_FLAGS) - string(REGEX REPLACE ${excptnEHRTTIRegEx} "" editedFlags "${addedFlags}") - string(REPLACE ${excptnRTTI_OFF} "" editedFlags "${editedFlags}") - set_property(TARGET ${TARGET} PROPERTY COMPILE_FLAGS "${editedFlags}") - - get_property(addedFlags TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS) - string(REGEX REPLACE ${excptnEHRTTIRegEx} "" editedFlags "${addedFlags}") - string(REPLACE ${excptnRTTI_OFF} "" editedFlags "${editedFlags}") - set_property(TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS "${editedFlags}") - - # Re-add the exception & rtti flags from LLVM - set_property(SOURCE main.cpp APPEND_STRING PROPERTY COMPILE_FLAGS - " ${excptnExceptions_DFLT} ${excptnRTTI_DFLT} ") - set_property(SOURCE Manager.cpp APPEND_STRING PROPERTY COMPILE_FLAGS - " ${excptnExceptions_DFLT} ${excptnRTTI_DFLT} ") - - # Invoke with exceptions & rtti - set_property(SOURCE Invoke.cpp APPEND_STRING PROPERTY COMPILE_FLAGS - " ${excptnExceptions_ON} ${excptnRTTI_ON} ") - - endif() -endfunction(clang_enable_exceptions) - -clang_enable_exceptions(clang-interpreter) diff --git a/examples/clang-interpreter/README.txt b/examples/clang-interpreter/README.txt deleted file mode 100644 index b4f8a935cef8..000000000000 --- a/examples/clang-interpreter/README.txt +++ /dev/null @@ -1,20 +0,0 @@ -This is an example of Clang based interpreter, for executing standalone C/C++ -programs. - -It demonstrates the following features: - 1. Parsing standard compiler command line arguments using the Driver library. - - 2. Constructing a Clang compiler instance, using the appropriate arguments - derived in step #1. - - 3. Invoking the Clang compiler to lex, parse, syntax check, and then generate - LLVM code. - - 4. Use the LLVM JIT functionality to execute the final module. - - 5. Intercepting a Win64 library call to allow throwing and catching exceptions - in and from the JIT. - -The implementation has many limitations and is not designed to be a full fledged -interpreter. It is designed to demonstrate a simple but functional use of the -Clang compiler libraries. diff --git a/examples/clang-interpreter/Test.cxx b/examples/clang-interpreter/Test.cxx deleted file mode 100644 index d39249214dc5..000000000000 --- a/examples/clang-interpreter/Test.cxx +++ /dev/null @@ -1,34 +0,0 @@ -//===-- examples/clang-interpreter/Test.cxx - Clang C Interpreter Example -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// Example throwing in and from the JIT (particularly on Win64). -// -// ./bin/clang-interpreter <src>/tools/clang/examples/clang-interpreter/Test.cxx - -#include <stdexcept> -#include <stdio.h> - -static void ThrowerAnError(const char* Name) { - throw std::runtime_error(Name); -} - -int main(int argc, const char** argv) { - for (int I = 0; I < argc; ++I) - printf("arg[%d]='%s'\n", I, argv[I]); - - try { - ThrowerAnError("In JIT"); - } catch (const std::exception& E) { - printf("Caught: '%s'\n", E.what()); - } catch (...) { - printf("Unknown exception\n"); - } - ThrowerAnError("From JIT"); - return 0; -} diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp deleted file mode 100644 index 1c83b1d3e75f..000000000000 --- a/examples/clang-interpreter/main.cpp +++ /dev/null @@ -1,222 +0,0 @@ -//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/Driver/Compilation.h" -#include "clang/Driver/Driver.h" -#include "clang/Driver/Tool.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" - -using namespace clang; -using namespace clang::driver; - -// This function isn't referenced outside its translation unit, but it -// can't use the "static" keyword because its address is used for -// GetMainExecutable (since some platforms don't support taking the -// address of main, and some platforms can't implement GetMainExecutable -// without being given the address of a function in the main executable). -std::string GetExecutablePath(const char *Argv0, void *MainAddr) { - return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); -} - -namespace llvm { -namespace orc { - -class SimpleJIT { -private: - ExecutionSession ES; - std::shared_ptr<SymbolResolver> Resolver; - std::unique_ptr<TargetMachine> TM; - const DataLayout DL; - LegacyRTDyldObjectLinkingLayer ObjectLayer; - LegacyIRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; - -public: - SimpleJIT() - : Resolver(createLegacyLookupResolver( - ES, - [this](const std::string &Name) -> JITSymbol { - if (auto Sym = CompileLayer.findSymbol(Name, false)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - if (auto SymAddr = - RTDyldMemoryManager::getSymbolAddressInProcess(Name)) - return JITSymbol(SymAddr, JITSymbolFlags::Exported); - return nullptr; - }, - [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })), - TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), - ObjectLayer(ES, - [this](VModuleKey) { - return LegacyRTDyldObjectLinkingLayer::Resources{ - std::make_shared<SectionMemoryManager>(), Resolver}; - }), - CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { - llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); - } - - const TargetMachine &getTargetMachine() const { return *TM; } - - VModuleKey addModule(std::unique_ptr<Module> M) { - // Add the module to the JIT with a new VModuleKey. - auto K = ES.allocateVModule(); - cantFail(CompileLayer.addModule(K, std::move(M))); - return K; - } - - JITSymbol findSymbol(const StringRef &Name) { - std::string MangledName; - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, DL); - return CompileLayer.findSymbol(MangledNameStream.str(), true); - } - - JITTargetAddress getSymbolAddress(const StringRef &Name) { - return cantFail(findSymbol(Name).getAddress()); - } - - void removeModule(VModuleKey K) { - cantFail(CompileLayer.removeModule(K)); - } -}; - -} // end namespace orc -} // end namespace llvm - -int main(int argc, const char **argv) { - // This just needs to be some symbol in the binary; C++ doesn't - // allow taking the address of ::main however. - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - std::string Path = GetExecutablePath(argv[0], MainAddr); - IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); - TextDiagnosticPrinter *DiagClient = - new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); - - IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); - DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); - - const std::string TripleStr = llvm::sys::getProcessTriple(); - llvm::Triple T(TripleStr); - - // Use ELF on Windows-32 and MingW for now. -#ifndef CLANG_INTERPRETER_COFF_FORMAT - if (T.isOSBinFormatCOFF()) - T.setObjectFormat(llvm::Triple::ELF); -#endif - - Driver TheDriver(Path, T.str(), Diags); - TheDriver.setTitle("clang interpreter"); - TheDriver.setCheckInputsExist(false); - - // FIXME: This is a hack to try to force the driver to do something we can - // recognize. We need to extend the driver library to support this use model - // (basically, exactly one input, and the operation mode is hard wired). - SmallVector<const char *, 16> Args(argv, argv + argc); - Args.push_back("-fsyntax-only"); - std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args)); - if (!C) - return 0; - - // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate. - - // We expect to get back exactly one command job, if we didn't something - // failed. Extract that job from the compilation. - const driver::JobList &Jobs = C->getJobs(); - if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { - SmallString<256> Msg; - llvm::raw_svector_ostream OS(Msg); - Jobs.Print(OS, "; ", true); - Diags.Report(diag::err_fe_expected_compiler_job) << OS.str(); - return 1; - } - - const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin()); - if (llvm::StringRef(Cmd.getCreator().getName()) != "clang") { - Diags.Report(diag::err_fe_expected_clang_command); - return 1; - } - - // Initialize a compiler invocation object from the clang (-cc1) arguments. - const llvm::opt::ArgStringList &CCArgs = Cmd.getArguments(); - std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation); - CompilerInvocation::CreateFromArgs(*CI, - const_cast<const char **>(CCArgs.data()), - const_cast<const char **>(CCArgs.data()) + - CCArgs.size(), - Diags); - - // Show the invocation, with -v. - if (CI->getHeaderSearchOpts().Verbose) { - llvm::errs() << "clang invocation:\n"; - Jobs.Print(llvm::errs(), "\n", true); - llvm::errs() << "\n"; - } - - // FIXME: This is copied from cc1_main.cpp; simplify and eliminate. - - // Create a compiler instance to handle the actual work. - CompilerInstance Clang; - Clang.setInvocation(std::move(CI)); - - // Create the compilers actual diagnostics engine. - Clang.createDiagnostics(); - if (!Clang.hasDiagnostics()) - return 1; - - // Infer the builtin include path if unspecified. - if (Clang.getHeaderSearchOpts().UseBuiltinIncludes && - Clang.getHeaderSearchOpts().ResourceDir.empty()) - Clang.getHeaderSearchOpts().ResourceDir = - CompilerInvocation::GetResourcesPath(argv[0], MainAddr); - - // Create and execute the frontend to generate an LLVM bitcode module. - std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction()); - if (!Clang.ExecuteAction(*Act)) - return 1; - - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - int Res = 255; - std::unique_ptr<llvm::Module> Module = Act->takeModule(); - - if (Module) { - llvm::orc::SimpleJIT J; - auto H = J.addModule(std::move(Module)); - auto Main = (int(*)(...))J.getSymbolAddress("main"); - Res = Main(); - J.removeModule(H); - } - - // Shutdown. - llvm::llvm_shutdown(); - - return Res; -} |