diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 46c60781cad..84e8783d20a 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -96,9 +96,6 @@ def unset_option; // Increase the edge weight. def inc_weight; -// Empty DAG marker. -def empty_dag_marker; - // Option list - a single place to specify options. class OptionList l> { list options = l; @@ -111,31 +108,17 @@ class OptionPreprocessor { // Map from suffixes to language names -class LangToSuffixes lst> { - string lang = str; - list suffixes = lst; -} +def lang_to_suffixes; -class LanguageMap lst> { - list map = lst; +class LanguageMap l> { + list map = l; } // Compilation graph -class EdgeBase { - string a = t1; - string b = t2; - dag weight = d; -} - -class Edge : EdgeBase; - -// Edge and SimpleEdge are synonyms. -class SimpleEdge : EdgeBase; - -// Optionally enabled edge. -class OptionalEdge : EdgeBase; - -class CompilationGraph lst> { - list edges = lst; +def edge; +def optional_edge; + +class CompilationGraph l> { + list edges = l; } diff --git a/test/LLVMC/Alias.td b/test/LLVMC/Alias.td index 45f7296b720..88e142dae27 100644 --- a/test/LLVMC/Alias.td +++ b/test/LLVMC/Alias.td @@ -21,4 +21,4 @@ def dummy_tool : Tool<[ (switch_on "dummy1"), (forward "dummy1"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/AppendCmdHook.td b/test/LLVMC/AppendCmdHook.td index b7e73fc4205..690ece779df 100644 --- a/test/LLVMC/AppendCmdHook.td +++ b/test/LLVMC/AppendCmdHook.td @@ -26,4 +26,4 @@ def dummy_tool : Tool<[ (switch_on "dummy2"), (append_cmd "-arg3 $CALL(MyHook)"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/EnvParentheses.td b/test/LLVMC/EnvParentheses.td index dbbb171d23f..403beb9521f 100644 --- a/test/LLVMC/EnvParentheses.td +++ b/test/LLVMC/EnvParentheses.td @@ -13,6 +13,6 @@ def dummy_tool : Tool<[ (out_language "dummy") ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; def Graph : CompilationGraph<[]>; diff --git a/test/LLVMC/ForwardAs.td b/test/LLVMC/ForwardAs.td index 521f3c291e2..326e94b0e86 100644 --- a/test/LLVMC/ForwardAs.td +++ b/test/LLVMC/ForwardAs.td @@ -18,4 +18,4 @@ def dummy_tool : Tool<[ (not_empty "dummy"), (forward_as "dummy", "unique_name"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/ForwardTransformedValue.td b/test/LLVMC/ForwardTransformedValue.td index a390d03d89f..10038f68d3e 100644 --- a/test/LLVMC/ForwardTransformedValue.td +++ b/test/LLVMC/ForwardTransformedValue.td @@ -24,4 +24,4 @@ def dummy_tool : Tool<[ (not_empty "b"), (forward_transformed_value "b", "HookB"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/ForwardValue.td b/test/LLVMC/ForwardValue.td index 93368f482a8..402fa50f7a2 100644 --- a/test/LLVMC/ForwardValue.td +++ b/test/LLVMC/ForwardValue.td @@ -21,4 +21,4 @@ def dummy_tool : Tool<[ (not_empty "b"), (forward_value "b"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/HookWithArguments.td b/test/LLVMC/HookWithArguments.td index ba5f8201f72..b3260a973b8 100644 --- a/test/LLVMC/HookWithArguments.td +++ b/test/LLVMC/HookWithArguments.td @@ -17,4 +17,4 @@ def dummy_tool : Tool<[ (out_language "dummy") ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/HookWithInFile.td b/test/LLVMC/HookWithInFile.td index b8ae7e21208..cc5da43b663 100644 --- a/test/LLVMC/HookWithInFile.td +++ b/test/LLVMC/HookWithInFile.td @@ -13,4 +13,4 @@ def dummy_tool : Tool<[ (out_language "dummy") ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/Init.td b/test/LLVMC/Init.td index 59459d9a7e3..8ab07d880b4 100644 --- a/test/LLVMC/Init.td +++ b/test/LLVMC/Init.td @@ -22,4 +22,4 @@ def dummy_tool : Tool<[ (not_empty "dummy2"), (forward "dummy2"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/LanguageMap.td b/test/LLVMC/LanguageMap.td new file mode 100644 index 00000000000..aa1149ca7f0 --- /dev/null +++ b/test/LLVMC/LanguageMap.td @@ -0,0 +1,29 @@ +// Check that LanguageMap is processed properly. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: FileCheck -input-file %t %s +// RUN: %compile_cxx -x c++ %t +// XFAIL: vg_leak + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[ +(switch_option "dummy1", (help "none")) +]>; + +def dummy_tool : Tool<[ +(command "dummy_cmd"), +(in_language "dummy_lang"), +(out_language "dummy_lang"), +(actions (case + (switch_on "dummy1"), (forward "dummy1"))) +]>; + +def lang_map : LanguageMap<[ + // CHECK: langMap["dummy"] = "dummy_lang" + // CHECK: langMap["DUM"] = "dummy_lang" + (lang_to_suffixes "dummy_lang", ["dummy", "DUM"]), + // CHECK: langMap["DUM2"] = "dummy_lang_2" + (lang_to_suffixes "dummy_lang_2", "DUM2") +]>; + +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/MultiValuedOption.td b/test/LLVMC/MultiValuedOption.td index 50c1f3d22a1..b6da6ce4c1d 100644 --- a/test/LLVMC/MultiValuedOption.td +++ b/test/LLVMC/MultiValuedOption.td @@ -21,4 +21,4 @@ def dummy_tool : Tool<[ (not_empty "baz"), (forward "baz"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/NoActions.td b/test/LLVMC/NoActions.td index 1bc1c0268f7..2573fbe2f2c 100644 --- a/test/LLVMC/NoActions.td +++ b/test/LLVMC/NoActions.td @@ -13,4 +13,4 @@ def dummy_tool : Tool<[ (out_language "dummy") ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/OneOrMore.td b/test/LLVMC/OneOrMore.td index fac22e6bc4b..bb0ad8b11b1 100644 --- a/test/LLVMC/OneOrMore.td +++ b/test/LLVMC/OneOrMore.td @@ -22,4 +22,4 @@ def dummy_tool : Tool<[ (not_empty "baz"), (forward "baz"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td index e1e8eff63de..556530b8f76 100644 --- a/test/LLVMC/OptionPreprocessor.td +++ b/test/LLVMC/OptionPreprocessor.td @@ -63,5 +63,5 @@ def dummy : Tool< (not_empty "foo_l"), (error))) ]>; -def Graph : CompilationGraph<[Edge<"root", "dummy">]>; +def Graph : CompilationGraph<[(edge "root", "dummy")]>; diff --git a/test/LLVMC/OutputSuffixHook.td b/test/LLVMC/OutputSuffixHook.td index f217dc72cfc..6bb2866c38b 100644 --- a/test/LLVMC/OutputSuffixHook.td +++ b/test/LLVMC/OutputSuffixHook.td @@ -21,4 +21,4 @@ def dummy_tool : Tool<[ (switch_on "dummy1"), (output_suffix "$CALL(MyHook)"))) ]>; -def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; +def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/tools/llvmc/examples/Simple/Simple.td b/tools/llvmc/examples/Simple/Simple.td index 7ceee93d7cd..b47483b5d38 100644 --- a/tools/llvmc/examples/Simple/Simple.td +++ b/tools/llvmc/examples/Simple/Simple.td @@ -36,6 +36,6 @@ def gcc : Tool< (out_file_option "-o") ]>; -def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; +def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>; -def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; +def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>; diff --git a/tools/llvmc/examples/mcc16/PIC16.td b/tools/llvmc/examples/mcc16/PIC16.td index 4f07284b153..6f0419675e0 100644 --- a/tools/llvmc/examples/mcc16/PIC16.td +++ b/tools/llvmc/examples/mcc16/PIC16.td @@ -202,33 +202,33 @@ def mplink : Tool<[ // Language map def LanguageMap : LanguageMap<[ - LangToSuffixes<"c", ["c"]>, - LangToSuffixes<"c-cpp-output", ["i"]>, - LangToSuffixes<"assembler", ["s"]>, - LangToSuffixes<"assembler-with-cpp", ["S"]>, - LangToSuffixes<"llvm-assembler", ["ll"]>, - LangToSuffixes<"llvm-bitcode", ["bc"]>, - LangToSuffixes<"object-code", ["o"]>, - LangToSuffixes<"executable", ["cof"]> + (lang_to_suffixes "c", "c"), + (lang_to_suffixes "c-cpp-output", "i"), + (lang_to_suffixes "assembler", "s"), + (lang_to_suffixes "assembler-with-cpp", "S"), + (lang_to_suffixes "llvm-assembler", "ll"), + (lang_to_suffixes "llvm-bitcode", "bc"), + (lang_to_suffixes "object-code", "o"), + (lang_to_suffixes "executable", "cof") ]>; // Compilation graph def CompilationGraph : CompilationGraph<[ - Edge<"root", "clang_cc">, - Edge<"root", "llvm_ld">, - OptionalEdge<"root", "llvm_ld_optimizer", (case - (switch_on "S"), (inc_weight), - (switch_on "c"), (inc_weight))>, - Edge<"root", "gpasm">, - Edge<"root", "mplink">, - Edge<"clang_cc", "llvm_ld">, - OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case - (switch_on "S"), (inc_weight), - (switch_on "c"), (inc_weight))>, - Edge<"llvm_ld", "pic16passes">, - Edge<"llvm_ld_optimizer", "pic16passes">, - Edge<"pic16passes", "llc">, - Edge<"llc", "gpasm">, - Edge<"gpasm", "mplink"> + (edge "root", "clang_cc"), + (edge "root", "llvm_ld"), + (optional_edge "root", "llvm_ld_optimizer", + (case (switch_on "S"), (inc_weight), + (switch_on "c"), (inc_weight))), + (edge "root", "gpasm"), + (edge "root", "mplink"), + (edge "clang_cc", "llvm_ld"), + (optional_edge "clang_cc", "llvm_ld_optimizer", + (case (switch_on "S"), (inc_weight), + (switch_on "c"), (inc_weight))), + (edge "llvm_ld", "pic16passes"), + (edge "llvm_ld_optimizer", "pic16passes"), + (edge "pic16passes", "llc"), + (edge "llc", "gpasm"), + (edge "gpasm", "mplink") ]>; diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in index 45b60b735b0..afc4053be79 100644 --- a/tools/llvmc/src/Base.td.in +++ b/tools/llvmc/src/Base.td.in @@ -304,73 +304,78 @@ def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@", // Language map -def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c++-header", ["hpp"]>, - LangToSuffixes<"c", ["c"]>, - LangToSuffixes<"c-header", ["h"]>, - LangToSuffixes<"c-cpp-output", ["i"]>, - LangToSuffixes<"objective-c-cpp-output", ["mi"]>, - LangToSuffixes<"objective-c++", ["mm"]>, - LangToSuffixes<"objective-c++-header", ["hmm"]>, - LangToSuffixes<"objective-c", ["m"]>, - LangToSuffixes<"objective-c-header", ["hm"]>, - LangToSuffixes<"assembler", ["s"]>, - LangToSuffixes<"assembler-with-cpp", ["S"]>, - LangToSuffixes<"llvm-assembler", ["ll"]>, - LangToSuffixes<"llvm-bitcode", ["bc"]>, - LangToSuffixes<"object-code", ["o", "*empty*"]>, - LangToSuffixes<"static-library", ["a", "lib"]>, - LangToSuffixes<"executable", ["out"]> - ]>; +def LanguageMap : LanguageMap<[ + (lang_to_suffixes "c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]), + (lang_to_suffixes "c++-header", "hpp"), + (lang_to_suffixes "c", "c"), + (lang_to_suffixes "c-header", "h"), + (lang_to_suffixes "c-cpp-output", "i"), + (lang_to_suffixes "objective-c-cpp-output", "mi"), + (lang_to_suffixes "objective-c++", "mm"), + (lang_to_suffixes "objective-c++-header", "hmm"), + (lang_to_suffixes "objective-c", "m"), + (lang_to_suffixes "objective-c-header", "hm"), + (lang_to_suffixes "assembler", "s"), + (lang_to_suffixes "assembler-with-cpp", "S"), + (lang_to_suffixes "llvm-assembler", "ll"), + (lang_to_suffixes "llvm-bitcode", "bc"), + (lang_to_suffixes "object-code", ["o", "*empty*"]), + (lang_to_suffixes "static-library", ["a", "lib"]), + (lang_to_suffixes "executable", ["out"]) +]>; // Compilation graph def CompilationGraph : CompilationGraph<[ - Edge<"root", "llvm_gcc_c">, - Edge<"root", "llvm_gcc_assembler">, - Edge<"root", "llvm_gcc_cpp">, - Edge<"root", "llvm_gcc_m">, - Edge<"root", "llvm_gcc_mxx">, - Edge<"root", "llc">, + (edge "root", "llvm_gcc_c"), + (edge "root", "llvm_gcc_assembler"), + (edge "root", "llvm_gcc_cpp"), + (edge "root", "llvm_gcc_m"), + (edge "root", "llvm_gcc_mxx"), + (edge "root", "llc"), - Edge<"root", "llvm_gcc_c_pch">, - Edge<"root", "llvm_gcc_cpp_pch">, - Edge<"root", "llvm_gcc_m_pch">, - Edge<"root", "llvm_gcc_mxx_pch">, + (edge "root", "llvm_gcc_c_pch"), + (edge "root", "llvm_gcc_cpp_pch"), + (edge "root", "llvm_gcc_m_pch"), + (edge "root", "llvm_gcc_mxx_pch"), - Edge<"llvm_gcc_c", "llc">, - Edge<"llvm_gcc_cpp", "llc">, - Edge<"llvm_gcc_m", "llc">, - Edge<"llvm_gcc_mxx", "llc">, - Edge<"llvm_as", "llc">, + (edge "llvm_gcc_c", "llc"), + (edge "llvm_gcc_cpp", "llc"), + (edge "llvm_gcc_m", "llc"), + (edge "llvm_gcc_mxx", "llc"), + (edge "llvm_as", "llc"), - OptionalEdge<"root", "llvm_as", - (case (switch_on "emit-llvm"), (inc_weight))>, - OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_m", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_mxx", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_as", "opt", (case (switch_on "opt"), (inc_weight))>, - Edge<"opt", "llc">, + (optional_edge "root", "llvm_as", + (case (switch_on "emit-llvm"), (inc_weight))), + (optional_edge "llvm_gcc_c", "opt", + (case (switch_on "opt"), (inc_weight))), + (optional_edge "llvm_gcc_cpp", "opt", + (case (switch_on "opt"), (inc_weight))), + (optional_edge "llvm_gcc_m", "opt", + (case (switch_on "opt"), (inc_weight))), + (optional_edge "llvm_gcc_mxx", "opt", + (case (switch_on "opt"), (inc_weight))), + (optional_edge "llvm_as", "opt", + (case (switch_on "opt"), (inc_weight))), + (edge "opt", "llc"), - Edge<"llc", "llvm_gcc_assembler">, - Edge<"llvm_gcc_assembler", "llvm_gcc_linker">, - OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", + (edge "llc", "llvm_gcc_assembler"), + (edge "llvm_gcc_assembler", "llvm_gcc_linker"), + (optional_edge "llvm_gcc_assembler", "llvm_gcc_cpp_linker", (case (or (input_languages_contain "c++"), (input_languages_contain "objective-c++")), (inc_weight), (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))>, + (parameter_equals "linker", "c++")), (inc_weight))), - Edge<"root", "llvm_gcc_linker">, - OptionalEdge<"root", "llvm_gcc_cpp_linker", + (edge "root", "llvm_gcc_linker"), + (optional_edge "root", "llvm_gcc_cpp_linker", (case (or (input_languages_contain "c++"), (input_languages_contain "objective-c++")), (inc_weight), (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))> - ]>; + (parameter_equals "linker", "c++")), (inc_weight))) +]>; diff --git a/tools/llvmc/src/Clang.td b/tools/llvmc/src/Clang.td index c8c396e6ed3..1d75743f4fe 100644 --- a/tools/llvmc/src/Clang.td +++ b/tools/llvmc/src/Clang.td @@ -70,18 +70,18 @@ def llvm_ld : Tool< // Compilation graph def ClangCompilationGraph : CompilationGraph<[ - OptionalEdge<"root", "clang_c", - (case (switch_on "clang"), (inc_weight))>, - OptionalEdge<"root", "clang_cpp", - (case (switch_on "clang"), (inc_weight))>, - OptionalEdge<"root", "clang_objective_c", - (case (switch_on "clang"), (inc_weight))>, - OptionalEdge<"root", "clang_objective_cpp", - (case (switch_on "clang"), (inc_weight))>, - Edge<"clang_c", "llc">, - Edge<"clang_cpp", "llc">, - Edge<"clang_objective_c", "llc">, - Edge<"clang_objective_cpp", "llc">, - OptionalEdge<"llc", "as", (case (switch_on "clang"), (inc_weight))>, - Edge<"as", "llvm_ld"> + (optional_edge "root", "clang_c", + (case (switch_on "clang"), (inc_weight))), + (optional_edge "root", "clang_cpp", + (case (switch_on "clang"), (inc_weight))), + (optional_edge "root", "clang_objective_c", + (case (switch_on "clang"), (inc_weight))), + (optional_edge "root", "clang_objective_cpp", + (case (switch_on "clang"), (inc_weight))), + (edge "clang_c", "llc"), + (edge "clang_cpp", "llc"), + (edge "clang_objective_c", "llc"), + (edge "clang_objective_cpp", "llc"), + (optional_edge "llc", "as", (case (switch_on "clang"), (inc_weight))), + (edge "as", "llvm_ld") ]>; diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 38b3713053c..cdeeea35897 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -33,6 +33,7 @@ namespace { /// Typedefs typedef std::vector RecordVector; +typedef std::vector DagVector; typedef std::vector StrVector; //===----------------------------------------------------------------------===// @@ -109,11 +110,6 @@ void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) { throw GetOperatorName(d) + ": too few arguments!"; } -// IsDagEmpty - is this DAG marked with an empty marker? -bool IsDagEmpty (const DagInit& d) { - return GetOperatorName(d) == "empty_dag_marker"; -} - // EscapeVariableName - Escape commas and other symbols not allowed // in the C++ variable names. Makes it possible to use options named // like "Wa," (useful for prefix options). @@ -622,7 +618,6 @@ void InvokeDagInitHandler(const FunctionObject* const Obj, ((Obj)->*(h))(Dag, IndentLevel, O); } - template typename HandlerTable::HandlerMap HandlerTable::Handlers_; @@ -791,7 +786,6 @@ public: OptionDescription OD(Type, Name); - CheckNumberOfArguments(d, 2); if (OD.isAlias()) { @@ -820,15 +814,14 @@ private: /// CollectOptionDescriptions - Collects option properties from all /// OptionLists. -void CollectOptionDescriptions (RecordVector::const_iterator B, - RecordVector::const_iterator E, +void CollectOptionDescriptions (const RecordVector& V, OptionDescriptions& OptDescs) { // For every OptionList: - for (; B!=E; ++B) { - RecordVector::value_type T = *B; + for (RecordVector::const_iterator B = V.begin(), + E = V.end(); B!=E; ++B) { // Throws an exception if the value does not exist. - ListInit* PropList = T->getValueAsListInit("options"); + ListInit* PropList = (*B)->getValueAsListInit("options"); // For every option description in this list: // collect the information and @@ -1005,12 +998,12 @@ private: /// CollectToolDescriptions - Gather information about tool properties /// from the parsed TableGen data (basically a wrapper for the /// CollectToolProperties function object). -void CollectToolDescriptions (RecordVector::const_iterator B, - RecordVector::const_iterator E, +void CollectToolDescriptions (const RecordVector& Tools, ToolDescriptions& ToolDescs) { // Iterate over a properties list of every Tool definition - for (;B!=E;++B) { + for (RecordVector::const_iterator B = Tools.begin(), + E = Tools.end(); B!=E; ++B) { const Record* T = *B; // Throws an exception if the value does not exist. ListInit* PropList = T->getValueAsListInit("properties"); @@ -1026,13 +1019,16 @@ void CollectToolDescriptions (RecordVector::const_iterator B, /// FillInEdgeVector - Merge all compilation graph definitions into /// one single edge list. -void FillInEdgeVector(RecordVector::const_iterator B, - RecordVector::const_iterator E, RecordVector& Out) { - for (; B != E; ++B) { - const ListInit* edges = (*B)->getValueAsListInit("edges"); +void FillInEdgeVector(const RecordVector& CompilationGraphs, + DagVector& Out) { + for (RecordVector::const_iterator B = CompilationGraphs.begin(), + E = CompilationGraphs.end(); B != E; ++B) { + const ListInit* Edges = (*B)->getValueAsListInit("edges"); - for (unsigned i = 0; i < edges->size(); ++i) - Out.push_back(edges->getElementAsRecord(i)); + for (ListInit::const_iterator B = Edges->begin(), + E = Edges->end(); B != E; ++B) { + Out.push_back(&InitPtrToDag(*B)); + } } } @@ -1053,18 +1049,18 @@ public: /// FilterNotInGraph - Filter out from ToolDescs all Tools not /// mentioned in the compilation graph definition. -void FilterNotInGraph (const RecordVector& EdgeVector, +void FilterNotInGraph (const DagVector& EdgeVector, ToolDescriptions& ToolDescs) { // List all tools mentioned in the graph. llvm::StringSet<> ToolsInGraph; - for (RecordVector::const_iterator B = EdgeVector.begin(), + for (DagVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; - const std::string& NodeA = Edge->getValueAsString("a"); - const std::string& NodeB = Edge->getValueAsString("b"); + const DagInit* Edge = *B; + const std::string& NodeA = InitPtrToString(Edge->getArg(0)); + const std::string& NodeB = InitPtrToString(Edge->getArg(1)); if (NodeA != "root") ToolsInGraph.insert(NodeA); @@ -1095,7 +1091,7 @@ void FillInToolToLang (const ToolDescriptions& ToolDescs, /// TypecheckGraph - Check that names for output and input languages /// on all edges do match. -void TypecheckGraph (const RecordVector& EdgeVector, +void TypecheckGraph (const DagVector& EdgeVector, const ToolDescriptions& ToolDescs) { StringMap > ToolToInLang; StringMap ToolToOutLang; @@ -1104,11 +1100,11 @@ void TypecheckGraph (const RecordVector& EdgeVector, StringMap::iterator IAE = ToolToOutLang.end(); StringMap >::iterator IBE = ToolToInLang.end(); - for (RecordVector::const_iterator B = EdgeVector.begin(), + for (DagVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; - const std::string& NodeA = Edge->getValueAsString("a"); - const std::string& NodeB = Edge->getValueAsString("b"); + const DagInit* Edge = *B; + const std::string& NodeA = InitPtrToString(Edge->getArg(0)); + const std::string& NodeB = InitPtrToString(Edge->getArg(1)); StringMap::iterator IA = ToolToOutLang.find(NodeA); StringMap >::iterator IB = ToolToInLang.find(NodeB); @@ -1250,7 +1246,7 @@ public: /// CheckForSuperfluousOptions - Check that there are no side /// effect-free options (specified only in the OptionList). Otherwise, /// output a warning. -void CheckForSuperfluousOptions (const RecordVector& Edges, +void CheckForSuperfluousOptions (const DagVector& EdgeVector, const ToolDescriptions& ToolDescs, const OptionDescriptions& OptDescs) { llvm::StringSet<> nonSuperfluousOptions; @@ -1268,13 +1264,13 @@ void CheckForSuperfluousOptions (const RecordVector& Edges, // Add all options mentioned in the 'case' clauses of the // OptionalEdges of the compilation graph to the set of // non-superfluous options. - for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end(); - B != E; ++B) { - const Record* Edge = *B; - DagInit& Weight = *Edge->getValueAsDag("weight"); - - if (!IsDagEmpty(Weight)) + for (DagVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const DagInit* Edge = *B; + if (Edge->getNumArgs() > 2) { + const DagInit& Weight = InitPtrToDag(Edge->getArg(2)); WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id()); + } } // Check that all options in OptDescs belong to the set of @@ -2616,31 +2612,72 @@ void EmitPreprocessOptions (const RecordKeeper& Records, O << "}\n\n"; } +class DoEmitPopulateLanguageMap; +typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler) +(const DagInit& D); + +class DoEmitPopulateLanguageMap +: public HandlerTable +{ +private: + raw_ostream& O_; + +public: + + explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) { + if (!staticMembersInitialized_) { + AddHandler("lang_to_suffixes", + &DoEmitPopulateLanguageMap::onLangToSuffixes); + + staticMembersInitialized_ = true; + } + } + + void operator() (Init* I) { + InvokeDagInitHandler(this, I); + } + +private: + + void onLangToSuffixes (const DagInit& d) { + CheckNumberOfArguments(d, 2); + + const std::string& Lang = InitPtrToString(d.getArg(0)); + Init* Suffixes = d.getArg(1); + + // Second argument to lang_to_suffixes is either a single string... + if (typeid(*Suffixes) == typeid(StringInit)) { + O_.indent(Indent1) << "langMap[\"" << InitPtrToString(Suffixes) + << "\"] = \"" << Lang << "\";\n"; + } + // ...or a list of strings. + else { + const ListInit& Lst = InitPtrToList(Suffixes); + assert(Lst.size() != 0); + for (ListInit::const_iterator B = Lst.begin(), E = Lst.end(); + B != E; ++B) { + O_.indent(Indent1) << "langMap[\"" << InitPtrToString(*B) + << "\"] = \"" << Lang << "\";\n"; + } + } + } + +}; + /// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function. void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O) { O << "int PopulateLanguageMap (LanguageMap& langMap) {\n"; - const RecordVector& LanguageMaps = + // For each LangMap: + const RecordVector& LangMaps = Records.getAllDerivedDefinitions("LanguageMap"); - for (RecordVector::const_iterator B = LanguageMaps.begin(), - E = LanguageMaps.end(); B!=E; ++B) { - ListInit* LangsToSuffixesList = (*B)->getValueAsListInit("map"); - if (!LangsToSuffixesList) - throw "Error in the language map definition!"; - - for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) { - const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); - - const std::string& Lang = LangToSuffixes->getValueAsString("lang"); - const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes"); - - for (unsigned i = 0; i < Suffixes->size(); ++i) - O.indent(Indent1) << "langMap[\"" - << InitPtrToString(Suffixes->getElement(i)) - << "\"] = \"" << Lang << "\";\n"; - } + for (RecordVector::const_iterator B = LangMaps.begin(), + E = LangMaps.end(); B!=E; ++B) { + ListInit* LangMap = (*B)->getValueAsListInit("map"); + std::for_each(LangMap->begin(), LangMap->end(), + DoEmitPopulateLanguageMap(O)); } O << '\n'; @@ -2681,7 +2718,7 @@ void EmitEdgePropertyHandlerCallback (const Init* i, unsigned IndentLevel, /// EmitEdgeClass - Emit a single Edge# class. void EmitEdgeClass (unsigned N, const std::string& Target, - DagInit* Case, const OptionDescriptions& OptDescs, + const DagInit* Case, const OptionDescriptions& OptDescs, raw_ostream& O) { // Class constructor. @@ -2704,24 +2741,26 @@ void EmitEdgeClass (unsigned N, const std::string& Target, } /// EmitEdgeClasses - Emit Edge* classes that represent graph edges. -void EmitEdgeClasses (const RecordVector& EdgeVector, +void EmitEdgeClasses (const DagVector& EdgeVector, const OptionDescriptions& OptDescs, raw_ostream& O) { int i = 0; - for (RecordVector::const_iterator B = EdgeVector.begin(), + for (DagVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; - const std::string& NodeB = Edge->getValueAsString("b"); - DagInit& Weight = *Edge->getValueAsDag("weight"); + const DagInit* Edge = *B; + const std::string& NodeB = InitPtrToString(Edge->getArg(1)); + + if (Edge->getNumArgs() > 2) { + const DagInit* Weight = &InitPtrToDag(Edge->getArg(2)); + EmitEdgeClass(i, NodeB, Weight, OptDescs, O); + } - if (!IsDagEmpty(Weight)) - EmitEdgeClass(i, NodeB, &Weight, OptDescs, O); ++i; } } /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function. -void EmitPopulateCompilationGraph (const RecordVector& EdgeVector, +void EmitPopulateCompilationGraph (const DagVector& EdgeVector, const ToolDescriptions& ToolDescs, raw_ostream& O) { @@ -2736,19 +2775,18 @@ void EmitPopulateCompilationGraph (const RecordVector& EdgeVector, // Insert edges. int i = 0; - for (RecordVector::const_iterator B = EdgeVector.begin(), + for (DagVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; - const std::string& NodeA = Edge->getValueAsString("a"); - const std::string& NodeB = Edge->getValueAsString("b"); - DagInit& Weight = *Edge->getValueAsDag("weight"); + const DagInit* Edge = *B; + const std::string& NodeA = InitPtrToString(Edge->getArg(0)); + const std::string& NodeB = InitPtrToString(Edge->getArg(1)); O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", "; - if (IsDagEmpty(Weight)) - O << "new SimpleEdge(\"" << NodeB << "\")"; - else + if (Edge->getNumArgs() > 2) O << "new Edge" << i << "()"; + else + O << "new SimpleEdge(\"" << NodeB << "\")"; O << "))\n"; O.indent(Indent2) << "return ret;\n"; @@ -2961,7 +2999,7 @@ void EmitIncludes(raw_ostream& O) { struct DriverData { OptionDescriptions OptDescs; ToolDescriptions ToolDescs; - RecordVector Edges; + DagVector Edges; bool HasSink; }; @@ -2982,19 +3020,17 @@ void CollectDriverData (const RecordKeeper& Records, DriverData& Data) { // Collect option properties. const RecordVector& OptionLists = Records.getAllDerivedDefinitions("OptionList"); - CollectOptionDescriptions(OptionLists.begin(), OptionLists.end(), - Data.OptDescs); + CollectOptionDescriptions(OptionLists, Data.OptDescs); // Collect tool properties. const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool"); - CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs); + CollectToolDescriptions(Tools, Data.ToolDescs); Data.HasSink = HasSink(Data.ToolDescs); // Collect compilation graph edges. const RecordVector& CompilationGraphs = Records.getAllDerivedDefinitions("CompilationGraph"); - FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(), - Data.Edges); + FillInEdgeVector(CompilationGraphs, Data.Edges); } /// CheckDriverData - Perform some sanity checks on the collected data. @@ -3035,6 +3071,7 @@ void EmitDriverCode(const DriverData& Data, raw_ostream& O) { EmitToolClassDefinition(*(*B), Data.OptDescs, O); // Emit Edge# classes. + // TODO: check for edge/optional_edge dag markers. EmitEdgeClasses(Data.Edges, Data.OptDescs, O); O << "} // End anonymous namespace.\n\n";