From: Mikhail Glushenkov Date: Tue, 15 Dec 2009 07:20:50 +0000 (+0000) Subject: Support hook invocation from 'append_cmd'. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=545f96814bd881d57d961aa51465e977f9172b2d;p=oota-llvm.git Support hook invocation from 'append_cmd'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91419 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/LLVMC/AppendCmdHook.td b/test/LLVMC/AppendCmdHook.td new file mode 100644 index 00000000000..888d6869999 --- /dev/null +++ b/test/LLVMC/AppendCmdHook.td @@ -0,0 +1,28 @@ +// Check that hooks can be invoked from 'append_cmd'. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: FileCheck -input-file=%t %s +// RUN: %compile_cxx -fexceptions -x c++ %t + +include "llvm/CompilerDriver/Common.td" + +// CHECK: std::string MyHook() + +def OptList : OptionList<[ +(switch_option "dummy1", (help "none")), +(switch_option "dummy2", (help "none")) +]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd $INFILE"), +(in_language "dummy_lang"), +(out_language "dummy_lang"), +(actions (case + // CHECK: push_back("-arg1") + // CHECK: push_back("-arg2") + (switch_on "dummy1"), (append_cmd "-arg1 -arg2"), + // CHECK: push_back("-arg3") + // CHECK: hooks::MyHook() + (switch_on "dummy2"), (append_cmd "-arg3 $CALL(MyHook)"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; diff --git a/test/LLVMC/OutputSuffixHook.td b/test/LLVMC/OutputSuffixHook.td new file mode 100644 index 00000000000..d1f9999b15c --- /dev/null +++ b/test/LLVMC/OutputSuffixHook.td @@ -0,0 +1,24 @@ +// Check that hooks can be invoked from 'output_suffix'. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: FileCheck -input-file=%t %s +// RUN: %compile_cxx -fexceptions -x c++ %t +// XFAIL: * + +include "llvm/CompilerDriver/Common.td" + +// CHECK: std::string MyHook() + +def OptList : OptionList<[ +(switch_option "dummy1", (help "none")) +]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd $INFILE"), +(in_language "dummy_lang"), +(out_language "dummy_lang"), +(actions (case + // CHECK: hooks::MyHook() + (switch_on "dummy1"), (output_suffix "$CALL(MyHook)"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 69001dd2759..6217f5c1d34 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -15,8 +15,6 @@ #include "Record.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include @@ -1454,9 +1452,9 @@ void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel, EmitCaseStatementCallback(Callback, O), IndentLevel); } -/// TokenizeCmdline - converts from "$CALL(HookName, 'Arg1', 'Arg2')/path" to -/// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path"] . -/// Helper function used by EmitCmdLineVecFill and. +/// TokenizeCmdline - converts from +/// "$CALL(HookName, 'Arg1', 'Arg2')/path -arg1 -arg2" to +/// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path", "-arg1", "-arg2"]. void TokenizeCmdline(const std::string& CmdLine, StrVector& Out) { const char* Delimiters = " \t\n\v\f\r"; enum TokenizerState @@ -1823,17 +1821,36 @@ class EmitActionHandlersCallback const OptionDescriptions& OptDescs; typedef EmitActionHandlersCallbackHandler Handler; - void onAppendCmd (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const + /// EmitHookInvocation - Common code for hook invocation from actions. Used by + /// onAppendCmd and onOutputSuffix. + void EmitHookInvocation(const std::string& Str, + const char* BlockOpen, const char* BlockClose, + unsigned IndentLevel, raw_ostream& O) const { - checkNumberOfArguments(&Dag, 1); - const std::string& Cmd = InitPtrToString(Dag.getArg(0)); StrVector Out; - llvm::SplitString(Cmd, Out); + TokenizeCmdline(Str, Out); for (StrVector::const_iterator B = Out.begin(), E = Out.end(); - B != E; ++B) - O.indent(IndentLevel) << "vec.push_back(\"" << *B << "\");\n"; + B != E; ++B) { + const std::string& cmd = *B; + + O.indent(IndentLevel) << BlockOpen; + + if (cmd.at(0) == '$') + B = SubstituteSpecialCommands(B, E, /* IsJoin = */ true, O); + else + O << '"' << cmd << '"'; + + O << BlockClose; + } + } + + void onAppendCmd (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 1); + this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)), + "vec.push_back(", ");\n", IndentLevel, O); } void onForward (const DagInit& Dag, @@ -1886,13 +1903,12 @@ class EmitActionHandlersCallback << (D.isParameter() ? ".c_str()" : "") << "));\n"; } - void onOutputSuffix (const DagInit& Dag, unsigned IndentLevel, raw_ostream& O) const { checkNumberOfArguments(&Dag, 1); - const std::string& OutSuf = InitPtrToString(Dag.getArg(0)); - O.indent(IndentLevel) << "output_suffix = \"" << OutSuf << "\";\n"; + this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)), + "output_suffix = ", ";\n", IndentLevel, O); } void onStopCompilation (const DagInit& Dag, @@ -2521,7 +2537,9 @@ public: {} void onAction (const DagInit& Dag) { - if (GetOperatorName(Dag) == "forward_transformed_value") { + const std::string& Name = GetOperatorName(Dag); + + if (Name == "forward_transformed_value") { checkNumberOfArguments(Dag, 2); const std::string& OptName = InitPtrToString(Dag.getArg(0)); const std::string& HookName = InitPtrToString(Dag.getArg(1)); @@ -2530,29 +2548,16 @@ public: HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook : HookInfo::ArgHook); } - } - - void operator()(const Init* Arg) { - - // We're invoked on an action (either a dag or a dag list). - if (typeid(*Arg) == typeid(DagInit)) { - const DagInit& Dag = InitPtrToDag(Arg); - this->onAction(Dag); - return; - } - else if (typeid(*Arg) == typeid(ListInit)) { - const ListInit& List = InitPtrToList(Arg); - for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E; - ++B) { - const DagInit& Dag = InitPtrToDag(*B); - this->onAction(Dag); - } - return; + else if (Name == "append_cmd" || Name == "output_suffix") { + checkNumberOfArguments(Dag, 1); + this->onCmdLine(InitPtrToString(Dag.getArg(0))); } + } - // We're invoked on a command line. + void onCmdLine(const std::string& Cmd) { StrVector cmds; - TokenizeCmdline(InitPtrToString(Arg), cmds); + TokenizeCmdline(Cmd, cmds); + for (StrVector::const_iterator B = cmds.begin(), E = cmds.end(); B != E; ++B) { const std::string& cmd = *B; @@ -2562,7 +2567,6 @@ public: checkedIncrement(B, E, "Syntax error in $CALL invocation!"); const std::string& HookName = *B; - if (HookName.at(0) == ')') throw "$CALL invoked with no arguments!"; @@ -2578,9 +2582,30 @@ public: + HookName; else HookNames_[HookName] = HookInfo(NumArgs); + } + } + } + + void operator()(const Init* Arg) { + // We're invoked on an action (either a dag or a dag list). + if (typeid(*Arg) == typeid(DagInit)) { + const DagInit& Dag = InitPtrToDag(Arg); + this->onAction(Dag); + return; + } + else if (typeid(*Arg) == typeid(ListInit)) { + const ListInit& List = InitPtrToList(Arg); + for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E; + ++B) { + const DagInit& Dag = InitPtrToDag(*B); + this->onAction(Dag); } + return; } + + // We're invoked on a command line. + this->onCmdLine(InitPtrToString(Arg)); } void operator()(const DagInit* Test, unsigned, bool) {