jansvoboda11 updated this revision to Diff 318459.
jansvoboda11 added a comment.

Fix formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D94472/new/

https://reviews.llvm.org/D94472

Files:
  clang/include/clang/Frontend/CompilerInvocation.h
  clang/lib/Frontend/CompilerInvocation.cpp
  llvm/include/llvm/Option/ArgList.h
  llvm/lib/Option/ArgList.cpp

Index: llvm/lib/Option/ArgList.cpp
===================================================================
--- llvm/lib/Option/ArgList.cpp
+++ llvm/lib/Option/ArgList.cpp
@@ -90,11 +90,22 @@
 }
 
 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
+  recordQueriedOpts(Id);
   SmallVector<const char *, 16> Values;
   AddAllArgValues(Values, Id);
   return std::vector<std::string>(Values.begin(), Values.end());
 }
 
+void ArgList::AddAllArgsExcept(ArgStringList &Output,
+                               const DenseSet<unsigned> &ExcludeIds) const {
+  for (const Arg *Arg : *this) {
+    if (!ExcludeIds.contains(Arg->getOption().getID())) {
+      Arg->claim();
+      Arg->render(*this, Output);
+    }
+  }
+}
+
 void ArgList::AddAllArgsExcept(ArgStringList &Output,
                                ArrayRef<OptSpecifier> Ids,
                                ArrayRef<OptSpecifier> ExcludeIds) const {
Index: llvm/include/llvm/Option/ArgList.h
===================================================================
--- llvm/include/llvm/Option/ArgList.h
+++ llvm/include/llvm/Option/ArgList.h
@@ -137,6 +137,16 @@
   /// The first and last index of each different OptSpecifier ID.
   DenseMap<unsigned, OptRange> OptRanges;
 
+  /// The OptSpecifiers that were queried from this argument list.
+  mutable DenseSet<unsigned> QueriedOpts;
+
+  /// Record the queried OptSpecifiers.
+  template <typename... OptSpecifiers>
+  void recordQueriedOpts(OptSpecifiers... Ids) const {
+    SmallVector<unsigned, 4> OptsSpecifiers({toOptSpecifier(Ids).getID()...});
+    QueriedOpts.insert(OptsSpecifiers.begin(), OptsSpecifiers.end());
+  }
+
   /// Get the range of indexes in which options with the specified IDs might
   /// reside, or (0, 0) if there are no such options.
   OptRange getRange(std::initializer_list<OptSpecifier> Ids) const;
@@ -203,6 +213,7 @@
   template<typename ...OptSpecifiers>
   iterator_range<filtered_iterator<sizeof...(OptSpecifiers)>>
   filtered(OptSpecifiers ...Ids) const {
+    recordQueriedOpts(Ids...);
     OptRange Range = getRange({toOptSpecifier(Ids)...});
     auto B = Args.begin() + Range.first;
     auto E = Args.begin() + Range.second;
@@ -214,6 +225,7 @@
   template<typename ...OptSpecifiers>
   iterator_range<filtered_reverse_iterator<sizeof...(OptSpecifiers)>>
   filtered_reverse(OptSpecifiers ...Ids) const {
+    recordQueriedOpts(Ids...);
     OptRange Range = getRange({toOptSpecifier(Ids)...});
     auto B = Args.rend() - Range.second;
     auto E = Args.rend() - Range.first;
@@ -308,6 +320,10 @@
       A->render(*this, Output);
   }
 
+  /// AddAllArgsExcept - Render all arguments not matching any of the excluded
+  /// ids.
+  void AddAllArgsExcept(ArgStringList &Output,
+                        const DenseSet<unsigned> &ExcludeIds) const;
   /// AddAllArgsExcept - Render all arguments matching any of the given ids
   /// and not matching any of the excluded ids.
   void AddAllArgsExcept(ArgStringList &Output, ArrayRef<OptSpecifier> Ids,
@@ -342,6 +358,9 @@
   ///
   void ClaimAllArgs() const;
 
+  /// Return the OptSpecifiers queried from this argument list.
+  const DenseSet<unsigned> &getQueriedOpts() const { return QueriedOpts; }
+
   /// @}
   /// @name Arg Synthesis
   /// @{
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -48,10 +48,12 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/CachedHashString.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SetOperations.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -151,10 +153,10 @@
 /// unnecessary template instantiations and just ignore it with a variadic
 /// argument.
 static void denormalizeSimpleFlag(SmallVectorImpl<const char *> &Args,
-                                  const char *Spelling,
-                                  CompilerInvocation::StringAllocator,
+                                  Twine Spelling,
+                                  CompilerInvocation::StringAllocator SA,
                                   Option::OptionClass, unsigned, /*T*/...) {
-  Args.push_back(Spelling);
+  Args.push_back(SA(Spelling));
 }
 
 template <typename T> static constexpr bool is_uint64_t_convertible() {
@@ -201,18 +203,18 @@
 }
 
 static void denormalizeStringImpl(SmallVectorImpl<const char *> &Args,
-                                  const char *Spelling,
+                                  Twine Spelling,
                                   CompilerInvocation::StringAllocator SA,
                                   Option::OptionClass OptClass, unsigned,
                                   Twine Value) {
   switch (OptClass) {
   case Option::SeparateClass:
   case Option::JoinedOrSeparateClass:
-    Args.push_back(Spelling);
+    Args.push_back(SA(Spelling));
     Args.push_back(SA(Value));
     break;
   case Option::JoinedClass:
-    Args.push_back(SA(Twine(Spelling) + Value));
+    Args.push_back(SA(Spelling + Value));
     break;
   default:
     llvm_unreachable("Cannot denormalize an option with option class "
@@ -222,7 +224,7 @@
 
 template <typename T>
 static void
-denormalizeString(SmallVectorImpl<const char *> &Args, const char *Spelling,
+denormalizeString(SmallVectorImpl<const char *> &Args, Twine Spelling,
                   CompilerInvocation::StringAllocator SA,
                   Option::OptionClass OptClass, unsigned TableIndex, T Value) {
   denormalizeStringImpl(Args, Spelling, SA, OptClass, TableIndex, Twine(Value));
@@ -523,9 +525,63 @@
   return 0;
 }
 
-static std::string GetOptName(llvm::opt::OptSpecifier OptSpecifier) {
-  static const OptTable &OptTable = getDriverOptTable();
-  return OptTable.getOption(OptSpecifier).getPrefixedName();
+static void GenerateArg(SmallVectorImpl<const char *> &Args,
+                        llvm::opt::OptSpecifier OptSpecifier,
+                        CompilerInvocation::StringAllocator SA) {
+  Option Opt = getDriverOptTable().getOption(OptSpecifier);
+  denormalizeSimpleFlag(Args, Opt.getPrefix() + Opt.getName(), SA,
+                        Option::OptionClass::FlagClass, 0);
+}
+
+static void GenerateArg(SmallVectorImpl<const char *> &Args,
+                        llvm::opt::OptSpecifier OptSpecifier,
+                        const Twine &Value,
+                        CompilerInvocation::StringAllocator SA) {
+  Option Opt = getDriverOptTable().getOption(OptSpecifier);
+  denormalizeString(Args, Opt.getPrefix() + Opt.getName(), SA, Opt.getKind(), 0,
+                    Value);
+}
+
+template <typename ParseFn, typename GenerateFn, typename ResetFn>
+static void RoundTrip(ParseFn &&Parse, GenerateFn &&Generate, ResetFn &&Reset,
+                      CompilerInvocation &Res, ArgList &OriginalArgs) {
+  // Set up the string allocator for generating command line arguments.
+  SmallVector<std::string, 32> GeneratedArgsStorage;
+  auto SA = [&GeneratedArgsStorage](const Twine &Arg) -> const char * {
+    return GeneratedArgsStorage.emplace_back(Arg.str()).c_str();
+  };
+
+  // Parse the original arguments and records which options the parser queried.
+  llvm::DenseSet<unsigned> QueriedBefore = OriginalArgs.getQueriedOpts();
+  Parse(Res, OriginalArgs);
+  llvm::DenseSet<unsigned> QueriedAfter = OriginalArgs.getQueriedOpts();
+  llvm::DenseSet<unsigned> QueriedDuring =
+      llvm::set_difference(QueriedAfter, QueriedBefore);
+
+  // Create an empty string list.
+  ArgStringList GeneratedArgStringList;
+  // Add all original arguments that were not queried by the parser.
+  OriginalArgs.AddAllArgsExcept(GeneratedArgStringList, QueriedDuring);
+  // Invoke the generator. If implemented correctly, it should complete the
+  // string list with arguments the parser queried, and have the same
+  // semantics as the original arguments.
+  Generate(Res, GeneratedArgStringList, SA);
+
+  // Construct InputArgList instance from the generated string list.
+  const OptTable &Opts = getDriverOptTable();
+  unsigned MissingArgIndex, MissingArgCount;
+  InputArgList GeneratedArgs =
+      Opts.ParseArgs(GeneratedArgStringList, MissingArgIndex, MissingArgCount,
+                     options::CC1Option);
+
+  // Reset the part of CompilerInvocation that the parser set up.
+  Reset(Res);
+
+  // Run the parser again. If the generated arguments have the same semantics
+  // as the original arguments, this should set up the CompilerInvocation part
+  // in the same way the first parser call did. Let's verify that by using this
+  // for the rest of the compilation process.
+  Parse(Res, GeneratedArgs);
 }
 
 static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
@@ -1812,9 +1868,9 @@
   return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
 }
 
-static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
-                                     SmallVectorImpl<const char *> &Args,
-                                     CompilerInvocation::StringAllocator SA) {
+void CompilerInvocation::GenerateHeaderSearchArgs(
+    const HeaderSearchOptions &Opts, SmallVectorImpl<const char *> &Args,
+    CompilerInvocation::StringAllocator SA) {
   const HeaderSearchOptions *HeaderSearchOpts = &Opts;
 #define HEADER_SEARCH_OPTION_WITH_MARSHALLING(                                 \
     PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,        \
@@ -1826,11 +1882,102 @@
       IMPLIED_CHECK, IMPLIED_VALUE, DENORMALIZER, EXTRACTOR, TABLE_INDEX)
 #include "clang/Driver/Options.inc"
 #undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
+
+  if (Opts.UseLibcxx)
+    GenerateArg(Args, OPT_stdlib_EQ, "libc++", SA);
+
+  if (!Opts.ModuleCachePath.empty())
+    GenerateArg(Args, OPT_fmodules_cache_path, Opts.ModuleCachePath, SA);
+
+  for (const auto &File : Opts.PrebuiltModuleFiles)
+    GenerateArg(Args, OPT_fmodule_file, File.first + "=" + File.second, SA);
+
+  for (const auto &Path : Opts.PrebuiltModulePaths)
+    GenerateArg(Args, OPT_fprebuilt_module_path, Path, SA);
+
+  for (const auto &Macro : Opts.ModulesIgnoreMacros)
+    GenerateArg(Args, OPT_fmodules_ignore_macro, Macro.val(), SA);
+
+  auto matches = [](const HeaderSearchOptions::Entry &Entry,
+                    frontend::IncludeDirGroup Group, bool IsFramework,
+                    bool IgnoreSysRoot) {
+    return Entry.Group == Group && Entry.IsFramework == IsFramework &&
+           Entry.IgnoreSysRoot == IgnoreSysRoot;
+  };
+
+  for (const HeaderSearchOptions::Entry &E : Opts.UserEntries) {
+    // Add -I..., -F..., and -index-header-map options in order.
+
+    if (E.Group == frontend::IndexHeaderMap)
+      GenerateArg(Args, OPT_index_header_map, SA);
+
+    Optional<OptSpecifier> Opt;
+
+    if (matches(E, frontend::IndexHeaderMap, true, true))
+      Opt = OPT_F;
+    else if (matches(E, frontend::IndexHeaderMap, false, true))
+      Opt = OPT_I;
+    else if (matches(E, frontend::Angled, true, true))
+      Opt = OPT_F;
+    else if (matches(E, frontend::Angled, false, true))
+      // Also handles [-iprefix=xx] -iwithprefixbefore=yy as -I[xx]yy.
+      Opt = OPT_I;
+
+    if (Opt) {
+      GenerateArg(Args, *Opt, E.Path, SA);
+      continue;
+    }
+
+    if (matches(E, frontend::After, false, true))
+      // Also handles [-iprefix=xx] -iwithprefix=yy as -idirafter=[xx]yy.
+      Opt = OPT_idirafter;
+    else if (matches(E, frontend::Quoted, false, true))
+      Opt = OPT_iquote;
+    else if (matches(E, frontend::System, false, true))
+      Opt = OPT_isystem;
+    else if (matches(E, frontend::System, false, false))
+      Opt = OPT_iwithsysroot;
+    else if (matches(E, frontend::System, true, true))
+      Opt = OPT_iframework;
+    else if (matches(E, frontend::System, true, false))
+      Opt = OPT_iframeworkwithsysroot;
+
+    else if (matches(E, frontend::CSystem, false, true))
+      // Add the paths for the various language specific isystem flags.
+      Opt = OPT_c_isystem;
+    else if (matches(E, frontend::CXXSystem, false, true))
+      Opt = OPT_cxx_isystem;
+    else if (matches(E, frontend::ObjCSystem, false, true))
+      Opt = OPT_objc_isystem;
+    else if (matches(E, frontend::ObjCXXSystem, false, true))
+      Opt = OPT_objcxx_isystem;
+
+    else if (matches(E, frontend::System, false, true))
+      // Add the internal paths from a driver that detects standard include
+      // paths.
+      Opt = OPT_internal_isystem;
+    else if (matches(E, frontend::ExternCSystem, false, true))
+      Opt = OPT_internal_externc_isystem;
+    else
+      llvm_unreachable("Tried to marshall invalid HeaderSearchOptions::Entry");
+
+    GenerateArg(Args, *Opt, E.Path, SA);
+  }
+
+  // Add the path prefixes which are implicitly treated as being system headers.
+  for (const auto &P : Opts.SystemHeaderPrefixes) {
+    OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
+                                        : OPT_no_system_header_prefix;
+    GenerateArg(Args, Opt, P.Prefix, SA);
+  }
+
+  for (const std::string &F : Opts.VFSOverlayFiles)
+    GenerateArg(Args, OPT_ivfsoverlay, F, SA);
 }
 
-static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
-                                  DiagnosticsEngine &Diags,
-                                  const std::string &WorkingDir) {
+static void ParseHeaderSearchArgsImpl(HeaderSearchOptions &Opts, ArgList &Args,
+                                      DiagnosticsEngine &Diags,
+                                      const std::string &WorkingDir) {
   HeaderSearchOptions *HeaderSearchOpts = &Opts;
   bool Success = true;
 
@@ -1961,6 +2108,28 @@
     Opts.AddVFSOverlayFile(A->getValue());
 }
 
+void CompilerInvocation::ParseHeaderSearchArgs(CompilerInvocation &Res,
+                                               HeaderSearchOptions &Opts,
+                                               ArgList &Args,
+                                               DiagnosticsEngine &Diags,
+                                               const std::string &WorkingDir) {
+  auto ParseHS = [&Diags, &WorkingDir](CompilerInvocation &Res, ArgList &Args) {
+    ParseHeaderSearchArgsImpl(Res.getHeaderSearchOpts(), Args, Diags,
+                              WorkingDir);
+  };
+  auto GenerateHS = [](CompilerInvocation &Res,
+                       SmallVectorImpl<const char *> &Args,
+                       CompilerInvocation::StringAllocator SA) {
+    GenerateHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, SA);
+  };
+  auto ResetHS = [](CompilerInvocation &Res) {
+    auto EmptyHeaderSearchOpts = std::make_shared<HeaderSearchOptions>();
+    Res.HeaderSearchOpts.swap(EmptyHeaderSearchOpts);
+  };
+
+  RoundTrip(ParseHS, GenerateHS, ResetHS, Res, Args);
+}
+
 void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
                                          const llvm::Triple &T,
                                          std::vector<std::string> &Includes,
@@ -2214,9 +2383,9 @@
                              SmallVectorImpl<const char *> &Args,
                              CompilerInvocation::StringAllocator SA) {
   if (Opts.IncludeDefaultHeader)
-    Args.push_back(SA(GetOptName(OPT_finclude_default_header)));
+    GenerateArg(Args, OPT_finclude_default_header, SA);
   if (Opts.DeclareOpenCLBuiltins)
-    Args.push_back(SA(GetOptName(OPT_fdeclare_opencl_builtins)));
+    GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA);
 }
 
 void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -3042,7 +3211,7 @@
                                       LangOpts.IsHeaderFile);
   ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
   llvm::Triple T(Res.getTargetOpts().Triple);
-  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
+  ParseHeaderSearchArgs(Res, Res.getHeaderSearchOpts(), Args, Diags,
                         Res.getFileSystemOpts().WorkingDir);
   if (DashX.getFormat() == InputKind::Precompiled ||
       DashX.getLanguage() == Language::LLVM_IR) {
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -260,6 +260,18 @@
                                const llvm::Triple &T,
                                const std::string &OutputFile,
                                const LangOptions &LangOptsRef);
+
+  /// Parse commnad line options that map to HeaderSearchOptions.
+  static void ParseHeaderSearchArgs(CompilerInvocation &Res,
+                                    HeaderSearchOptions &Opts,
+                                    llvm::opt::ArgList &Args,
+                                    DiagnosticsEngine &Diags,
+                                    const std::string &WorkingDir);
+
+  /// Generate command line options from HeaderSearchOptions.
+  static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
+                                       SmallVectorImpl<const char *> &Args,
+                                       CompilerInvocation::StringAllocator SA);
 };
 
 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to