azabaznov created this revision.
azabaznov added reviewers: aaron.ballman, Anastasia, svenvh.
Herald added subscribers: dexonsmith, kerbowa, sunfish, kbarton, 
jgravelle-google, sbc100, nhaehnle, jvesely, nemanjai, dschuff.
azabaznov requested review of this revision.
Herald added subscribers: cfe-commits, aheejin.
Herald added a project: clang.

- Function CreateTargetInfo() has an access to language options which makes 
target immutable after creation without modification of language options 
themselves. Target specific hook TargetInfo::adjustAccordingToLangOpts() can be 
used if such modification depends on certain target.

- Introduce LangOptions::adjustAccordingToTI() to apply changes to language 
options based on target info (also without modification of target info). This 
also involves adding of some hooks (hasAtomics() / hasAltivec() as this options 
are used in PPC and WebAssembly in original TargetInfo::adjust()) which 
potentially can be reused.

- Validation of OpenCL target is in CreateTargetInfo() as language options are 
available at that point.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110036

Files:
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/LangOptions.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/AMDGPU.cpp
  clang/lib/Basic/Targets/AMDGPU.h
  clang/lib/Basic/Targets/PPC.cpp
  clang/lib/Basic/Targets/PPC.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Frontend/ASTUnit.cpp
  clang/lib/Frontend/ChainedIncludesSource.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Interpreter/Interpreter.cpp
  clang/tools/clang-import-test/clang-import-test.cpp
  clang/unittests/Analysis/MacroExpansionContextTest.cpp
  clang/unittests/Basic/SourceManagerTest.cpp
  clang/unittests/CodeGen/TestCompiler.h
  clang/unittests/Lex/HeaderSearchTest.cpp
  clang/unittests/Lex/LexerTest.cpp
  clang/unittests/Lex/PPCallbacksTest.cpp
  clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp

Index: clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
===================================================================
--- clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -36,7 +36,7 @@
       TargetOpts(new TargetOptions)
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
   }
 
   FileSystemOptions FileMgrOpts;
Index: clang/unittests/Lex/PPCallbacksTest.cpp
===================================================================
--- clang/unittests/Lex/PPCallbacksTest.cpp
+++ clang/unittests/Lex/PPCallbacksTest.cpp
@@ -136,7 +136,7 @@
         Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
   }
 
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
Index: clang/unittests/Lex/LexerTest.cpp
===================================================================
--- clang/unittests/Lex/LexerTest.cpp
+++ clang/unittests/Lex/LexerTest.cpp
@@ -43,7 +43,7 @@
       TargetOpts(new TargetOptions)
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
   }
 
   std::unique_ptr<Preprocessor> CreatePP(StringRef Source,
Index: clang/unittests/Lex/HeaderSearchTest.cpp
===================================================================
--- clang/unittests/Lex/HeaderSearchTest.cpp
+++ clang/unittests/Lex/HeaderSearchTest.cpp
@@ -34,7 +34,7 @@
         Search(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags,
                LangOpts, Target.get()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
   }
 
   void addSearchDir(llvm::StringRef Dir) {
Index: clang/unittests/CodeGen/TestCompiler.h
===================================================================
--- clang/unittests/CodeGen/TestCompiler.h
+++ clang/unittests/CodeGen/TestCompiler.h
@@ -45,7 +45,8 @@
     compiler.getTargetOpts().Triple = Tr.getTriple();
     compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
         compiler.getDiagnostics(),
-        std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
+        std::make_shared<clang::TargetOptions>(compiler.getTargetOpts()),
+        compiler.getLangOpts()));
 
     const clang::TargetInfo &TInfo = compiler.getTarget();
     PtrSize = TInfo.getPointerWidth(0) / 8;
Index: clang/unittests/Basic/SourceManagerTest.cpp
===================================================================
--- clang/unittests/Basic/SourceManagerTest.cpp
+++ clang/unittests/Basic/SourceManagerTest.cpp
@@ -38,7 +38,7 @@
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
   }
 
   FileSystemOptions FileMgrOpts;
Index: clang/unittests/Analysis/MacroExpansionContextTest.cpp
===================================================================
--- clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -39,7 +39,7 @@
         Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-pc-linux-unknown";
-    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts, LangOpts);
     LangOpts.CPlusPlus20 = 1; // For __VA_OPT__
   }
 
Index: clang/tools/clang-import-test/clang-import-test.cpp
===================================================================
--- clang/tools/clang-import-test/clang-import-test.cpp
+++ clang/tools/clang-import-test/clang-import-test.cpp
@@ -205,10 +205,12 @@
 
   Ins->setInvocation(std::move(Inv));
 
-  TargetInfo *TI = TargetInfo::CreateTargetInfo(
-      Ins->getDiagnostics(), Ins->getInvocation().TargetOpts);
+  TargetInfo *TI = TargetInfo::CreateTargetInfo(Ins->getDiagnostics(),
+                                                Ins->getInvocation().TargetOpts,
+                                                *Ins->getInvocation().LangOpts);
   Ins->setTarget(TI);
-  Ins->getTarget().adjust(Ins->getDiagnostics(), Ins->getLangOpts());
+  Ins->getLangOpts().adjustAccordingToTI(Ins->getDiagnostics(),
+                                         Ins->getTarget());
   Ins->createFileManager();
   Ins->createSourceManager(Ins->getFileManager());
   Ins->createPreprocessor(TU_Complete);
Index: clang/lib/Interpreter/Interpreter.cpp
===================================================================
--- clang/lib/Interpreter/Interpreter.cpp
+++ clang/lib/Interpreter/Interpreter.cpp
@@ -104,13 +104,15 @@
   Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
 
   Clang->setTarget(TargetInfo::CreateTargetInfo(
-      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts,
+      Clang->getLangOpts()));
   if (!Clang->hasTarget())
     return llvm::createStringError(std::errc::state_not_recoverable,
                                    "Initialization failed. "
                                    "Target is missing");
 
-  Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts());
+  Clang->getLangOpts().adjustAccordingToTI(Clang->getDiagnostics(),
+                                           Clang->getTarget());
 
   return std::move(Clang);
 }
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -99,8 +99,8 @@
 
 bool CompilerInstance::createTarget() {
   // Create the target instance.
-  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
-                                         getInvocation().TargetOpts));
+  setTarget(TargetInfo::CreateTargetInfo(
+      getDiagnostics(), getInvocation().TargetOpts, getLangOpts()));
   if (!hasTarget())
     return false;
 
@@ -117,7 +117,8 @@
     if (getFrontendOpts().AuxTargetFeatures)
       TO->FeaturesAsWritten = getFrontendOpts().AuxTargetFeatures.getValue();
     TO->HostTriple = getTarget().getTriple().str();
-    setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
+    setAuxTarget(
+        TargetInfo::CreateTargetInfo(getDiagnostics(), TO, getLangOpts()));
   }
 
   if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) {
@@ -133,16 +134,7 @@
     // FIXME: can we disable FEnvAccess?
   }
 
-  // We should do it here because target knows nothing about
-  // language options when it's being created.
-  if (getLangOpts().OpenCL &&
-      !getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics()))
-    return false;
-
-  // Inform the target of the language options.
-  // FIXME: We shouldn't need to do this, the target should be immutable once
-  // created. This complexity should be lifted elsewhere.
-  getTarget().adjust(getDiagnostics(), getLangOpts());
+  getLangOpts().adjustAccordingToTI(getDiagnostics(), getTarget());
 
   // Adjust target options based on codegen options.
   getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts());
@@ -457,7 +449,7 @@
                                       getSourceManager(), *HeaderInfo, *this,
                                       /*IdentifierInfoLookup=*/nullptr,
                                       /*OwnsHeaderSearch=*/true, TUKind);
-  getTarget().adjust(getDiagnostics(), getLangOpts());
+  getLangOpts().adjustAccordingToTI(getDiagnostics(), getTarget());
   PP->Initialize(getTarget(), getAuxTarget());
 
   if (PPOpts.DetailedRecord)
Index: clang/lib/Frontend/ChainedIncludesSource.cpp
===================================================================
--- clang/lib/Frontend/ChainedIncludesSource.cpp
+++ clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -150,7 +150,8 @@
     Clang->setInvocation(std::move(CInvok));
     Clang->setDiagnostics(Diags.get());
     Clang->setTarget(TargetInfo::CreateTargetInfo(
-        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
+        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts,
+        Clang->getLangOpts()));
     Clang->createFileManager();
     Clang->createSourceManager(Clang->getFileManager());
     Clang->createPreprocessor(TU_Prefix);
Index: clang/lib/Frontend/ASTUnit.cpp
===================================================================
--- clang/lib/Frontend/ASTUnit.cpp
+++ clang/lib/Frontend/ASTUnit.cpp
@@ -567,8 +567,8 @@
       return false;
 
     this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
-    Target =
-        TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts,
+                                          LangOpt);
 
     updated();
     return false;
@@ -584,11 +584,7 @@
     if (!Target || !InitializedLanguage)
       return;
 
-    // Inform the target of the language options.
-    //
-    // FIXME: We shouldn't need to do this, the target should be immutable once
-    // created. This complexity should be lifted elsewhere.
-    Target->adjust(PP.getDiagnostics(), LangOpt);
+    LangOpt.adjustAccordingToTI(PP.getDiagnostics(), *Target);
 
     // Initialize the preprocessor.
     PP.Initialize(*Target);
Index: clang/lib/Basic/Targets/WebAssembly.h
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.h
+++ clang/lib/Basic/Targets/WebAssembly.h
@@ -140,7 +140,7 @@
 
   bool hasProtectedVisibility() const override { return false; }
 
-  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
+  bool hasAtomics() const override { return HasAtomics; }
 };
 
 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
Index: clang/lib/Basic/Targets/WebAssembly.cpp
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.cpp
+++ clang/lib/Basic/Targets/WebAssembly.cpp
@@ -234,16 +234,6 @@
                                              Builtin::FirstTSBuiltin);
 }
 
-void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
-                                   LangOptions &Opts) {
-  // If the Atomics feature isn't available, turn off POSIXThreads and
-  // ThreadModel, so that we don't predefine _REENTRANT or __STDCPP_THREADS__.
-  if (!HasAtomics) {
-    Opts.POSIXThreads = false;
-    Opts.setThreadModel(LangOptions::ThreadModelKind::Single);
-  }
-}
-
 void WebAssembly32TargetInfo::getTargetDefines(const LangOptions &Opts,
                                                MacroBuilder &Builder) const {
   WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
Index: clang/lib/Basic/Targets/SPIR.h
===================================================================
--- clang/lib/Basic/Targets/SPIR.h
+++ clang/lib/Basic/Targets/SPIR.h
@@ -135,8 +135,8 @@
     AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
   }
 
-  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
-    TargetInfo::adjust(Diags, Opts);
+  void adjustAccordingToLangOpts(const LangOptions &Opts) override {
+    TargetInfo::adjustAccordingToLangOpts(Opts);
     // FIXME: SYCL specification considers unannotated pointers and references
     // to be pointing to the generic address space. See section 5.9.3 of
     // SYCL 2020 specification.
Index: clang/lib/Basic/Targets/PPC.h
===================================================================
--- clang/lib/Basic/Targets/PPC.h
+++ clang/lib/Basic/Targets/PPC.h
@@ -92,8 +92,7 @@
     HasIbm128 = true;
   }
 
-  // Set the language option for altivec based on our value.
-  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
+  void adjustAccordingToLangOpts(const LangOptions &Opts) override;
 
   // Note: GCC recognizes the following additional cpus:
   //  401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
@@ -355,6 +354,8 @@
   bool isSPRegName(StringRef RegName) const override {
     return RegName.equals("r1") || RegName.equals("x1");
   }
+
+  bool hasAltivec() const override { return HasAltivec; }
 };
 
 class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
Index: clang/lib/Basic/Targets/PPC.cpp
===================================================================
--- clang/lib/Basic/Targets/PPC.cpp
+++ clang/lib/Basic/Targets/PPC.cpp
@@ -769,15 +769,12 @@
   Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
 }
 
-void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
-  if (HasAltivec)
-    Opts.AltiVec = 1;
-  TargetInfo::adjust(Diags, Opts);
+void PPCTargetInfo::adjustAccordingToLangOpts(const LangOptions &Opts) {
+  TargetInfo::adjustAccordingToLangOpts(Opts);
   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
     LongDoubleFormat = Opts.PPCIEEELongDouble
                            ? &llvm::APFloat::IEEEquad()
                            : &llvm::APFloat::PPCDoubleDouble();
-  Opts.IEEE128 = 1;
 }
 
 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
Index: clang/lib/Basic/Targets/AMDGPU.h
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.h
+++ clang/lib/Basic/Targets/AMDGPU.h
@@ -93,7 +93,7 @@
 
   void setAddressSpaceMap(bool DefaultIsPrivate);
 
-  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
+  void adjustAccordingToLangOpts(const LangOptions &Opts) override;
 
   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
     if (isR600(getTriple()))
Index: clang/lib/Basic/Targets/AMDGPU.cpp
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.cpp
+++ clang/lib/Basic/Targets/AMDGPU.cpp
@@ -356,8 +356,8 @@
   MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
 }
 
-void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
-  TargetInfo::adjust(Diags, Opts);
+void AMDGPUTargetInfo::adjustAccordingToLangOpts(const LangOptions &Opts) {
+  TargetInfo::adjustAccordingToLangOpts(Opts);
   // ToDo: There are still a few places using default address space as private
   // address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL
   // can be removed from the following line.
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -654,7 +654,8 @@
 /// options.
 TargetInfo *
 TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
-                             const std::shared_ptr<TargetOptions> &Opts) {
+                             const std::shared_ptr<TargetOptions> &Opts,
+                             const LangOptions &LangOpts) {
   llvm::Triple Triple(Opts->Triple);
 
   // Construct the target
@@ -719,7 +720,10 @@
   Target->setCommandLineOpenCLOpts();
   Target->setMaxAtomicWidth();
 
-  if (!Target->validateTarget(Diags))
+  Target->adjustAccordingToLangOpts(LangOpts);
+
+  if (!Target->validateTarget(Diags) ||
+      (LangOpts.OpenCL && !Target->validateOpenCLTarget(LangOpts, Diags)))
     return nullptr;
 
   Target->CheckFixedPointBits();
Index: clang/lib/Basic/TargetInfo.cpp
===================================================================
--- clang/lib/Basic/TargetInfo.cpp
+++ clang/lib/Basic/TargetInfo.cpp
@@ -345,11 +345,9 @@
   };
 }
 
-/// adjust - Set forced language options.
-/// Apply changes to the target information with respect to certain
-/// language options which change the target configuration and adjust
-/// the language based on the target options where applicable.
-void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
+/// adjustAccordingToLanguageOptions - Apply changes to the target
+/// information with respect to certain language options.
+void TargetInfo::adjustAccordingToLangOpts(const LangOptions &Opts) {
   if (Opts.NoBitFieldTypeAlign)
     UseBitFieldTypeAlignment = false;
 
@@ -399,23 +397,6 @@
     HalfFormat = &llvm::APFloat::IEEEhalf();
     FloatFormat = &llvm::APFloat::IEEEsingle();
     LongDoubleFormat = &llvm::APFloat::IEEEquad();
-
-    // OpenCL C v3.0 s6.7.5 - The generic address space requires support for
-    // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space
-    // feature
-    // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0
-    // or later and __opencl_c_pipes feature
-    // FIXME: These language options are also defined in setLangDefaults()
-    // for OpenCL C 2.0 but with no access to target capabilities. Target
-    // should be immutable once created and thus these language options need
-    // to be defined only once.
-    if (Opts.getOpenCLCompatibleVersion() == 300) {
-      const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();
-      Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(
-          OpenCLFeaturesMap, "__opencl_c_generic_address_space");
-      Opts.OpenCLPipes =
-          hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
-    }
   }
 
   if (Opts.DoubleSize) {
@@ -450,11 +431,6 @@
   // its corresponding signed type.
   PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
   CheckFixedPointBits();
-
-  if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {
-    Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
-    Opts.ProtectParens = false;
-  }
 }
 
 bool TargetInfo::initFeatureMap(
Index: clang/lib/Basic/LangOptions.cpp
===================================================================
--- clang/lib/Basic/LangOptions.cpp
+++ clang/lib/Basic/LangOptions.cpp
@@ -11,6 +11,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
 
@@ -68,6 +70,43 @@
       break;
 }
 
+void LangOptions::adjustAccordingToTI(DiagnosticsEngine &Diags,
+                                      const TargetInfo &TI) {
+  if (OpenCL) {
+    // OpenCL C v3.0 s6.7.5 - The generic address space requires support for
+    // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space
+    // feature
+    // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0
+    // or later and __opencl_c_pipes feature
+    // FIXME: These language options are also defined in setLangDefaults()
+    // for OpenCL C 2.0 but with no access to target capabilities. Target
+    // should be immutable once created and thus these language options need
+    // to be defined only once.
+    if (getOpenCLCompatibleVersion() == 300) {
+      const auto &OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
+      OpenCLGenericAddressSpace = TI.hasFeatureEnabled(
+          OpenCLFeaturesMap, "__opencl_c_generic_address_space");
+      OpenCLPipes = TI.hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
+    }
+  }
+
+  if (ProtectParens && !TI.checkArithmeticFenceSupported()) {
+    Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
+    ProtectParens = false;
+  }
+
+  if (TI.getTriple().isWasm() && !TI.hasAtomics()) {
+    // If the Atomics feature isn't available, turn off POSIXThreads and
+    // ThreadModel, so that we don't predefine _REENTRANT or __STDCPP_THREADS__.
+    POSIXThreads = false;
+    setThreadModel(LangOptions::ThreadModelKind::Single);
+  } else if (TI.getTriple().isPPC()) {
+    if (TI.hasAltivec())
+      AltiVec = 1;
+    IEEE128 = 1;
+  }
+}
+
 std::string LangOptions::getOpenCLVersionString() const {
   std::string Result;
   {
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -248,9 +248,11 @@
   /// \param Opts - The options to use to initialize the target. The target may
   /// modify the options to canonicalize the target feature information to match
   /// what the backend expects.
+  /// \param LangOpts - Language options to adjust target information with.
   static TargetInfo *
   CreateTargetInfo(DiagnosticsEngine &Diags,
-                   const std::shared_ptr<TargetOptions> &Opts);
+                   const std::shared_ptr<TargetOptions> &Opts,
+                   const LangOptions &LangOpts);
 
   virtual ~TargetInfo();
 
@@ -727,6 +729,10 @@
             llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
   }
 
+  virtual bool hasAtomics() const { return false; }
+
+  virtual bool hasAltivec() const { return false; }
+
   /// Return the maximum vector alignment supported for the given target.
   unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
   /// Return default simd alignment for the given target. Generally, this
@@ -1176,13 +1182,6 @@
             getTriple().getVendor() == llvm::Triple::SCEI);
   }
 
-  /// Set forced language options.
-  ///
-  /// Apply changes to the target information with respect to certain
-  /// language options which change the target configuration and adjust
-  /// the language based on the target options where applicable.
-  virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts);
-
   /// Adjust target options based on codegen options.
   virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
                                    TargetOptions &TargetOpts) const {}
@@ -1567,11 +1566,6 @@
     return true;
   }
 
-  /// Check that OpenCL target has valid options setting based on OpenCL
-  /// version.
-  virtual bool validateOpenCLTarget(const LangOptions &Opts,
-                                    DiagnosticsEngine &Diags) const;
-
   virtual void setAuxTarget(const TargetInfo *Aux) {}
 
   /// Whether target allows debuginfo types for decl only variables/functions.
@@ -1595,7 +1589,16 @@
     return None;
   }
 
- private:
+  /// Apply changes to the target information with respect to certain
+  /// language options.
+  virtual void adjustAccordingToLangOpts(const LangOptions &Opts);
+
+  /// Check that OpenCL target has valid options setting based on OpenCL
+  /// version.
+  virtual bool validateOpenCLTarget(const LangOptions &Opts,
+                                    DiagnosticsEngine &Diags) const;
+
+private:
   // Assert the values for the fractional and integral bits for each fixed point
   // type follow the restrictions given in clause 6.2.6.3 of N1169.
   void CheckFixedPointBits() const;
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -29,6 +29,9 @@
 
 namespace clang {
 
+class DiagnosticsEngine;
+class TargetInfo;
+
 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that
 /// this large collection of bitfields is a trivial class type.
 class LangOptionsBase {
@@ -381,6 +384,9 @@
 
   LangOptions();
 
+  /// Inform language options about target capabilities.
+  void adjustAccordingToTI(DiagnosticsEngine &Diags, const TargetInfo &TI);
+
   // Define accessors/mutators for language options of enumeration type.
 #define LANGOPT(Name, Bits, Default, Description)
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to