Frontend: Allow passing -cc1 level arguments to plugins. Patch by Troy Straszheim!
llvm-svn: 106113
This commit is contained in:
parent
26036fd722
commit
7c995e8fac
|
@ -31,11 +31,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PrintFunctionNamesAction : public ASTFrontendAction {
|
||||
class PrintFunctionNamesAction : public PluginASTAction {
|
||||
protected:
|
||||
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
|
||||
return new PrintFunctionsConsumer();
|
||||
}
|
||||
|
||||
bool ParseArgs(const std::vector<std::string>& args) {
|
||||
for (unsigned i=0; i<args.size(); ++i)
|
||||
llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
|
||||
if (args.size() && args[0] == "help")
|
||||
PrintHelp(llvm::errs());
|
||||
|
||||
return true;
|
||||
}
|
||||
void PrintHelp(llvm::raw_ostream& ros) {
|
||||
ros << "Help for PrintFunctionNames plugin goes here\n";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -264,8 +264,11 @@ def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
|
|||
def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
|
||||
def load : Separate<"-load">, MetaVarName<"<dsopath>">,
|
||||
HelpText<"Load the named plugin (dynamic shared object)">;
|
||||
def plugin : Separate<"-plugin">,
|
||||
def plugin : Separate<"-plugin">, MetaVarName<"<name>">,
|
||||
HelpText<"Use the named plugin action (use \"help\" to list available options)">;
|
||||
def plugin_arg : JoinedAndSeparate<"-plugin-arg-">,
|
||||
MetaVarName<"<name> <arg>">,
|
||||
HelpText<"Pass <arg> to plugin <name>">;
|
||||
def resource_dir : Separate<"-resource-dir">,
|
||||
HelpText<"The directory which holds the compiler resource files">;
|
||||
def version : Flag<"-version">,
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class ASTConsumer;
|
||||
|
@ -214,6 +219,16 @@ public:
|
|||
virtual bool usesPreprocessorOnly() const { return false; }
|
||||
};
|
||||
|
||||
class PluginASTAction : public ASTFrontendAction {
|
||||
protected:
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
|
||||
llvm::StringRef InFile) = 0;
|
||||
|
||||
public:
|
||||
virtual bool ParseArgs(const std::vector<std::string>& arg) = 0;
|
||||
virtual void PrintHelp(llvm::raw_ostream&) = 0;
|
||||
};
|
||||
|
||||
/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
|
||||
/// based frontend actions.
|
||||
class PreprocessorFrontendAction : public FrontendAction {
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
/// The name of the action to run when using a plugin action.
|
||||
std::string ActionName;
|
||||
|
||||
/// Arg to pass to the plugin
|
||||
std::vector<std::string> PluginArgs;
|
||||
|
||||
/// The list of plugins to load.
|
||||
std::vector<std::string> Plugins;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
namespace clang {
|
||||
|
||||
/// The frontend plugin registry.
|
||||
typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
|
||||
typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
|
|||
case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
|
||||
assert(0 && "Invalid option with help text.");
|
||||
|
||||
case Option::MultiArgClass: case Option::JoinedAndSeparateClass:
|
||||
case Option::MultiArgClass:
|
||||
assert(0 && "Cannot print metavar for this kind of option.");
|
||||
|
||||
case Option::FlagClass:
|
||||
|
@ -277,6 +277,7 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
|
|||
Name += ' ';
|
||||
// FALLTHROUGH
|
||||
case Option::JoinedClass: case Option::CommaJoinedClass:
|
||||
case Option::JoinedAndSeparateClass:
|
||||
if (const char *MetaVarName = Opts.getOptionMetaVar(Id))
|
||||
Name += MetaVarName;
|
||||
else
|
||||
|
|
|
@ -397,6 +397,10 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
|
|||
if (!Opts.ActionName.empty()) {
|
||||
Res.push_back("-plugin");
|
||||
Res.push_back(Opts.ActionName);
|
||||
for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i) {
|
||||
Res.push_back("-plugin-arg-" + Opts.ActionName);
|
||||
Res.push_back(Opts.PluginArgs[i]);
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) {
|
||||
Res.push_back("-load");
|
||||
|
@ -989,9 +993,17 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
|||
Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
|
||||
}
|
||||
}
|
||||
if (const Arg *A = Args.getLastArg(OPT_plugin)) {
|
||||
|
||||
if (const Arg* A = Args.getLastArg(OPT_plugin)) {
|
||||
Opts.Plugins.push_back(A->getValue(Args,0));
|
||||
Opts.ProgramAction = frontend::PluginAction;
|
||||
Opts.ActionName = A->getValue(Args);
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
||||
end = Args.filtered_end(); it != end; ++it) {
|
||||
if ((*it)->getValue(Args, 0) == Opts.ActionName)
|
||||
Opts.PluginArgs.push_back((*it)->getValue(Args, 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
|
||||
|
|
|
@ -85,21 +85,15 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
|
|||
case ParseSyntaxOnly: return new SyntaxOnlyAction();
|
||||
|
||||
case PluginAction: {
|
||||
if (CI.getFrontendOpts().ActionName == "help") {
|
||||
llvm::errs() << "clang -cc1 plugins:\n";
|
||||
for (FrontendPluginRegistry::iterator it =
|
||||
FrontendPluginRegistry::begin(),
|
||||
ie = FrontendPluginRegistry::end();
|
||||
it != ie; ++it)
|
||||
llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (FrontendPluginRegistry::iterator it =
|
||||
FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
|
||||
it != ie; ++it) {
|
||||
if (it->getName() == CI.getFrontendOpts().ActionName)
|
||||
return it->instantiate();
|
||||
if (it->getName() == CI.getFrontendOpts().ActionName) {
|
||||
PluginASTAction* plugin = it->instantiate();
|
||||
plugin->ParseArgs(CI.getFrontendOpts().PluginArgs);
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
|
||||
|
|
Loading…
Reference in New Issue