Index: examples/PrintFunctionNames/CMakeLists.txt =================================================================== --- examples/PrintFunctionNames/CMakeLists.txt +++ examples/PrintFunctionNames/CMakeLists.txt @@ -10,6 +10,7 @@ endif() add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp) +target_link_libraries(PrintFunctionNames libclang) if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) target_link_libraries(PrintFunctionNames ${cmake_2_8_12_PRIVATE} Index: examples/PrintFunctionNames/PrintFunctionNames.cpp =================================================================== --- examples/PrintFunctionNames/PrintFunctionNames.cpp +++ examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -23,26 +23,36 @@ class PrintFunctionsConsumer : public ASTConsumer { public: + PrintFunctionsConsumer(const CompilerInstance &CI) : CI(CI) {} + virtual bool HandleTopLevelDecl(DeclGroupRef DG) { + DiagnosticsEngine &DE = CI.getDiagnostics(); for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) { const Decl *D = *i; - if (const NamedDecl *ND = dyn_cast(D)) + if (const NamedDecl *ND = dyn_cast(D)) { llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n"; + unsigned DiagID = DE.getCustomDiagID(DiagnosticsEngine::Error, + "functions are bad '%0'"); + DE.Report(ND->getLocStart(), DiagID) << ND->getNameAsString(); + } } return true; } + +private: + const CompilerInstance &CI; }; class PrintFunctionNamesAction : public PluginASTAction { protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) { - return llvm::make_unique(); + return llvm::make_unique(CI); } bool ParseArgs(const CompilerInstance &CI, - const std::vector& args) { + const std::vector &args) { for (unsigned i = 0, e = args.size(); i != e; ++i) { llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n"; @@ -60,13 +70,11 @@ return true; } - void PrintHelp(llvm::raw_ostream& ros) { + void PrintHelp(llvm::raw_ostream &ros) { ros << "Help for PrintFunctionNames plugin goes here\n"; } - }; - } static FrontendPluginRegistry::Add -X("print-fns", "print function names"); + X("print-fns", "print function names"); Index: include/clang/Frontend/CompilerInstance.h =================================================================== --- include/clang/Frontend/CompilerInstance.h +++ include/clang/Frontend/CompilerInstance.h @@ -709,6 +709,9 @@ void addDependencyCollector(std::shared_ptr Listener) { DependencyCollectors.push_back(std::move(Listener)); } + + /// \brief Load plugins that were added by -load + void loadPlugins(); }; } // end namespace clang Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -1130,6 +1130,8 @@ llvm::CrashRecoveryContextCleanupRegistrar ActCleanup(Act.get()); + Clang->loadPlugins(); + if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) goto error; Index: lib/Frontend/CompilerInstance.cpp =================================================================== --- lib/Frontend/CompilerInstance.cpp +++ lib/Frontend/CompilerInstance.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/DynamicLibrary.h" #include #include #include @@ -1619,3 +1620,15 @@ return false; } void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } + +void +CompilerInstance::loadPlugins(){ + for (unsigned i = 0, e = getFrontendOpts().Plugins.size(); i != e; ++i) { + const std::string &Path = getFrontendOpts().Plugins[i]; + std::string Error; + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) + << Path << Error; + } +} + Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -180,14 +180,7 @@ } // Load any requested plugins. - for (unsigned i = 0, - e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { - const std::string &Path = Clang->getFrontendOpts().Plugins[i]; - std::string Error; - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) - Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) - << Path << Error; - } + Clang->loadPlugins(); // Honor -mllvm. // Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -301,3 +301,20 @@ clang_VirtualFileOverlay_dispose clang_VirtualFileOverlay_setCaseSensitivity clang_VirtualFileOverlay_writeToBuffer +_ZN5clang15PluginASTAction6anchorEv +_ZN4llvm11raw_ostream5writeEPKcm +_ZN4llvm4errsEv +_ZN5clang11ASTConsumer33HandleTopLevelDeclInObjCContainerENS_12DeclGroupRefE +_ZN5clang14FrontendActionD2Ev +_ZN5clang13DiagnosticIDs15getCustomDiagIDENS0_5LevelEN4llvm9StringRefE +_ZN5clang17ASTFrontendAction13ExecuteActionEv +_ZN5clang11ASTConsumer24HandleImplicitImportDeclEPNS_10ImportDeclE +_ZN5clang14FrontendAction22shouldEraseOutputFilesEv +_ZNK5clang15DeclarationName11getAsStringEv +_ZN5clang17DiagnosticsEngine21EmitCurrentDiagnosticEb +_ZN5clang11ASTConsumer21HandleInterestingDeclENS_12DeclGroupRefE +_ZN5clang14FrontendActionC2Ev +_ZN4llvm8RegistryIN5clang15PluginASTActionENS_14RegistryTraitsIS2_EEE4nodeC1ERKNS_19SimpleRegistryEntryIS2_EE +_ZTVN5clang15PluginASTActionE +_ZTVN5clang17ASTFrontendActionE +_ZTVN5clang11ASTConsumerE