Merged to 6.0 in r325500.
On Fri, Feb 16, 2018 at 8:44 PM, Reid Kleckner via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: rnk > Date: Fri Feb 16 11:44:47 2018 > New Revision: 325375 > > URL: http://llvm.org/viewvc/llvm-project?rev=325375&view=rev > Log: > [MS] Make constexpr static data members implicitly inline > > This handles them exactly the same way that we handle const integral > static data members with inline definitions, which is what MSVC does. > > As a follow-up, now that we have a way to mark variables inline in the > AST, we should consider marking them implicitly inline there instead of > only treating them as inline in CodeGen. Unfortunately, this breaks a > lot of dllimport test cases, so that is future work for now. > > Fixes PR36125. > > Modified: > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/test/CodeGenCXX/static-data-member.cpp > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=325375&r1=325374&r2=325375&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Feb 16 11:44:47 2018 > @@ -5857,7 +5857,7 @@ CharUnits ASTContext::getObjCEncodingTyp > bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) > const { > return getTargetInfo().getCXXABI().isMicrosoft() && > VD->isStaticDataMember() && > - VD->getType()->isIntegralOrEnumerationType() && > + (VD->getType()->isIntegralOrEnumerationType() || VD->isConstexpr()) > && > !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); > } > > > Modified: cfe/trunk/test/CodeGenCXX/static-data-member.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-data-member.cpp?rev=325375&r1=325374&r2=325375&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/static-data-member.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/static-data-member.cpp Fri Feb 16 11:44:47 2018 > @@ -1,6 +1,10 @@ > -// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s > -// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | \ > -// RUN: FileCheck --check-prefix=MACHO %s > +// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++14 -emit-llvm -o - %s | > FileCheck %s > +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++14 -emit-llvm -o - %s > \ > +// RUN: | FileCheck %s --check-prefix=MACHO > +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++14 -emit-llvm -o - > %s \ > +// RUN: | FileCheck %s --check-prefix=MSVC > +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++17 -emit-llvm -o - > %s \ > +// RUN: | FileCheck %s --check-prefix=MSVC > > // CHECK: @_ZN5test11A1aE = constant i32 10, align 4 > // CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4 > @@ -9,12 +13,25 @@ > // MACHO: @_ZGVN5test31AIiE1xE = weak_odr global i64 0 > // MACHO-NOT: comdat > > +// MSVC: @"\01?a@A@test1@@2HB" = linkonce_odr constant i32 10, comdat, align > 4 > +// MSVC: @"\01?i@S@test1@@2HA" = external global i32 > +// MSVC: @"\01?x@?$A@H@?A@test2@@2HA" = internal global i32 0, align 4 > + > // CHECK: _ZN5test51U2k0E = global i32 0 > // CHECK: _ZN5test51U2k1E = global i32 0 > // CHECK: _ZN5test51U2k2E = constant i32 76 > // CHECK-NOT: test51U2k3E > // CHECK-NOT: test51U2k4E > > +// On Linux in C++14, neither of these are inline. > +// CHECK: @_ZN16inline_constexpr1A10just_constE = available_externally > constant i32 42 > +// CHECK: @_ZN16inline_constexpr1A10const_exprE = available_externally > constant i32 43 > +// > +// In MSVC, these are both implicitly inline regardless of the C++ standard > +// version. > +// MSVC: @"\01?just_const@A@inline_constexpr@@2HB" = linkonce_odr constant > i32 42, comdat, align 4 > +// MSVC: @"\01?const_expr@A@inline_constexpr@@2HB" = linkonce_odr constant > i32 43, comdat, align 4 > + > // PR5564. > namespace test1 { > struct A { > @@ -28,7 +45,7 @@ namespace test1 { > }; > > void f() { > - int a = S::i; > + int a = *&A::a + S::i; > } > } > > @@ -50,6 +67,11 @@ namespace test2 { > // CHECK: [[TMP:%.*]] = call i32 @_ZN5test23fooEv() > // CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test212_GLOBAL__N_11AIiE1xE, > align 4 > // CHECK-NEXT: ret void > + > + // MSVC-LABEL: define internal void > @"\01??__Ex@?$A@H@?A@test2@@2HA@YAXXZ"() > + // MSVC: [[TMP:%.*]] = call i32 @"\01?foo@test2@@YAHXZ"() > + // MSVC-NEXT: store i32 [[TMP]], i32* @"\01?x@?$A@H@?A@test2@@2HA", align 4 > + // MSVC-NEXT: ret void > } > > // Test that we don't use threadsafe statics when initializing > @@ -108,3 +130,13 @@ namespace test5 { > // CHECK: store i32 {{.*}}, i32* @_ZN5test51U2k1E > // CHECK-NOT: store {{.*}} i32* @_ZN5test51U2k2E > } > + > +// Test that MSVC mode static constexpr data members are always inline, even > pre > +// C++17. > +namespace inline_constexpr { > +struct A { > + static const int just_const = 42; > + static constexpr int const_expr = 43; > +}; > +int useit() { return *&A::just_const + *&A::const_expr; } > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits