[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread Artem Chikin via cfe-commits

https://github.com/artemcm updated 
https://github.com/llvm/llvm-project/pull/88977

>From 04e826688a504e141f3407567616bcf5cce9e2cc Mon Sep 17 00:00:00 2001
From: Artem Chikin 
Date: Wed, 20 Dec 2023 10:56:42 -0800
Subject: [PATCH] [NFC] Parameterize Initialization of 'clang::CodeGenerator'
 on a TargetInfo instance which may differ from the one in the ASTContext

As per https://github.com/apple/swift/pull/65930, Swift compiler's built-in 
Clang instance may require to perform type-checking against one OS version and 
compilation/code-generation against an earlier version. This change allows 
Swift to configure it's built-in Clang code-generator with a custom 
'TargetInfo'.
---
 clang/include/clang/AST/ASTConsumer.h |  5 
 clang/lib/CodeGen/CodeGenModule.cpp   | 29 +--
 clang/lib/CodeGen/CodeGenModule.h |  3 +-
 clang/lib/CodeGen/ModuleBuilder.cpp   | 21 +-
 .../ObjectFilePCHContainerOperations.cpp  |  5 ++--
 5 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index ebcd8059284d8d..774d19565e57b0 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -26,6 +26,7 @@ namespace clang {
   class VarDecl;
   class FunctionDecl;
   class ImportDecl;
+  class TargetInfo;
 
 /// ASTConsumer - This is an abstract interface that should be implemented by
 /// clients that read ASTs.  This abstraction layer allows the client to be
@@ -46,6 +47,10 @@ class ASTConsumer {
   /// ASTContext.
   virtual void Initialize(ASTContext &Context) {}
 
+  /// Initialize - This is called to initialize the consumer, providing the
+  /// ASTContext.
+  virtual void Initialize(ASTContext &Context, const TargetInfo 
&CodeGenTargetInfo) {}
+
   /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
   /// called by the parser to process every top-level Decl*.
   ///
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 0c447b20cef40d..8380b71ababe5b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -333,14 +333,13 @@ CodeGenModule::CodeGenModule(ASTContext &C,
  IntrusiveRefCntPtr FS,
  const HeaderSearchOptions &HSO,
  const PreprocessorOptions &PPO,
- const CodeGenOptions &CGO, llvm::Module &M,
- DiagnosticsEngine &diags,
+ const CodeGenOptions &CGO, const TargetInfo &CGTI,
+ llvm::Module &M, DiagnosticsEngine &diags,
  CoverageSourceInfo *CoverageInfo)
 : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
   PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
-  Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
-  VMContext(M.getContext()), Types(*this), VTables(*this),
-  SanitizerMD(new SanitizerMetadata(*this)) {
+  Target(CGTI), ABI(createCXXABI(*this)), VMContext(M.getContext()),
+  Types(*this), VTables(*this), SanitizerMD(new SanitizerMetadata(*this)) {
 
   // Initialize the type cache.
   llvm::LLVMContext &LLVMContext = M.getContext();
@@ -353,20 +352,18 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   BFloatTy = llvm::Type::getBFloatTy(LLVMContext);
   FloatTy = llvm::Type::getFloatTy(LLVMContext);
   DoubleTy = llvm::Type::getDoubleTy(LLVMContext);
-  PointerWidthInBits = C.getTargetInfo().getPointerWidth(LangAS::Default);
+  PointerWidthInBits = Target.getPointerWidth(LangAS::Default);
   PointerAlignInBytes =
-  C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(LangAS::Default))
+  C.toCharUnitsFromBits(Target.getPointerAlign(LangAS::Default))
   .getQuantity();
   SizeSizeInBytes =
-
C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity();
-  IntAlignInBytes =
-C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
-  CharTy =
-llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth());
-  IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
-  IntPtrTy = llvm::IntegerType::get(LLVMContext,
-C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
+  C.toCharUnitsFromBits(Target.getMaxPointerWidth()).getQuantity();
+  IntAlignInBytes = C.toCharUnitsFromBits(Target.getIntAlign()).getQuantity();
+  CharTy = llvm::IntegerType::get(LLVMContext, Target.getCharWidth());
+  IntTy = llvm::IntegerType::get(LLVMContext, Target.getIntWidth());
+  IntPtrTy = llvm::IntegerType::get(LLVMContext, Target.getMaxPointerWidth());
+  Int8PtrTy = Int8Ty->getPointerTo(0);
+  Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
   

[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread Michael Spencer via cfe-commits


@@ -26,123 +26,132 @@ namespace clang {
   class VarDecl;
   class FunctionDecl;
   class ImportDecl;
-
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// clients that read ASTs.  This abstraction layer allows the client to be
-/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
-class ASTConsumer {
-  /// Whether this AST consumer also requires information about
-  /// semantic analysis.
-  bool SemaConsumer = false;
-
-  friend class SemaConsumer;
-
-public:
-  ASTConsumer() = default;
-
-  virtual ~ASTConsumer() {}
-
-  /// Initialize - This is called to initialize the consumer, providing the
-  /// ASTContext.
-  virtual void Initialize(ASTContext &Context) {}
-
-  /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
-  /// called by the parser to process every top-level Decl*.
-  ///
-  /// \returns true to continue parsing, or false to abort parsing.
-  virtual bool HandleTopLevelDecl(DeclGroupRef D);
-
-  /// This callback is invoked each time an inline (method or friend)
-  /// function definition in a class is completed.
-  virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
-
-  /// HandleInterestingDecl - Handle the specified interesting declaration. 
This
-  /// is called by the AST reader when deserializing things that might interest
-  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
-  virtual void HandleInterestingDecl(DeclGroupRef D);
-
-  /// HandleTranslationUnit - This method is called when the ASTs for entire
-  /// translation unit have been parsed.
-  virtual void HandleTranslationUnit(ASTContext &Ctx) {}
-
-  /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
-  /// (e.g. struct, union, enum, class) is completed.  This allows the client 
to
-  /// hack on the type, which can occur at any point in the file (because these
-  /// can be defined in declspecs).
-  virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
-  /// This callback is invoked the first time each TagDecl is required to
-  /// be complete.
-  virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
-
-  /// Invoked when a function is implicitly instantiated.
-  /// Note that at this point it does not have a body, its body is
-  /// instantiated at the end of the translation unit and passed to
-  /// HandleTopLevelDecl.
-  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
-
-  /// Handle the specified top-level declaration that occurred inside
-  /// and ObjC container.
-  /// The default implementation ignored them.
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-
-  /// Handle an ImportDecl that was implicitly created due to an
-  /// inclusion directive.
-  /// The default implementation passes it to HandleTopLevelDecl.
-  virtual void HandleImplicitImportDecl(ImportDecl *D);
-
-  /// CompleteTentativeDefinition - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given tentative definition should be
-  /// completed.
-  ///
-  /// The variable declaration itself will be a tentative
-  /// definition. If it had an incomplete array type, its type will
-  /// have already been changed to an array of size 1. However, the
-  /// declaration remains a tentative definition and has not been
-  /// modified by the introduction of an implicit zero initializer.
-  virtual void CompleteTentativeDefinition(VarDecl *D) {}
-
-  /// CompleteExternalDeclaration - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given external declaration should be
-  /// completed.
-  virtual void CompleteExternalDeclaration(VarDecl *D) {}
-
-  /// Callback invoked when an MSInheritanceAttr has been attached to a
-  /// CXXRecordDecl.
-  virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
-
-  /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
-  // variable has been instantiated.
-  virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
-
-  /// Callback involved at the end of a translation unit to
-  /// notify the consumer that a vtable for the given C++ class is
-  /// required.
-  ///
-  /// \param RD The class whose vtable was used.
-  virtual void HandleVTable(CXXRecordDecl *RD) {}
-
-  /// If the consumer is interested in entities getting modified after
-  /// their initial creation, it should return a pointer to
-  /// an ASTMutationListener here.
-  virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
-
-  /// If the consumer is interested in entities being deserialized from
-  /// AST files, it should return a pointer to a ASTDeserializationListener 
here
-  virtual ASTDeserializationListener *GetASTDeserializationListener() {
-return nullptr;
-  }
-
-  /// PrintStats - If desired, print any statistics.
-  virtual void PrintStats() {}
-
-  /// This callback is called for each funct

[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread Michael Spencer via cfe-commits


@@ -26,123 +26,132 @@ namespace clang {
   class VarDecl;
   class FunctionDecl;
   class ImportDecl;
-
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// clients that read ASTs.  This abstraction layer allows the client to be
-/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
-class ASTConsumer {
-  /// Whether this AST consumer also requires information about
-  /// semantic analysis.
-  bool SemaConsumer = false;
-
-  friend class SemaConsumer;
-
-public:
-  ASTConsumer() = default;
-
-  virtual ~ASTConsumer() {}
-
-  /// Initialize - This is called to initialize the consumer, providing the
-  /// ASTContext.
-  virtual void Initialize(ASTContext &Context) {}
-
-  /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
-  /// called by the parser to process every top-level Decl*.
-  ///
-  /// \returns true to continue parsing, or false to abort parsing.
-  virtual bool HandleTopLevelDecl(DeclGroupRef D);
-
-  /// This callback is invoked each time an inline (method or friend)
-  /// function definition in a class is completed.
-  virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
-
-  /// HandleInterestingDecl - Handle the specified interesting declaration. 
This
-  /// is called by the AST reader when deserializing things that might interest
-  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
-  virtual void HandleInterestingDecl(DeclGroupRef D);
-
-  /// HandleTranslationUnit - This method is called when the ASTs for entire
-  /// translation unit have been parsed.
-  virtual void HandleTranslationUnit(ASTContext &Ctx) {}
-
-  /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
-  /// (e.g. struct, union, enum, class) is completed.  This allows the client 
to
-  /// hack on the type, which can occur at any point in the file (because these
-  /// can be defined in declspecs).
-  virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
-  /// This callback is invoked the first time each TagDecl is required to
-  /// be complete.
-  virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
-
-  /// Invoked when a function is implicitly instantiated.
-  /// Note that at this point it does not have a body, its body is
-  /// instantiated at the end of the translation unit and passed to
-  /// HandleTopLevelDecl.
-  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
-
-  /// Handle the specified top-level declaration that occurred inside
-  /// and ObjC container.
-  /// The default implementation ignored them.
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-
-  /// Handle an ImportDecl that was implicitly created due to an
-  /// inclusion directive.
-  /// The default implementation passes it to HandleTopLevelDecl.
-  virtual void HandleImplicitImportDecl(ImportDecl *D);
-
-  /// CompleteTentativeDefinition - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given tentative definition should be
-  /// completed.
-  ///
-  /// The variable declaration itself will be a tentative
-  /// definition. If it had an incomplete array type, its type will
-  /// have already been changed to an array of size 1. However, the
-  /// declaration remains a tentative definition and has not been
-  /// modified by the introduction of an implicit zero initializer.
-  virtual void CompleteTentativeDefinition(VarDecl *D) {}
-
-  /// CompleteExternalDeclaration - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given external declaration should be
-  /// completed.
-  virtual void CompleteExternalDeclaration(VarDecl *D) {}
-
-  /// Callback invoked when an MSInheritanceAttr has been attached to a
-  /// CXXRecordDecl.
-  virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
-
-  /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
-  // variable has been instantiated.
-  virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
-
-  /// Callback involved at the end of a translation unit to
-  /// notify the consumer that a vtable for the given C++ class is
-  /// required.
-  ///
-  /// \param RD The class whose vtable was used.
-  virtual void HandleVTable(CXXRecordDecl *RD) {}
-
-  /// If the consumer is interested in entities getting modified after
-  /// their initial creation, it should return a pointer to
-  /// an ASTMutationListener here.
-  virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
-
-  /// If the consumer is interested in entities being deserialized from
-  /// AST files, it should return a pointer to a ASTDeserializationListener 
here
-  virtual ASTDeserializationListener *GetASTDeserializationListener() {
-return nullptr;
-  }
-
-  /// PrintStats - If desired, print any statistics.
-  virtual void PrintStats() {}
-
-  /// This callback is called for each funct

[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I don't understand the scenario you're envisioning here.  If, for example, 
`sizeof(long)` is different in the AST vs. CodeGen, everything will very likely 
explode.  And I don't want to make an open-ended commitment to support 
modifying properties of the target based on whatever happens to work at the 
moment.

What properties of the target can you safely manipulate?  Would it make sense 
to store those properties in a separate datastructure?

https://github.com/llvm/llvm-project/pull/88977
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 281d71604f418eb952e967d9dc4b26241b7f96aa 
c86ee8d6fc2b0d3995f0dee4e7bc206ef6e05c8b -- 
clang/include/clang/AST/ASTConsumer.h clang/lib/CodeGen/CodeGenModule.cpp 
clang/lib/CodeGen/CodeGenModule.h clang/lib/CodeGen/ModuleBuilder.cpp 
clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index 774d19565e..eeac3ea001 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -28,126 +28,130 @@ namespace clang {
   class ImportDecl;
   class TargetInfo;
 
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// clients that read ASTs.  This abstraction layer allows the client to be
-/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
-class ASTConsumer {
-  /// Whether this AST consumer also requires information about
-  /// semantic analysis.
-  bool SemaConsumer = false;
-
-  friend class SemaConsumer;
-
-public:
-  ASTConsumer() = default;
-
-  virtual ~ASTConsumer() {}
-
-  /// Initialize - This is called to initialize the consumer, providing the
-  /// ASTContext.
-  virtual void Initialize(ASTContext &Context) {}
-
-  /// Initialize - This is called to initialize the consumer, providing the
-  /// ASTContext.
-  virtual void Initialize(ASTContext &Context, const TargetInfo 
&CodeGenTargetInfo) {}
-
-  /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
-  /// called by the parser to process every top-level Decl*.
-  ///
-  /// \returns true to continue parsing, or false to abort parsing.
-  virtual bool HandleTopLevelDecl(DeclGroupRef D);
-
-  /// This callback is invoked each time an inline (method or friend)
-  /// function definition in a class is completed.
-  virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
-
-  /// HandleInterestingDecl - Handle the specified interesting declaration. 
This
-  /// is called by the AST reader when deserializing things that might interest
-  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
-  virtual void HandleInterestingDecl(DeclGroupRef D);
-
-  /// HandleTranslationUnit - This method is called when the ASTs for entire
-  /// translation unit have been parsed.
-  virtual void HandleTranslationUnit(ASTContext &Ctx) {}
-
-  /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
-  /// (e.g. struct, union, enum, class) is completed.  This allows the client 
to
-  /// hack on the type, which can occur at any point in the file (because these
-  /// can be defined in declspecs).
-  virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
-  /// This callback is invoked the first time each TagDecl is required to
-  /// be complete.
-  virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
-
-  /// Invoked when a function is implicitly instantiated.
-  /// Note that at this point it does not have a body, its body is
-  /// instantiated at the end of the translation unit and passed to
-  /// HandleTopLevelDecl.
-  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
-
-  /// Handle the specified top-level declaration that occurred inside
-  /// and ObjC container.
-  /// The default implementation ignored them.
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-
-  /// Handle an ImportDecl that was implicitly created due to an
-  /// inclusion directive.
-  /// The default implementation passes it to HandleTopLevelDecl.
-  virtual void HandleImplicitImportDecl(ImportDecl *D);
-
-  /// CompleteTentativeDefinition - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given tentative definition should be
-  /// completed.
-  ///
-  /// The variable declaration itself will be a tentative
-  /// definition. If it had an incomplete array type, its type will
-  /// have already been changed to an array of size 1. However, the
-  /// declaration remains a tentative definition and has not been
-  /// modified by the introduction of an implicit zero initializer.
-  virtual void CompleteTentativeDefinition(VarDecl *D) {}
-
-  /// CompleteExternalDeclaration - Callback invoked at the end of a 
translation
-  /// unit to notify the consumer that the given external declaration should be
-  /// completed.
-  virtual void CompleteExternalDeclaration(VarDecl *D) {}
-
-  /// Callback invoked when an MSInheritanceAttr has been attached to a
-  /// CXXRecordDecl.
-  virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
-
-  /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
-  // variable has been instantiated.
-  virtual void HandleCXXSta

[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Artem Chikin (artemcm)


Changes

A client's Clang instance may require to perform type-checking against one OS 
version and compilation/code-generation against an earlier version. This change 
allows such clients to configure their built-in Clang code-generator with a 
custom `TargetInfo`.

---
Full diff: https://github.com/llvm/llvm-project/pull/88977.diff


5 Files Affected:

- (modified) clang/include/clang/AST/ASTConsumer.h (+5) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+13-10) 
- (modified) clang/lib/CodeGen/CodeGenModule.h (+3-1) 
- (modified) clang/lib/CodeGen/ModuleBuilder.cpp (+11-6) 
- (modified) clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp (+2-1) 


``diff
diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index ebcd8059284d8d..774d19565e57b0 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -26,6 +26,7 @@ namespace clang {
   class VarDecl;
   class FunctionDecl;
   class ImportDecl;
+  class TargetInfo;
 
 /// ASTConsumer - This is an abstract interface that should be implemented by
 /// clients that read ASTs.  This abstraction layer allows the client to be
@@ -46,6 +47,10 @@ class ASTConsumer {
   /// ASTContext.
   virtual void Initialize(ASTContext &Context) {}
 
+  /// Initialize - This is called to initialize the consumer, providing the
+  /// ASTContext.
+  virtual void Initialize(ASTContext &Context, const TargetInfo 
&CodeGenTargetInfo) {}
+
   /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
   /// called by the parser to process every top-level Decl*.
   ///
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 0c447b20cef40d..52ff65c0986931 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -333,12 +333,14 @@ CodeGenModule::CodeGenModule(ASTContext &C,
  IntrusiveRefCntPtr FS,
  const HeaderSearchOptions &HSO,
  const PreprocessorOptions &PPO,
- const CodeGenOptions &CGO, llvm::Module &M,
+ const CodeGenOptions &CGO,
+ const TargetInfo &CGTI,
+ llvm::Module &M,
  DiagnosticsEngine &diags,
  CoverageSourceInfo *CoverageInfo)
 : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
   PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
-  Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
+  Target(CGTI), ABI(createCXXABI(*this)),
   VMContext(M.getContext()), Types(*this), VTables(*this),
   SanitizerMD(new SanitizerMetadata(*this)) {
 
@@ -353,20 +355,21 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   BFloatTy = llvm::Type::getBFloatTy(LLVMContext);
   FloatTy = llvm::Type::getFloatTy(LLVMContext);
   DoubleTy = llvm::Type::getDoubleTy(LLVMContext);
-  PointerWidthInBits = C.getTargetInfo().getPointerWidth(LangAS::Default);
+  PointerWidthInBits = Target.getPointerWidth(LangAS::Default);
   PointerAlignInBytes =
-  C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(LangAS::Default))
+  C.toCharUnitsFromBits(Target.getPointerAlign(LangAS::Default))
   .getQuantity();
   SizeSizeInBytes =
-
C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity();
+C.toCharUnitsFromBits(Target.getMaxPointerWidth()).getQuantity();
   IntAlignInBytes =
-C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
+C.toCharUnitsFromBits(Target.getIntAlign()).getQuantity();
   CharTy =
-llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth());
-  IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
+llvm::IntegerType::get(LLVMContext, Target.getCharWidth());
+  IntTy = llvm::IntegerType::get(LLVMContext, Target.getIntWidth());
   IntPtrTy = llvm::IntegerType::get(LLVMContext,
-C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
+Target.getMaxPointerWidth());
+  Int8PtrTy = Int8Ty->getPointerTo(0);
+  Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
   llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
diff --git a/clang/lib/CodeGen/CodeGenModule.h 
b/clang/lib/CodeGen/CodeGenModule.h
index 1cc447765e2c97..7721941ce370af 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -613,7 +613,9 @@ class CodeGenModule : public CodeGenTypeCache {
   CodeGenModule(ASTContext &C, IntrusiveRefCntPtr FS,
 const HeaderSearchOptions &headersearchopts,
 const PreprocessorOptions &ppopts,
-const CodeGenOptions &Co

[clang] [NFC] Parameterize Initialization of `clang::CodeGenerator` on a `TargetInfo` instance which may differ from the one in the `ASTContext` (PR #88977)

2024-04-16 Thread Artem Chikin via cfe-commits

https://github.com/artemcm created 
https://github.com/llvm/llvm-project/pull/88977

A client's Clang instance may require to perform type-checking against one OS 
version and compilation/code-generation against an earlier version. This change 
allows such clients to configure their built-in Clang code-generator with a 
custom `TargetInfo`.

>From c86ee8d6fc2b0d3995f0dee4e7bc206ef6e05c8b Mon Sep 17 00:00:00 2001
From: Artem Chikin 
Date: Wed, 20 Dec 2023 10:56:42 -0800
Subject: [PATCH] [NFC] Parameterize Initialization of 'clang::CodeGenerator'
 on a TargetInfo instance which may differ from the one in the ASTContext

As per https://github.com/apple/swift/pull/65930, Swift compiler's built-in 
Clang instance may require to perform type-checking against one OS version and 
compilation/code-generation against an earlier version. This change allows 
Swift to configure it's built-in Clang code-generator with a custom 
'TargetInfo'.
---
 clang/include/clang/AST/ASTConsumer.h |  5 
 clang/lib/CodeGen/CodeGenModule.cpp   | 23 +++
 clang/lib/CodeGen/CodeGenModule.h |  4 +++-
 clang/lib/CodeGen/ModuleBuilder.cpp   | 17 +-
 .../ObjectFilePCHContainerOperations.cpp  |  3 ++-
 5 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index ebcd8059284d8d..774d19565e57b0 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -26,6 +26,7 @@ namespace clang {
   class VarDecl;
   class FunctionDecl;
   class ImportDecl;
+  class TargetInfo;
 
 /// ASTConsumer - This is an abstract interface that should be implemented by
 /// clients that read ASTs.  This abstraction layer allows the client to be
@@ -46,6 +47,10 @@ class ASTConsumer {
   /// ASTContext.
   virtual void Initialize(ASTContext &Context) {}
 
+  /// Initialize - This is called to initialize the consumer, providing the
+  /// ASTContext.
+  virtual void Initialize(ASTContext &Context, const TargetInfo 
&CodeGenTargetInfo) {}
+
   /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
   /// called by the parser to process every top-level Decl*.
   ///
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 0c447b20cef40d..52ff65c0986931 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -333,12 +333,14 @@ CodeGenModule::CodeGenModule(ASTContext &C,
  IntrusiveRefCntPtr FS,
  const HeaderSearchOptions &HSO,
  const PreprocessorOptions &PPO,
- const CodeGenOptions &CGO, llvm::Module &M,
+ const CodeGenOptions &CGO,
+ const TargetInfo &CGTI,
+ llvm::Module &M,
  DiagnosticsEngine &diags,
  CoverageSourceInfo *CoverageInfo)
 : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
   PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
-  Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
+  Target(CGTI), ABI(createCXXABI(*this)),
   VMContext(M.getContext()), Types(*this), VTables(*this),
   SanitizerMD(new SanitizerMetadata(*this)) {
 
@@ -353,20 +355,21 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   BFloatTy = llvm::Type::getBFloatTy(LLVMContext);
   FloatTy = llvm::Type::getFloatTy(LLVMContext);
   DoubleTy = llvm::Type::getDoubleTy(LLVMContext);
-  PointerWidthInBits = C.getTargetInfo().getPointerWidth(LangAS::Default);
+  PointerWidthInBits = Target.getPointerWidth(LangAS::Default);
   PointerAlignInBytes =
-  C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(LangAS::Default))
+  C.toCharUnitsFromBits(Target.getPointerAlign(LangAS::Default))
   .getQuantity();
   SizeSizeInBytes =
-
C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity();
+C.toCharUnitsFromBits(Target.getMaxPointerWidth()).getQuantity();
   IntAlignInBytes =
-C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
+C.toCharUnitsFromBits(Target.getIntAlign()).getQuantity();
   CharTy =
-llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth());
-  IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
+llvm::IntegerType::get(LLVMContext, Target.getCharWidth());
+  IntTy = llvm::IntegerType::get(LLVMContext, Target.getIntWidth());
   IntPtrTy = llvm::IntegerType::get(LLVMContext,
-C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
+Target.getMaxPointerWidth());
+  Int8PtrTy = Int8Ty->getPointerTo(0);
+  Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =