Fix the GUID type not found error on Windows

Predefined declarations (like _GUID) are special forward declarations
inserted by Clang and aren't serialized into the pcm and their
definition pointers aren't retained across serialization and
deserialization, which causes this type not found error. Avoid putting
non-defining predefined declarations into the swift lookup table when
their definitions exist in the same module so that the definitions
will be associated with the base name and avoid this error.
This commit is contained in:
Hiroshi Yamauchi
2025-11-19 17:27:50 -08:00
parent 73fd67b7e4
commit be641d73ef
3 changed files with 44 additions and 7 deletions

View File

@@ -2180,6 +2180,17 @@ void SwiftLookupTableWriter::populateTableWithDecl(SwiftLookupTable &table,
if (decl->isFromASTFile())
return;
// Exclude a predefined declaration that's not a definition if its
// definition exists in the same module so that the definition will
// be associated with the base name, noting predefined declarations
// won't be serialized into the pcm and its state including its
// definition pointer won't be reconstructed after deserialization,
// which would cause a type not found error.
if (Writer.isDeclPredefined(decl))
if (auto tagDecl = dyn_cast<clang::TagDecl>(decl))
if (!tagDecl->isThisDeclarationADefinition() && tagDecl->getDefinition())
return;
// Iterate into extern "C" {} type declarations.
if (auto linkageDecl = dyn_cast<clang::LinkageSpecDecl>(decl)) {
for (auto *decl : linkageDecl->noload_decls()) {

View File

@@ -0,0 +1,32 @@
// REQUIRES: OS=windows-msvc
// Test that a struct named _GUID is found and usable in C++ when it is
// defined, not just forward declared, within the same Clang module where
// _GUID is specially-handled as a predefined (forward) declaration on
// Windows.
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend -c -primary-file %t/Test.swift -cxx-interoperability-mode=default -I %t -Xcc -fmodule-map-file=%t/module.modulemap -Xcc -I -Xcc %t -module-name Test -o %t/Test.swift.o -module-cache-path %t/module-cache
//--- Test.swift
import TestMod
extension TestMod._GUID {
public func m() -> Int { 42 }
}
//--- test.h
#ifndef TEST_H
#define TEST_H
typedef struct _GUID {
int Data;
} GUID;
#endif // TEST_H
//--- module.modulemap
module TestMod {
header "test.h"
}

View File

@@ -1,10 +1,4 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module %S/Inputs/wrapped-modularization-error-remarks/A/A.swift -cxx-interoperability-mode=default -Xcc -fmodule-map-file=%S/Inputs/wrapped-modularization-error-remarks/CxxLib/include/module.modulemap -Xcc -I -Xcc %S/Inputs/wrapped-modularization-error-remarks/CxxLib/include -module-name A -o %t/A.swiftmodule
// RUN: not %target-swift-frontend -c -primary-file %S/Inputs/wrapped-modularization-error-remarks/B/B.swift -cxx-interoperability-mode=default -I %t -Xcc -fmodule-map-file=%S/Inputs/wrapped-modularization-error-remarks/CxxLib/include/module.modulemap -Xcc -I -Xcc %S/Inputs/wrapped-modularization-error-remarks/CxxLib/include -module-name B -o %t/B.swift.o -Rmodule-recovery 2>&1 | %FileCheck %s
// RUN: %target-swift-frontend -c -primary-file %S/Inputs/wrapped-modularization-error-remarks/B/B.swift -cxx-interoperability-mode=default -I %t -Xcc -fmodule-map-file=%S/Inputs/wrapped-modularization-error-remarks/CxxLib/include/module.modulemap -Xcc -I -Xcc %S/Inputs/wrapped-modularization-error-remarks/CxxLib/include -module-name B -o %t/B.swift.o -Rmodule-recovery
// REQUIRES: OS=windows-msvc
// Check that the diagnostics/remark from the wrapped ModularizationError is emitted.
// CHECK: remark: reference to type '_GUID' broken by a context change; '_GUID' is not found, it was expected to be in 'CxxLib'
// CHECK: note: could not deserialize type for 'queryInterface'
// CHECK: error: cannot inherit from class 'Window' because it has overridable members that could not be loaded
// CHECK: note: could not deserialize 'queryInterface'