<div dir="ltr">Updated with 8487bfd4e9ae186f9f588ef989d27a96cc2438c9</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Oct 14, 2020 at 1:53 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Wed, 14 Oct 2020 at 12:31, Leonard Chan via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Leonard Chan<br>
Date: 2020-10-14T12:31:21-07:00<br>
New Revision: 683b308c07bf827255fe1403056413f790e03729<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/683b308c07bf827255fe1403056413f790e03729" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/683b308c07bf827255fe1403056413f790e03729</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/683b308c07bf827255fe1403056413f790e03729.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/683b308c07bf827255fe1403056413f790e03729.diff</a><br>
<br>
LOG: [clang] Add -fc++-abi= flag for specifying which C++ ABI to use<br>
<br>
This implements the flag proposed in RFC <a href="http://lists.llvm.org/pipermail/cfe-dev/2020-August/066437.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/cfe-dev/2020-August/066437.html</a>.<br>
<br>
The goal is to add a way to override the default target C++ ABI through<br>
a compiler flag. This makes it easier to test and transition between different<br>
C++ ABIs through compile flags rather than build flags.<br>
<br>
In this patch:<br>
- Store `-fc++-abi=` in a LangOpt. This isn't stored in a<br>
  CodeGenOpt because there are instances outside of codegen where Clang<br>
  needs to know what the ABI is (particularly through<br>
  ASTContext::createCXXABI), and we should be able to override the<br>
  target default if the flag is provided at that point.<br>
- Expose the existing ABIs in TargetCXXABI as values that can be passed<br>
  through this flag.<br>
  - Create a .def file for these ABIs to make it easier to check flag<br>
    values.<br>
  - Add an error for diagnosing bad ABI flag values.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D85802" rel="noreferrer" target="_blank">https://reviews.llvm.org/D85802</a><br>
<br>
Added: <br>
    clang/include/clang/Basic/TargetCXXABI.def<br>
    clang/test/Frontend/invalid-cxx-abi.cpp<br>
<br>
Modified: <br>
    clang/include/clang/AST/ASTContext.h<br>
    clang/include/clang/Basic/DiagnosticDriverKinds.td<br>
    clang/include/clang/Basic/LangOptions.h<br>
    clang/include/clang/Basic/TargetCXXABI.h<br>
    clang/include/clang/Driver/Options.td<br>
    clang/lib/AST/ASTContext.cpp<br>
    clang/lib/CodeGen/CodeGenModule.cpp<br>
    clang/lib/CodeGen/ItaniumCXXABI.cpp<br>
    clang/lib/Driver/ToolChains/Clang.cpp<br>
    clang/lib/Frontend/CompilerInvocation.cpp<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h<br>
index 3f4079e2569b..e5c80866a0a9 100644<br>
--- a/clang/include/clang/AST/ASTContext.h<br>
+++ b/clang/include/clang/AST/ASTContext.h<br>
@@ -39,6 +39,7 @@<br>
 #include "clang/Basic/SanitizerBlacklist.h"<br>
 #include "clang/Basic/SourceLocation.h"<br>
 #include "clang/Basic/Specifiers.h"<br>
+#include "clang/Basic/TargetCXXABI.h"<br>
 #include "clang/Basic/XRayLists.h"<br>
 #include "llvm/ADT/APSInt.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
@@ -697,6 +698,11 @@ class ASTContext : public RefCountedBase<ASTContext> {<br>
     return FullSourceLoc(Loc,SourceMgr);<br>
   }<br>
<br>
+  /// Return the C++ ABI kind that should be used. The C++ ABI can be overriden<br>
+  /// at compile time with `-fc++-abi=`. If this is not provided, we instead use<br>
+  /// the default ABI set by the target.<br>
+  TargetCXXABI::Kind getCXXABIKind() const;<br>
+<br>
   /// All comments in this translation unit.<br>
   RawCommentList Comments;<br>
<br>
<br>
diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td<br>
index 29bc19e5a84e..f1b3d4d9087e 100644<br>
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td<br>
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td<br>
@@ -524,4 +524,6 @@ def err_drv_invalid_object_mode : Error<"OBJECT_MODE setting %0 is not recognize<br>
<br>
 def err_drv_invalid_sve_vector_bits : Error<<br>
   "'-msve-vector-bits' is not supported without SVE enabled">;<br>
+<br>
+def err_invalid_cxx_abi : Error<"Invalid C++ ABI name '%0'">;<br></blockquote><div><br></div><div>Diagnostics should start with a lowercase letter.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 }<br>
<br>
diff  --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h<br>
index 84d25c359c55..147fab614308 100644<br>
--- a/clang/include/clang/Basic/LangOptions.h<br>
+++ b/clang/include/clang/Basic/LangOptions.h<br>
@@ -18,6 +18,7 @@<br>
 #include "clang/Basic/LLVM.h"<br>
 #include "clang/Basic/ObjCRuntime.h"<br>
 #include "clang/Basic/Sanitizers.h"<br>
+#include "clang/Basic/TargetCXXABI.h"<br>
 #include "clang/Basic/Visibility.h"<br>
 #include "llvm/ADT/FloatingPointMode.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
@@ -294,6 +295,10 @@ class LangOptions : public LangOptionsBase {<br>
   /// host code generation.<br>
   std::string OMPHostIRFile;<br>
<br>
+  /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.<br>
+  /// This overrides the default ABI used by the target.<br>
+  llvm::Optional<TargetCXXABI::Kind> CXXABI;<br>
+<br>
   /// Indicates whether the front-end is explicitly told that the<br>
   /// input is a header file (i.e. -x c-header).<br>
   bool IsHeaderFile = false;<br>
<br>
diff  --git a/clang/include/clang/Basic/TargetCXXABI.def b/clang/include/clang/Basic/TargetCXXABI.def<br>
new file mode 100644<br>
index 000000000000..0ae0bb555f60<br>
--- /dev/null<br>
+++ b/clang/include/clang/Basic/TargetCXXABI.def<br>
@@ -0,0 +1,129 @@<br>
+//===--- TargetCXXABI.def - Target C++ ABI database --------------- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines the various C++ ABI kinds used on <br>
diff erent platforms.<br>
+// Users of this file must define the CXXABI macro to make use of this<br>
+// information.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef CXXABI<br>
+#error Define the CXXABI macro to handle C++ ABI kinds.<br>
+#endif<br>
+<br>
+#ifndef ITANIUM_CXXABI<br>
+#define ITANIUM_CXXABI(Name, Str) CXXABI(Name, Str)<br>
+#endif<br>
+<br>
+#ifndef MICROSOFT_CXXABI<br>
+#define MICROSOFT_CXXABI(Name, Str) CXXABI(Name, Str)<br>
+#endif<br>
+<br>
+/// The generic Itanium ABI is the standard ABI of most open-source<br>
+/// and Unix-like platforms.  It is the primary ABI targeted by<br>
+/// many compilers, including Clang and GCC.<br>
+///<br>
+/// It is documented here:<br>
+///   <a href="http://www.codesourcery.com/public/cxx-abi/" rel="noreferrer" target="_blank">http://www.codesourcery.com/public/cxx-abi/</a><br>
+ITANIUM_CXXABI(GenericItanium, "itanium")<br>
+<br>
+/// The generic ARM ABI is a modified version of the Itanium ABI<br>
+/// proposed by ARM for use on ARM-based platforms.<br>
+///<br>
+/// These changes include:<br>
+///   - the representation of member function pointers is adjusted<br>
+///     to not conflict with the 'thumb' bit of ARM function pointers;<br>
+///   - constructors and destructors return 'this';<br>
+///   - guard variables are smaller;<br>
+///   - inline functions are never key functions;<br>
+///   - array cookies have a slightly <br>
diff erent layout; </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+///   - additional convenience functions are specified;<br>
+///   - and more!<br>
+///<br>
+/// It is documented here:<br>
+///    <a href="http://infocenter.arm.com" rel="noreferrer" target="_blank">http://infocenter.arm.com</a><br>
+///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf<br>
+ITANIUM_CXXABI(GenericARM, "arm")<br>
+<br>
+/// The iOS ABI is a partial implementation of the ARM ABI.<br>
+/// Several of the features of the ARM ABI were not fully implemented<br>
+/// in the compilers that iOS was launched with.<br>
+///<br>
+/// Essentially, the iOS ABI includes the ARM changes to:<br>
+///   - member function pointers,<br>
+///   - guard variables,<br>
+///   - array cookies, and<br>
+///   - constructor/destructor signatures.<br>
+ITANIUM_CXXABI(iOS, "ios")<br>
+<br>
+/// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more<br>
+/// closely, but we don't guarantee to follow it perfectly.<br>
+///<br>
+/// It is documented here:<br>
+///    <a href="http://infocenter.arm.com" rel="noreferrer" target="_blank">http://infocenter.arm.com</a><br>
+///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf<br>
+ITANIUM_CXXABI(iOS64, "ios64")<br>
+<br>
+/// WatchOS is a modernisation of the iOS ABI, which roughly means it's<br>
+/// the iOS64 ABI ported to 32-bits. The primary <br>
diff erence from iOS64 is </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+/// that RTTI objects must still be unique at the moment.<br>
+ITANIUM_CXXABI(WatchOS, "watchos")<br>
+<br>
+/// The generic AArch64 ABI is also a modified version of the Itanium ABI,<br>
+/// but it has fewer divergences than the 32-bit ARM ABI.<br>
+///<br>
+/// The relevant changes from the generic ABI in this case are:<br>
+///   - representation of member function pointers adjusted as in ARM.<br>
+///   - guard variables  are smaller.<br>
+ITANIUM_CXXABI(GenericAArch64, "aarch64")<br>
+<br>
+/// The generic Mips ABI is a modified version of the Itanium ABI.<br>
+///<br>
+/// At the moment, only change from the generic ABI in this case is:<br>
+///   - representation of member function pointers adjusted as in ARM.<br>
+ITANIUM_CXXABI(GenericMIPS, "mips")<br>
+<br>
+/// The WebAssembly ABI is a modified version of the Itanium ABI.<br>
+///<br>
+/// The changes from the Itanium ABI are:<br>
+///   - representation of member function pointers is adjusted, as in ARM;<br>
+///   - member functions are not specially aligned;<br>
+///   - constructors and destructors return 'this', as in ARM;<br>
+///   - guard variables are 32-bit on wasm32, as in ARM;<br>
+///   - unused bits of guard variables are reserved, as in ARM;<br>
+///   - inline functions are never key functions, as in ARM;<br>
+///   - C++11 POD rules are used for tail padding, as in iOS64.<br>
+///<br>
+/// TODO: At present the WebAssembly ABI is not considered stable, so none<br>
+/// of these details is necessarily final yet.<br>
+ITANIUM_CXXABI(WebAssembly, "webassembly")<br>
+<br>
+/// The Fuchsia ABI is a modified version of the Itanium ABI.<br>
+///<br>
+/// The relevant changes from the Itanium ABI are:<br>
+///   - constructors and destructors return 'this', as in ARM.<br>
+ITANIUM_CXXABI(Fuchsia, "fuchsia")<br>
+<br>
+/// The XL ABI is the ABI used by IBM xlclang compiler and is a modified<br>
+/// version of the Itanium ABI.<br>
+///<br>
+/// The relevant changes from the Itanium ABI are:<br>
+///   - static initialization is adjusted to use sinit and sterm functions;<br>
+ITANIUM_CXXABI(XL, "xl")<br>
+<br>
+/// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and<br>
+/// compatible compilers).<br>
+///<br>
+/// FIXME: should this be split into Win32 and Win64 variants?<br>
+///<br>
+/// Only scattered and incomplete official documentation exists.<br>
+MICROSOFT_CXXABI(Microsoft, "microsoft")<br>
+<br>
+#undef CXXABI<br>
+#undef ITANIUM_CXXABI<br>
+#undef MICROSOFT_CXXABI<br>
<br>
diff  --git a/clang/include/clang/Basic/TargetCXXABI.h b/clang/include/clang/Basic/TargetCXXABI.h<br>
index 93f70fc70dd8..ed6438a9b236 100644<br>
--- a/clang/include/clang/Basic/TargetCXXABI.h<br>
+++ b/clang/include/clang/Basic/TargetCXXABI.h<br>
@@ -15,6 +15,7 @@<br>
 #ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H<br>
 #define LLVM_CLANG_BASIC_TARGETCXXABI_H<br>
<br>
+#include "llvm/ADT/StringMap.h"<br>
 #include "llvm/Support/ErrorHandling.h"<br>
<br>
 namespace clang {<br>
@@ -24,105 +25,8 @@ class TargetCXXABI {<br>
 public:<br>
   /// The basic C++ ABI kind.<br>
   enum Kind {<br>
-    /// The generic Itanium ABI is the standard ABI of most open-source<br>
-    /// and Unix-like platforms.  It is the primary ABI targeted by<br>
-    /// many compilers, including Clang and GCC.<br>
-    ///<br>
-    /// It is documented here:<br>
-    ///   <a href="http://www.codesourcery.com/public/cxx-abi/" rel="noreferrer" target="_blank">http://www.codesourcery.com/public/cxx-abi/</a><br>
-    GenericItanium,<br>
-<br>
-    /// The generic ARM ABI is a modified version of the Itanium ABI<br>
-    /// proposed by ARM for use on ARM-based platforms.<br>
-    ///<br>
-    /// These changes include:<br>
-    ///   - the representation of member function pointers is adjusted<br>
-    ///     to not conflict with the 'thumb' bit of ARM function pointers;<br>
-    ///   - constructors and destructors return 'this';<br>
-    ///   - guard variables are smaller;<br>
-    ///   - inline functions are never key functions;<br>
-    ///   - array cookies have a slightly <br>
diff erent layout;<br>
-    ///   - additional convenience functions are specified;<br>
-    ///   - and more!<br>
-    ///<br>
-    /// It is documented here:<br>
-    ///    <a href="http://infocenter.arm.com" rel="noreferrer" target="_blank">http://infocenter.arm.com</a><br>
-    ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf<br>
-    GenericARM,<br>
-<br>
-    /// The iOS ABI is a partial implementation of the ARM ABI.<br>
-    /// Several of the features of the ARM ABI were not fully implemented<br>
-    /// in the compilers that iOS was launched with.<br>
-    ///<br>
-    /// Essentially, the iOS ABI includes the ARM changes to:<br>
-    ///   - member function pointers,<br>
-    ///   - guard variables,<br>
-    ///   - array cookies, and<br>
-    ///   - constructor/destructor signatures.<br>
-    iOS,<br>
-<br>
-    /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more<br>
-    /// closely, but we don't guarantee to follow it perfectly.<br>
-    ///<br>
-    /// It is documented here:<br>
-    ///    <a href="http://infocenter.arm.com" rel="noreferrer" target="_blank">http://infocenter.arm.com</a><br>
-    ///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf<br>
-    iOS64,<br>
-<br>
-    /// WatchOS is a modernisation of the iOS ABI, which roughly means it's<br>
-    /// the iOS64 ABI ported to 32-bits. The primary <br>
diff erence from iOS64 is<br>
-    /// that RTTI objects must still be unique at the moment.<br>
-    WatchOS,<br>
-<br>
-    /// The generic AArch64 ABI is also a modified version of the Itanium ABI,<br>
-    /// but it has fewer divergences than the 32-bit ARM ABI.<br>
-    ///<br>
-    /// The relevant changes from the generic ABI in this case are:<br>
-    ///   - representation of member function pointers adjusted as in ARM.<br>
-    ///   - guard variables  are smaller.<br>
-    GenericAArch64,<br>
-<br>
-    /// The generic Mips ABI is a modified version of the Itanium ABI.<br>
-    ///<br>
-    /// At the moment, only change from the generic ABI in this case is:<br>
-    ///   - representation of member function pointers adjusted as in ARM.<br>
-    GenericMIPS,<br>
-<br>
-    /// The WebAssembly ABI is a modified version of the Itanium ABI.<br>
-    ///<br>
-    /// The changes from the Itanium ABI are:<br>
-    ///   - representation of member function pointers is adjusted, as in ARM;<br>
-    ///   - member functions are not specially aligned;<br>
-    ///   - constructors and destructors return 'this', as in ARM;<br>
-    ///   - guard variables are 32-bit on wasm32, as in ARM;<br>
-    ///   - unused bits of guard variables are reserved, as in ARM;<br>
-    ///   - inline functions are never key functions, as in ARM;<br>
-    ///   - C++11 POD rules are used for tail padding, as in iOS64.<br>
-    ///<br>
-    /// TODO: At present the WebAssembly ABI is not considered stable, so none<br>
-    /// of these details is necessarily final yet.<br>
-    WebAssembly,<br>
-<br>
-    /// The Fuchsia ABI is a modified version of the Itanium ABI.<br>
-    ///<br>
-    /// The relevant changes from the Itanium ABI are:<br>
-    ///   - constructors and destructors return 'this', as in ARM.<br>
-    Fuchsia,<br>
-<br>
-    /// The XL ABI is the ABI used by IBM xlclang compiler and is a modified<br>
-    /// version of the Itanium ABI.<br>
-    ///<br>
-    /// The relevant changes from the Itanium ABI are:<br>
-    ///   - static initialization is adjusted to use sinit and sterm functions;<br>
-    XL,<br>
-<br>
-    /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and<br>
-    /// compatible compilers).<br>
-    ///<br>
-    /// FIXME: should this be split into Win32 and Win64 variants?<br>
-    ///<br>
-    /// Only scattered and incomplete official documentation exists.<br>
-    Microsoft<br>
+#define CXXABI(Name, Str) Name,<br>
+#include "TargetCXXABI.def"<br>
   };<br>
<br>
 private:<br>
@@ -131,7 +35,20 @@ class TargetCXXABI {<br>
   // audit the users to pass it by reference instead.<br>
   Kind TheKind;<br>
<br>
+  static const auto &getABIMap() {<br>
+    static llvm::StringMap<Kind> ABIMap = {<br>
+#define CXXABI(Name, Str) {Str, Name},<br>
+#include "TargetCXXABI.def"<br>
+    };<br>
+    return ABIMap;<br>
+  }<br>
+<br>
 public:<br>
+  static Kind getKind(StringRef Name) { return getABIMap().lookup(Name); }<br>
+  static bool isABI(StringRef Name) {<br>
+    return getABIMap().find(Name) != getABIMap().end();<br>
+  }<br>
+<br>
   /// A bogus initialization of the platform ABI.<br>
   TargetCXXABI() : TheKind(GenericItanium) {}<br>
<br>
@@ -146,19 +63,11 @@ class TargetCXXABI {<br>
   /// Does this ABI generally fall into the Itanium family of ABIs?<br>
   bool isItaniumFamily() const {<br>
     switch (getKind()) {<br>
-    case Fuchsia:<br>
-    case GenericAArch64:<br>
-    case GenericItanium:<br>
-    case GenericARM:<br>
-    case iOS:<br>
-    case iOS64:<br>
-    case WatchOS:<br>
-    case GenericMIPS:<br>
-    case WebAssembly:<br>
-    case XL:<br>
+#define CXXABI(Name, Str)<br>
+#define ITANIUM_CXXABI(Name, Str) case Name:<br>
+#include "TargetCXXABI.def"<br>
       return true;<br>
-<br>
-    case Microsoft:<br>
+    default:<br>
       return false;<br>
     }<br>
     llvm_unreachable("bad ABI kind");<br>
@@ -167,20 +76,12 @@ class TargetCXXABI {<br>
   /// Is this ABI an MSVC-compatible ABI?<br>
   bool isMicrosoft() const {<br>
     switch (getKind()) {<br>
-    case Fuchsia:<br>
-    case GenericAArch64:<br>
-    case GenericItanium:<br>
-    case GenericARM:<br>
-    case iOS:<br>
-    case iOS64:<br>
-    case WatchOS:<br>
-    case GenericMIPS:<br>
-    case WebAssembly:<br>
-    case XL:<br>
-      return false;<br>
-<br>
-    case Microsoft:<br>
+#define CXXABI(Name, Str)<br>
+#define MICROSOFT_CXXABI(Name, Str) case Name:<br>
+#include "TargetCXXABI.def"<br>
       return true;<br>
+    default:<br>
+      return false;<br>
     }<br>
     llvm_unreachable("bad ABI kind");<br>
   }<br>
<br>
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td<br>
index 34868bd31115..0365657bf728 100644<br>
--- a/clang/include/clang/Driver/Options.td<br>
+++ b/clang/include/clang/Driver/Options.td<br>
@@ -1371,6 +1371,10 @@ def fno_experimental_relative_cxx_abi_vtables : Flag<["-"], "fno-experimental-re<br>
   Group<f_Group>, Flags<[CC1Option]>,<br>
   HelpText<"Do not use the experimental C++ class ABI for classes with virtual tables">;<br>
<br>
+def fcxx_abi_EQ : Joined<["-"], "fc++-abi=">,<br>
+                  Group<f_clang_Group>, Flags<[CC1Option]>,<br>
+                  HelpText<"C++ ABI to use. This will override the target C++ ABI.">;<br>
+<br>
 def flat__namespace : Flag<["-"], "flat_namespace">;<br>
 def flax_vector_conversions_EQ : Joined<["-"], "flax-vector-conversions=">, Group<f_Group>,<br>
   HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">, Flags<[CC1Option]>;<br>
<br>
diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp<br>
index 8caff6b33379..f3680d7adfee 100644<br>
--- a/clang/lib/AST/ASTContext.cpp<br>
+++ b/clang/lib/AST/ASTContext.cpp<br>
@@ -879,10 +879,15 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(<br>
   return CanonTTP;<br>
 }<br>
<br>
+TargetCXXABI::Kind ASTContext::getCXXABIKind() const {<br>
+  auto Kind = getTargetInfo().getCXXABI().getKind();<br>
+  return getLangOpts().CXXABI.getValueOr(Kind);<br>
+}<br>
+<br>
 CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {<br>
   if (!LangOpts.CPlusPlus) return nullptr;<br>
<br>
-  switch (T.getCXXABI().getKind()) {<br>
+  switch (getCXXABIKind()) {<br>
   case TargetCXXABI::Fuchsia:<br>
   case TargetCXXABI::GenericARM: // Same as Itanium at this level<br>
   case TargetCXXABI::iOS:<br>
<br>
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp<br>
index 93b49ec981e8..aaf20ea5e41c 100644<br>
--- a/clang/lib/CodeGen/CodeGenModule.cpp<br>
+++ b/clang/lib/CodeGen/CodeGenModule.cpp<br>
@@ -75,19 +75,14 @@ static llvm::cl::opt<bool> LimitedCoverage(<br>
 static const char AnnotationSection[] = "llvm.metadata";<br>
<br>
 static CGCXXABI *createCXXABI(CodeGenModule &CGM) {<br>
-  switch (CGM.getTarget().getCXXABI().getKind()) {<br>
-  case TargetCXXABI::Fuchsia:<br>
-  case TargetCXXABI::GenericAArch64:<br>
-  case TargetCXXABI::GenericARM:<br>
-  case TargetCXXABI::iOS:<br>
-  case TargetCXXABI::iOS64:<br>
-  case TargetCXXABI::WatchOS:<br>
-  case TargetCXXABI::GenericMIPS:<br>
-  case TargetCXXABI::GenericItanium:<br>
-  case TargetCXXABI::WebAssembly:<br>
-  case TargetCXXABI::XL:<br>
+  switch (CGM.getContext().getCXXABIKind()) {<br>
+#define ITANIUM_CXXABI(Name, Str) case TargetCXXABI::Name:<br>
+#define CXXABI(Name, Str)<br>
+#include "clang/Basic/TargetCXXABI.def"<br>
     return CreateItaniumCXXABI(CGM);<br>
-  case TargetCXXABI::Microsoft:<br>
+#define MICROSOFT_CXXABI(Name, Str) case TargetCXXABI::Name:<br>
+#define CXXABI(Name, Str)<br>
+#include "clang/Basic/TargetCXXABI.def"<br>
     return CreateMicrosoftCXXABI(CGM);<br>
   }<br>
<br>
<br>
diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp<br>
index cfb736ce0ff1..d4fe0ce5cbcb 100644<br>
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp<br>
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp<br>
@@ -542,7 +542,7 @@ class XLCXXABI final : public ItaniumCXXABI {<br>
 }<br>
<br>
 CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {<br>
-  switch (CGM.getTarget().getCXXABI().getKind()) {<br>
+  switch (CGM.getContext().getCXXABIKind()) {<br>
   // For IR-generation purposes, there's no significant <br>
diff erence<br>
   // between the ARM and iOS ABIs.<br>
   case TargetCXXABI::GenericARM:<br>
<br>
diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp<br>
index d16de8928ec1..39fcf240449c 100644<br>
--- a/clang/lib/Driver/ToolChains/Clang.cpp<br>
+++ b/clang/lib/Driver/ToolChains/Clang.cpp<br>
@@ -5029,6 +5029,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,<br>
                    /*Default=*/false))<br>
     Args.AddLastArg(CmdArgs, options::OPT_ffixed_point);<br>
<br>
+  if (Arg *A = Args.getLastArg(options::OPT_fcxx_abi_EQ))<br>
+    A->render(Args, CmdArgs);<br>
+<br>
   // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}<br>
   // (-ansi is equivalent to -std=c89 or -std=c++98).<br>
   //<br>
<br>
diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp<br>
index a4c56cc4e51e..13320ebb03c5 100644<br>
--- a/clang/lib/Frontend/CompilerInvocation.cpp<br>
+++ b/clang/lib/Frontend/CompilerInvocation.cpp<br>
@@ -3513,6 +3513,15 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,<br>
       Args.hasFlag(OPT_fexperimental_relative_cxx_abi_vtables,<br>
                    OPT_fno_experimental_relative_cxx_abi_vtables,<br>
                    /*default=*/false);<br>
+<br>
+  // The value can be empty, which indicates the system default should be used.<br>
+  StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);<br>
+  if (!CXXABI.empty()) {<br>
+    if (!TargetCXXABI::isABI(CXXABI))<br>
+      Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;<br>
+    else<br>
+      Opts.CXXABI = TargetCXXABI::getKind(CXXABI);<br>
+  }<br>
 }<br>
<br>
 static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {<br>
<br>
diff  --git a/clang/test/Frontend/invalid-cxx-abi.cpp b/clang/test/Frontend/invalid-cxx-abi.cpp<br>
new file mode 100644<br>
index 000000000000..20c6d7bde22c<br>
--- /dev/null<br>
+++ b/clang/test/Frontend/invalid-cxx-abi.cpp<br>
@@ -0,0 +1,16 @@<br>
+// These should succeed.<br>
+// RUN: %clang_cc1 -fc++-abi=itanium %s<br>
+// RUN: %clang_cc1 -fc++-abi=arm %s<br>
+// RUN: %clang_cc1 -fc++-abi=ios %s<br>
+// RUN: %clang_cc1 -fc++-abi=ios64 %s<br>
+// RUN: %clang_cc1 -fc++-abi=aarch64 %s<br>
+// RUN: %clang_cc1 -fc++-abi=mips %s<br>
+// RUN: %clang_cc1 -fc++-abi=webassembly %s<br>
+// RUN: %clang_cc1 -fc++-abi=fuchsia %s<br>
+// RUN: %clang_cc1 -fc++-abi=xl %s<br>
+// RUN: %clang_cc1 -fc++-abi=microsoft %s<br>
+<br>
+// RUN: not %clang_cc1 -fc++-abi=InvalidABI %s 2>&1 | FileCheck %s -check-prefix=INVALID<br>
+// RUN: not %clang_cc1 -fc++-abi=Fuchsia %s 2>&1 | FileCheck %s -check-prefix=CASE-SENSITIVE<br>
+// INVALID: error: Invalid C++ ABI name 'InvalidABI'<br>
+// CASE-SENSITIVE: error: Invalid C++ ABI name 'Fuchsia'<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div>
</blockquote></div>