From 93c8d86be9653ad07cd77ba6e177c3ab778a81b7 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Tue, 15 Dec 2009 03:04:52 +0000 Subject: [PATCH] Validate the generated C++ code in llvmc tests. Checks that the code generated by 'tblgen --emit-llvmc' can be actually compiled. Also fixes two bugs found in this way: - forward_transformed_value didn't work with non-list arguments - cl::ZeroOrOne is now called cl::Optional llvm-svn: 91404 --- include/llvm/CompilerDriver/Common.td | 2 +- test/LLVMC/EmptyCompilationGraph.td | 3 +- test/LLVMC/EnvParentheses.td | 1 + test/LLVMC/ExternOptions.td | 1 + test/LLVMC/ForwardAs.td | 1 + test/LLVMC/ForwardTransformedValue.td | 5 ++- test/LLVMC/ForwardValue.td | 1 + test/LLVMC/HookWithArguments.td | 1 + test/LLVMC/HookWithInFile.td | 1 + test/LLVMC/Init.td | 1 + test/LLVMC/MultiValuedOption.td | 1 + test/LLVMC/MultipleCompilationGraphs.td | 3 +- test/LLVMC/NoActions.td | 4 +- test/LLVMC/NoCompilationGraph.td | 3 +- test/LLVMC/OneOrMore.td | 5 ++- test/LLVMC/OptionPreprocessor.td | 1 + test/LLVMC/TestWarnings.td | 2 +- tools/llvmc/doc/LLVMC-Reference.rst | 6 +-- utils/TableGen/LLVMCConfigurationEmitter.cpp | 39 ++++++++++---------- 19 files changed, 49 insertions(+), 32 deletions(-) diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index cfd675b9ad5..8d2f63b3306 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -42,9 +42,9 @@ def hidden; def init; def multi_val; def one_or_more; +def optional; def really_hidden; def required; -def zero_or_one; def comma_separated; // The 'case' construct. diff --git a/test/LLVMC/EmptyCompilationGraph.td b/test/LLVMC/EmptyCompilationGraph.td index b30f84c6e2a..934905b15e9 100644 --- a/test/LLVMC/EmptyCompilationGraph.td +++ b/test/LLVMC/EmptyCompilationGraph.td @@ -1,5 +1,6 @@ // Check that the compilation graph can be empty. -// RUN: tblgen -I %p/../../include --gen-llvmc %s +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/EnvParentheses.td b/test/LLVMC/EnvParentheses.td index 694468f2dda..77aab95c5f0 100644 --- a/test/LLVMC/EnvParentheses.td +++ b/test/LLVMC/EnvParentheses.td @@ -2,6 +2,7 @@ // http://llvm.org/bugs/show_bug.cgi?id=4157 // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: not grep {)));} %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/ExternOptions.td b/test/LLVMC/ExternOptions.td index 5c69af7d805..4694b106e2b 100644 --- a/test/LLVMC/ExternOptions.td +++ b/test/LLVMC/ExternOptions.td @@ -2,6 +2,7 @@ // The dummy tool and graph are required to silence warnings. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep {extern .* AutoGeneratedSwitch_Wall} %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/ForwardAs.td b/test/LLVMC/ForwardAs.td index 51bd494610e..54fc050a981 100644 --- a/test/LLVMC/ForwardAs.td +++ b/test/LLVMC/ForwardAs.td @@ -2,6 +2,7 @@ // http://llvm.org/bugs/show_bug.cgi?id=4159 // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep unique_name %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/ForwardTransformedValue.td b/test/LLVMC/ForwardTransformedValue.td index 478d1267282..0cda1bf1a5b 100644 --- a/test/LLVMC/ForwardTransformedValue.td +++ b/test/LLVMC/ForwardTransformedValue.td @@ -1,8 +1,9 @@ // Check that forward_transformed_value works. // The dummy tool and graph are required to silence warnings. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: grep HookA %t -// RUN: grep HookB %t +// RUN: grep HookA %t | count 2 +// RUN: grep HookB %t | count 2 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/ForwardValue.td b/test/LLVMC/ForwardValue.td index aebb198fd15..29f61a4c0cf 100644 --- a/test/LLVMC/ForwardValue.td +++ b/test/LLVMC/ForwardValue.td @@ -3,6 +3,7 @@ // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep {vec.push_back\(AutoGeneratedParameter_a\)} %t // RUN: grep {std::copy\(AutoGeneratedList_b.begin\(\)} %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/HookWithArguments.td b/test/LLVMC/HookWithArguments.td index 3bdb3eeb9d4..909dc8bf9b4 100644 --- a/test/LLVMC/HookWithArguments.td +++ b/test/LLVMC/HookWithArguments.td @@ -4,6 +4,7 @@ // RUN: grep "/path" %t | count 1 // RUN: grep "VARIABLE" %t | count 1 // RUN: grep "/2path" %t | count 1 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/HookWithInFile.td b/test/LLVMC/HookWithInFile.td index a2cc4d81549..7fb3df1c9a6 100644 --- a/test/LLVMC/HookWithInFile.td +++ b/test/LLVMC/HookWithInFile.td @@ -1,6 +1,7 @@ // Check that a hook can be given $INFILE as an argument. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep Hook\\(inFile.c_str\\(\\)\\) %t | count 1 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/Init.td b/test/LLVMC/Init.td index d9a4fc1c1b1..3d68d050ee9 100644 --- a/test/LLVMC/Init.td +++ b/test/LLVMC/Init.td @@ -2,6 +2,7 @@ // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep cl::init(\\"some-string\\") %t | count 1 // RUN: grep cl::init(true) %t | count 1 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/MultiValuedOption.td b/test/LLVMC/MultiValuedOption.td index bd1e0338f75..108eb86dbeb 100644 --- a/test/LLVMC/MultiValuedOption.td +++ b/test/LLVMC/MultiValuedOption.td @@ -2,6 +2,7 @@ // The dummy tool and graph are required to silence warnings. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t // RUN: grep cl::multi_val(2) %t | count 1 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/MultipleCompilationGraphs.td b/test/LLVMC/MultipleCompilationGraphs.td index 64dbc9b1845..9702248b572 100644 --- a/test/LLVMC/MultipleCompilationGraphs.td +++ b/test/LLVMC/MultipleCompilationGraphs.td @@ -1,5 +1,6 @@ // Check that multiple compilation graphs are allowed. -// RUN: tblgen -I %p/../../include --gen-llvmc %s +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/NoActions.td b/test/LLVMC/NoActions.td index 2a4a7495ab0..7b8e721397a 100644 --- a/test/LLVMC/NoActions.td +++ b/test/LLVMC/NoActions.td @@ -1,5 +1,7 @@ // Check that tools without associated actions are accepted. -// RUN: tblgen -I %p/../../include --gen-llvmc %s | grep dummy_tool +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: grep dummy_tool %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/NoCompilationGraph.td b/test/LLVMC/NoCompilationGraph.td index 2eea3e98343..96c1f17e18e 100644 --- a/test/LLVMC/NoCompilationGraph.td +++ b/test/LLVMC/NoCompilationGraph.td @@ -1,4 +1,5 @@ // Check that the compilation graph is not required. -// RUN: tblgen -I %p/../../include --gen-llvmc %s +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/OneOrMore.td b/test/LLVMC/OneOrMore.td index 38b7eb7dffe..08be7cfe8a7 100644 --- a/test/LLVMC/OneOrMore.td +++ b/test/LLVMC/OneOrMore.td @@ -1,14 +1,15 @@ // Check that (one_or_more) and (zero_or_one) properties work. // The dummy tool and graph are required to silence warnings. // RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: grep cl::ZeroOrOne %t | count 1 +// RUN: grep cl::Optional %t | count 1 // RUN: grep cl::OneOrMore %t | count 1 +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" def OptList : OptionList<[ (prefix_list_option "foo", (one_or_more)), - (parameter_list_option "baz", (zero_or_one))]>; + (parameter_list_option "baz", (optional))]>; def dummy_tool : Tool<[ (cmd_line "dummy_cmd $INFILE"), diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td index 5b9f4357fea..2f5e68bfe51 100644 --- a/test/LLVMC/OptionPreprocessor.td +++ b/test/LLVMC/OptionPreprocessor.td @@ -3,6 +3,7 @@ // RUN: grep W1 %t // RUN: grep W2 %t // RUN: grep W3 %t +// RUN: %compile_cxx -fexceptions -x c++ %t include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/TestWarnings.td b/test/LLVMC/TestWarnings.td index 1a4064e44b2..9523e24702e 100644 --- a/test/LLVMC/TestWarnings.td +++ b/test/LLVMC/TestWarnings.td @@ -1,4 +1,4 @@ -// Check that the compiler warns about unused options. +// Check that warnings about unused options are really emitted. // This should fail because the output is printed on stderr. // RUN: ignore tblgen -I %p/../../include --gen-llvmc %s |& grep "option '-Wall' has no effect!" diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst index 789fc09a493..4d80a2a6e16 100644 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ b/tools/llvmc/doc/LLVMC-Reference.rst @@ -336,8 +336,8 @@ separate option groups syntactically. it is synonymous with ``required``. Incompatible with ``required`` and ``zero_or_one``. - - ``zero_or_one`` - the option can be specified zero or one times. Useful - only for list options in conjunction with ``multi_val``. Incompatible with + - ``optional`` - the option can be specified zero or one times. Useful only + for list options in conjunction with ``multi_val``. Incompatible with ``required`` and ``one_or_more``. - ``hidden`` - the description of this option will not appear in @@ -356,7 +356,7 @@ separate option groups syntactically. - ``multi_val n`` - this option takes *n* arguments (can be useful in some special cases). Usage example: ``(parameter_list_option "foo", (multi_val 3))``; the command-line syntax is '-foo a b c'. Only list options can have - this attribute; you can, however, use the ``one_or_more``, ``zero_or_one`` + this attribute; you can, however, use the ``one_or_more``, ``optional`` and ``required`` properties. - ``init`` - this option has a default value, either a string (if it is a diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index acffc435f1a..69001dd2759 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -211,7 +211,7 @@ OptionType::OptionType stringToOptionType(const std::string& T) { namespace OptionDescriptionFlags { enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, ReallyHidden = 0x4, Extern = 0x8, - OneOrMore = 0x10, ZeroOrOne = 0x20, + OneOrMore = 0x10, Optional = 0x20, CommaSeparated = 0x40 }; } @@ -260,8 +260,8 @@ struct OptionDescription { bool isOneOrMore() const; void setOneOrMore(); - bool isZeroOrOne() const; - void setZeroOrOne(); + bool isOptional() const; + void setOptional(); bool isHidden() const; void setHidden(); @@ -331,11 +331,11 @@ void OptionDescription::setOneOrMore() { Flags |= OptionDescriptionFlags::OneOrMore; } -bool OptionDescription::isZeroOrOne() const { - return Flags & OptionDescriptionFlags::ZeroOrOne; +bool OptionDescription::isOptional() const { + return Flags & OptionDescriptionFlags::Optional; } -void OptionDescription::setZeroOrOne() { - Flags |= OptionDescriptionFlags::ZeroOrOne; +void OptionDescription::setOptional() { + Flags |= OptionDescriptionFlags::Optional; } bool OptionDescription::isHidden() const { @@ -548,7 +548,7 @@ public: AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore); AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); AddHandler("required", &CollectOptionProperties::onRequired); - AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne); + AddHandler("optional", &CollectOptionProperties::onOptional); AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated); staticMembersInitialized_ = true; @@ -595,8 +595,8 @@ private: void onRequired (const DagInit* d) { checkNumberOfArguments(d, 0); - if (optDesc_.isOneOrMore() || optDesc_.isZeroOrOne()) - throw "Only one of (required), (zero_or_one) or " + if (optDesc_.isOneOrMore() || optDesc_.isOptional()) + throw "Only one of (required), (optional) or " "(one_or_more) properties is allowed!"; optDesc_.setRequired(); } @@ -617,8 +617,8 @@ private: void onOneOrMore (const DagInit* d) { checkNumberOfArguments(d, 0); - if (optDesc_.isRequired() || optDesc_.isZeroOrOne()) - throw "Only one of (required), (zero_or_one) or " + if (optDesc_.isRequired() || optDesc_.isOptional()) + throw "Only one of (required), (optional) or " "(one_or_more) properties is allowed!"; if (!OptionType::IsList(optDesc_.Type)) llvm::errs() << "Warning: specifying the 'one_or_more' property " @@ -626,15 +626,15 @@ private: optDesc_.setOneOrMore(); } - void onZeroOrOne (const DagInit* d) { + void onOptional (const DagInit* d) { checkNumberOfArguments(d, 0); if (optDesc_.isRequired() || optDesc_.isOneOrMore()) - throw "Only one of (required), (zero_or_one) or " + throw "Only one of (required), (optional) or " "(one_or_more) properties is allowed!"; if (!OptionType::IsList(optDesc_.Type)) - llvm::errs() << "Warning: specifying the 'zero_or_one' property" + llvm::errs() << "Warning: specifying the 'optional' property" "on a non-list option will have no effect.\n"; - optDesc_.setZeroOrOne(); + optDesc_.setOptional(); } void onMultiVal (const DagInit* d) { @@ -1882,7 +1882,8 @@ class EmitActionHandlersCallback const OptionDescription& D = OptDescs.FindListOrParameter(Name); O.indent(IndentLevel) << "vec.push_back(" << "hooks::" - << Hook << "(" << D.GenVariableName() << "));\n"; + << Hook << "(" << D.GenVariableName() + << (D.isParameter() ? ".c_str()" : "") << "));\n"; } @@ -2211,8 +2212,8 @@ void EmitOptionDefinitions (const OptionDescriptions& descs, else if (val.isOneOrMore() && val.isList()) { O << ", cl::OneOrMore"; } - else if (val.isZeroOrOne() && val.isList()) { - O << ", cl::ZeroOrOne"; + else if (val.isOptional() && val.isList()) { + O << ", cl::Optional"; } if (val.isReallyHidden())