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