Merge pull request #83238 from kubamracek/const-cgfloat-typedef

[ClangImporter] Skip importing values for CGFloat typedefs on top of CGFloats direct
This commit is contained in:
Kuba (Brecka) Mracek
2025-07-23 10:43:24 -07:00
committed by GitHub
7 changed files with 69 additions and 12 deletions

View File

@@ -1123,6 +1123,10 @@ namespace swift {
/// invocations directly from clang cc1 args.
bool ClangImporterDirectCC1Scan = false;
/// Whether we should import values (initializer expressions) of constant
/// globals.
bool EnableConstValueImporting = true;
/// Return a hash code of any components from these options that should
/// contribute to a Swift Bridging PCH hash.
llvm::hash_code getPCHHashComponents() const {

View File

@@ -534,6 +534,10 @@ def disable_clangimporter_source_import : Flag<["-"],
"disable-clangimporter-source-import">,
HelpText<"Disable ClangImporter and forward all requests straight the DWARF importer.">;
def disable_const_value_importing : Flag<["-"],
"disable-const-value-importing">,
HelpText<"Disable constant value importing in ClangImporter.">;
def disable_implicit_concurrency_module_import : Flag<["-"],
"disable-implicit-concurrency-module-import">,
HelpText<"Disable the implicit import of the _Concurrency module.">;

View File

@@ -4613,16 +4613,18 @@ namespace {
ValueDecl *result = nullptr;
bool initIsEvaluatable = false;
if (auto init = decl->getInit()) {
// Don't import values for partial specializations. TODO: Should we stop
// importing partially specialized variables completely?
bool partial = isa<clang::VarTemplatePartialSpecializationDecl>(decl);
if (Impl.SwiftContext.ClangImporterOpts.EnableConstValueImporting) {
if (auto init = decl->getInit()) {
// Don't import values for partial specializations. TODO: Should we
// stop importing partially specialized variables completely?
bool partial = isa<clang::VarTemplatePartialSpecializationDecl>(decl);
// Don't import values when type-dependent or value-dependent.
bool typeDependent = decl->getType()->isDependentType();
bool valueDependent = init->isValueDependent();
// Don't import values when type-dependent or value-dependent.
bool typeDependent = decl->getType()->isDependentType();
bool valueDependent = init->isValueDependent();
initIsEvaluatable = !partial && !typeDependent && !valueDependent;
initIsEvaluatable = !partial && !typeDependent && !valueDependent;
}
}
// If the variable is const (we're importing it as a let), and has an
@@ -4639,8 +4641,12 @@ namespace {
ImportDiagnosticAdder(Impl, decl, decl->getLocation()),
isInSystemModule(dc), Bridgeability::None, ImportTypeAttrs());
// FIXME: Handle CGFloat too.
if (type && !type->isCGFloat()) {
// Do not attempt to import CGFloat values, for now. Importing
// CGFloats is special cased in the importer, and needs more handling.
bool isCGFloat = (type && type->isCGFloat()) ||
(type && synthesizer.isCGFloat(type));
if (type && !isCGFloat) {
auto convertKind = ConstantConvertKind::None;
// Request conversions on enums, and swift_wrapper((enum/struct))
// types

View File

@@ -197,6 +197,16 @@ Type SwiftDeclSynthesizer::getConstantLiteralType(
}
}
bool SwiftDeclSynthesizer::isCGFloat(Type type) {
auto found = ImporterImpl.RawTypes.find(type->getAnyNominal());
if (found == ImporterImpl.RawTypes.end()) {
return false;
}
Type importTy = found->second;
return importTy->isCGFloat();
}
ValueDecl *SwiftDeclSynthesizer::createConstant(Identifier name,
DeclContext *dc, Type type,
const clang::APValue &value,

View File

@@ -345,6 +345,8 @@ public:
/// function for the availability domain represented by `var`.
FuncDecl *makeAvailabilityDomainPredicate(const clang::VarDecl *var);
bool isCGFloat(Type type);
private:
Type getConstantLiteralType(Type type, ConstantConvertKind convertKind);
};

View File

@@ -2142,6 +2142,9 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args,
Opts.DisableSourceImport |=
Args.hasArg(OPT_disable_clangimporter_source_import);
if (Args.hasArg(OPT_disable_const_value_importing))
Opts.EnableConstValueImporting = false;
Opts.ClangImporterDirectCC1Scan |=
Args.hasArg(OPT_experimental_clang_importer_direct_cc1_scan);
// Forward the FrontendOptions to clang importer option so it can be

View File

@@ -1,7 +1,11 @@
// RUN: %empty-directory(%t/src)
// RUN: split-file %s %t/src
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %t/src/main.swift \
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t/modules) -Xcc -DCGFLOAT_IN_COREFOUNDATION -DCGFLOAT_IN_COREFOUNDATION -emit-module -o %t/modules/CoreFoundation.swiftmodule %clang-importer-sdk-path/swift-modules/CoreFoundation.swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t/modules) -Xcc -DCGFLOAT_IN_COREFOUNDATION -DCGFLOAT_IN_COREFOUNDATION -emit-module -o %t/modules/CoreGraphics.swiftmodule %clang-importer-sdk-path/swift-modules/CoreGraphics.swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t/modules) -Xcc -DCGFLOAT_IN_COREFOUNDATION -DCGFLOAT_IN_COREFOUNDATION -emit-module -o %t/modules/Foundation.swiftmodule %clang-importer-sdk-path/swift-modules/Foundation.swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %t/modules) %t/src/main.swift \
// RUN: -import-bridging-header %t/src/test.h \
// RUN: -module-name main -I %t -emit-sil | %FileCheck %s
@@ -10,18 +14,35 @@
//--- test.h
#include <objc/objc.h>
@import CoreFoundation;
@import CoreGraphics;
@import Foundation;
@interface MyClass : NSObject
@end
__attribute__((swift_name("MyClass.value")))
static const int MyClassValue = -1;
static const CGFloat myFloatConstValue = 42.0;
typedef CGFloat MyFloatType __attribute__((swift_wrapper(struct)));
static const MyFloatType MyFloatTypeValue1 = 10;
static const MyFloatType MyFloatTypeValue2 = 20;
static const MyFloatType MyFloatTypeValue3 = 30;
//--- main.swift
func foo() {
print(MyClass.value)
print(myFloatConstValue)
print(MyFloatType.value1)
print(MyFloatType.value2)
print(MyFloatType.value3)
}
// CHECK: sil shared [transparent] @$sSo7MyClassC5values5Int32VvgZ : $@convention(method) (@thick MyClass.Type) -> Int32 {
// CHECK: // static MyClass.value.getter
// CHECK-NEXT: // Isolation: nonisolated
// CHECK-NEXT: sil shared [transparent] @$sSo7MyClassC5values5Int32VvgZ : $@convention(method) (@thick MyClass.Type) -> Int32 {
// CHECK-NEXT: // %0 "self"
// CHECK-NEXT: bb0(%0 : $@thick MyClass.Type):
// CHECK-NEXT: debug_value %0, let, name "self", argno 1
@@ -29,3 +50,10 @@ func foo() {
// CHECK-NEXT: %3 = struct $Int32 (%2)
// CHECK-NEXT: return %3
// CHECK-NEXT: }
// CGFloats are not imported:
// CHECK-NOT: // myFloatConstValue.getter
// CHECK-NOT: // static MyFloatType.value1.getter
// CHECK-NOT: // static MyFloatType.value2.getter
// CHECK-NOT: // static MyFloatType.value3.getter