forked from OSchip/llvm-project
Add pluggable action support to clang-cc, via -plugin command line option.
- Expects the plugin has been loaded with -load. - Using this may require disabling TOOL_NO_EXPORTS in the clang-cc Makefile, this breaks the llvm::Registry way of working (static constructors are bad, kids). This should be replaced with a "real" plugin model that has explicit plugin interfaces. llvm-svn: 88824
This commit is contained in:
parent
f5b2869b75
commit
d392dd0709
|
@ -28,6 +28,8 @@ def err_fe_no_fixit_and_codegen : Error<
|
|||
"FIX-ITs cannot be applied when generating code">;
|
||||
def err_fe_unable_to_find_fixit_file : Error<
|
||||
"FIX-IT could not find file '%0'">;
|
||||
def err_fe_invalid_plugin_name : Error<
|
||||
"unable to find plugin '%0'">;
|
||||
|
||||
def err_verify_bogus_characters : Error<
|
||||
"bogus characters before '{{' in expected string">;
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace frontend {
|
|||
ParseNoop, ///< Parse with noop callbacks.
|
||||
ParsePrintCallbacks, ///< Parse and print each callback.
|
||||
ParseSyntaxOnly, ///< Parse and perform semantic analysis.
|
||||
PluginAction, ///< Run a plugin action, \see ActionName.
|
||||
PrintDeclContext, ///< Print DeclContext and their Decls.
|
||||
PrintPreprocessedInput, ///< -E mode.
|
||||
RewriteBlocks, ///< ObjC->C Rewriter for Blocks.
|
||||
|
@ -109,12 +110,16 @@ public:
|
|||
/// The frontend action to perform.
|
||||
frontend::ActionKind ProgramAction;
|
||||
|
||||
/// The name of the action to run when using a plugin action.
|
||||
std::string ActionName;
|
||||
|
||||
public:
|
||||
FrontendOptions() {
|
||||
DebugCodeCompletionPrinter = 0;
|
||||
DisableFree = 0;
|
||||
EmptyInputOnly = 0;
|
||||
ProgramAction = frontend::ParseSyntaxOnly;
|
||||
ActionName = "";
|
||||
RelocatablePCH = 0;
|
||||
ShowMacrosInCodeCompletion = 0;
|
||||
ShowStats = 0;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
|
||||
#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
|
||||
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "llvm/Support/Registry.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// The frontend plugin registry.
|
||||
typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
|
@ -26,6 +26,7 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/RegistryParser.h"
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace clang;
|
||||
|
@ -383,6 +384,11 @@ OutputFile("o",
|
|||
llvm::cl::value_desc("path"),
|
||||
llvm::cl::desc("Specify output file"));
|
||||
|
||||
static llvm::cl::opt<std::string>
|
||||
PluginActionName("plugin",
|
||||
llvm::cl::desc("Use the named plugin action "
|
||||
"(use \"help\" to list available options)"));
|
||||
|
||||
static llvm::cl::opt<ActionKind>
|
||||
ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
|
||||
llvm::cl::init(ParseSyntaxOnly),
|
||||
|
@ -885,12 +891,18 @@ void clang::InitializeDiagnosticOptions(DiagnosticOptions &Opts) {
|
|||
void clang::InitializeFrontendOptions(FrontendOptions &Opts) {
|
||||
using namespace frontendoptions;
|
||||
|
||||
// Select program action.
|
||||
Opts.ProgramAction = ProgAction;
|
||||
if (PluginActionName.getPosition()) {
|
||||
Opts.ProgramAction = frontend::PluginAction;
|
||||
Opts.ActionName = PluginActionName;
|
||||
}
|
||||
|
||||
Opts.CodeCompletionAt = CodeCompletionAt;
|
||||
Opts.DebugCodeCompletionPrinter = CodeCompletionDebugPrinter;
|
||||
Opts.DisableFree = DisableFree;
|
||||
Opts.EmptyInputOnly = EmptyInputOnly;
|
||||
Opts.FixItLocations = FixItAtLocations;
|
||||
Opts.ProgramAction = ProgAction;
|
||||
Opts.OutputFile = OutputFile;
|
||||
Opts.RelocatablePCH = RelocatablePCH;
|
||||
Opts.ShowMacrosInCodeCompletion = CodeCompletionWantsMacros;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||
#include "clang/Frontend/FrontendPluginRegistry.h"
|
||||
#include "clang/Frontend/PathDiagnosticClients.h"
|
||||
#include "clang/Frontend/PreprocessorOptions.h"
|
||||
#include "clang/Frontend/PreprocessorOutputOptions.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/PluginLoader.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Registry.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/System/Host.h"
|
||||
|
@ -81,11 +83,13 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
|
|||
/// anything.
|
||||
llvm::Timer *ClangFrontendTimer = 0;
|
||||
|
||||
static FrontendAction *CreateFrontendAction(frontend::ActionKind AK) {
|
||||
static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
|
||||
using namespace clang::frontend;
|
||||
|
||||
switch (AK) {
|
||||
default: return 0;
|
||||
switch (CI.getFrontendOpts().ProgramAction) {
|
||||
default:
|
||||
llvm::llvm_unreachable("Invalid program action!");
|
||||
|
||||
case ASTDump: return new ASTDumpAction();
|
||||
case ASTPrint: return new ASTPrintAction();
|
||||
case ASTPrintXML: return new ASTPrintXMLAction();
|
||||
|
@ -105,6 +109,30 @@ static FrontendAction *CreateFrontendAction(frontend::ActionKind AK) {
|
|||
case ParseNoop: return new ParseOnlyAction();
|
||||
case ParsePrintCallbacks: return new PrintParseAction();
|
||||
case ParseSyntaxOnly: return new SyntaxOnlyAction();
|
||||
|
||||
case PluginAction: {
|
||||
if (CI.getFrontendOpts().ActionName == "help") {
|
||||
llvm::errs() << "clang-cc plugins:\n";
|
||||
for (FrontendPluginRegistry::iterator it =
|
||||
FrontendPluginRegistry::begin(),
|
||||
ie = FrontendPluginRegistry::end();
|
||||
it != ie; ++it)
|
||||
llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (FrontendPluginRegistry::iterator it =
|
||||
FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
|
||||
it != ie; ++it) {
|
||||
if (it->getName() == CI.getFrontendOpts().ActionName)
|
||||
return it->instantiate();
|
||||
}
|
||||
|
||||
CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
|
||||
<< CI.getFrontendOpts().ActionName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case PrintDeclContext: return new DeclContextPrintAction();
|
||||
case PrintPreprocessedInput: return new PrintPreprocessedAction();
|
||||
case RewriteBlocks: return new RewriteBlocksAction();
|
||||
|
@ -279,9 +307,10 @@ int main(int argc, char **argv) {
|
|||
Clang.createPreprocessor();
|
||||
}
|
||||
|
||||
llvm::OwningPtr<FrontendAction> Act(
|
||||
CreateFrontendAction(Clang.getFrontendOpts().ProgramAction));
|
||||
assert(Act && "Invalid program action!");
|
||||
llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
|
||||
if (!Act)
|
||||
break;
|
||||
|
||||
Act->setCurrentTimer(ClangFrontendTimer);
|
||||
if (Act->BeginSourceFile(Clang, InFile, IsAST)) {
|
||||
Act->Execute();
|
||||
|
@ -315,3 +344,4 @@ int main(int argc, char **argv) {
|
|||
|
||||
return (Clang.getDiagnostics().getNumErrors() != 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue