From f9f2c95eca3a186b39d2a2e0b3c52a0fae35b71b Mon Sep 17 00:00:00 2001 From: Yuka Takahashi Date: Tue, 29 Aug 2017 00:09:31 +0000 Subject: [PATCH] Revert "Revert r311552: [Bash-autocompletion] Add support for static analyzer flags" This reverts commit 7c46b80c022e18d43c1fdafb117b0c409c5a6d1e. r311552 broke lld buildbot because I've changed OptionInfos type from ArrayRef to vector. However the bug is fixed, so I'll commit this again. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311958 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Option/OptParser.td | 2 ++ include/llvm/Option/OptTable.h | 15 +++++++++++++-- lib/Option/OptTable.cpp | 25 +++++++++++++++++++------ utils/TableGen/OptParserEmitter.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td index 48122369871..9c373741770 100644 --- a/include/llvm/Option/OptParser.td +++ b/include/llvm/Option/OptParser.td @@ -93,6 +93,7 @@ class Option prefixes, string name, OptionKind kind> { string HelpText = ?; string MetaVarName = ?; string Values = ?; + code ValuesCode = ?; list Flags = []; OptionGroup Group = ?; Option Alias = ?; @@ -128,6 +129,7 @@ class Group { OptionGroup Group = group; } class HelpText { string HelpText = text; } class MetaVarName { string MetaVarName = name; } class Values { string Values = value; } +class ValuesCode { code ValuesCode = valuecode; } // Predefined options. diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h index 6acece96703..57a6954f487 100644 --- a/include/llvm/Option/OptTable.h +++ b/include/llvm/Option/OptTable.h @@ -57,8 +57,8 @@ public: }; private: - /// \brief The static option information table. - ArrayRef OptionInfos; + /// \brief The option information table. + std::vector OptionInfos; bool IgnoreCase; unsigned TheInputOptionID = 0; @@ -143,6 +143,17 @@ public: std::vector findByPrefix(StringRef Cur, unsigned short DisableFlags) const; + /// Add Values to Option's Values class + /// + /// \param [in] Option - Prefix + Name of the flag which Values will be + /// changed. For example, "-analyzer-checker". + /// \param [in] Values - String of Values seperated by ",", such as + /// "foo, bar..", where foo and bar is the argument which the Option flag + /// takes + /// + /// \return true in success, and false in fail. + bool addValues(const char *Option, const char *Values); + /// \brief Parse a single argument; returning the new argument and /// updating Index. /// diff --git a/lib/Option/OptTable.cpp b/lib/Option/OptTable.cpp index 4e3b132db86..c1bb05e817f 100644 --- a/lib/Option/OptTable.cpp +++ b/lib/Option/OptTable.cpp @@ -196,7 +196,7 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str, // Returns true if one of the Prefixes + In.Names matches Option static bool optionMatches(const OptTable::Info &In, StringRef Option) { - if (In.Values && In.Prefixes) + if (In.Prefixes) for (size_t I = 0; In.Prefixes[I]; I++) if (Option == std::string(In.Prefixes[I]) + In.Name) return true; @@ -209,8 +209,9 @@ static bool optionMatches(const OptTable::Info &In, StringRef Option) { std::vector OptTable::suggestValueCompletions(StringRef Option, StringRef Arg) const { // Search all options and return possible values. - for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) { - if (!optionMatches(In, Option)) + for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { + const Info &In = OptionInfos[I]; + if (!In.Values || !optionMatches(In, Option)) continue; SmallVector Candidates; @@ -228,7 +229,8 @@ OptTable::suggestValueCompletions(StringRef Option, StringRef Arg) const { std::vector OptTable::findByPrefix(StringRef Cur, unsigned short DisableFlags) const { std::vector Ret; - for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) { + for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { + const Info &In = OptionInfos[I]; if (!In.Prefixes || (!In.HelpText && !In.GroupID)) continue; if (In.Flags & DisableFlags) @@ -245,6 +247,17 @@ OptTable::findByPrefix(StringRef Cur, unsigned short DisableFlags) const { return Ret; } +bool OptTable::addValues(const char *Option, const char *Values) { + for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { + Info &In = OptionInfos[I]; + if (optionMatches(In, Option)) { + In.Values = Values; + return true; + } + } + return false; +} + Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, unsigned FlagsToInclude, unsigned FlagsToExclude) const { @@ -256,8 +269,8 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, if (isInput(PrefixesUnion, Str)) return new Arg(getOption(TheInputOptionID), Str, Index++, Str); - const Info *Start = OptionInfos.begin() + FirstSearchableIndex; - const Info *End = OptionInfos.end(); + const Info *Start = OptionInfos.data() + FirstSearchableIndex; + const Info *End = OptionInfos.data() + OptionInfos.size(); StringRef Name = StringRef(Str).ltrim(PrefixChars); // Search for the first next option which could be a prefix. diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index e3777d036a2..ce0541d9794 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -298,5 +298,31 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { OS << ")\n"; } OS << "#endif // OPTION\n"; + + OS << "\n"; + OS << "#ifdef OPTTABLE_ARG_INIT\n"; + OS << "//////////\n"; + OS << "// Option Values\n\n"; + for (unsigned I = 0, E = Opts.size(); I != E; ++I) { + const Record &R = *Opts[I]; + if (isa(R.getValueInit("ValuesCode"))) + continue; + OS << "{\n"; + OS << R.getValueAsString("ValuesCode"); + OS << "\n"; + for (const std::string &Pref : R.getValueAsListOfStrings("Prefixes")) { + OS << "bool ValuesWereAdded = "; + OS << "Opt.addValues("; + std::string S = (Pref + R.getValueAsString("Name")).str(); + write_cstring(OS, S); + OS << ", Values);\n"; + OS << "(void)ValuesWereAdded;\n"; + OS << "assert(ValuesWereAdded && \"Couldn't add values to " + "OptTable!\");\n"; + } + OS << "}\n"; + } + OS << "\n"; + OS << "#endif // OPTTABLE_ARG_INIT\n"; } } // end namespace llvm -- 2.50.1