[clang] 93471e6 - [clang] NFC, move CompilerInvocation::setLangDefaults to LangOptions.h

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 13 00:53:28 PDT 2022


Author: Haojian Wu
Date: 2022-04-13T09:44:39+02:00
New Revision: 93471e65df48372ee59bd0c2f8ba58a254ba1ca5

URL: https://github.com/llvm/llvm-project/commit/93471e65df48372ee59bd0c2f8ba58a254ba1ca5
DIFF: https://github.com/llvm/llvm-project/commit/93471e65df48372ee59bd0c2f8ba58a254ba1ca5.diff

LOG: [clang] NFC, move CompilerInvocation::setLangDefaults to LangOptions.h

The function is moved from clangFrontend to clangBasic, which allows tools
(e.g. clang pseudoparser) which don't depend on clangFrontend to use.

Differential Revision: https://reviews.llvm.org/D121375

Added: 
    

Modified: 
    clang/include/clang/Basic/LangOptions.h
    clang/include/clang/Basic/LangStandard.h
    clang/include/clang/Frontend/CompilerInvocation.h
    clang/lib/Basic/LangOptions.cpp
    clang/lib/Basic/LangStandards.cpp
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index f82992877c0b4..b0cc4c98e881e 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -450,6 +450,20 @@ class LangOptions : public LangOptionsBase {
 
   LangOptions();
 
+  /// Set language defaults for the given input language and
+  /// language standard in the given LangOptions object.
+  ///
+  /// \param Opts - The LangOptions object to set up.
+  /// \param Lang - The input language.
+  /// \param T - The target triple.
+  /// \param Includes - If the language requires extra headers to be implicitly
+  ///                   included, they will be appended to this list.
+  /// \param LangStd - The input language standard.
+  static void
+  setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
+                  std::vector<std::string> &Includes,
+                  LangStandard::Kind LangStd = LangStandard::lang_unspecified);
+
   // Define accessors/mutators for language options of enumeration type.
 #define LANGOPT(Name, Bits, Default, Description)
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \

diff  --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h
index fdfd2e7773a87..263985d6b1389 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -12,6 +12,10 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/StringRef.h"
 
+namespace llvm {
+class Triple;
+}
+
 namespace clang {
 
 /// The language for the input, used to select and validate the language
@@ -138,6 +142,9 @@ struct LangStandard {
   static const LangStandard *getLangStandardForName(StringRef Name);
 };
 
+LangStandard::Kind getDefaultLanguageStandard(clang::Language Lang,
+                                              const llvm::Triple &T);
+
 }  // end namespace clang
 
 #endif

diff  --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index 922c84a3bee2c..0753a6632f81e 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -219,19 +219,6 @@ class CompilerInvocation : public CompilerInvocationRefBase,
   /// executable), for finding the builtin compiler path.
   static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
 
-  /// Set language defaults for the given input language and
-  /// language standard in the given LangOptions object.
-  ///
-  /// \param Opts - The LangOptions object to set up.
-  /// \param IK - The input language.
-  /// \param T - The target triple.
-  /// \param Includes - The affected list of included files.
-  /// \param LangStd - The input language standard.
-  static void
-  setLangDefaults(LangOptions &Opts, InputKind IK, const llvm::Triple &T,
-                  std::vector<std::string> &Includes,
-                  LangStandard::Kind LangStd = LangStandard::lang_unspecified);
-
   /// Retrieve a module hash string that is suitable for uniquely
   /// identifying the conditions under which the module was built.
   std::string getModuleHash() const;

diff  --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index b6dc73d66304d..8c19d7e86795e 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -78,6 +78,126 @@ std::string LangOptions::getOpenCLVersionString() const {
   return Result;
 }
 
+void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
+                                  const llvm::Triple &T,
+                                  std::vector<std::string> &Includes,
+                                  LangStandard::Kind LangStd) {
+  // Set some properties which depend solely on the input kind; it would be nice
+  // to move these to the language standard, and have the driver resolve the
+  // input kind + language standard.
+  //
+  // FIXME: Perhaps a better model would be for a single source file to have
+  // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
+  // simultaneously active?
+  if (Lang == Language::Asm) {
+    Opts.AsmPreprocessor = 1;
+  } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) {
+    Opts.ObjC = 1;
+  }
+
+  if (LangStd == LangStandard::lang_unspecified)
+    LangStd = getDefaultLanguageStandard(Lang, T);
+  const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+  Opts.LangStd = LangStd;
+  Opts.LineComment = Std.hasLineComments();
+  Opts.C99 = Std.isC99();
+  Opts.C11 = Std.isC11();
+  Opts.C17 = Std.isC17();
+  Opts.C2x = Std.isC2x();
+  Opts.CPlusPlus = Std.isCPlusPlus();
+  Opts.CPlusPlus11 = Std.isCPlusPlus11();
+  Opts.CPlusPlus14 = Std.isCPlusPlus14();
+  Opts.CPlusPlus17 = Std.isCPlusPlus17();
+  Opts.CPlusPlus20 = Std.isCPlusPlus20();
+  Opts.CPlusPlus2b = Std.isCPlusPlus2b();
+  Opts.GNUMode = Std.isGNUMode();
+  Opts.GNUCVersion = 0;
+  Opts.HexFloats = Std.hasHexFloats();
+  Opts.ImplicitInt = Std.hasImplicitInt();
+  Opts.WChar = Std.isCPlusPlus();
+  Opts.Digraphs = Std.hasDigraphs();
+
+  Opts.HLSL = Lang == Language::HLSL;
+
+  // Set OpenCL Version.
+  Opts.OpenCL = Std.isOpenCL();
+  if (LangStd == LangStandard::lang_opencl10)
+    Opts.OpenCLVersion = 100;
+  else if (LangStd == LangStandard::lang_opencl11)
+    Opts.OpenCLVersion = 110;
+  else if (LangStd == LangStandard::lang_opencl12)
+    Opts.OpenCLVersion = 120;
+  else if (LangStd == LangStandard::lang_opencl20)
+    Opts.OpenCLVersion = 200;
+  else if (LangStd == LangStandard::lang_opencl30)
+    Opts.OpenCLVersion = 300;
+  else if (LangStd == LangStandard::lang_openclcpp10)
+    Opts.OpenCLCPlusPlusVersion = 100;
+  else if (LangStd == LangStandard::lang_openclcpp2021)
+    Opts.OpenCLCPlusPlusVersion = 202100;
+  else if (LangStd == LangStandard::lang_hlsl2015)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
+  else if (LangStd == LangStandard::lang_hlsl2016)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
+  else if (LangStd == LangStandard::lang_hlsl2017)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
+  else if (LangStd == LangStandard::lang_hlsl2018)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
+  else if (LangStd == LangStandard::lang_hlsl2021)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
+  else if (LangStd == LangStandard::lang_hlsl202x)
+    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
+
+  // OpenCL has some additional defaults.
+  if (Opts.OpenCL) {
+    Opts.AltiVec = 0;
+    Opts.ZVector = 0;
+    Opts.setDefaultFPContractMode(LangOptions::FPM_On);
+    Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
+    Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
+    Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
+
+    // Include default header file for OpenCL.
+    if (Opts.IncludeDefaultHeader) {
+      if (Opts.DeclareOpenCLBuiltins) {
+        // Only include base header file for builtin types and constants.
+        Includes.push_back("opencl-c-base.h");
+      } else {
+        Includes.push_back("opencl-c.h");
+      }
+    }
+  }
+
+  Opts.HIP = Lang == Language::HIP;
+  Opts.CUDA = Lang == Language::CUDA || Opts.HIP;
+  if (Opts.HIP) {
+    // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
+    // fuses multiplication/addition instructions without contract flag from
+    // device library functions in LLVM bitcode, which causes accuracy loss in
+    // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
+    // For device library functions in bitcode to work, 'Strict' or 'Standard'
+    // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
+    // FP contract option is used to allow fuse across statements in frontend
+    // whereas respecting contract flag in backend.
+    Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
+  } else if (Opts.CUDA) {
+    if (T.isSPIRV()) {
+      // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
+      Opts.OpenCLVersion = 200;
+    }
+    // Allow fuse across statements disregarding pragmas.
+    Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
+  }
+
+  Opts.RenderScript = Lang == Language::RenderScript;
+
+  // OpenCL, C++ and C2x have bool, true, false keywords.
+  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
+
+  // OpenCL has half keyword
+  Opts.Half = Opts.OpenCL;
+}
+
 FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
   FPOptions result(LO);
   return result;

diff  --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index ee27bfd12113c..2671217f3aa8c 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -8,6 +8,7 @@
 
 #include "clang/Basic/LangStandard.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
 
@@ -42,4 +43,47 @@ const LangStandard *LangStandard::getLangStandardForName(StringRef Name) {
   return &getLangStandardForKind(K);
 }
 
-
+LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang,
+                                                     const llvm::Triple &T) {
+  switch (Lang) {
+  case Language::Unknown:
+  case Language::LLVM_IR:
+    llvm_unreachable("Invalid input kind!");
+  case Language::OpenCL:
+    return LangStandard::lang_opencl12;
+  case Language::OpenCLCXX:
+    return LangStandard::lang_openclcpp10;
+  case Language::CUDA:
+    return LangStandard::lang_cuda;
+  case Language::Asm:
+  case Language::C:
+#if defined(CLANG_DEFAULT_STD_C)
+    return CLANG_DEFAULT_STD_C;
+#else
+    // The PS4 uses C99 as the default C standard.
+    if (T.isPS4())
+      return LangStandard::lang_gnu99;
+    return LangStandard::lang_gnu17;
+#endif
+  case Language::ObjC:
+#if defined(CLANG_DEFAULT_STD_C)
+    return CLANG_DEFAULT_STD_C;
+#else
+    return LangStandard::lang_gnu11;
+#endif
+  case Language::CXX:
+  case Language::ObjCXX:
+#if defined(CLANG_DEFAULT_STD_CXX)
+    return CLANG_DEFAULT_STD_CXX;
+#else
+    return LangStandard::lang_gnucxx14;
+#endif
+  case Language::RenderScript:
+    return LangStandard::lang_c99;
+  case Language::HIP:
+    return LangStandard::lang_hip;
+  case Language::HLSL:
+    return LangStandard::lang_hlsl2021;
+  }
+  llvm_unreachable("unhandled Language kind!");
+}

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 6aa85586df069..87e613a5dce9c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3173,178 +3173,6 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
   return Diags.getNumErrors() == NumErrorsBefore;
 }
 
-void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
-                                         const llvm::Triple &T,
-                                         std::vector<std::string> &Includes,
-                                         LangStandard::Kind LangStd) {
-  // Set some properties which depend solely on the input kind; it would be nice
-  // to move these to the language standard, and have the driver resolve the
-  // input kind + language standard.
-  //
-  // FIXME: Perhaps a better model would be for a single source file to have
-  // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
-  // simultaneously active?
-  if (IK.getLanguage() == Language::Asm) {
-    Opts.AsmPreprocessor = 1;
-  } else if (IK.isObjectiveC()) {
-    Opts.ObjC = 1;
-  }
-
-  if (LangStd == LangStandard::lang_unspecified) {
-    // Based on the base language, pick one.
-    switch (IK.getLanguage()) {
-    case Language::Unknown:
-    case Language::LLVM_IR:
-      llvm_unreachable("Invalid input kind!");
-    case Language::OpenCL:
-      LangStd = LangStandard::lang_opencl12;
-      break;
-    case Language::OpenCLCXX:
-      LangStd = LangStandard::lang_openclcpp10;
-      break;
-    case Language::CUDA:
-      LangStd = LangStandard::lang_cuda;
-      break;
-    case Language::Asm:
-    case Language::C:
-#if defined(CLANG_DEFAULT_STD_C)
-      LangStd = CLANG_DEFAULT_STD_C;
-#else
-      // The PS4 uses C99 as the default C standard.
-      if (T.isPS4())
-        LangStd = LangStandard::lang_gnu99;
-      else
-        LangStd = LangStandard::lang_gnu17;
-#endif
-      break;
-    case Language::ObjC:
-#if defined(CLANG_DEFAULT_STD_C)
-      LangStd = CLANG_DEFAULT_STD_C;
-#else
-      LangStd = LangStandard::lang_gnu11;
-#endif
-      break;
-    case Language::CXX:
-    case Language::ObjCXX:
-#if defined(CLANG_DEFAULT_STD_CXX)
-      LangStd = CLANG_DEFAULT_STD_CXX;
-#else
-      LangStd = LangStandard::lang_gnucxx14;
-#endif
-      break;
-    case Language::RenderScript:
-      LangStd = LangStandard::lang_c99;
-      break;
-    case Language::HIP:
-      LangStd = LangStandard::lang_hip;
-      break;
-    case Language::HLSL:
-      LangStd = LangStandard::lang_hlsl2021;
-      break;
-    }
-  }
-
-  const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
-  Opts.LangStd = LangStd;
-  Opts.LineComment = Std.hasLineComments();
-  Opts.C99 = Std.isC99();
-  Opts.C11 = Std.isC11();
-  Opts.C17 = Std.isC17();
-  Opts.C2x = Std.isC2x();
-  Opts.CPlusPlus = Std.isCPlusPlus();
-  Opts.CPlusPlus11 = Std.isCPlusPlus11();
-  Opts.CPlusPlus14 = Std.isCPlusPlus14();
-  Opts.CPlusPlus17 = Std.isCPlusPlus17();
-  Opts.CPlusPlus20 = Std.isCPlusPlus20();
-  Opts.CPlusPlus2b = Std.isCPlusPlus2b();
-  Opts.GNUMode = Std.isGNUMode();
-  Opts.GNUCVersion = 0;
-  Opts.HexFloats = Std.hasHexFloats();
-  Opts.ImplicitInt = Std.hasImplicitInt();
-  Opts.WChar = Std.isCPlusPlus();
-  Opts.Digraphs = Std.hasDigraphs();
-
-  Opts.HLSL = IK.getLanguage() == Language::HLSL;
-
-  // Set OpenCL Version.
-  Opts.OpenCL = Std.isOpenCL();
-  if (LangStd == LangStandard::lang_opencl10)
-    Opts.OpenCLVersion = 100;
-  else if (LangStd == LangStandard::lang_opencl11)
-    Opts.OpenCLVersion = 110;
-  else if (LangStd == LangStandard::lang_opencl12)
-    Opts.OpenCLVersion = 120;
-  else if (LangStd == LangStandard::lang_opencl20)
-    Opts.OpenCLVersion = 200;
-  else if (LangStd == LangStandard::lang_opencl30)
-    Opts.OpenCLVersion = 300;
-  else if (LangStd == LangStandard::lang_openclcpp10)
-    Opts.OpenCLCPlusPlusVersion = 100;
-  else if (LangStd == LangStandard::lang_openclcpp2021)
-    Opts.OpenCLCPlusPlusVersion = 202100;
-  else if (LangStd == LangStandard::lang_hlsl2015)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
-  else if (LangStd == LangStandard::lang_hlsl2016)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
-  else if (LangStd == LangStandard::lang_hlsl2017)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
-  else if (LangStd == LangStandard::lang_hlsl2018)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
-  else if (LangStd == LangStandard::lang_hlsl2021)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
-  else if (LangStd == LangStandard::lang_hlsl202x)
-    Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
-
-  // OpenCL has some additional defaults.
-  if (Opts.OpenCL) {
-    Opts.AltiVec = 0;
-    Opts.ZVector = 0;
-    Opts.setDefaultFPContractMode(LangOptions::FPM_On);
-    Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
-    Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
-    Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
-
-    // Include default header file for OpenCL.
-    if (Opts.IncludeDefaultHeader) {
-      if (Opts.DeclareOpenCLBuiltins) {
-        // Only include base header file for builtin types and constants.
-        Includes.push_back("opencl-c-base.h");
-      } else {
-        Includes.push_back("opencl-c.h");
-      }
-    }
-  }
-
-  Opts.HIP = IK.getLanguage() == Language::HIP;
-  Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP;
-  if (Opts.HIP) {
-    // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
-    // fuses multiplication/addition instructions without contract flag from
-    // device library functions in LLVM bitcode, which causes accuracy loss in
-    // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
-    // For device library functions in bitcode to work, 'Strict' or 'Standard'
-    // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
-    // FP contract option is used to allow fuse across statements in frontend
-    // whereas respecting contract flag in backend.
-    Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
-  } else if (Opts.CUDA) {
-    if (T.isSPIRV()) {
-      // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
-      Opts.OpenCLVersion = 200;
-    }
-    // Allow fuse across statements disregarding pragmas.
-    Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
-  }
-
-  Opts.RenderScript = IK.getLanguage() == Language::RenderScript;
-
-  // OpenCL, C++ and C2x have bool, true, false keywords.
-  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
-
-  // OpenCL has half keyword
-  Opts.Half = Opts.OpenCL;
-}
-
 /// Check if input file kind and language standard are compatible.
 static bool IsInputCompatibleWithStandard(InputKind IK,
                                           const LangStandard &S) {
@@ -3783,7 +3611,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
   Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
   Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
 
-  CompilerInvocation::setLangDefaults(Opts, IK, T, Includes, LangStd);
+  LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
 
   // The key paths of codegen options defined in Options.td start with
   // "LangOpts->". Let's provide the expected variable name and type.


        


More information about the cfe-commits mailing list