From b5c4239606d3b34b5aac20b93d4c052ac4c39ce7 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Fri, 5 Mar 2010 04:46:39 +0000 Subject: [PATCH] Make it not an error to specify -O* options several times. As in 'llvmc -O2 -O2 test.c'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97787 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CompilerDriver/Common.td | 1 + tools/llvmc/doc/LLVMC-Reference.rst | 26 ++++--- tools/llvmc/plugins/Base/Base.td.in | 8 +-- utils/TableGen/LLVMCConfigurationEmitter.cpp | 76 +++++++++++++++----- 4 files changed, 78 insertions(+), 33 deletions(-) diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 479bd6e12f0..31a627d6273 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -45,6 +45,7 @@ def hidden; def init; def multi_val; def one_or_more; +def zero_or_more; def optional; def really_hidden; def required; diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst index dfe38980375..ca8500d615d 100644 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ b/tools/llvmc/doc/LLVMC-Reference.rst @@ -329,16 +329,22 @@ separate option groups syntactically. - ``required`` - this option must be specified exactly once (or, in case of the list options without the ``multi_val`` property, at least - once). Incompatible with ``zero_or_one`` and ``one_or_more``. - - - ``one_or_more`` - the option must be specified at least one time. Useful - only for list options in conjunction with ``multi_val``; for ordinary lists - it is synonymous with ``required``. Incompatible with ``required`` and - ``zero_or_one``. - - - ``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``. + once). Incompatible with ``optional`` and ``one_or_more``. + + - ``optional`` - the option can be specified either zero times or exactly + once. The default for switch options. Useful only for list options in + conjunction with ``multi_val``. Incompatible with ``required``, + ``zero_or_more`` and ``one_or_more``. + + - ``one_or_more`` - the option must be specified at least once. Can be useful + to allow switch options be both obligatory and be specified multiple + times. For list options is useful only in conjunction with ``multi_val``; + for ordinary it is synonymous with ``required``. Incompatible with + ``required``, ``optional`` and ``zero_or_more``. + + - ``zero_or_more`` - the option can be specified zero or more times. Useful + to allow a single switch option to be specified more than + once. Incompatible with ``required``, ``optional`` and ``one_or_more``. - ``hidden`` - the description of this option will not appear in the ``--help`` output (but will appear in the ``--help-hidden`` diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in index 7b82313dc06..ac0f665925c 100644 --- a/tools/llvmc/plugins/Base/Base.td.in +++ b/tools/llvmc/plugins/Base/Base.td.in @@ -25,13 +25,13 @@ def OptList : OptionList<[ (switch_option "opt", (help "Enable opt")), (switch_option "O0", - (help "Turn off optimization")), + (help "Turn off optimization"), (zero_or_more)), (switch_option "O1", - (help "Optimization level 1")), + (help "Optimization level 1"), (zero_or_more)), (switch_option "O2", - (help "Optimization level 2")), + (help "Optimization level 2"), (zero_or_more)), (switch_option "O3", - (help "Optimization level 3")), + (help "Optimization level 3"), (zero_or_more)), (switch_option "S", (help "Stop after compilation, do not assemble")), (switch_option "c", diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index db590534e89..da2d54f5439 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -230,7 +230,8 @@ namespace OptionDescriptionFlags { enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, ReallyHidden = 0x4, Extern = 0x8, OneOrMore = 0x10, Optional = 0x20, - CommaSeparated = 0x40, ForwardNotSplit = 0x80 }; + CommaSeparated = 0x40, ForwardNotSplit = 0x80, + ZeroOrMore = 0x100 }; } /// OptionDescription - Represents data contained in a single @@ -260,6 +261,9 @@ struct OptionDescription { /// Merge - Merge two option descriptions. void Merge (const OptionDescription& other); + /// CheckConsistency - Check that the flags are consistent. + void CheckConsistency() const; + // Misc convenient getters/setters. bool isAlias() const; @@ -281,6 +285,9 @@ struct OptionDescription { bool isOneOrMore() const; void setOneOrMore(); + bool isZeroOrMore() const; + void setZeroOrMore(); + bool isOptional() const; void setOptional(); @@ -301,6 +308,20 @@ struct OptionDescription { }; +void OptionDescription::CheckConsistency() const { + unsigned i = 0; + + i += this->isRequired(); + i += this->isOptional(); + i += this->isOneOrMore(); + i += this->isZeroOrMore(); + + if (i > 1) { + throw "Only one of (required), (optional), (one_or_more) or " + "(zero_or_more) properties is allowed!"; + } +} + void OptionDescription::Merge (const OptionDescription& other) { if (other.Type != Type) @@ -359,6 +380,13 @@ void OptionDescription::setOneOrMore() { Flags |= OptionDescriptionFlags::OneOrMore; } +bool OptionDescription::isZeroOrMore() const { + return Flags & OptionDescriptionFlags::ZeroOrMore; +} +void OptionDescription::setZeroOrMore() { + Flags |= OptionDescriptionFlags::ZeroOrMore; +} + bool OptionDescription::isOptional() const { return Flags & OptionDescriptionFlags::Optional; } @@ -593,6 +621,7 @@ public: AddHandler("init", &CollectOptionProperties::onInit); AddHandler("multi_val", &CollectOptionProperties::onMultiVal); AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore); + AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore); AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); AddHandler("required", &CollectOptionProperties::onRequired); AddHandler("optional", &CollectOptionProperties::onOptional); @@ -651,10 +680,9 @@ private: void onRequired (const DagInit& d) { CheckNumberOfArguments(d, 0); - if (optDesc_.isOneOrMore() || optDesc_.isOptional()) - throw "Only one of (required), (optional) or " - "(one_or_more) properties is allowed!"; + optDesc_.setRequired(); + optDesc_.CheckConsistency(); } void onInit (const DagInit& d) { @@ -673,24 +701,31 @@ private: void onOneOrMore (const DagInit& d) { CheckNumberOfArguments(d, 0); - 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 " - "on a non-list option will have no effect.\n"; + optDesc_.setOneOrMore(); + optDesc_.CheckConsistency(); + } + + void onZeroOrMore (const DagInit& d) { + CheckNumberOfArguments(d, 0); + + if (OptionType::IsList(optDesc_.Type)) + llvm::errs() << "Warning: specifying the 'zero_or_more' property " + "on a list option has no effect.\n"; + + optDesc_.setZeroOrMore(); + optDesc_.CheckConsistency(); } void onOptional (const DagInit& d) { CheckNumberOfArguments(d, 0); - if (optDesc_.isRequired() || optDesc_.isOneOrMore()) - throw "Only one of (required), (optional) or " - "(one_or_more) properties is allowed!"; + if (!OptionType::IsList(optDesc_.Type)) llvm::errs() << "Warning: specifying the 'optional' property" - "on a non-list option will have no effect.\n"; + "on a non-list option has no effect.\n"; + optDesc_.setOptional(); + optDesc_.CheckConsistency(); } void onMultiVal (const DagInit& d) { @@ -2323,12 +2358,15 @@ void EmitOptionDefinitions (const OptionDescriptions& descs, else O << ", cl::Required"; } - else if (val.isOneOrMore() && val.isList()) { - O << ", cl::OneOrMore"; - } - else if (val.isOptional() && val.isList()) { + + if (val.isOptional()) O << ", cl::Optional"; - } + + if (val.isOneOrMore()) + O << ", cl::OneOrMore"; + + if (val.isZeroOrMore()) + O << ", cl::ZeroOrMore"; if (val.isReallyHidden()) O << ", cl::ReallyHidden"; -- 2.34.1