summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-10-08 04:53:31 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-10-08 04:53:31 +0000
commit3f02150d316dd8d468c5750fe894da3ffcc9a8a8 (patch)
tree520a1a74813218dd1709147e41e9930fa4e36d71 /clang
parent3459ce2e5ebbabb8d4dde3809da50dc89e1b0b35 (diff)
downloadbcm5719-llvm-3f02150d316dd8d468c5750fe894da3ffcc9a8a8.tar.gz
bcm5719-llvm-3f02150d316dd8d468c5750fe894da3ffcc9a8a8.zip
[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. llvm-svn: 249656
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ASTContext.cpp13
-rw-r--r--clang/lib/AST/Decl.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp3
-rw-r--r--clang/test/CodeGen/inline.c2
-rw-r--r--clang/test/CodeGenCXX/inline-functions.cpp50
7 files changed, 46 insertions, 29 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 47d0107a66d..ffa8cbbf6c5 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/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<DLLExportAttr>()) ||
FD->hasAttr<GNUInlineAttr>()) {
// 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/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 594cfa359c5..098298f0c59 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/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<DLLExportAttr>())
+ if (!Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ !hasAttr<DLLExportAttr>())
return false;
for (const FunctionDecl *FD = getMostRecentDecl(); FD;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 9e9963cd192..40eb678d585 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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<AlignedAttr>())
return true;
QualType VarType = D->getType();
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index b73d332ff4d..0be5c5592b2 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/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<VarDecl>(Member)) {
if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 467b36dfeec..23d4491d04c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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/clang/test/CodeGen/inline.c b/clang/test/CodeGen/inline.c
index 16e95c03c87..fe7efe36e65 100644
--- a/clang/test/CodeGen/inline.c
+++ b/clang/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/clang/test/CodeGenCXX/inline-functions.cpp b/clang/test/CodeGenCXX/inline-functions.cpp
index 20da1f63180..f1169f91913 100644
--- a/clang/test/CodeGenCXX/inline-functions.cpp
+++ b/clang/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<typename> struct B { };
@@ -15,18 +16,21 @@ template<> struct B<char> {
inline void f();
};
-// CHECK-NOT: _ZN1BIcE1fEv
+// NORMAL-NOT: _ZN1BIcE1fEv
+// MSVCCOMPAT-NOT: @"\01?f@?$B@D@@QEAAXXZ"
void B<char>::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() { }
// <rdar://problem/8740363>
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 <typename T>
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 <typename T>
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<int> Foo() { return S<int>(); }
-// 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"(
}
OpenPOWER on IntegriCloud