From: David Majnemer Date: Thu, 8 Oct 2015 04:53:31 +0000 (+0000) Subject: [MSVC Compat] Enable ABI impacting non-conforming behavior independently of -fms... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e1572f4b7678ac8a7a1ecde247b2d765b5ebdee2;p=clang [MSVC Compat] Enable ABI impacting non-conforming behavior independently of -fms-compatibility No ABI for C++ currently makes it possible to implement the standard 100% perfectly. We wrongly hid some of our compatible behavior behind -fms-compatibility instead of tying it to the compiler ABI. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@249656 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 47d0107a66..ffa8cbbf6c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -5033,9 +5033,10 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { } bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { - return getLangOpts().MSVCCompat && VD->isStaticDataMember() && - VD->getType()->isIntegralOrEnumerationType() && - VD->isFirstDecl() && !VD->isOutOfLine() && VD->hasInit(); + return getTargetInfo().getCXXABI().isMicrosoft() && + VD->isStaticDataMember() && + VD->getType()->isIntegralOrEnumerationType() && VD->isFirstDecl() && + !VD->isOutOfLine() && VD->hasInit(); } static inline @@ -8270,7 +8271,8 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, if (!FD->isInlined()) return External; - if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat && + if ((!Context.getLangOpts().CPlusPlus && + !Context.getTargetInfo().getCXXABI().isMicrosoft() && !FD->hasAttr()) || FD->hasAttr()) { // FIXME: This doesn't match gcc's behavior for dllexport inline functions. @@ -8346,7 +8348,8 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, return GVA_StrongExternal; case TSK_ExplicitSpecialization: - return Context.getLangOpts().MSVCCompat && VD->isStaticDataMember() + return Context.getTargetInfo().getCXXABI().isMicrosoft() && + VD->isStaticDataMember() ? GVA_StrongODR : GVA_StrongExternal; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 594cfa359c..098298f0c5 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2703,7 +2703,8 @@ bool FunctionDecl::isMSExternInline() const { assert(isInlined() && "expected to get called on an inlined function!"); const ASTContext &Context = getASTContext(); - if (!Context.getLangOpts().MSVCCompat && !hasAttr()) + if (!Context.getTargetInfo().getCXXABI().isMicrosoft() && + !hasAttr()) return false; for (const FunctionDecl *FD = getMostRecentDecl(); FD; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 9e9963cd19..40eb678d58 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2386,7 +2386,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, // Declarations with a required alignment do not have common linakge in MSVC // mode. - if (Context.getLangOpts().MSVCCompat) { + if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { if (D->hasAttr()) return true; QualType VarType = D->getType(); diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index b73d332ff4..0be5c5592b 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -175,7 +175,7 @@ namespace { // For MSVC compatibility, treat declarations of static data members with // inline initializers as definitions. - if (Ctx->getLangOpts().MSVCCompat) { + if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) { for (Decl *Member : D->decls()) { if (VarDecl *VD = dyn_cast(Member)) { if (Ctx->isMSStaticDataMemberInlineDefinition(VD) && diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 467b36dfee..23d4491d04 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -11768,9 +11768,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, UPPC_FixedUnderlyingType)) EnumUnderlying = Context.IntTy.getTypePtr(); - } else if (getLangOpts().MSVCCompat) + } else if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { // Microsoft enums are always of int type. EnumUnderlying = Context.IntTy.getTypePtr(); + } } DeclContext *SearchDC = CurContext; diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c index 16e95c03c8..fe7efe36e6 100644 --- a/test/CodeGen/inline.c +++ b/test/CodeGen/inline.c @@ -53,7 +53,7 @@ // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv() // RUN: echo "MS C Mode tests:" -// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-optzns -emit-llvm -o - -std=c99 -fms-compatibility | FileCheck %s --check-prefix=CHECK4 +// RUN: %clang_cc1 %s -triple i386-pc-win32 -O1 -disable-llvm-optzns -emit-llvm -o - -std=c99 | FileCheck %s --check-prefix=CHECK4 // CHECK4-NOT: define weak_odr void @_Exit( // CHECK4-LABEL: define weak_odr i32 @ei() // CHECK4-LABEL: define i32 @bar() diff --git a/test/CodeGenCXX/inline-functions.cpp b/test/CodeGenCXX/inline-functions.cpp index 20da1f6318..f1169f9191 100644 --- a/test/CodeGenCXX/inline-functions.cpp +++ b/test/CodeGenCXX/inline-functions.cpp @@ -1,12 +1,13 @@ // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NORMAL -// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSVCCOMPAT +// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -triple=x86_64-pc-win32 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSVCCOMPAT // CHECK: ; ModuleID struct A { inline void f(); }; -// CHECK-NOT: define void @_ZN1A1fEv +// NORMAL-NOT: define void @_ZN1A1fEv +// MSVCCOMPAT-NOT: define void @"\01?f@A@@QEAAXXZ" void A::f() { } template struct B { }; @@ -15,18 +16,21 @@ template<> struct B { inline void f(); }; -// CHECK-NOT: _ZN1BIcE1fEv +// NORMAL-NOT: _ZN1BIcE1fEv +// MSVCCOMPAT-NOT: @"\01?f@?$B@D@@QEAAXXZ" void B::f() { } // We need a final CHECK line here. -// CHECK-LABEL: define void @_Z1fv +// NORMAL-LABEL: define void @_Z1fv +// MSVCCOMPAT-LABEL: define void @"\01?f@@YAXXZ" void f() { } // inline void f1(int); -// CHECK-LABEL: define linkonce_odr void @_Z2f1i +// NORMAL-LABEL: define linkonce_odr void @_Z2f1i +// MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f1@@YAXH@Z" void f1(int) { } void test_f1() { f1(17); } @@ -39,7 +43,8 @@ namespace test1 { void g() {} }; - // CHECK-LABEL: define linkonce_odr void @_ZN5test11C4funcEv( + // NORMAL-LABEL: define linkonce_odr void @_ZN5test11C4funcEv( + // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?func@C@test1@@QEAAXXZ"( class C { public: @@ -66,59 +71,65 @@ namespace test2 { A a; f(a); } - // CHECK-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE + // NORMAL-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE + // MSVCCOMPAT-LABEL: define linkonce_odr void @"\01?f@test2@@YAXAEBUA@1@@Z" } -// MSVCCOMPAT-LABEL: define weak_odr void @_Z17ExternAndInlineFnv // NORMAL-NOT: _Z17ExternAndInlineFnv +// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternAndInlineFn@@YAXXZ" extern inline void ExternAndInlineFn() {} -// MSVCCOMPAT-LABEL: define weak_odr void @_Z18InlineThenExternFnv // NORMAL-NOT: _Z18InlineThenExternFnv +// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternFn@@YAXXZ" inline void InlineThenExternFn() {} extern void InlineThenExternFn(); -// CHECK-LABEL: define void @_Z18ExternThenInlineFnv +// NORMAL-LABEL: define void @_Z18ExternThenInlineFnv +// MSVCCOMPAT-LABEL: define void @"\01?ExternThenInlineFn@@YAXXZ" extern void ExternThenInlineFn() {} -// MSVCCOMPAT-LABEL: define weak_odr void @_Z25ExternThenInlineThenDefFnv // NORMAL-NOT: _Z25ExternThenInlineThenDefFnv +// MSVCCOMPAT-LABEL: define weak_odr void @"\01?ExternThenInlineThenDefFn@@YAXXZ" extern void ExternThenInlineThenDefFn(); inline void ExternThenInlineThenDefFn(); void ExternThenInlineThenDefFn() {} -// MSVCCOMPAT-LABEL: define weak_odr void @_Z25InlineThenExternThenDefFnv // NORMAL-NOT: _Z25InlineThenExternThenDefFnv +// MSVCCOMPAT-LABEL: define weak_odr void @"\01?InlineThenExternThenDefFn@@YAXXZ" inline void InlineThenExternThenDefFn(); extern void InlineThenExternThenDefFn(); void InlineThenExternThenDefFn() {} -// MSVCCOMPAT-LABEL: define weak_odr i32 @_Z20ExternAndConstexprFnv // NORMAL-NOT: _Z17ExternAndConstexprFnv +// MSVCCOMPAT-LABEL: define weak_odr i32 @"\01?ExternAndConstexprFn@@YAHXZ" extern constexpr int ExternAndConstexprFn() { return 0; } -// CHECK-NOT: _Z11ConstexprFnv +// NORMAL-NOT: _Z11ConstexprFnv +// MSVCCOMPAT-NOT: @"\01?ConstexprFn@@YAHXZ" constexpr int ConstexprFn() { return 0; } template extern inline void ExternInlineOnPrimaryTemplate(T); -// CHECK-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_ +// NORMAL-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_ +// MSVCCOMPAT-LABEL: define void @"\01??$ExternInlineOnPrimaryTemplate@H@@YAXH@Z" template <> void ExternInlineOnPrimaryTemplate(int) {} template extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(T); -// MSVCCOMPAT-LABEL: define weak_odr void @_Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_ // NORMAL-NOT: _Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_ +// MSVCCOMPAT-LABEL: define weak_odr void @"\01??$ExternInlineOnPrimaryTemplateAndSpecialization@H@@YAXH@Z" template <> extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(int) {} struct TypeWithInlineMethods { - // CHECK-NOT: _ZN21TypeWithInlineMethods9StaticFunEv + // NORMAL-NOT: _ZN21TypeWithInlineMethods9StaticFunEv + // MSVCCOMPAT-NOT: @"\01?StaticFun@TypeWithInlineMethods@@SAXXZ" static void StaticFun() {} - // CHECK-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv + // NORMAL-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv + // MSVCCOMPAT-NOT: @"\01?NonStaticFun@TypeWithInlineMethods@@QEAAXXZ" void NonStaticFun() { StaticFun(); } }; @@ -134,5 +145,6 @@ struct S { }; __attribute__((used)) inline S Foo() { return S(); } -// CHECK-LABEL: define linkonce_odr void @_ZN7PR229593FooEv( +// NORMAL-LABEL: define linkonce_odr void @_ZN7PR229593FooEv( +// MSVCCOMPAT-LABEL: define linkonce_odr i8 @"\01?Foo@PR22959@@YA?AU?$S@H@1@XZ"( }