<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Dec 23, 2022 at 12:49 PM via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: serge-sans-paille<br>
Date: 2022-12-23T12:48:17+01:00<br>
New Revision: 5ce4e92264102de21760c94db9166afe8f71fcf6<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/5ce4e92264102de21760c94db9166afe8f71fcf6" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/5ce4e92264102de21760c94db9166afe8f71fcf6</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/5ce4e92264102de21760c94db9166afe8f71fcf6.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/5ce4e92264102de21760c94db9166afe8f71fcf6.diff</a><br>
<br>
LOG: [clang] Use a StringRef instead of a raw char pointer to store builtin and call information<br>
<br>
This avoids recomputing string length that is already known at compile<br>
time.<br>
<br>
It has a slight impact on preprocessing / compile time, see<br>
<br>
<a href="https://llvm-compile-time-tracker.com/compare.php?from=3f36d2d579d8b0e8824d9dd99bfa79f456858f88&to=e49640c507ddc6615b5e503144301c8e41f8f434&stat=instructions:u" rel="noreferrer" target="_blank">https://llvm-compile-time-tracker.com/compare.php?from=3f36d2d579d8b0e8824d9dd99bfa79f456858f88&to=e49640c507ddc6615b5e503144301c8e41f8f434&stat=instructions:u</a><br>
<br>
This is a recommit of 719d98dfa841c522d8d452f0685e503538415a53 with a<br>
change to llvm/utils/TableGen/OptParserEmitter.cpp to cope with GCC bug<br>
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108158" rel="noreferrer" target="_blank">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108158</a><br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D139881" rel="noreferrer" target="_blank">https://reviews.llvm.org/D139881</a></blockquote><div><br></div><div>Unfortunately, I still see a lot of build failures like this with gcc 12.2.1:</div><div><br></div><div>llvm-project/llvm/tools/llvm-mt/llvm-mt.cpp:59:1: error: modification of ‘<temporary>’ is not a constant expression</div><div><br></div><div>Nikita<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    clang-tools-extra/clangd/CompileCommands.cpp<br>
    clang/include/clang/Basic/Builtins.h<br>
    clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h<br>
    clang/lib/AST/ExprConstant.cpp<br>
    clang/lib/Basic/Builtins.cpp<br>
    clang/lib/CodeGen/CGBuiltin.cpp<br>
    clang/lib/Driver/DriverOptions.cpp<br>
    clang/lib/Sema/SemaChecking.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp<br>
    clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp<br>
    clang/lib/StaticAnalyzer/Core/CallDescription.cpp<br>
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp<br>
    clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp<br>
    clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp<br>
    clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp<br>
    clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp<br>
    clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp<br>
    lld/COFF/DriverUtils.cpp<br>
    lld/ELF/DriverUtils.cpp<br>
    lld/MachO/DriverUtils.cpp<br>
    lld/MinGW/Driver.cpp<br>
    lld/wasm/Driver.cpp<br>
    lldb/tools/driver/Driver.cpp<br>
    lldb/tools/lldb-server/lldb-gdbserver.cpp<br>
    lldb/tools/lldb-vscode/lldb-vscode.cpp<br>
    llvm/include/llvm/ADT/ArrayRef.h<br>
    llvm/include/llvm/Option/OptTable.h<br>
    llvm/include/llvm/Option/Option.h<br>
    llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp<br>
    llvm/lib/Option/OptTable.cpp<br>
    llvm/lib/Option/Option.cpp<br>
    llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp<br>
    llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp<br>
    llvm/tools/dsymutil/dsymutil.cpp<br>
    llvm/tools/llvm-cvtres/llvm-cvtres.cpp<br>
    llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp<br>
    llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp<br>
    llvm/tools/llvm-ifs/llvm-ifs.cpp<br>
    llvm/tools/llvm-lipo/llvm-lipo.cpp<br>
    llvm/tools/llvm-ml/llvm-ml.cpp<br>
    llvm/tools/llvm-mt/llvm-mt.cpp<br>
    llvm/tools/llvm-nm/llvm-nm.cpp<br>
    llvm/tools/llvm-objcopy/ObjcopyOptions.cpp<br>
    llvm/tools/llvm-objdump/llvm-objdump.cpp<br>
    llvm/tools/llvm-rc/llvm-rc.cpp<br>
    llvm/tools/llvm-readobj/llvm-readobj.cpp<br>
    llvm/tools/llvm-size/llvm-size.cpp<br>
    llvm/tools/llvm-strings/llvm-strings.cpp<br>
    llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp<br>
    llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp<br>
    llvm/unittests/Option/OptionParsingTest.cpp<br>
    llvm/utils/TableGen/OptParserEmitter.cpp<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp<br>
index e88d92189c1fb..dbd2a8ada93f4 100644<br>
--- a/clang-tools-extra/clangd/CompileCommands.cpp<br>
+++ b/clang-tools-extra/clangd/CompileCommands.cpp<br>
@@ -466,8 +466,10 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {<br>
       NextAlias[T] = Self;<br>
     };<br>
     // Also grab prefixes for each option, these are not fully exposed.<br>
-    const char *const *Prefixes[DriverID::LastOption] = {nullptr};<br>
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;<br>
+    std::initializer_list<llvm::StringLiteral> Prefixes[DriverID::LastOption];<br>
+<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELP, METAVAR, VALUES)                                          \<br>
   Prefixes[DriverID::OPT_##ID] = PREFIX;<br>
@@ -499,7 +501,7 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {<br>
       llvm::SmallVector<Rule> Rules;<br>
       // Iterate over each alias, to add rules for parsing it.<br>
       for (unsigned A = ID; A != DriverID::OPT_INVALID; A = NextAlias[A]) {<br>
-        if (Prefixes[A] == nullptr) // option groups.<br>
+        if (!Prefixes[A].size()) // option groups.<br>
           continue;<br>
         auto Opt = DriverTable.getOption(A);<br>
         // Exclude - and -foo pseudo-options.<br>
@@ -508,8 +510,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {<br>
         auto Modes = getModes(Opt);<br>
         std::pair<unsigned, unsigned> ArgCount = getArgCount(Opt);<br>
         // Iterate over each spelling of the alias, e.g. -foo vs --foo.<br>
-        for (auto *Prefix = Prefixes[A]; *Prefix != nullptr; ++Prefix) {<br>
-          llvm::SmallString<64> Buf(*Prefix);<br>
+        for (StringRef Prefix : Prefixes[A]) {<br>
+          llvm::SmallString<64> Buf(Prefix);<br>
           Buf.append(Opt.getName());<br>
           llvm::StringRef Spelling = Result->try_emplace(Buf).first->getKey();<br>
           Rules.emplace_back();<br>
<br>
diff  --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h<br>
index 5396477411106..6050ec47910ed 100644<br>
--- a/clang/include/clang/Basic/Builtins.h<br>
+++ b/clang/include/clang/Basic/Builtins.h<br>
@@ -57,7 +57,8 @@ enum ID {<br>
 };<br>
<br>
 struct Info {<br>
-  const char *Name, *Type, *Attributes, *HeaderName;<br>
+  llvm::StringRef Name;<br>
+  const char *Type, *Attributes, *HeaderName;<br>
   LanguageID Langs;<br>
   const char *Features;<br>
 };<br>
@@ -86,9 +87,7 @@ class Context {<br>
<br>
   /// Return the identifier name for the specified builtin,<br>
   /// e.g. "__builtin_abs".<br>
-  const char *getName(unsigned ID) const {<br>
-    return getRecord(ID).Name;<br>
-  }<br>
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }<br>
<br>
   /// Get the type descriptor string for the specified builtin.<br>
   const char *getTypeString(unsigned ID) const {<br>
<br>
diff  --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h<br>
index 368972d0382b5..091c3ce20e717 100644<br>
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h<br>
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h<br>
@@ -63,13 +63,12 @@ class CallDescription {<br>
   /// @param RequiredArgs The number of arguments that is expected to match a<br>
   /// call. Omit this parameter to match every occurrence of call with a given<br>
   /// name regardless the number of arguments.<br>
-  CallDescription(CallDescriptionFlags Flags,<br>
-                  ArrayRef<const char *> QualifiedName,<br>
+  CallDescription(CallDescriptionFlags Flags, ArrayRef<StringRef> QualifiedName,<br>
                   MaybeCount RequiredArgs = std::nullopt,<br>
                   MaybeCount RequiredParams = std::nullopt);<br>
<br>
   /// Construct a CallDescription with default flags.<br>
-  CallDescription(ArrayRef<const char *> QualifiedName,<br>
+  CallDescription(ArrayRef<StringRef> QualifiedName,<br>
                   MaybeCount RequiredArgs = std::nullopt,<br>
                   MaybeCount RequiredParams = std::nullopt);<br>
<br>
<br>
diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp<br>
index 30a7b5880ec09..120ceb9ad0814 100644<br>
--- a/clang/lib/AST/ExprConstant.cpp<br>
+++ b/clang/lib/AST/ExprConstant.cpp<br>
@@ -9242,8 +9242,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
   case Builtin::BIwmemchr:<br>
     if (Info.getLangOpts().CPlusPlus11)<br>
       Info.CCEDiag(E, diag::note_constexpr_invalid_function)<br>
-        << /*isConstexpr*/0 << /*isConstructor*/0<br>
-        << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");<br>
+          << /*isConstexpr*/ 0 << /*isConstructor*/ 0<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();<br>
     else<br>
       Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);<br>
     [[fallthrough]];<br>
@@ -9288,7 +9288,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
     // FIXME: We can compare the bytes in the correct order.<br>
     if (IsRawByte && !isOneByteCharacterType(CharTy)) {<br>
       Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)<br>
-          << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()<br>
           << CharTy;<br>
       return false;<br>
     }<br>
@@ -9350,8 +9350,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
   case Builtin::BIwmemmove:<br>
     if (Info.getLangOpts().CPlusPlus11)<br>
       Info.CCEDiag(E, diag::note_constexpr_invalid_function)<br>
-        << /*isConstexpr*/0 << /*isConstructor*/0<br>
-        << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");<br>
+          << /*isConstexpr*/ 0 << /*isConstructor*/ 0<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();<br>
     else<br>
       Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);<br>
     [[fallthrough]];<br>
@@ -12209,8 +12209,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
     // A call to strlen is not a constant expression.<br>
     if (Info.getLangOpts().CPlusPlus11)<br>
       Info.CCEDiag(E, diag::note_constexpr_invalid_function)<br>
-        << /*isConstexpr*/0 << /*isConstructor*/0<br>
-        << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");<br>
+          << /*isConstexpr*/ 0 << /*isConstructor*/ 0<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();<br>
     else<br>
       Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);<br>
     [[fallthrough]];<br>
@@ -12234,8 +12234,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
     // A call to strlen is not a constant expression.<br>
     if (Info.getLangOpts().CPlusPlus11)<br>
       Info.CCEDiag(E, diag::note_constexpr_invalid_function)<br>
-        << /*isConstexpr*/0 << /*isConstructor*/0<br>
-        << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");<br>
+          << /*isConstexpr*/ 0 << /*isConstructor*/ 0<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();<br>
     else<br>
       Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);<br>
     [[fallthrough]];<br>
@@ -12290,7 +12290,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,<br>
         !(isOneByteCharacterType(CharTy1) && isOneByteCharacterType(CharTy2))) {<br>
       // FIXME: Consider using our bit_cast implementation to support this.<br>
       Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)<br>
-          << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")<br>
+          << ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()<br>
           << CharTy1 << CharTy2;<br>
       return false;<br>
     }<br>
<br>
diff  --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp<br>
index 0e0566878c30c..375f474f84ad6 100644<br>
--- a/clang/lib/Basic/Builtins.cpp<br>
+++ b/clang/lib/Basic/Builtins.cpp<br>
@@ -18,8 +18,9 @@<br>
 #include "llvm/ADT/StringRef.h"<br>
 using namespace clang;<br>
<br>
-static const Builtin::Info BuiltinInfo[] = {<br>
-  { "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr},<br>
+static constexpr Builtin::Info BuiltinInfo[] = {<br>
+    {"not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,<br>
+     nullptr},<br>
 #define BUILTIN(ID, TYPE, ATTRS)                                               \<br>
   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },<br>
 #define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \<br>
<br>
diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp<br>
index a194fc7b105cb..4efd4f15cf066 100644<br>
--- a/clang/lib/CodeGen/CGBuiltin.cpp<br>
+++ b/clang/lib/CodeGen/CGBuiltin.cpp<br>
@@ -134,7 +134,7 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,<br>
                  AIXLongDouble64Builtins.end())<br>
       Name = AIXLongDouble64Builtins[BuiltinID];<br>
     else<br>
-      Name = Context.BuiltinInfo.getName(BuiltinID) + 10;<br>
+      Name = Context.BuiltinInfo.getName(BuiltinID).substr(10);<br>
   }<br>
<br>
   llvm::FunctionType *Ty =<br>
@@ -5302,7 +5302,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,<br>
     LargestVectorWidth = std::max(LargestVectorWidth, VectorWidth);<br>
<br>
   // See if we have a target specific intrinsic.<br>
-  const char *Name = getContext().BuiltinInfo.getName(BuiltinID);<br>
+  StringRef Name = getContext().BuiltinInfo.getName(BuiltinID);<br>
   Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;<br>
   StringRef Prefix =<br>
       llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());<br>
<br>
diff  --git a/clang/lib/Driver/DriverOptions.cpp b/clang/lib/Driver/DriverOptions.cpp<br>
index 169bb137c2896..a22e9b6f78fd2 100644<br>
--- a/clang/lib/Driver/DriverOptions.cpp<br>
+++ b/clang/lib/Driver/DriverOptions.cpp<br>
@@ -16,11 +16,12 @@ using namespace clang::driver;<br>
 using namespace clang::driver::options;<br>
 using namespace llvm::opt;<br>
<br>
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #include "clang/Driver/Options.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr  OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {PREFIX, NAME,  HELPTEXT,    METAVAR,     OPT_##ID,  Option::KIND##Class,    \<br>
<br>
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp<br>
index 67c4ea5812298..75296306c98e9 100644<br>
--- a/clang/lib/Sema/SemaChecking.cpp<br>
+++ b/clang/lib/Sema/SemaChecking.cpp<br>
@@ -6956,7 +6956,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {<br>
   // Get the decl for the concrete builtin from this, we can tell what the<br>
   // concrete integer type we should convert to is.<br>
   unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];<br>
-  const char *NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);<br>
+  StringRef NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);<br>
   FunctionDecl *NewBuiltinDecl;<br>
   if (NewBuiltinID == BuiltinID)<br>
     NewBuiltinDecl = FDecl;<br>
@@ -11008,7 +11008,7 @@ static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range,<br>
                             unsigned AbsKind, QualType ArgType) {<br>
   bool EmitHeaderHint = true;<br>
   const char *HeaderName = nullptr;<br>
-  const char *FunctionName = nullptr;<br>
+  StringRef FunctionName;<br>
   if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {<br>
     FunctionName = "std::abs";<br>
     if (ArgType->isIntegralOrEnumerationType()) {<br>
@@ -11116,7 +11116,7 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,<br>
   // Unsigned types cannot be negative.  Suggest removing the absolute value<br>
   // function call.<br>
   if (ArgType->isUnsignedIntegerType()) {<br>
-    const char *FunctionName =<br>
+    StringRef FunctionName =<br>
         IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind);<br>
     Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;<br>
     Diag(Call->getExprLoc(), diag::note_remove_abs)<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp<br>
index 4edf0e7cea7f8..615d994f2b275 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp<br>
@@ -532,10 +532,10 @@ namespace {<br>
 class CFRetainReleaseChecker : public Checker<check::PreCall> {<br>
   mutable APIMisuse BT{this, "null passed to CF memory management function"};<br>
   const CallDescriptionSet ModelledCalls = {<br>
-      {"CFRetain", 1},<br>
-      {"CFRelease", 1},<br>
-      {"CFMakeCollectable", 1},<br>
-      {"CFAutorelease", 1},<br>
+      {{"CFRetain"}, 1},<br>
+      {{"CFRelease"}, 1},<br>
+      {{"CFMakeCollectable"}, 1},<br>
+      {{"CFAutorelease"}, 1},<br>
   };<br>
<br>
 public:<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp<br>
index 8416ab39e1943..76f091562cd57 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp<br>
@@ -64,19 +64,15 @@ class BlockInCriticalSectionChecker : public Checker<check::PostCall> {<br>
 REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)<br>
<br>
 BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()<br>
-    : IILockGuard(nullptr), IIUniqueLock(nullptr),<br>
-      LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),<br>
-      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),<br>
-      PthreadLockFn("pthread_mutex_lock"),<br>
-      PthreadTryLockFn("pthread_mutex_trylock"),<br>
-      PthreadUnlockFn("pthread_mutex_unlock"),<br>
-      MtxLock("mtx_lock"),<br>
-      MtxTimedLock("mtx_timedlock"),<br>
-      MtxTryLock("mtx_trylock"),<br>
-      MtxUnlock("mtx_unlock"),<br>
-      ClassLockGuard("lock_guard"),<br>
-      ClassUniqueLock("unique_lock"),<br>
-      IdentifierInfoInitialized(false) {<br>
+    : IILockGuard(nullptr), IIUniqueLock(nullptr), LockFn({"lock"}),<br>
+      UnlockFn({"unlock"}), SleepFn({"sleep"}), GetcFn({"getc"}),<br>
+      FgetsFn({"fgets"}), ReadFn({"read"}), RecvFn({"recv"}),<br>
+      PthreadLockFn({"pthread_mutex_lock"}),<br>
+      PthreadTryLockFn({"pthread_mutex_trylock"}),<br>
+      PthreadUnlockFn({"pthread_mutex_unlock"}), MtxLock({"mtx_lock"}),<br>
+      MtxTimedLock({"mtx_timedlock"}), MtxTryLock({"mtx_trylock"}),<br>
+      MtxUnlock({"mtx_unlock"}), ClassLockGuard("lock_guard"),<br>
+      ClassUniqueLock("unique_lock"), IdentifierInfoInitialized(false) {<br>
   // Initialize the bug type.<br>
   BlockInCritSectionBugType.reset(<br>
       new BugType(this, "Call to blocking function in critical section",<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp<br>
index 09549534fcfd2..cd760b1ae62ec 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp<br>
@@ -134,45 +134,46 @@ class CStringChecker : public Checker< eval::Call,<br>
                                      const CallExpr *)>;<br>
<br>
   CallDescriptionMap<FnCheck> Callbacks = {<br>
-      {{CDF_MaybeBuiltin, "memcpy", 3},<br>
+      {{CDF_MaybeBuiltin, {"memcpy"}, 3},<br>
        std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Regular)},<br>
-      {{CDF_MaybeBuiltin, "wmemcpy", 3},<br>
+      {{CDF_MaybeBuiltin, {"wmemcpy"}, 3},<br>
        std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Wide)},<br>
-      {{CDF_MaybeBuiltin, "mempcpy", 3},<br>
+      {{CDF_MaybeBuiltin, {"mempcpy"}, 3},<br>
        std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Regular)},<br>
-      {{CDF_None, "wmempcpy", 3},<br>
+      {{CDF_None, {"wmempcpy"}, 3},<br>
        std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Wide)},<br>
-      {{CDF_MaybeBuiltin, "memcmp", 3},<br>
+      {{CDF_MaybeBuiltin, {"memcmp"}, 3},<br>
        std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},<br>
-      {{CDF_MaybeBuiltin, "wmemcmp", 3},<br>
+      {{CDF_MaybeBuiltin, {"wmemcmp"}, 3},<br>
        std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Wide)},<br>
-      {{CDF_MaybeBuiltin, "memmove", 3},<br>
+      {{CDF_MaybeBuiltin, {"memmove"}, 3},<br>
        std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Regular)},<br>
-      {{CDF_MaybeBuiltin, "wmemmove", 3},<br>
+      {{CDF_MaybeBuiltin, {"wmemmove"}, 3},<br>
        std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Wide)},<br>
-      {{CDF_MaybeBuiltin, "memset", 3}, &CStringChecker::evalMemset},<br>
-      {{CDF_MaybeBuiltin, "explicit_memset", 3}, &CStringChecker::evalMemset},<br>
-      {{CDF_MaybeBuiltin, "strcpy", 2}, &CStringChecker::evalStrcpy},<br>
-      {{CDF_MaybeBuiltin, "strncpy", 3}, &CStringChecker::evalStrncpy},<br>
-      {{CDF_MaybeBuiltin, "stpcpy", 2}, &CStringChecker::evalStpcpy},<br>
-      {{CDF_MaybeBuiltin, "strlcpy", 3}, &CStringChecker::evalStrlcpy},<br>
-      {{CDF_MaybeBuiltin, "strcat", 2}, &CStringChecker::evalStrcat},<br>
-      {{CDF_MaybeBuiltin, "strncat", 3}, &CStringChecker::evalStrncat},<br>
-      {{CDF_MaybeBuiltin, "strlcat", 3}, &CStringChecker::evalStrlcat},<br>
-      {{CDF_MaybeBuiltin, "strlen", 1}, &CStringChecker::evalstrLength},<br>
-      {{CDF_MaybeBuiltin, "wcslen", 1}, &CStringChecker::evalstrLength},<br>
-      {{CDF_MaybeBuiltin, "strnlen", 2}, &CStringChecker::evalstrnLength},<br>
-      {{CDF_MaybeBuiltin, "wcsnlen", 2}, &CStringChecker::evalstrnLength},<br>
-      {{CDF_MaybeBuiltin, "strcmp", 2}, &CStringChecker::evalStrcmp},<br>
-      {{CDF_MaybeBuiltin, "strncmp", 3}, &CStringChecker::evalStrncmp},<br>
-      {{CDF_MaybeBuiltin, "strcasecmp", 2}, &CStringChecker::evalStrcasecmp},<br>
-      {{CDF_MaybeBuiltin, "strncasecmp", 3}, &CStringChecker::evalStrncasecmp},<br>
-      {{CDF_MaybeBuiltin, "strsep", 2}, &CStringChecker::evalStrsep},<br>
-      {{CDF_MaybeBuiltin, "bcopy", 3}, &CStringChecker::evalBcopy},<br>
-      {{CDF_MaybeBuiltin, "bcmp", 3},<br>
+      {{CDF_MaybeBuiltin, {"memset"}, 3}, &CStringChecker::evalMemset},<br>
+      {{CDF_MaybeBuiltin, {"explicit_memset"}, 3}, &CStringChecker::evalMemset},<br>
+      {{CDF_MaybeBuiltin, {"strcpy"}, 2}, &CStringChecker::evalStrcpy},<br>
+      {{CDF_MaybeBuiltin, {"strncpy"}, 3}, &CStringChecker::evalStrncpy},<br>
+      {{CDF_MaybeBuiltin, {"stpcpy"}, 2}, &CStringChecker::evalStpcpy},<br>
+      {{CDF_MaybeBuiltin, {"strlcpy"}, 3}, &CStringChecker::evalStrlcpy},<br>
+      {{CDF_MaybeBuiltin, {"strcat"}, 2}, &CStringChecker::evalStrcat},<br>
+      {{CDF_MaybeBuiltin, {"strncat"}, 3}, &CStringChecker::evalStrncat},<br>
+      {{CDF_MaybeBuiltin, {"strlcat"}, 3}, &CStringChecker::evalStrlcat},<br>
+      {{CDF_MaybeBuiltin, {"strlen"}, 1}, &CStringChecker::evalstrLength},<br>
+      {{CDF_MaybeBuiltin, {"wcslen"}, 1}, &CStringChecker::evalstrLength},<br>
+      {{CDF_MaybeBuiltin, {"strnlen"}, 2}, &CStringChecker::evalstrnLength},<br>
+      {{CDF_MaybeBuiltin, {"wcsnlen"}, 2}, &CStringChecker::evalstrnLength},<br>
+      {{CDF_MaybeBuiltin, {"strcmp"}, 2}, &CStringChecker::evalStrcmp},<br>
+      {{CDF_MaybeBuiltin, {"strncmp"}, 3}, &CStringChecker::evalStrncmp},<br>
+      {{CDF_MaybeBuiltin, {"strcasecmp"}, 2}, &CStringChecker::evalStrcasecmp},<br>
+      {{CDF_MaybeBuiltin, {"strncasecmp"}, 3},<br>
+       &CStringChecker::evalStrncasecmp},<br>
+      {{CDF_MaybeBuiltin, {"strsep"}, 2}, &CStringChecker::evalStrsep},<br>
+      {{CDF_MaybeBuiltin, {"bcopy"}, 3}, &CStringChecker::evalBcopy},<br>
+      {{CDF_MaybeBuiltin, {"bcmp"}, 3},<br>
        std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},<br>
-      {{CDF_MaybeBuiltin, "bzero", 2}, &CStringChecker::evalBzero},<br>
-      {{CDF_MaybeBuiltin, "explicit_bzero", 2}, &CStringChecker::evalBzero},<br>
+      {{CDF_MaybeBuiltin, {"bzero"}, 2}, &CStringChecker::evalBzero},<br>
+      {{CDF_MaybeBuiltin, {"explicit_bzero"}, 2}, &CStringChecker::evalBzero},<br>
   };<br>
<br>
   // These require a bit of special handling.<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp<br>
index ce8d6c8798703..9ace1583eb538 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp<br>
@@ -43,7 +43,7 @@ class ChrootChecker : public Checker<eval::Call, check::PreCall> {<br>
   // This bug refers to possibly break out of a chroot() jail.<br>
   mutable std::unique_ptr<BuiltinBug> BT_BreakJail;<br>
<br>
-  const CallDescription Chroot{"chroot", 1}, Chdir{"chdir", 1};<br>
+  const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1};<br>
<br>
 public:<br>
   ChrootChecker() {}<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp<br>
index 77a3218f55fbb..67962f75f9bfa 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp<br>
@@ -72,26 +72,26 @@ class ContainerModeling<br>
                                                    SVal) const;<br>
<br>
   CallDescriptionMap<NoItParamFn> NoIterParamFunctions = {<br>
-      {{"clear", 0}, &ContainerModeling::handleClear},<br>
-      {{"assign", 2}, &ContainerModeling::handleAssign},<br>
-      {{"push_back", 1}, &ContainerModeling::handlePushBack},<br>
-      {{"emplace_back", 1}, &ContainerModeling::handlePushBack},<br>
-      {{"pop_back", 0}, &ContainerModeling::handlePopBack},<br>
-      {{"push_front", 1}, &ContainerModeling::handlePushFront},<br>
-      {{"emplace_front", 1}, &ContainerModeling::handlePushFront},<br>
-      {{"pop_front", 0}, &ContainerModeling::handlePopFront},<br>
+      {{{"clear"}, 0}, &ContainerModeling::handleClear},<br>
+      {{{"assign"}, 2}, &ContainerModeling::handleAssign},<br>
+      {{{"push_back"}, 1}, &ContainerModeling::handlePushBack},<br>
+      {{{"emplace_back"}, 1}, &ContainerModeling::handlePushBack},<br>
+      {{{"pop_back"}, 0}, &ContainerModeling::handlePopBack},<br>
+      {{{"push_front"}, 1}, &ContainerModeling::handlePushFront},<br>
+      {{{"emplace_front"}, 1}, &ContainerModeling::handlePushFront},<br>
+      {{{"pop_front"}, 0}, &ContainerModeling::handlePopFront},<br>
   };<br>
<br>
   CallDescriptionMap<OneItParamFn> OneIterParamFunctions = {<br>
-      {{"insert", 2}, &ContainerModeling::handleInsert},<br>
-      {{"emplace", 2}, &ContainerModeling::handleInsert},<br>
-      {{"erase", 1}, &ContainerModeling::handleErase},<br>
-      {{"erase_after", 1}, &ContainerModeling::handleEraseAfter},<br>
+      {{{"insert"}, 2}, &ContainerModeling::handleInsert},<br>
+      {{{"emplace"}, 2}, &ContainerModeling::handleInsert},<br>
+      {{{"erase"}, 1}, &ContainerModeling::handleErase},<br>
+      {{{"erase_after"}, 1}, &ContainerModeling::handleEraseAfter},<br>
   };<br>
<br>
   CallDescriptionMap<TwoItParamFn> TwoIterParamFunctions = {<br>
-      {{"erase", 2}, &ContainerModeling::handleErase},<br>
-      {{"erase_after", 2}, &ContainerModeling::handleEraseAfter},<br>
+      {{{"erase"}, 2}, &ContainerModeling::handleErase},<br>
+      {{{"erase_after"}, 2}, &ContainerModeling::handleEraseAfter},<br>
   };<br>
 };<br>
<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp<br>
index 47fd57c7db9bd..832bb78c48035 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp<br>
@@ -41,9 +41,9 @@ class DebugContainerModeling<br>
                                                  CheckerContext &) const;<br>
<br>
   CallDescriptionMap<FnCheck> Callbacks = {<br>
-      {{"clang_analyzer_container_begin", 1},<br>
+      {{{"clang_analyzer_container_begin"}, 1},<br>
        &DebugContainerModeling::analyzerContainerBegin},<br>
-      {{"clang_analyzer_container_end", 1},<br>
+      {{{"clang_analyzer_container_end"}, 1},<br>
        &DebugContainerModeling::analyzerContainerEnd},<br>
   };<br>
<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp<br>
index 6add9a007a87e..d05298b42c55c 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp<br>
@@ -42,11 +42,11 @@ class DebugIteratorModeling<br>
                                                  CheckerContext &) const;<br>
<br>
   CallDescriptionMap<FnCheck> Callbacks = {<br>
-      {{"clang_analyzer_iterator_position", 1},<br>
+      {{{"clang_analyzer_iterator_position"}, 1},<br>
        &DebugIteratorModeling::analyzerIteratorPosition},<br>
-      {{"clang_analyzer_iterator_container", 1},<br>
+      {{{"clang_analyzer_iterator_container"}, 1},<br>
        &DebugIteratorModeling::analyzerIteratorContainer},<br>
-      {{"clang_analyzer_iterator_validity", 1},<br>
+      {{{"clang_analyzer_iterator_validity"}, 1},<br>
        &DebugIteratorModeling::analyzerIteratorValidity},<br>
   };<br>
<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp<br>
index a9e249de38047..5f79c162f10df 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoModeling.cpp<br>
@@ -57,11 +57,11 @@ class ErrnoModeling<br>
<br>
 private:<br>
   // FIXME: Names from `ErrnoLocationFuncNames` are used to build this set.<br>
-  CallDescriptionSet ErrnoLocationCalls{{"__errno_location", 0, 0},<br>
-                                        {"___errno", 0, 0},<br>
-                                        {"__errno", 0, 0},<br>
-                                        {"_errno", 0, 0},<br>
-                                        {"__error", 0, 0}};<br>
+  CallDescriptionSet ErrnoLocationCalls{{{"__errno_location"}, 0, 0},<br>
+                                        {{"___errno"}, 0, 0},<br>
+                                        {{"__errno"}, 0, 0},<br>
+                                        {{"_errno"}, 0, 0},<br>
+                                        {{"__error"}, 0, 0}};<br>
 };<br>
<br>
 } // namespace<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp<br>
index 924407ebe2d18..3b9ff0cca0fa3 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp<br>
@@ -69,13 +69,13 @@ class ErrnoTesterChecker : public Checker<eval::Call> {<br>
<br>
   using EvalFn = std::function<void(CheckerContext &, const CallEvent &)>;<br>
   const CallDescriptionMap<EvalFn> TestCalls{<br>
-      {{"ErrnoTesterChecker_setErrno", 1}, &ErrnoTesterChecker::evalSetErrno},<br>
-      {{"ErrnoTesterChecker_getErrno", 0}, &ErrnoTesterChecker::evalGetErrno},<br>
-      {{"ErrnoTesterChecker_setErrnoIfError", 0},<br>
+      {{{"ErrnoTesterChecker_setErrno"}, 1}, &ErrnoTesterChecker::evalSetErrno},<br>
+      {{{"ErrnoTesterChecker_getErrno"}, 0}, &ErrnoTesterChecker::evalGetErrno},<br>
+      {{{"ErrnoTesterChecker_setErrnoIfError"}, 0},<br>
        &ErrnoTesterChecker::evalSetErrnoIfError},<br>
-      {{"ErrnoTesterChecker_setErrnoIfErrorRange", 0},<br>
+      {{{"ErrnoTesterChecker_setErrnoIfErrorRange"}, 0},<br>
        &ErrnoTesterChecker::evalSetErrnoIfErrorRange},<br>
-      {{"ErrnoTesterChecker_setErrnoCheckState", 0},<br>
+      {{{"ErrnoTesterChecker_setErrnoCheckState"}, 0},<br>
        &ErrnoTesterChecker::evalSetErrnoCheckState}};<br>
 };<br>
<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp<br>
index 0f7973e740993..80f9f88816129 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp<br>
@@ -304,7 +304,7 @@ struct GenericTaintRuleParser {<br>
                                  TaintConfiguration &&Config) const;<br>
<br>
 private:<br>
-  using NamePartsTy = llvm::SmallVector<SmallString<32>, 2>;<br>
+  using NamePartsTy = llvm::SmallVector<StringRef, 2>;<br>
<br>
   /// Validate part of the configuration, which contains a list of argument<br>
   /// indexes.<br>
@@ -444,10 +444,8 @@ GenericTaintRuleParser::parseNameParts(const Config &C) {<br>
   if (!C.Scope.empty()) {<br>
     // If the Scope argument contains multiple "::" parts, those are considered<br>
     // namespace identifiers.<br>
-    llvm::SmallVector<StringRef, 2> NSParts;<br>
-    StringRef{C.Scope}.split(NSParts, "::", /*MaxSplit*/ -1,<br>
+    StringRef{C.Scope}.split(NameParts, "::", /*MaxSplit*/ -1,<br>
                              /*KeepEmpty*/ false);<br>
-    NameParts.append(NSParts.begin(), NSParts.end());<br>
   }<br>
   NameParts.emplace_back(C.Name);<br>
   return NameParts;<br>
@@ -458,10 +456,7 @@ void GenericTaintRuleParser::consumeRulesFromConfig(const Config &C,<br>
                                                     GenericTaintRule &&Rule,<br>
                                                     RulesContTy &Rules) {<br>
   NamePartsTy NameParts = parseNameParts(C);<br>
-  llvm::SmallVector<const char *, 2> CallDescParts{NameParts.size()};<br>
-  llvm::transform(NameParts, CallDescParts.begin(),<br>
-                  [](SmallString<32> &S) { return S.c_str(); });<br>
-  Rules.emplace_back(CallDescription(CallDescParts), std::move(Rule));<br>
+  Rules.emplace_back(CallDescription(NameParts), std::move(Rule));<br>
 }<br>
<br>
 void GenericTaintRuleParser::parseConfig(const std::string &Option,<br>
@@ -531,128 +526,128 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {<br>
<br>
   RulesConstructionTy GlobalCRules{<br>
       // Sources<br>
-      {{"fdopen"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"fopen"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"freopen"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"getch"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"getchar"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"getchar_unlocked"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"gets"}, TR::Source({{0}, ReturnValueIndex})},<br>
-      {{"gets_s"}, TR::Source({{0}, ReturnValueIndex})},<br>
-      {{"scanf"}, TR::Source({{}, 1})},<br>
-      {{"scanf_s"}, TR::Source({{}, {1}})},<br>
-      {{"wgetch"}, TR::Source({{}, ReturnValueIndex})},<br>
+      {{{"fdopen"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"fopen"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"freopen"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"getch"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"getchar"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"getchar_unlocked"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"gets"}}, TR::Source({{0}, ReturnValueIndex})},<br>
+      {{{"gets_s"}}, TR::Source({{0}, ReturnValueIndex})},<br>
+      {{{"scanf"}}, TR::Source({{}, 1})},<br>
+      {{{"scanf_s"}}, TR::Source({{}, {1}})},<br>
+      {{{"wgetch"}}, TR::Source({{}, ReturnValueIndex})},<br>
       // Sometimes the line between taint sources and propagators is blurry.<br>
       // _IO_getc is choosen to be a source, but could also be a propagator.<br>
       // This way it is simpler, as modeling it as a propagator would require<br>
       // to model the possible sources of _IO_FILE * values, which the _IO_getc<br>
       // function takes as parameters.<br>
-      {{"_IO_getc"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"getcwd"}, TR::Source({{0, ReturnValueIndex}})},<br>
-      {{"getwd"}, TR::Source({{0, ReturnValueIndex}})},<br>
-      {{"readlink"}, TR::Source({{1, ReturnValueIndex}})},<br>
-      {{"readlinkat"}, TR::Source({{2, ReturnValueIndex}})},<br>
-      {{"get_current_dir_name"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"gethostname"}, TR::Source({{0}})},<br>
-      {{"getnameinfo"}, TR::Source({{2, 4}})},<br>
-      {{"getseuserbyname"}, TR::Source({{1, 2}})},<br>
-      {{"getgroups"}, TR::Source({{1, ReturnValueIndex}})},<br>
-      {{"getlogin"}, TR::Source({{ReturnValueIndex}})},<br>
-      {{"getlogin_r"}, TR::Source({{0}})},<br>
+      {{{"_IO_getc"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"getcwd"}}, TR::Source({{0, ReturnValueIndex}})},<br>
+      {{{"getwd"}}, TR::Source({{0, ReturnValueIndex}})},<br>
+      {{{"readlink"}}, TR::Source({{1, ReturnValueIndex}})},<br>
+      {{{"readlinkat"}}, TR::Source({{2, ReturnValueIndex}})},<br>
+      {{{"get_current_dir_name"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"gethostname"}}, TR::Source({{0}})},<br>
+      {{{"getnameinfo"}}, TR::Source({{2, 4}})},<br>
+      {{{"getseuserbyname"}}, TR::Source({{1, 2}})},<br>
+      {{{"getgroups"}}, TR::Source({{1, ReturnValueIndex}})},<br>
+      {{{"getlogin"}}, TR::Source({{ReturnValueIndex}})},<br>
+      {{{"getlogin_r"}}, TR::Source({{0}})},<br>
<br>
       // Props<br>
-      {{"atoi"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"atol"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"atoll"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"fgetc"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"fgetln"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"fgets"}, TR::Prop({{2}}, {{0, ReturnValueIndex}})},<br>
-      {{"fscanf"}, TR::Prop({{0}}, {{}, 2})},<br>
-      {{"fscanf_s"}, TR::Prop({{0}}, {{}, {2}})},<br>
-      {{"sscanf"}, TR::Prop({{0}}, {{}, 2})},<br>
-<br>
-      {{"getc"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"getc_unlocked"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"getdelim"}, TR::Prop({{3}}, {{0}})},<br>
-      {{"getline"}, TR::Prop({{2}}, {{0}})},<br>
-      {{"getw"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"pread"}, TR::Prop({{0, 1, 2, 3}}, {{1, ReturnValueIndex}})},<br>
-      {{"read"}, TR::Prop({{0, 2}}, {{1, ReturnValueIndex}})},<br>
-      {{"strchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strrchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"tolower"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"toupper"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"fread"}, TR::Prop({{3}}, {{0, ReturnValueIndex}})},<br>
-      {{"recv"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-      {{"recvfrom"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-<br>
-      {{"ttyname"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"ttyname_r"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-<br>
-      {{"basename"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"dirname"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"fnmatch"}, TR::Prop({{1}}, {{ReturnValueIndex}})},<br>
-      {{"memchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"memrchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"rawmemchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-<br>
-      {{"mbtowc"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{"wctomb"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{"wcwidth"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-<br>
-      {{"memcmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
-      {{"memcpy"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{"memmove"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
+      {{{"atoi"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"atol"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"atoll"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"fgetc"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"fgetln"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"fgets"}}, TR::Prop({{2}}, {{0, ReturnValueIndex}})},<br>
+      {{{"fscanf"}}, TR::Prop({{0}}, {{}, 2})},<br>
+      {{{"fscanf_s"}}, TR::Prop({{0}}, {{}, {2}})},<br>
+      {{{"sscanf"}}, TR::Prop({{0}}, {{}, 2})},<br>
+<br>
+      {{{"getc"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"getc_unlocked"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"getdelim"}}, TR::Prop({{3}}, {{0}})},<br>
+      {{{"getline"}}, TR::Prop({{2}}, {{0}})},<br>
+      {{{"getw"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"pread"}}, TR::Prop({{0, 1, 2, 3}}, {{1, ReturnValueIndex}})},<br>
+      {{{"read"}}, TR::Prop({{0, 2}}, {{1, ReturnValueIndex}})},<br>
+      {{{"strchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strrchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"tolower"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"toupper"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"fread"}}, TR::Prop({{3}}, {{0, ReturnValueIndex}})},<br>
+      {{{"recv"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+      {{{"recvfrom"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+<br>
+      {{{"ttyname"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"ttyname_r"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+<br>
+      {{{"basename"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"dirname"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"fnmatch"}}, TR::Prop({{1}}, {{ReturnValueIndex}})},<br>
+      {{{"memchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"memrchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"rawmemchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+<br>
+      {{{"mbtowc"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
+      {{{"wctomb"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
+      {{{"wcwidth"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+<br>
+      {{{"memcmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
+      {{{"memcpy"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
+      {{{"memmove"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
       // If memmem was called with a tainted needle and the search was<br>
       // successful, that would mean that the value pointed by the return value<br>
       // has the same content as the needle. If we choose to go by the policy of<br>
       // content equivalence implies taintedness equivalence, that would mean<br>
       // haystack should be considered a propagation source argument.<br>
-      {{"memmem"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"memmem"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
       // The comment for memmem above also applies to strstr.<br>
-      {{"strstr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strcasestr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strstr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strcasestr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
-      {{"strchrnul"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strchrnul"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
-      {{"index"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"rindex"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"index"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"rindex"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
       // FIXME: In case of arrays, only the first element of the array gets<br>
       // tainted.<br>
-      {{"qsort"}, TR::Prop({{0}}, {{0}})},<br>
-      {{"qsort_r"}, TR::Prop({{0}}, {{0}})},<br>
-<br>
-      {{"strcmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
-      {{"strcasecmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
-      {{"strncmp"}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},<br>
-      {{"strncasecmp"}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},<br>
-      {{"strspn"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
-      {{"strcspn"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
-      {{"strpbrk"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strndup"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strndupa"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strlen"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strnlen"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"strtol"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-      {{"strtoll"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-      {{"strtoul"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-      {{"strtoull"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
-<br>
-      {{"isalnum"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isalpha"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isascii"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isblank"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"iscntrl"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isdigit"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isgraph"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"islower"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isprint"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"ispunct"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isspace"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isupper"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{"isxdigit"}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"qsort"}}, TR::Prop({{0}}, {{0}})},<br>
+      {{{"qsort_r"}}, TR::Prop({{0}}, {{0}})},<br>
+<br>
+      {{{"strcmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
+      {{{"strcasecmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
+      {{{"strncmp"}}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},<br>
+      {{{"strncasecmp"}}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},<br>
+      {{{"strspn"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
+      {{{"strcspn"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},<br>
+      {{{"strpbrk"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strndup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strndupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strnlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"strtol"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+      {{{"strtoll"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+      {{{"strtoul"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+      {{{"strtoull"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},<br>
+<br>
+      {{{"isalnum"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isalpha"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isascii"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isblank"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"iscntrl"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isdigit"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isgraph"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"islower"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isprint"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"ispunct"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isspace"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isupper"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{{"isxdigit"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
       {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncat)}},<br>
        TR::Prop({{1, 2}}, {{0, ReturnValueIndex}})},<br>
@@ -660,37 +655,40 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {<br>
        TR::Prop({{1, 2}}, {{0}})},<br>
       {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcat)}},<br>
        TR::Prop({{1, 2}}, {{0}})},<br>
-      {{CDF_MaybeBuiltin, {"snprintf"}},<br>
+      {{CDF_MaybeBuiltin, {{"snprintf"}}},<br>
        TR::Prop({{1}, 3}, {{0, ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"sprintf"}},<br>
+      {{CDF_MaybeBuiltin, {{"sprintf"}}},<br>
        TR::Prop({{1}, 2}, {{0, ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"strcpy"}},<br>
+      {{CDF_MaybeBuiltin, {{"strcpy"}}},<br>
        TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"stpcpy"}},<br>
+      {{CDF_MaybeBuiltin, {{"stpcpy"}}},<br>
        TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"strcat"}},<br>
+      {{CDF_MaybeBuiltin, {{"strcat"}}},<br>
        TR::Prop({{1}}, {{0, ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"strdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"strdupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
-      {{CDF_MaybeBuiltin, {"wcsdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{CDF_MaybeBuiltin, {{"strdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{CDF_MaybeBuiltin, {{"strdupa"}}},<br>
+       TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
+      {{CDF_MaybeBuiltin, {{"wcsdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},<br>
<br>
       // Sinks<br>
-      {{"system"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"popen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execl"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execle"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execlp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execvp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execvP"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"execve"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{"dlopen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
-      {{CDF_MaybeBuiltin, {"malloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
-      {{CDF_MaybeBuiltin, {"calloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
-      {{CDF_MaybeBuiltin, {"alloca"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
-      {{CDF_MaybeBuiltin, {"memccpy"}}, TR::Sink({{3}}, MsgTaintedBufferSize)},<br>
-      {{CDF_MaybeBuiltin, {"realloc"}}, TR::Sink({{1}}, MsgTaintedBufferSize)},<br>
-      {{{"setproctitle"}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},<br>
-      {{{"setproctitle_fast"}},<br>
+      {{{"system"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"popen"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execl"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execle"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execlp"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execvp"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execvP"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"execve"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{{"dlopen"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},<br>
+      {{CDF_MaybeBuiltin, {{"malloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
+      {{CDF_MaybeBuiltin, {{"calloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
+      {{CDF_MaybeBuiltin, {{"alloca"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},<br>
+      {{CDF_MaybeBuiltin, {{"memccpy"}}},<br>
+       TR::Sink({{3}}, MsgTaintedBufferSize)},<br>
+      {{CDF_MaybeBuiltin, {{"realloc"}}},<br>
+       TR::Sink({{1}}, MsgTaintedBufferSize)},<br>
+      {{{{"setproctitle"}}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},<br>
+      {{{{"setproctitle_fast"}}},<br>
        TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},<br>
<br>
       // SinkProps<br>
@@ -706,7 +704,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {<br>
       {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrndup)}},<br>
        TR::SinkProp({{1}}, {{0, 1}}, {{ReturnValueIndex}},<br>
                     MsgTaintedBufferSize)},<br>
-      {{CDF_MaybeBuiltin, {"bcopy"}},<br>
+      {{CDF_MaybeBuiltin, {{"bcopy"}}},<br>
        TR::SinkProp({{2}}, {{0, 2}}, {{1}}, MsgTaintedBufferSize)}};<br>
<br>
   // `getenv` returns taint only in untrusted environments.<br>
@@ -714,7 +712,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {<br>
     // void setproctitle_init(int argc, char *argv[], char *envp[])<br>
     GlobalCRules.push_back(<br>
         {{{"setproctitle_init"}}, TR::Sink({{1, 2}}, MsgCustomSink)});<br>
-    GlobalCRules.push_back({{"getenv"}, TR::Source({{ReturnValueIndex}})});<br>
+    GlobalCRules.push_back({{{"getenv"}}, TR::Source({{ReturnValueIndex}})});<br>
   }<br>
<br>
   StaticTaintRules.emplace(std::make_move_iterator(GlobalCRules.begin()),<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp<br>
index 139bc0e99d78a..6952953627e30 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp<br>
@@ -86,7 +86,7 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,<br>
 #undef CALL<br>
   };<br>
<br>
-  CallDescription OsRefRetain{"os_ref_retain", 1};<br>
+  CallDescription OsRefRetain{{"os_ref_retain"}, 1};<br>
<br>
   void checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const;<br>
<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp<br>
index 9f8017266bb93..aa24f1a03d145 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp<br>
@@ -392,10 +392,10 @@ class MallocChecker<br>
                                      const CallEvent &Call, CheckerContext &C)>;<br>
<br>
   const CallDescriptionMap<CheckFn> FreeingMemFnMap{<br>
-      {{"free", 1}, &MallocChecker::checkFree},<br>
-      {{"if_freenameindex", 1}, &MallocChecker::checkIfFreeNameIndex},<br>
-      {{"kfree", 1}, &MallocChecker::checkFree},<br>
-      {{"g_free", 1}, &MallocChecker::checkFree},<br>
+      {{{"free"}, 1}, &MallocChecker::checkFree},<br>
+      {{{"if_freenameindex"}, 1}, &MallocChecker::checkIfFreeNameIndex},<br>
+      {{{"kfree"}, 1}, &MallocChecker::checkFree},<br>
+      {{{"g_free"}, 1}, &MallocChecker::checkFree},<br>
   };<br>
<br>
   bool isFreeingCall(const CallEvent &Call) const;<br>
@@ -404,41 +404,41 @@ class MallocChecker<br>
   friend class NoOwnershipChangeVisitor;<br>
<br>
   CallDescriptionMap<CheckFn> AllocatingMemFnMap{<br>
-      {{"alloca", 1}, &MallocChecker::checkAlloca},<br>
-      {{"_alloca", 1}, &MallocChecker::checkAlloca},<br>
-      {{"malloc", 1}, &MallocChecker::checkBasicAlloc},<br>
-      {{"malloc", 3}, &MallocChecker::checkKernelMalloc},<br>
-      {{"calloc", 2}, &MallocChecker::checkCalloc},<br>
-      {{"valloc", 1}, &MallocChecker::checkBasicAlloc},<br>
-      {{CDF_MaybeBuiltin, "strndup", 2}, &MallocChecker::checkStrdup},<br>
-      {{CDF_MaybeBuiltin, "strdup", 1}, &MallocChecker::checkStrdup},<br>
-      {{"_strdup", 1}, &MallocChecker::checkStrdup},<br>
-      {{"kmalloc", 2}, &MallocChecker::checkKernelMalloc},<br>
-      {{"if_nameindex", 1}, &MallocChecker::checkIfNameIndex},<br>
-      {{CDF_MaybeBuiltin, "wcsdup", 1}, &MallocChecker::checkStrdup},<br>
-      {{CDF_MaybeBuiltin, "_wcsdup", 1}, &MallocChecker::checkStrdup},<br>
-      {{"g_malloc", 1}, &MallocChecker::checkBasicAlloc},<br>
-      {{"g_malloc0", 1}, &MallocChecker::checkGMalloc0},<br>
-      {{"g_try_malloc", 1}, &MallocChecker::checkBasicAlloc},<br>
-      {{"g_try_malloc0", 1}, &MallocChecker::checkGMalloc0},<br>
-      {{"g_memdup", 2}, &MallocChecker::checkGMemdup},<br>
-      {{"g_malloc_n", 2}, &MallocChecker::checkGMallocN},<br>
-      {{"g_malloc0_n", 2}, &MallocChecker::checkGMallocN0},<br>
-      {{"g_try_malloc_n", 2}, &MallocChecker::checkGMallocN},<br>
-      {{"g_try_malloc0_n", 2}, &MallocChecker::checkGMallocN0},<br>
+      {{{"alloca"}, 1}, &MallocChecker::checkAlloca},<br>
+      {{{"_alloca"}, 1}, &MallocChecker::checkAlloca},<br>
+      {{{"malloc"}, 1}, &MallocChecker::checkBasicAlloc},<br>
+      {{{"malloc"}, 3}, &MallocChecker::checkKernelMalloc},<br>
+      {{{"calloc"}, 2}, &MallocChecker::checkCalloc},<br>
+      {{{"valloc"}, 1}, &MallocChecker::checkBasicAlloc},<br>
+      {{CDF_MaybeBuiltin, {"strndup"}, 2}, &MallocChecker::checkStrdup},<br>
+      {{CDF_MaybeBuiltin, {"strdup"}, 1}, &MallocChecker::checkStrdup},<br>
+      {{{"_strdup"}, 1}, &MallocChecker::checkStrdup},<br>
+      {{{"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc},<br>
+      {{{"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex},<br>
+      {{CDF_MaybeBuiltin, {"wcsdup"}, 1}, &MallocChecker::checkStrdup},<br>
+      {{CDF_MaybeBuiltin, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup},<br>
+      {{{"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc},<br>
+      {{{"g_malloc0"}, 1}, &MallocChecker::checkGMalloc0},<br>
+      {{{"g_try_malloc"}, 1}, &MallocChecker::checkBasicAlloc},<br>
+      {{{"g_try_malloc0"}, 1}, &MallocChecker::checkGMalloc0},<br>
+      {{{"g_memdup"}, 2}, &MallocChecker::checkGMemdup},<br>
+      {{{"g_malloc_n"}, 2}, &MallocChecker::checkGMallocN},<br>
+      {{{"g_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0},<br>
+      {{{"g_try_malloc_n"}, 2}, &MallocChecker::checkGMallocN},<br>
+      {{{"g_try_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0},<br>
   };<br>
<br>
   CallDescriptionMap<CheckFn> ReallocatingMemFnMap{<br>
-      {{"realloc", 2},<br>
+      {{{"realloc"}, 2},<br>
        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},<br>
-      {{"reallocf", 2},<br>
+      {{{"reallocf"}, 2},<br>
        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, true)},<br>
-      {{"g_realloc", 2},<br>
+      {{{"g_realloc"}, 2},<br>
        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},<br>
-      {{"g_try_realloc", 2},<br>
+      {{{"g_try_realloc"}, 2},<br>
        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},<br>
-      {{"g_realloc_n", 3}, &MallocChecker::checkReallocN},<br>
-      {{"g_try_realloc_n", 3}, &MallocChecker::checkReallocN},<br>
+      {{{"g_realloc_n"}, 3}, &MallocChecker::checkReallocN},<br>
+      {{{"g_try_realloc_n"}, 3}, &MallocChecker::checkReallocN},<br>
   };<br>
<br>
   bool isMemCall(const CallEvent &Call) const;<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp<br>
index 1906ca5c8f554..0b3d635a50a3f 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp<br>
@@ -33,7 +33,7 @@ class MmapWriteExecChecker : public Checker<check::PreCall> {<br>
   static int ProtRead;<br>
   mutable std::unique_ptr<BugType> BT;<br>
 public:<br>
-  MmapWriteExecChecker() : MmapFn("mmap", 6), MprotectFn("mprotect", 3) {}<br>
+  MmapWriteExecChecker() : MmapFn({"mmap"}, 6), MprotectFn({"mprotect"}, 3) {}<br>
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;<br>
   int ProtExecOv;<br>
   int ProtReadOv;<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp<br>
index e877dd119ff61..929bd6bc3eb39 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp<br>
@@ -87,7 +87,7 @@ class PthreadLockChecker : public Checker<check::PostCall, check::DeadSymbols,<br>
                                               CheckerKind CheckKind) const;<br>
   CallDescriptionMap<FnCheck> PThreadCallbacks = {<br>
       // Init.<br>
-      {{"pthread_mutex_init", 2}, &PthreadLockChecker::InitAnyLock},<br>
+      {{{"pthread_mutex_init"}, 2}, &PthreadLockChecker::InitAnyLock},<br>
       // TODO: pthread_rwlock_init(2 arguments).<br>
       // TODO: lck_mtx_init(3 arguments).<br>
       // TODO: lck_mtx_alloc_init(2 arguments) => returns the mutex.<br>
@@ -95,74 +95,74 @@ class PthreadLockChecker : public Checker<check::PostCall, check::DeadSymbols,<br>
       // TODO: lck_rw_alloc_init(2 arguments) => returns the mutex.<br>
<br>
       // Acquire.<br>
-      {{"pthread_mutex_lock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"pthread_rwlock_rdlock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"pthread_rwlock_wrlock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"lck_mtx_lock", 1}, &PthreadLockChecker::AcquireXNULock},<br>
-      {{"lck_rw_lock_exclusive", 1}, &PthreadLockChecker::AcquireXNULock},<br>
-      {{"lck_rw_lock_shared", 1}, &PthreadLockChecker::AcquireXNULock},<br>
+      {{{"pthread_mutex_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"pthread_rwlock_rdlock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"pthread_rwlock_wrlock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"lck_mtx_lock"}, 1}, &PthreadLockChecker::AcquireXNULock},<br>
+      {{{"lck_rw_lock_exclusive"}, 1}, &PthreadLockChecker::AcquireXNULock},<br>
+      {{{"lck_rw_lock_shared"}, 1}, &PthreadLockChecker::AcquireXNULock},<br>
<br>
       // Try.<br>
-      {{"pthread_mutex_trylock", 1}, &PthreadLockChecker::TryPthreadLock},<br>
-      {{"pthread_rwlock_tryrdlock", 1}, &PthreadLockChecker::TryPthreadLock},<br>
-      {{"pthread_rwlock_trywrlock", 1}, &PthreadLockChecker::TryPthreadLock},<br>
-      {{"lck_mtx_try_lock", 1}, &PthreadLockChecker::TryXNULock},<br>
-      {{"lck_rw_try_lock_exclusive", 1}, &PthreadLockChecker::TryXNULock},<br>
-      {{"lck_rw_try_lock_shared", 1}, &PthreadLockChecker::TryXNULock},<br>
+      {{{"pthread_mutex_trylock"}, 1}, &PthreadLockChecker::TryPthreadLock},<br>
+      {{{"pthread_rwlock_tryrdlock"}, 1}, &PthreadLockChecker::TryPthreadLock},<br>
+      {{{"pthread_rwlock_trywrlock"}, 1}, &PthreadLockChecker::TryPthreadLock},<br>
+      {{{"lck_mtx_try_lock"}, 1}, &PthreadLockChecker::TryXNULock},<br>
+      {{{"lck_rw_try_lock_exclusive"}, 1}, &PthreadLockChecker::TryXNULock},<br>
+      {{{"lck_rw_try_lock_shared"}, 1}, &PthreadLockChecker::TryXNULock},<br>
<br>
       // Release.<br>
-      {{"pthread_mutex_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"pthread_rwlock_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"lck_mtx_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"lck_rw_unlock_exclusive", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"lck_rw_unlock_shared", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"lck_rw_done", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"pthread_mutex_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"pthread_rwlock_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"lck_mtx_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"lck_rw_unlock_exclusive"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"lck_rw_unlock_shared"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"lck_rw_done"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
<br>
       // Destroy.<br>
-      {{"pthread_mutex_destroy", 1}, &PthreadLockChecker::DestroyPthreadLock},<br>
-      {{"lck_mtx_destroy", 2}, &PthreadLockChecker::DestroyXNULock},<br>
+      {{{"pthread_mutex_destroy"}, 1}, &PthreadLockChecker::DestroyPthreadLock},<br>
+      {{{"lck_mtx_destroy"}, 2}, &PthreadLockChecker::DestroyXNULock},<br>
       // TODO: pthread_rwlock_destroy(1 argument).<br>
       // TODO: lck_rw_destroy(2 arguments).<br>
   };<br>
<br>
   CallDescriptionMap<FnCheck> FuchsiaCallbacks = {<br>
       // Init.<br>
-      {{"spin_lock_init", 1}, &PthreadLockChecker::InitAnyLock},<br>
+      {{{"spin_lock_init"}, 1}, &PthreadLockChecker::InitAnyLock},<br>
<br>
       // Acquire.<br>
-      {{"spin_lock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"spin_lock_save", 3}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"sync_mutex_lock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
-      {{"sync_mutex_lock_with_waiter", 1},<br>
+      {{{"spin_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"spin_lock_save"}, 3}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"sync_mutex_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"sync_mutex_lock_with_waiter"}, 1},<br>
        &PthreadLockChecker::AcquirePthreadLock},<br>
<br>
       // Try.<br>
-      {{"spin_trylock", 1}, &PthreadLockChecker::TryFuchsiaLock},<br>
-      {{"sync_mutex_trylock", 1}, &PthreadLockChecker::TryFuchsiaLock},<br>
-      {{"sync_mutex_timedlock", 2}, &PthreadLockChecker::TryFuchsiaLock},<br>
+      {{{"spin_trylock"}, 1}, &PthreadLockChecker::TryFuchsiaLock},<br>
+      {{{"sync_mutex_trylock"}, 1}, &PthreadLockChecker::TryFuchsiaLock},<br>
+      {{{"sync_mutex_timedlock"}, 2}, &PthreadLockChecker::TryFuchsiaLock},<br>
<br>
       // Release.<br>
-      {{"spin_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"spin_unlock_restore", 3}, &PthreadLockChecker::ReleaseAnyLock},<br>
-      {{"sync_mutex_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"spin_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"spin_unlock_restore"}, 3}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"sync_mutex_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
   };<br>
<br>
   CallDescriptionMap<FnCheck> C11Callbacks = {<br>
       // Init.<br>
-      {{"mtx_init", 2}, &PthreadLockChecker::InitAnyLock},<br>
+      {{{"mtx_init"}, 2}, &PthreadLockChecker::InitAnyLock},<br>
<br>
       // Acquire.<br>
-      {{"mtx_lock", 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
+      {{{"mtx_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},<br>
<br>
       // Try.<br>
-      {{"mtx_trylock", 1}, &PthreadLockChecker::TryC11Lock},<br>
-      {{"mtx_timedlock", 2}, &PthreadLockChecker::TryC11Lock},<br>
+      {{{"mtx_trylock"}, 1}, &PthreadLockChecker::TryC11Lock},<br>
+      {{{"mtx_timedlock"}, 2}, &PthreadLockChecker::TryC11Lock},<br>
<br>
       // Release.<br>
-      {{"mtx_unlock", 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
+      {{{"mtx_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},<br>
<br>
       // Destroy<br>
-      {{"mtx_destroy", 1}, &PthreadLockChecker::DestroyPthreadLock},<br>
+      {{{"mtx_destroy"}, 1}, &PthreadLockChecker::DestroyPthreadLock},<br>
   };<br>
<br>
   ProgramStateRef resolvePossiblyDestroyedMutex(ProgramStateRef state,<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp<br>
index 8c87a548fd91e..9251c895614ca 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp<br>
@@ -90,7 +90,7 @@ class SimpleStreamChecker : public Checker<check::PostCall,<br>
 REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState)<br>
<br>
 SimpleStreamChecker::SimpleStreamChecker()<br>
-    : OpenFn("fopen"), CloseFn("fclose", 1) {<br>
+    : OpenFn({"fopen"}), CloseFn({"fclose"}, 1) {<br>
   // Initialize the bug types.<br>
   DoubleCloseBugType.reset(<br>
       new BugType(this, "Double fclose", "Unix Stream API Error"));<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp<br>
index 92eef20d2daaf..107ff5aa0d9d0 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp<br>
@@ -85,10 +85,10 @@ class SmartPtrModeling<br>
   using SmartPtrMethodHandlerFn =<br>
       void (SmartPtrModeling::*)(const CallEvent &Call, CheckerContext &) const;<br>
   CallDescriptionMap<SmartPtrMethodHandlerFn> SmartPtrMethodHandlers{<br>
-      {{"reset"}, &SmartPtrModeling::handleReset},<br>
-      {{"release"}, &SmartPtrModeling::handleRelease},<br>
-      {{"swap", 1}, &SmartPtrModeling::handleSwapMethod},<br>
-      {{"get"}, &SmartPtrModeling::handleGet}};<br>
+      {{{"reset"}}, &SmartPtrModeling::handleReset},<br>
+      {{{"release"}}, &SmartPtrModeling::handleRelease},<br>
+      {{{"swap"}, 1}, &SmartPtrModeling::handleSwapMethod},<br>
+      {{{"get"}}, &SmartPtrModeling::handleGet}};<br>
   const CallDescription StdSwapCall{{"std", "swap"}, 2};<br>
   const CallDescription StdMakeUniqueCall{{"std", "make_unique"}};<br>
   const CallDescription StdMakeUniqueForOverwriteCall{<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp<br>
index fb90fc9c91ea3..b6516988c0876 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp<br>
@@ -236,42 +236,43 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,<br>
<br>
 private:<br>
   CallDescriptionMap<FnDescription> FnDescriptions = {<br>
-      {{"fopen"}, {nullptr, &StreamChecker::evalFopen, ArgNone}},<br>
-      {{"freopen", 3},<br>
+      {{{"fopen"}}, {nullptr, &StreamChecker::evalFopen, ArgNone}},<br>
+      {{{"freopen"}, 3},<br>
        {&StreamChecker::preFreopen, &StreamChecker::evalFreopen, 2}},<br>
-      {{"tmpfile"}, {nullptr, &StreamChecker::evalFopen, ArgNone}},<br>
-      {{"fclose", 1},<br>
+      {{{"tmpfile"}}, {nullptr, &StreamChecker::evalFopen, ArgNone}},<br>
+      {{{"fclose"}, 1},<br>
        {&StreamChecker::preDefault, &StreamChecker::evalFclose, 0}},<br>
-      {{"fread", 4},<br>
+      {{{"fread"}, 4},<br>
        {&StreamChecker::preFread,<br>
         std::bind(&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, true), 3}},<br>
-      {{"fwrite", 4},<br>
+      {{{"fwrite"}, 4},<br>
        {&StreamChecker::preFwrite,<br>
         std::bind(&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, false), 3}},<br>
-      {{"fseek", 3}, {&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}},<br>
-      {{"ftell", 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
-      {{"rewind", 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
-      {{"fgetpos", 2}, {&StreamChecker::preDefault, nullptr, 0}},<br>
-      {{"fsetpos", 2}, {&StreamChecker::preDefault, nullptr, 0}},<br>
-      {{"clearerr", 1},<br>
+      {{{"fseek"}, 3},<br>
+       {&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}},<br>
+      {{{"ftell"}, 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
+      {{{"rewind"}, 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
+      {{{"fgetpos"}, 2}, {&StreamChecker::preDefault, nullptr, 0}},<br>
+      {{{"fsetpos"}, 2}, {&StreamChecker::preDefault, nullptr, 0}},<br>
+      {{{"clearerr"}, 1},<br>
        {&StreamChecker::preDefault, &StreamChecker::evalClearerr, 0}},<br>
-      {{"feof", 1},<br>
+      {{{"feof"}, 1},<br>
        {&StreamChecker::preDefault,<br>
         std::bind(&StreamChecker::evalFeofFerror, _1, _2, _3, _4, ErrorFEof),<br>
         0}},<br>
-      {{"ferror", 1},<br>
+      {{{"ferror"}, 1},<br>
        {&StreamChecker::preDefault,<br>
         std::bind(&StreamChecker::evalFeofFerror, _1, _2, _3, _4, ErrorFError),<br>
         0}},<br>
-      {{"fileno", 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
+      {{{"fileno"}, 1}, {&StreamChecker::preDefault, nullptr, 0}},<br>
   };<br>
<br>
   CallDescriptionMap<FnDescription> FnTestDescriptions = {<br>
-      {{"StreamTesterChecker_make_feof_stream", 1},<br>
+      {{{"StreamTesterChecker_make_feof_stream"}, 1},<br>
        {nullptr,<br>
         std::bind(&StreamChecker::evalSetFeofFerror, _1, _2, _3, _4, ErrorFEof),<br>
         0}},<br>
-      {{"StreamTesterChecker_make_ferror_stream", 1},<br>
+      {{{"StreamTesterChecker_make_ferror_stream"}, 1},<br>
        {nullptr,<br>
         std::bind(&StreamChecker::evalSetFeofFerror, _1, _2, _3, _4,<br>
                   ErrorFError),<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp<br>
index fbefd5f9ffdc9..2d1b873abf73f 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp<br>
@@ -100,27 +100,26 @@ class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,<br>
 };<br>
<br>
 const SmallVector<ValistChecker::VAListAccepter, 15><br>
-    ValistChecker::VAListAccepters = {<br>
-        {{"vfprintf", 3}, 2},<br>
-        {{"vfscanf", 3}, 2},<br>
-        {{"vprintf", 2}, 1},<br>
-        {{"vscanf", 2}, 1},<br>
-        {{"vsnprintf", 4}, 3},<br>
-        {{"vsprintf", 3}, 2},<br>
-        {{"vsscanf", 3}, 2},<br>
-        {{"vfwprintf", 3}, 2},<br>
-        {{"vfwscanf", 3}, 2},<br>
-        {{"vwprintf", 2}, 1},<br>
-        {{"vwscanf", 2}, 1},<br>
-        {{"vswprintf", 4}, 3},<br>
-        // vswprintf is the wide version of vsnprintf,<br>
-        // vsprintf has no wide version<br>
-        {{"vswscanf", 3}, 2}};<br>
-<br>
-const CallDescription<br>
-    ValistChecker::VaStart("__builtin_va_start", /*Args=*/2, /*Params=*/1),<br>
-    ValistChecker::VaCopy("__builtin_va_copy", 2),<br>
-    ValistChecker::VaEnd("__builtin_va_end", 1);<br>
+    ValistChecker::VAListAccepters = {{{{"vfprintf"}, 3}, 2},<br>
+                                      {{{"vfscanf"}, 3}, 2},<br>
+                                      {{{"vprintf"}, 2}, 1},<br>
+                                      {{{"vscanf"}, 2}, 1},<br>
+                                      {{{"vsnprintf"}, 4}, 3},<br>
+                                      {{{"vsprintf"}, 3}, 2},<br>
+                                      {{{"vsscanf"}, 3}, 2},<br>
+                                      {{{"vfwprintf"}, 3}, 2},<br>
+                                      {{{"vfwscanf"}, 3}, 2},<br>
+                                      {{{"vwprintf"}, 2}, 1},<br>
+                                      {{{"vwscanf"}, 2}, 1},<br>
+                                      {{{"vswprintf"}, 4}, 3},<br>
+                                      // vswprintf is the wide version of<br>
+                                      // vsnprintf, vsprintf has no wide version<br>
+                                      {{{"vswscanf"}, 3}, 2}};<br>
+<br>
+const CallDescription ValistChecker::VaStart({"__builtin_va_start"}, /*Args=*/2,<br>
+                                             /*Params=*/1),<br>
+    ValistChecker::VaCopy({"__builtin_va_copy"}, 2),<br>
+    ValistChecker::VaEnd({"__builtin_va_end"}, 1);<br>
 } // end anonymous namespace<br>
<br>
 void ValistChecker::checkPreCall(const CallEvent &Call,<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp<br>
index 084789509533e..aae1a17bc0ae5 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp<br>
@@ -39,11 +39,11 @@ class InvalidPtrChecker<br>
<br>
   // SEI CERT ENV31-C<br>
   const CallDescriptionMap<HandlerFn> EnvpInvalidatingFunctions = {<br>
-      {{"setenv", 3}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
-      {{"unsetenv", 1}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
-      {{"putenv", 1}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
-      {{"_putenv_s", 2}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
-      {{"_wputenv_s", 2}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
+      {{{"setenv"}, 3}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
+      {{{"unsetenv"}, 1}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
+      {{{"putenv"}, 1}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
+      {{{"_putenv_s"}, 2}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
+      {{{"_wputenv_s"}, 2}, &InvalidPtrChecker::EnvpInvalidatingCall},<br>
   };<br>
<br>
   void postPreviousReturnInvalidatingCall(const CallEvent &Call,<br>
@@ -51,13 +51,15 @@ class InvalidPtrChecker<br>
<br>
   // SEI CERT ENV34-C<br>
   const CallDescriptionMap<HandlerFn> PreviousCallInvalidatingFunctions = {<br>
-      {{"getenv", 1}, &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
-      {{"setlocale", 2},<br>
+      {{{"getenv"}, 1}, &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
+      {{{"setlocale"}, 2},<br>
        &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
-      {{"strerror", 1}, &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
-      {{"localeconv", 0},<br>
+      {{{"strerror"}, 1},<br>
+       &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
+      {{{"localeconv"}, 0},<br>
+       &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
+      {{{"asctime"}, 1},<br>
        &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
-      {{"asctime", 1}, &InvalidPtrChecker::postPreviousReturnInvalidatingCall},<br>
   };<br>
<br>
 public:<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp<br>
index ed3bdafad084d..eae162cda6931 100644<br>
--- a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp<br>
@@ -30,7 +30,7 @@ class PutenvWithAutoChecker : public Checker<check::PostCall> {<br>
 private:<br>
   BugType BT{this, "'putenv' function should not be called with auto variables",<br>
              categories::SecurityError};<br>
-  const CallDescription Putenv{"putenv", 1};<br>
+  const CallDescription Putenv{{"putenv"}, 1};<br>
<br>
 public:<br>
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;<br>
<br>
diff  --git a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp<br>
index 44b61d0750af0..229fb4883ed29 100644<br>
--- a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp<br>
+++ b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp<br>
@@ -36,7 +36,7 @@ static MaybeCount readRequiredParams(MaybeCount RequiredArgs,<br>
 }<br>
<br>
 ento::CallDescription::CallDescription(CallDescriptionFlags Flags,<br>
-                                       ArrayRef<const char *> QualifiedName,<br>
+                                       ArrayRef<StringRef> QualifiedName,<br>
                                        MaybeCount RequiredArgs /*= None*/,<br>
                                        MaybeCount RequiredParams /*= None*/)<br>
     : RequiredArgs(RequiredArgs),<br>
@@ -44,11 +44,12 @@ ento::CallDescription::CallDescription(CallDescriptionFlags Flags,<br>
       Flags(Flags) {<br>
   assert(!QualifiedName.empty());<br>
   this->QualifiedName.reserve(QualifiedName.size());<br>
-  llvm::copy(QualifiedName, std::back_inserter(this->QualifiedName));<br>
+  llvm::transform(QualifiedName, std::back_inserter(this->QualifiedName),<br>
+                  [](StringRef From) { return From.str(); });<br>
 }<br>
<br>
 /// Construct a CallDescription with default flags.<br>
-ento::CallDescription::CallDescription(ArrayRef<const char *> QualifiedName,<br>
+ento::CallDescription::CallDescription(ArrayRef<StringRef> QualifiedName,<br>
                                        MaybeCount RequiredArgs /*= None*/,<br>
                                        MaybeCount RequiredParams /*= None*/)<br>
     : CallDescription(CDF_None, QualifiedName, RequiredArgs, RequiredParams) {}<br>
<br>
diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp<br>
index 0d75ba02a280e..33711886766b1 100644<br>
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp<br>
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp<br>
@@ -121,11 +121,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "LinkerWrapperOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {PREFIX, NAME,  HELPTEXT,    METAVAR,     OPT_##ID,  Option::KIND##Class,    \<br>
<br>
diff  --git a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp<br>
index 832281766e437..26f69df5dddc1 100644<br>
--- a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp<br>
+++ b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp<br>
@@ -33,11 +33,11 @@ class InterestingnessTestChecker : public Checker<check::PreCall> {<br>
                                        const CallEvent &, CheckerContext &)>;<br>
<br>
   CallDescriptionMap<HandlerFn> Handlers = {<br>
-      {{"setInteresting", 1}, &InterestingnessTestChecker::handleInteresting},<br>
-      {{"setNotInteresting", 1},<br>
+      {{{"setInteresting"}, 1}, &InterestingnessTestChecker::handleInteresting},<br>
+      {{{"setNotInteresting"}, 1},<br>
        &InterestingnessTestChecker::handleNotInteresting},<br>
-      {{"check", 1}, &InterestingnessTestChecker::handleCheck},<br>
-      {{"bug", 1}, &InterestingnessTestChecker::handleBug},<br>
+      {{{"check"}, 1}, &InterestingnessTestChecker::handleCheck},<br>
+      {{{"bug"}, 1}, &InterestingnessTestChecker::handleBug},<br>
   };<br>
<br>
   void handleInteresting(const CallEvent &Call, CheckerContext &C) const;<br>
<br>
diff  --git a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp<br>
index 991a45d30103b..14fb03545265b 100644<br>
--- a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp<br>
+++ b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp<br>
@@ -135,8 +135,8 @@ class CallDescriptionAction : public ASTFrontendAction {<br>
 TEST(CallDescription, SimpleNameMatching) {<br>
   EXPECT_TRUE(tooling::runToolOnCode(<br>
       std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({<br>
-          {{"bar"}, false}, // false: there's no call to 'bar' in this code.<br>
-          {{"foo"}, true},  // true: there's a call to 'foo' in this code.<br>
+          {{{"bar"}}, false}, // false: there's no call to 'bar' in this code.<br>
+          {{{"foo"}}, true},  // true: there's a call to 'foo' in this code.<br>
       })),<br>
       "void foo(); void bar() { foo(); }"));<br>
 }<br>
@@ -144,8 +144,8 @@ TEST(CallDescription, SimpleNameMatching) {<br>
 TEST(CallDescription, RequiredArguments) {<br>
   EXPECT_TRUE(tooling::runToolOnCode(<br>
       std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({<br>
-          {{"foo", 1}, true},<br>
-          {{"foo", 2}, false},<br>
+          {{{"foo"}, 1}, true},<br>
+          {{{"foo"}, 2}, false},<br>
       })),<br>
       "void foo(int); void foo(int, int); void bar() { foo(1); }"));<br>
 }<br>
@@ -153,8 +153,8 @@ TEST(CallDescription, RequiredArguments) {<br>
 TEST(CallDescription, LackOfRequiredArguments) {<br>
   EXPECT_TRUE(tooling::runToolOnCode(<br>
       std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({<br>
-          {{"foo", std::nullopt}, true},<br>
-          {{"foo", 2}, false},<br>
+          {{{"foo"}, std::nullopt}, true},<br>
+          {{{"foo"}, 2}, false},<br>
       })),<br>
       "void foo(int); void foo(int, int); void bar() { foo(1); }"));<br>
 }<br>
@@ -479,7 +479,7 @@ TEST(CallDescription, NegativeMatchQualifiedNames) {<br>
       std::unique_ptr<FrontendAction>(new CallDescriptionAction<>({<br>
           {{{"foo", "bar"}}, false},<br>
           {{{"bar", "foo"}}, false},<br>
-          {{"foo"}, true},<br>
+          {{{"foo"}}, true},<br>
       })),<br>
       "void foo(); struct bar { void foo(); }; void test() { foo(); }"));<br>
 }<br>
@@ -488,7 +488,8 @@ TEST(CallDescription, MatchBuiltins) {<br>
   // Test CDF_MaybeBuiltin - a flag that allows matching weird builtins.<br>
   EXPECT_TRUE(tooling::runToolOnCode(<br>
       std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(<br>
-          {{{"memset", 3}, false}, {{CDF_MaybeBuiltin, "memset", 3}, true}})),<br>
+          {{{{"memset"}, 3}, false},<br>
+           {{CDF_MaybeBuiltin, {"memset"}, 3}, true}})),<br>
       "void foo() {"<br>
       "  int x;"<br>
       "  __builtin___memset_chk(&x, 0, sizeof(x),"<br>
@@ -499,8 +500,8 @@ TEST(CallDescription, MatchBuiltins) {<br>
     SCOPED_TRACE("multiple similar builtins");<br>
     EXPECT_TRUE(tooling::runToolOnCode(<br>
         std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(<br>
-            {{{CDF_MaybeBuiltin, "memcpy", 3}, false},<br>
-             {{CDF_MaybeBuiltin, "wmemcpy", 3}, true}})),<br>
+            {{{CDF_MaybeBuiltin, {"memcpy"}, 3}, false},<br>
+             {{CDF_MaybeBuiltin, {"wmemcpy"}, 3}, true}})),<br>
         R"(void foo(wchar_t *x, wchar_t *y) {<br>
             __builtin_wmemcpy(x, y, sizeof(wchar_t));<br>
           })"));<br>
@@ -509,8 +510,8 @@ TEST(CallDescription, MatchBuiltins) {<br>
     SCOPED_TRACE("multiple similar builtins reversed order");<br>
     EXPECT_TRUE(tooling::runToolOnCode(<br>
         std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(<br>
-            {{{CDF_MaybeBuiltin, "wmemcpy", 3}, true},<br>
-             {{CDF_MaybeBuiltin, "memcpy", 3}, false}})),<br>
+            {{{CDF_MaybeBuiltin, {"wmemcpy"}, 3}, true},<br>
+             {{CDF_MaybeBuiltin, {"memcpy"}, 3}, false}})),<br>
         R"(void foo(wchar_t *x, wchar_t *y) {<br>
             __builtin_wmemcpy(x, y, sizeof(wchar_t));<br>
           })"));<br>
@@ -518,8 +519,8 @@ TEST(CallDescription, MatchBuiltins) {<br>
   {<br>
     SCOPED_TRACE("lookbehind and lookahead mismatches");<br>
     EXPECT_TRUE(tooling::runToolOnCode(<br>
-        std::unique_ptr<FrontendAction>(<br>
-            new CallDescriptionAction<>({{{CDF_MaybeBuiltin, "func"}, false}})),<br>
+        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(<br>
+            {{{CDF_MaybeBuiltin, {"func"}}, false}})),<br>
         R"(<br>
           void funcXXX();<br>
           void XXXfunc();<br>
@@ -533,8 +534,8 @@ TEST(CallDescription, MatchBuiltins) {<br>
   {<br>
     SCOPED_TRACE("lookbehind and lookahead matches");<br>
     EXPECT_TRUE(tooling::runToolOnCode(<br>
-        std::unique_ptr<FrontendAction>(<br>
-            new CallDescriptionAction<>({{{CDF_MaybeBuiltin, "func"}, true}})),<br>
+        std::unique_ptr<FrontendAction>(new CallDescriptionAction<>(<br>
+            {{{CDF_MaybeBuiltin, {"func"}}, true}})),<br>
         R"(<br>
           void func();<br>
           void func_XXX();<br>
@@ -561,7 +562,7 @@ TEST(CallDescription, MatchBuiltins) {<br>
<br>
 class CallDescChecker<br>
     : public Checker<check::PreCall, check::PreStmt<CallExpr>> {<br>
-  CallDescriptionSet Set = {{"bar", 0}};<br>
+  CallDescriptionSet Set = {{{"bar"}, 0}};<br>
<br>
 public:<br>
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const {<br>
<br>
diff  --git a/clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp b/clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp<br>
index e6c07d6292338..d3eb4b7a94d32 100644<br>
--- a/clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp<br>
+++ b/clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp<br>
@@ -18,7 +18,7 @@ using namespace ento;<br>
<br>
 namespace {<br>
 class EvalCallBase : public Checker<eval::Call> {<br>
-  const CallDescription Foo = {"foo", 0};<br>
+  const CallDescription Foo = {{"foo"}, 0};<br>
<br>
 public:<br>
   bool evalCall(const CallEvent &Call, CheckerContext &C) const {<br>
<br>
diff  --git a/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp b/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp<br>
index c778b189aca78..3f36a6494bd4a 100644<br>
--- a/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp<br>
+++ b/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp<br>
@@ -30,9 +30,9 @@ class FalsePositiveGenerator : public Checker<eval::Call> {<br>
   using HandlerFn = bool (Self::*)(const CallEvent &Call,<br>
                                    CheckerContext &) const;<br>
   CallDescriptionMap<HandlerFn> Callbacks = {<br>
-      {{"reachedWithContradiction", 0}, &Self::reachedWithContradiction},<br>
-      {{"reachedWithNoContradiction", 0}, &Self::reachedWithNoContradiction},<br>
-      {{"reportIfCanBeTrue", 1}, &Self::reportIfCanBeTrue},<br>
+      {{{"reachedWithContradiction"}, 0}, &Self::reachedWithContradiction},<br>
+      {{{"reachedWithNoContradiction"}, 0}, &Self::reachedWithNoContradiction},<br>
+      {{{"reportIfCanBeTrue"}, 1}, &Self::reportIfCanBeTrue},<br>
   };<br>
<br>
   bool report(CheckerContext &C, ProgramStateRef State,<br>
<br>
diff  --git a/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp b/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp<br>
index a9700e6e7766d..69e29b47f9257 100644<br>
--- a/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp<br>
+++ b/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp<br>
@@ -86,17 +86,17 @@ class StatefulChecker : public Checker<check::PreCall> {<br>
<br>
 public:<br>
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const {<br>
-    if (CallDescription{"preventError", 0}.matches(Call)) {<br>
+    if (CallDescription{{"preventError"}, 0}.matches(Call)) {<br>
       C.addTransition(C.getState()->set<ErrorPrevented>(true));<br>
       return;<br>
     }<br>
<br>
-    if (CallDescription{"allowError", 0}.matches(Call)) {<br>
+    if (CallDescription{{"allowError"}, 0}.matches(Call)) {<br>
       C.addTransition(C.getState()->set<ErrorPrevented>(false));<br>
       return;<br>
     }<br>
<br>
-    if (CallDescription{"error", 0}.matches(Call)) {<br>
+    if (CallDescription{{"error"}, 0}.matches(Call)) {<br>
       if (C.getState()->get<ErrorPrevented>())<br>
         return;<br>
       const ExplodedNode *N = C.generateErrorNode();<br>
<br>
diff  --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp<br>
index 26802f8beeb0b..9a8d88c38c376 100644<br>
--- a/lld/COFF/DriverUtils.cpp<br>
+++ b/lld/COFF/DriverUtils.cpp<br>
@@ -772,12 +772,13 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,<br>
 // Create OptTable<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in Options.td<br>
-static constexpr llvm::opt::OptTable::Info infoTable[] = {<br>
+static constexpr std::initializer_list<llvm::opt::OptTable::Info> infoTable = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, llvm::opt::Option::KIND##Class, \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp<br>
index 4915069bee3c6..9c31d13cc913f 100644<br>
--- a/lld/ELF/DriverUtils.cpp<br>
+++ b/lld/ELF/DriverUtils.cpp<br>
@@ -34,12 +34,13 @@ using namespace lld::elf;<br>
 // Create OptTable<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in Options.td<br>
-static constexpr opt::OptTable::Info optInfo[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> optInfo = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp<br>
index be03d88f5a720..efc8e32322954 100644<br>
--- a/lld/MachO/DriverUtils.cpp<br>
+++ b/lld/MachO/DriverUtils.cpp<br>
@@ -35,12 +35,13 @@ using namespace lld;<br>
 using namespace lld::macho;<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) const char *NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in Options.td<br>
-static constexpr OptTable::Info optInfo[] = {<br>
+static constexpr std::initializer_list<OptTable::Info> optInfo = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, Option::KIND##Class,            \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp<br>
index cab2d0c97532b..b35fbd6b5c3fb 100644<br>
--- a/lld/MinGW/Driver.cpp<br>
+++ b/lld/MinGW/Driver.cpp<br>
@@ -61,12 +61,13 @@ enum {<br>
 };<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in Options.td<br>
-static constexpr opt::OptTable::Info infoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> infoTable = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp<br>
index 657156bde83c7..a3925a2519eb4 100644<br>
--- a/lld/wasm/Driver.cpp<br>
+++ b/lld/wasm/Driver.cpp<br>
@@ -101,12 +101,13 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,<br>
 }<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in Options.td<br>
-static constexpr opt::OptTable::Info optInfo[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> optInfo = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp<br>
index 73152f350395f..76b0d7bf60a56 100644<br>
--- a/lldb/tools/driver/Driver.cpp<br>
+++ b/lldb/tools/driver/Driver.cpp<br>
@@ -59,7 +59,7 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE) constexpr llvm::StringLiteral NAME[] = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
<br>
diff  --git a/lldb/tools/lldb-server/lldb-gdbserver.cpp b/lldb/tools/lldb-server/lldb-gdbserver.cpp<br>
index 4dd8a37ef3dad..8565c39efe9b6 100644<br>
--- a/lldb/tools/lldb-server/lldb-gdbserver.cpp<br>
+++ b/lldb/tools/lldb-server/lldb-gdbserver.cpp<br>
@@ -278,7 +278,7 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE) constexpr llvm::StringLiteral NAME[] = VALUE;<br>
 #include "LLGSOptions.inc"<br>
 #undef PREFIX<br>
<br>
<br>
diff  --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp<br>
index a80d4a90e39b0..b2b7ea4e1d825 100644<br>
--- a/lldb/tools/lldb-vscode/lldb-vscode.cpp<br>
+++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp<br>
@@ -79,7 +79,7 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE) constexpr llvm::StringLiteral NAME[] = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
<br>
diff  --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h<br>
index 09c6188469ea5..6f23de9a7136f 100644<br>
--- a/llvm/include/llvm/ADT/ArrayRef.h<br>
+++ b/llvm/include/llvm/ADT/ArrayRef.h<br>
@@ -74,12 +74,12 @@ namespace llvm {<br>
       : Data(&OneElt), Length(1) {}<br>
<br>
     /// Construct an ArrayRef from a pointer and length.<br>
-    /*implicit*/ ArrayRef(const T *data, size_t length)<br>
-      : Data(data), Length(length) {}<br>
+    constexpr /*implicit*/ ArrayRef(const T *data, size_t length)<br>
+        : Data(data), Length(length) {}<br>
<br>
     /// Construct an ArrayRef from a range.<br>
-    ArrayRef(const T *begin, const T *end)<br>
-      : Data(begin), Length(end - begin) {}<br>
+    constexpr ArrayRef(const T *begin, const T *end)<br>
+        : Data(begin), Length(end - begin) {}<br>
<br>
     /// Construct an ArrayRef from a SmallVector. This is templated in order to<br>
     /// avoid instantiating SmallVectorTemplateCommon<T> whenever we<br>
@@ -111,9 +111,9 @@ namespace llvm {<br>
 #pragma GCC diagnostic push<br>
 #pragma GCC diagnostic ignored "-Winit-list-lifetime"<br>
 #endif<br>
-    /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)<br>
-    : Data(Vec.begin() == Vec.end() ? (T*)nullptr : Vec.begin()),<br>
-      Length(Vec.size()) {}<br>
+    constexpr /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)<br>
+        : Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),<br>
+          Length(Vec.size()) {}<br>
 #if LLVM_GNUC_PREREQ(9, 0, 0)<br>
 #pragma GCC diagnostic pop<br>
 #endif<br>
<br>
diff  --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h<br>
index 10d67b1b34915..52354eb954559 100644<br>
--- a/llvm/include/llvm/Option/OptTable.h<br>
+++ b/llvm/include/llvm/Option/OptTable.h<br>
@@ -44,7 +44,7 @@ class OptTable {<br>
   struct Info {<br>
     /// A null terminated array of prefix strings to apply to name while<br>
     /// matching.<br>
-    const char *const *Prefixes;<br>
+    ArrayRef<StringLiteral> Prefixes;<br>
     StringRef Name;<br>
     const char *HelpText;<br>
     const char *MetaVar;<br>
<br>
diff  --git a/llvm/include/llvm/Option/Option.h b/llvm/include/llvm/Option/Option.h<br>
index 106f6863fca1c..9b35e81cd9914 100644<br>
--- a/llvm/include/llvm/Option/Option.h<br>
+++ b/llvm/include/llvm/Option/Option.h<br>
@@ -124,8 +124,9 @@ class Option {<br>
<br>
   /// Get the default prefix for this option.<br>
   StringRef getPrefix() const {<br>
-    const char *Prefix = *Info->Prefixes;<br>
-    return Prefix ? Prefix : StringRef();<br>
+    return Info->Prefixes.empty()<br>
+               ? StringRef()<br>
+               : static_cast<const StringRef &>(Info->Prefixes[0]);<br>
   }<br>
<br>
   /// Get the name of this option with the default prefix.<br>
<br>
diff  --git a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp<br>
index 8c1c7e26c0833..10ed8a7ec61cd 100644<br>
--- a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp<br>
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp<br>
@@ -12,18 +12,21 @@<br>
<br>
 #include "COFFDirectiveParser.h"<br>
<br>
+#include <array><br>
+<br>
 using namespace llvm;<br>
 using namespace jitlink;<br>
<br>
 #define DEBUG_TYPE "jitlink"<br>
<br>
 // Create prefix string literals used in Options.td<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "COFFOptions.inc"<br>
 #undef PREFIX<br>
<br>
 // Create table mapping all options defined in COFFOptions.td<br>
-static constexpr opt::OptTable::Info infoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> infoTable = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1,                                                                         \<br>
    X2,                                                                         \<br>
<br>
diff  --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp<br>
index 786760f2c64ac..c21072bda4026 100644<br>
--- a/llvm/lib/Option/OptTable.cpp<br>
+++ b/llvm/lib/Option/OptTable.cpp<br>
@@ -62,12 +62,10 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {<br>
   if (int N = StrCmpOptionName(A.Name, B.Name))<br>
     return N < 0;<br>
<br>
-  for (const char * const *APre = A.Prefixes,<br>
-                  * const *BPre = B.Prefixes;<br>
-                          *APre != nullptr && *BPre != nullptr; ++APre, ++BPre){<br>
-    if (int N = StrCmpOptionName(*APre, *BPre))<br>
+  for (size_t I = 0, K = std::min(A.Prefixes.size(), B.Prefixes.size()); I != K;<br>
+       ++I)<br>
+    if (int N = StrCmpOptionName(A.Prefixes[I], B.Prefixes[I]))<br>
       return N < 0;<br>
-  }<br>
<br>
   // Names are the same, check that classes are in order; exactly one<br>
   // should be joined, and it should succeed the other.<br>
@@ -131,11 +129,8 @@ OptTable::OptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase)<br>
   // Build prefixes.<br>
   for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions() + 1;<br>
                 i != e; ++i) {<br>
-    if (const char *const *P = getInfo(i).Prefixes) {<br>
-      for (; *P != nullptr; ++P) {<br>
-        PrefixesUnion.insert(*P);<br>
-      }<br>
-    }<br>
+    const auto &P = getInfo(i).Prefixes;<br>
+    PrefixesUnion.insert(P.begin(), P.end());<br>
   }<br>
<br>
   // Build prefix chars.<br>
@@ -168,8 +163,7 @@ static bool isInput(const StringSet<> &Prefixes, StringRef Arg) {<br>
 /// \returns Matched size. 0 means no match.<br>
 static unsigned matchOption(const OptTable::Info *I, StringRef Str,<br>
                             bool IgnoreCase) {<br>
-  for (const char * const *Pre = I->Prefixes; *Pre != nullptr; ++Pre) {<br>
-    StringRef Prefix(*Pre);<br>
+  for (auto Prefix : I->Prefixes) {<br>
     if (Str.startswith(Prefix)) {<br>
       StringRef Rest = Str.substr(Prefix.size());<br>
       bool Matched = IgnoreCase ? Rest.startswith_insensitive(I->Name)<br>
@@ -183,13 +177,10 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,<br>
<br>
 // Returns true if one of the Prefixes + In.Names matches Option<br>
 static bool optionMatches(const OptTable::Info &In, StringRef Option) {<br>
-  if (In.Prefixes) {<br>
-    StringRef InName(In.Name);<br>
-    for (size_t I = 0; In.Prefixes[I]; I++)<br>
-      if (Option.endswith(InName))<br>
-        if (Option.slice(0, Option.size() - InName.size()) == In.Prefixes[I])<br>
-          return true;<br>
-  }<br>
+  for (auto Prefix : In.Prefixes)<br>
+    if (Option.endswith(In.Name))<br>
+      if (Option.slice(0, Option.size() - In.Name.size()) == Prefix)<br>
+        return true;<br>
   return false;<br>
 }<br>
<br>
@@ -221,13 +212,13 @@ OptTable::findByPrefix(StringRef Cur, unsigned int DisableFlags) const {<br>
   std::vector<std::string> Ret;<br>
   for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) {<br>
     const Info &In = OptionInfos[I];<br>
-    if (!In.Prefixes || (!In.HelpText && !In.GroupID))<br>
+    if (In.Prefixes.empty() || (!In.HelpText && !In.GroupID))<br>
       continue;<br>
     if (In.Flags & DisableFlags)<br>
       continue;<br>
<br>
-    for (int I = 0; In.Prefixes[I]; I++) {<br>
-      std::string S = std::string(In.Prefixes[I]) + std::string(In.Name) + "\t";<br>
+    for (auto Prefix : In.Prefixes) {<br>
+      std::string S = (Prefix + In.Name + "\t").str();<br>
       if (In.HelpText)<br>
         S += In.HelpText;<br>
       if (StringRef(S).startswith(Cur) && S != std::string(Cur) + "\t")<br>
@@ -265,7 +256,7 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,<br>
<br>
     // * Ignore positional argument option candidates (which do not<br>
     //   have prefixes).<br>
-    if (!CandidateInfo.Prefixes)<br>
+    if (CandidateInfo.Prefixes.empty())<br>
       continue;<br>
<br>
     // Now check if the candidate ends with a character commonly used when<br>
@@ -285,8 +276,7 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,<br>
     // Consider each possible prefix for each candidate to find the most<br>
     // appropriate one. For example, if a user asks for "--helm", suggest<br>
     // "--help" over "-help".<br>
-    for (int P = 0;<br>
-         const char *const CandidatePrefix = CandidateInfo.Prefixes[P]; P++) {<br>
+    for (auto CandidatePrefix : CandidateInfo.Prefixes) {<br>
       std::string Candidate = (CandidatePrefix + CandidateName).str();<br>
       StringRef CandidateRef = Candidate;<br>
       unsigned Distance =<br>
<br>
diff  --git a/llvm/lib/Option/Option.cpp b/llvm/lib/Option/Option.cpp<br>
index ebdba8949223b..1f1eb93bcca05 100644<br>
--- a/llvm/lib/Option/Option.cpp<br>
+++ b/llvm/lib/Option/Option.cpp<br>
@@ -58,11 +58,10 @@ void Option::print(raw_ostream &O) const {<br>
 #undef P<br>
   }<br>
<br>
-  if (Info->Prefixes) {<br>
+  if (!Info->Prefixes.empty()) {<br>
     O << " Prefixes:[";<br>
-    for (const char *const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) {<br>
-      O << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", ");<br>
-    }<br>
+    for (size_t I = 0, N = Info->Prefixes.size(); I != N; ++I)<br>
+      O << '"' << Info->Prefixes[I] << (I == N - 1 ? "\"" : "\", ");<br>
     O << ']';<br>
   }<br>
<br>
<br>
diff  --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp<br>
index c8ef0d16983bd..9bdff119a3f4b 100644<br>
--- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp<br>
+++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp<br>
@@ -37,11 +37,12 @@ enum {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr llvm::opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, llvm::opt::Option::KIND##Class, \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp<br>
index 7f06ed097c031..74a20a4ab7421 100644<br>
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp<br>
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp<br>
@@ -41,11 +41,12 @@ enum {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \<br>
   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \<br>
    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},<br>
<br>
diff  --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp<br>
index 5ed3b2bf609fa..7c4e3d99ffa5e 100644<br>
--- a/llvm/tools/dsymutil/dsymutil.cpp<br>
+++ b/llvm/tools/dsymutil/dsymutil.cpp<br>
@@ -63,11 +63,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp<br>
index b2be58b72d62a..6dbf0a7a91e54 100644<br>
--- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp<br>
+++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp<br>
@@ -44,11 +44,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp<br>
index 52a75eee64b54..bbf4b63081997 100644<br>
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp<br>
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp<br>
@@ -32,11 +32,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp<br>
index eeb92a750e4ad..1c1ebdc6f790a 100644<br>
--- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp<br>
+++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp<br>
@@ -40,11 +40,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Options.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp<br>
index bef280075b8bd..f64acf96826ea 100644<br>
--- a/llvm/tools/llvm-ifs/llvm-ifs.cpp<br>
+++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp<br>
@@ -60,11 +60,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp<br>
index b4a76e18d389d..78cda7566bc4e 100644<br>
--- a/llvm/tools/llvm-lipo/llvm-lipo.cpp<br>
+++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp<br>
@@ -73,26 +73,27 @@ enum LipoID {<br>
 #undef OPTION<br>
 };<br>
<br>
-// LipoInfoTable below references LIPO_##PREFIX. OptionGroup has prefix nullptr.<br>
-constexpr const char *const *LIPO_nullptr = nullptr;<br>
-#define PREFIX(NAME, VALUE) const char *const LIPO_##NAME[] = VALUE;<br>
+namespace lipo {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;<br>
 #include "LipoOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info LipoInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> LipoInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {LIPO_##PREFIX, NAME,      HELPTEXT,                                         \<br>
-   METAVAR,       LIPO_##ID, opt::Option::KIND##Class,                         \<br>
-   PARAM,         FLAGS,     LIPO_##GROUP,                                     \<br>
-   LIPO_##ALIAS,  ALIASARGS, VALUES},<br>
+  {PREFIX,       NAME,      HELPTEXT,                                          \<br>
+   METAVAR,      LIPO_##ID, opt::Option::KIND##Class,                          \<br>
+   PARAM,        FLAGS,     LIPO_##GROUP,                                      \<br>
+   LIPO_##ALIAS, ALIASARGS, VALUES},<br>
 #include "LipoOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace lipo<br>
<br>
 class LipoOptTable : public opt::OptTable {<br>
 public:<br>
-  LipoOptTable() : OptTable(LipoInfoTable) {}<br>
+  LipoOptTable() : OptTable(lipo::LipoInfoTable) {}<br>
 };<br>
<br>
 enum class LipoAction {<br>
<br>
diff  --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp<br>
index 762658045f5b5..5c773bdae9502 100644<br>
--- a/llvm/tools/llvm-ml/llvm-ml.cpp<br>
+++ b/llvm/tools/llvm-ml/llvm-ml.cpp<br>
@@ -60,11 +60,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-mt/llvm-mt.cpp b/llvm/tools/llvm-mt/llvm-mt.cpp<br>
index 3f70c892ac68a..b6d57faed3369 100644<br>
--- a/llvm/tools/llvm-mt/llvm-mt.cpp<br>
+++ b/llvm/tools/llvm-mt/llvm-mt.cpp<br>
@@ -41,11 +41,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
 {                                                                              \<br>
<br>
diff  --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp<br>
index 47644f07fd82d..953637ca678ed 100644<br>
--- a/llvm/tools/llvm-nm/llvm-nm.cpp<br>
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp<br>
@@ -64,11 +64,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp<br>
index bf39f8ce39051..287744be100c5 100644<br>
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp<br>
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp<br>
@@ -36,32 +36,27 @@ enum ObjcopyID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const OBJCOPY_##NAME[] = VALUE;<br>
+namespace objcopy_opt {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "ObjcopyOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info ObjcopyInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> ObjcopyInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {OBJCOPY_##PREFIX,                                                           \<br>
-   NAME,                                                                       \<br>
-   HELPTEXT,                                                                   \<br>
-   METAVAR,                                                                    \<br>
-   OBJCOPY_##ID,                                                               \<br>
-   opt::Option::KIND##Class,                                                   \<br>
-   PARAM,                                                                      \<br>
-   FLAGS,                                                                      \<br>
-   OBJCOPY_##GROUP,                                                            \<br>
-   OBJCOPY_##ALIAS,                                                            \<br>
-   ALIASARGS,                                                                  \<br>
-   VALUES},<br>
+  {PREFIX,          NAME,         HELPTEXT,                                    \<br>
+   METAVAR,         OBJCOPY_##ID, opt::Option::KIND##Class,                    \<br>
+   PARAM,           FLAGS,        OBJCOPY_##GROUP,                             \<br>
+   OBJCOPY_##ALIAS, ALIASARGS,    VALUES},<br>
 #include "ObjcopyOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace objcopy_opt<br>
<br>
 class ObjcopyOptTable : public opt::OptTable {<br>
 public:<br>
-  ObjcopyOptTable() : OptTable(ObjcopyInfoTable) {<br>
+  ObjcopyOptTable() : OptTable(objcopy_opt::ObjcopyInfoTable) {<br>
     setGroupedShortOptions(true);<br>
   }<br>
 };<br>
@@ -75,15 +70,18 @@ enum InstallNameToolID {<br>
 #undef OPTION<br>
 };<br>
<br>
+namespace install_name_tool {<br>
+<br>
 #define PREFIX(NAME, VALUE)                                                    \<br>
-  const char *const INSTALL_NAME_TOOL_##NAME[] = VALUE;<br>
+  constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "InstallNameToolOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info><br>
+    InstallNameToolInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {INSTALL_NAME_TOOL_##PREFIX,                                                 \<br>
+  {PREFIX,                                                                     \<br>
    NAME,                                                                       \<br>
    HELPTEXT,                                                                   \<br>
    METAVAR,                                                                    \<br>
@@ -98,10 +96,12 @@ static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = {<br>
 #include "InstallNameToolOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace install_name_tool<br>
<br>
 class InstallNameToolOptTable : public opt::OptTable {<br>
 public:<br>
-  InstallNameToolOptTable() : OptTable(InstallNameToolInfoTable) {}<br>
+  InstallNameToolOptTable()<br>
+      : OptTable(install_name_tool::InstallNameToolInfoTable) {}<br>
 };<br>
<br>
 enum BitcodeStripID {<br>
@@ -113,14 +113,18 @@ enum BitcodeStripID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const BITCODE_STRIP_##NAME[] = VALUE;<br>
+namespace bitcode_strip {<br>
+<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "BitcodeStripOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info><br>
+    BitcodeStripInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {BITCODE_STRIP_##PREFIX,                                                     \<br>
+  {PREFIX,                                                                     \<br>
    NAME,                                                                       \<br>
    HELPTEXT,                                                                   \<br>
    METAVAR,                                                                    \<br>
@@ -135,10 +139,11 @@ static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = {<br>
 #include "BitcodeStripOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace bitcode_strip<br>
<br>
 class BitcodeStripOptTable : public opt::OptTable {<br>
 public:<br>
-  BitcodeStripOptTable() : OptTable(BitcodeStripInfoTable) {}<br>
+  BitcodeStripOptTable() : OptTable(bitcode_strip::BitcodeStripInfoTable) {}<br>
 };<br>
<br>
 enum StripID {<br>
@@ -150,24 +155,29 @@ enum StripID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const STRIP_##NAME[] = VALUE;<br>
+namespace strip {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "StripOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info StripInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> StripInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {STRIP_##PREFIX, NAME,       HELPTEXT,                                       \<br>
-   METAVAR,        STRIP_##ID, opt::Option::KIND##Class,                       \<br>
-   PARAM,          FLAGS,      STRIP_##GROUP,                                  \<br>
-   STRIP_##ALIAS,  ALIASARGS,  VALUES},<br>
+  {PREFIX,        NAME,       HELPTEXT,                                        \<br>
+   METAVAR,       STRIP_##ID, opt::Option::KIND##Class,                        \<br>
+   PARAM,         FLAGS,      STRIP_##GROUP,                                   \<br>
+   STRIP_##ALIAS, ALIASARGS,  VALUES},<br>
 #include "StripOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace strip<br>
<br>
 class StripOptTable : public opt::OptTable {<br>
 public:<br>
-  StripOptTable() : OptTable(StripInfoTable) { setGroupedShortOptions(true); }<br>
+  StripOptTable() : OptTable(strip::StripInfoTable) {<br>
+    setGroupedShortOptions(true);<br>
+  }<br>
 };<br>
<br>
 } // namespace<br>
<br>
diff  --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp<br>
index bb02cd016938c..5cd6acbc63f87 100644<br>
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp<br>
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp<br>
@@ -119,28 +119,29 @@ class CommonOptTable : public opt::OptTable {<br>
 };<br>
<br>
 // ObjdumpOptID is in ObjdumpOptID.h<br>
-<br>
-#define PREFIX(NAME, VALUE) const char *const OBJDUMP_##NAME[] = VALUE;<br>
+namespace objdump_opt {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "ObjdumpOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info ObjdumpInfoTable[] = {<br>
-#define OBJDUMP_nullptr nullptr<br>
+static constexpr std::initializer_list<opt::OptTable::Info> ObjdumpInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {OBJDUMP_##PREFIX, NAME,         HELPTEXT,                                   \<br>
-   METAVAR,          OBJDUMP_##ID, opt::Option::KIND##Class,                   \<br>
-   PARAM,            FLAGS,        OBJDUMP_##GROUP,                            \<br>
-   OBJDUMP_##ALIAS,  ALIASARGS,    VALUES},<br>
+  {PREFIX,          NAME,         HELPTEXT,                                    \<br>
+   METAVAR,         OBJDUMP_##ID, opt::Option::KIND##Class,                    \<br>
+   PARAM,           FLAGS,        OBJDUMP_##GROUP,                             \<br>
+   OBJDUMP_##ALIAS, ALIASARGS,    VALUES},<br>
 #include "ObjdumpOpts.inc"<br>
 #undef OPTION<br>
-#undef OBJDUMP_nullptr<br>
 };<br>
+} // namespace objdump_opt<br>
<br>
 class ObjdumpOptTable : public CommonOptTable {<br>
 public:<br>
   ObjdumpOptTable()<br>
-      : CommonOptTable(ObjdumpInfoTable, " [options] <input object files>",<br>
+      : CommonOptTable(objdump_opt::ObjdumpInfoTable,<br>
+                       " [options] <input object files>",<br>
                        "llvm object file dumper") {}<br>
 };<br>
<br>
@@ -153,27 +154,28 @@ enum OtoolOptID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const OTOOL_##NAME[] = VALUE;<br>
+namespace otool {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "OtoolOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info OtoolInfoTable[] = {<br>
-#define OTOOL_nullptr nullptr<br>
+static constexpr std::initializer_list<opt::OptTable::Info> OtoolInfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {OTOOL_##PREFIX, NAME,       HELPTEXT,                                       \<br>
-   METAVAR,        OTOOL_##ID, opt::Option::KIND##Class,                       \<br>
-   PARAM,          FLAGS,      OTOOL_##GROUP,                                  \<br>
-   OTOOL_##ALIAS,  ALIASARGS,  VALUES},<br>
+  {PREFIX,        NAME,       HELPTEXT,                                        \<br>
+   METAVAR,       OTOOL_##ID, opt::Option::KIND##Class,                        \<br>
+   PARAM,         FLAGS,      OTOOL_##GROUP,                                   \<br>
+   OTOOL_##ALIAS, ALIASARGS,  VALUES},<br>
 #include "OtoolOpts.inc"<br>
 #undef OPTION<br>
-#undef OTOOL_nullptr<br>
 };<br>
+} // namespace otool<br>
<br>
 class OtoolOptTable : public CommonOptTable {<br>
 public:<br>
   OtoolOptTable()<br>
-      : CommonOptTable(OtoolInfoTable, " [option...] [file...]",<br>
+      : CommonOptTable(otool::OtoolInfoTable, " [option...] [file...]",<br>
                        "Mach-O object file displaying tool") {}<br>
 };<br>
<br>
<br>
diff  --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp<br>
index 00fb9c1f74809..ff21213fc300e 100644<br>
--- a/llvm/tools/llvm-rc/llvm-rc.cpp<br>
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp<br>
@@ -55,11 +55,13 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+namespace rc_opt {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
@@ -70,10 +72,11 @@ static constexpr opt::OptTable::Info InfoTable[] = {<br>
 #include "Opts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace rc_opt<br>
<br>
 class RcOptTable : public opt::OptTable {<br>
 public:<br>
-  RcOptTable() : OptTable(InfoTable, /* IgnoreCase = */ true) {}<br>
+  RcOptTable() : OptTable(rc_opt::InfoTable, /* IgnoreCase = */ true) {}<br>
 };<br>
<br>
 enum Windres_ID {<br>
@@ -85,25 +88,28 @@ enum Windres_ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const WINDRES_##NAME[] = VALUE;<br>
+namespace windres_opt {<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "WindresOpts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info WindresInfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
-  {                                                                            \<br>
-      WINDRES_##PREFIX, NAME,         HELPTEXT,                                \<br>
-      METAVAR,          WINDRES_##ID, opt::Option::KIND##Class,                \<br>
-      PARAM,            FLAGS,        WINDRES_##GROUP,                         \<br>
-      WINDRES_##ALIAS,  ALIASARGS,    VALUES},<br>
+  {PREFIX,          NAME,         HELPTEXT,                                    \<br>
+   METAVAR,         WINDRES_##ID, opt::Option::KIND##Class,                    \<br>
+   PARAM,           FLAGS,        WINDRES_##GROUP,                             \<br>
+   WINDRES_##ALIAS, ALIASARGS,    VALUES},<br>
 #include "WindresOpts.inc"<br>
 #undef OPTION<br>
 };<br>
+} // namespace windres_opt<br>
<br>
 class WindresOptTable : public opt::OptTable {<br>
 public:<br>
-  WindresOptTable() : OptTable(WindresInfoTable, /* IgnoreCase = */ false) {}<br>
+  WindresOptTable()<br>
+      : OptTable(windres_opt::InfoTable, /* IgnoreCase = */ false) {}<br>
 };<br>
<br>
 static ExitOnError ExitOnErr;<br>
<br>
diff  --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp<br>
index 7cb20360308d9..57598b084e84b 100644<br>
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp<br>
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp<br>
@@ -61,11 +61,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp<br>
index de2e285fb5cdd..884f6f029e5c0 100644<br>
--- a/llvm/tools/llvm-size/llvm-size.cpp<br>
+++ b/llvm/tools/llvm-size/llvm-size.cpp<br>
@@ -47,11 +47,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-strings/llvm-strings.cpp b/llvm/tools/llvm-strings/llvm-strings.cpp<br>
index 918ca5f9ff1a3..afaa00ba5040a 100644<br>
--- a/llvm/tools/llvm-strings/llvm-strings.cpp<br>
+++ b/llvm/tools/llvm-strings/llvm-strings.cpp<br>
@@ -39,11 +39,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp<br>
index 833506aa7ee9e..b7e7fd2abb806 100644<br>
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp<br>
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp<br>
@@ -56,11 +56,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp<br>
index 05fb5ffb7392a..fa5ef6df948f9 100644<br>
--- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp<br>
+++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp<br>
@@ -35,11 +35,12 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
-static constexpr opt::OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<opt::OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {                                                                            \<br>
<br>
diff  --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp<br>
index 1857345309b71..2f10e2622e424 100644<br>
--- a/llvm/unittests/Option/OptionParsingTest.cpp<br>
+++ b/llvm/unittests/Option/OptionParsingTest.cpp<br>
@@ -25,7 +25,8 @@ enum ID {<br>
 #undef OPTION<br>
 };<br>
<br>
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;<br>
+#define PREFIX(NAME, VALUE)                                                    \<br>
+  static constexpr std::initializer_list<StringLiteral> NAME = VALUE;<br>
 #include "Opts.inc"<br>
 #undef PREFIX<br>
<br>
@@ -35,7 +36,7 @@ enum OptionFlags {<br>
   OptFlag3 = (1 << 6)<br>
 };<br>
<br>
-static constexpr OptTable::Info InfoTable[] = {<br>
+static constexpr std::initializer_list<OptTable::Info> InfoTable = {<br>
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \<br>
                HELPTEXT, METAVAR, VALUES)                                      \<br>
   {PREFIX, NAME,  HELPTEXT,    METAVAR,     OPT_##ID,  Option::KIND##Class,    \<br>
<br>
diff  --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp<br>
index e8bc9daaea49d..e734b8f48b455 100644<br>
--- a/llvm/utils/TableGen/OptParserEmitter.cpp<br>
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp<br>
@@ -54,9 +54,10 @@ static std::string getOptionSpelling(const Record &R) {<br>
<br>
 static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {<br>
   size_t PrefixLength;<br>
-  OS << "llvm::StringRef(&";<br>
-  write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength)));<br>
-  OS << "[" << PrefixLength << "], " << R.getValueAsString("Name").size() << ")";<br>
+  OS << "llvm::StringLiteral(";<br>
+  write_cstring(<br>
+      OS, StringRef(getOptionSpelling(R, PrefixLength)).substr(PrefixLength));<br>
+  OS << ")";<br>
 }<br>
<br>
 class MarshallingInfo {<br>
@@ -251,8 +252,8 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {<br>
     // Prefix values.<br>
     OS << ", {";<br>
     for (const auto &PrefixKey : Prefix.first)<br>
-      OS << "\"" << PrefixKey << "\" COMMA ";<br>
-    OS << "nullptr})\n";<br>
+      OS << "llvm::StringLiteral(\"" << PrefixKey << "\") COMMA ";<br>
+    OS << "})\n";<br>
   }<br>
   OS << "#undef COMMA\n";<br>
   OS << "#endif // PREFIX\n\n";<br>
@@ -265,7 +266,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {<br>
     OS << "OPTION(";<br>
<br>
     // The option prefix;<br>
-    OS << "nullptr";<br>
+    OS << "{}";<br>
<br>
     // The option string.<br>
     OS << ", \"" << R.getValueAsString("Name") << '"';<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>