Skip to content

Commit e600816

Browse files
committed
ClangImporter: synchronize clang and Swift
This synchronizes the C/C++ standard that Swift uses for the clang importer with the defaults of the clang compiler. The default for the C standard remains the same at `gnu11`. However, if clang was built with a different default C standard, that will be preferred. The default for the C++ standard is moved to C++14. Although this is a reduced version, it matches what the current clang compiler defaults to. Additionally, if the user built clang with a different C++ standard, that standard would be preferred. Although the C++ support is a bit more conservative, the idea is that we can be certain that the clang version fully supports this standard as it it the default version for clang. The test change made here replaces the use of `auto` type parameters to templates which is a C++17 feature. Reduce the example to a C++14 equivalent. The clang version seems to behave differently in preventing the synthesis of the constexpr value. This persists into the newer clang releases as well. This is reasonable as the value does not need to be exported necessarily and users will be able to materialize the value. We use the optimizer to ensure that the value is inlined. This also repairs the C++ interop tests on Windows with a newer C++ runtime from Microsoft.
1 parent 7fb4815 commit e600816

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,28 @@ importer::getNormalInvocationArguments(
538538
});
539539
}
540540

541-
invocationArgStrs.insert(invocationArgStrs.end(), {
542-
EnableCXXInterop ? "-std=gnu++17" : "-std=gnu11",
543-
});
541+
{
542+
const clang::LangStandard &stdcxx =
543+
#if defined(CLANG_DEFAULT_STD_CXX)
544+
*clang::LangStandard::getLangStandardForName(CLANG_DEFAULT_STD_CXX);
545+
#else
546+
clang::LangStandard::getLangStandardForKind(
547+
clang::LangStandard::lang_gnucxx14);
548+
#endif
549+
550+
const clang::LangStandard &stdc =
551+
#if defined(CLANG_DEFAULT_STD_C)
552+
*clang::LangStandard::getLangStandardForName(CLANG_DEFAULT_STD_C);
553+
#else
554+
clang::LangStandard::getLangStandardForKind(
555+
clang::LangStandard::lang_gnu11);
556+
#endif
557+
558+
invocationArgStrs.insert(invocationArgStrs.end(), {
559+
(Twine("-std=") + StringRef(EnableCXXInterop ? stdcxx.getName()
560+
: stdc.getName())).str()
561+
});
562+
}
544563

545564
// Set C language options.
546565
if (triple.isOSDarwin()) {

test/Interop/Cxx/static/constexpr-static-member-var.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-clang -c %S/Inputs/static-member-var.cpp -I %S/Inputs -o %t/static-member-var.o -std=c++17
3-
// RUN: %target-build-swift %s -I %S/Inputs -o %t/statics %t/static-member-var.o -Xfrontend -enable-cxx-interop
3+
// NOTE: we must use `-O` here to ensure that the constexpr value is inlined and no undefined reference remains.
4+
// RUN: %target-build-swift -O %s -I %S/Inputs -o %t/statics %t/static-member-var.o -Xfrontend -enable-cxx-interop
45
// RUN: %target-codesign %t/statics
56
// RUN: %target-run %t/statics
67
//

test/Interop/Cxx/static/static-member-var-irgen.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
//to depend on external definitions. However, our code generation pattern loads
1515
//the value dynamically. Instead, we should inline known constants. That would
1616
//allow Swift code to even read the value of WithIncompleteStaticMember::notDefined.
17-
// CHECK: @{{_ZN25WithConstexprStaticMember13definedInlineE|"\?definedInline@WithConstexprStaticMember@@2HB"}} = linkonce_odr {{(dso_local )?}}constant i32 139, {{(comdat, )?}}align 4
17+
// NOTE: we allow both available_externally and linkonce_odr as there are
18+
// differences in between MSVC and itanium model semantics where the constexpr
19+
// value is emitted into COMDAT.
20+
// CHECK: @{{_ZN25WithConstexprStaticMember13definedInlineE|"\?definedInline@WithConstexprStaticMember@@2HB"}} = {{available_externally|linkonce_odr}} {{(dso_local )?}}constant i32 139, {{(comdat, )?}}align 4
1821

1922
import StaticMemberVar
2023

test/Interop/Cxx/templates/Inputs/class-template-non-type-parameter.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_NON_TYPE_PARAMETER_H
22
#define TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_NON_TYPE_PARAMETER_H
33

4-
template<class T, auto Size>
4+
#if defined(__clang__)
5+
using size_t = __SIZE_TYPE__;
6+
#endif
7+
8+
template<class T, size_t Size>
59
struct MagicArray {
610
T t[Size];
711
};

0 commit comments

Comments
 (0)