swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
66.85k stars 10.3k forks source link

Cxx to Swift Interop issue - Use of undeclared identifier #71390

Open litewrap opened 5 months ago

litewrap commented 5 months ago

Description

The context: On Swift side, when calling a method within a class that return an array of class. The problem: Calling the method from C++ failed with message like "Use of undeclared identifier" in the C++ header file

Reproduction

Swift Side:


import Foundation

public class MyObject {
    public init() { }
}

public class MyModule {
    public init() { }

    public func getArray() -> [MyObject] {
        let objects: [MyObject] = []
        return objects
    }
}

C++ side:

#include <iostream>
#include <string>
#include <stdio.h>

#include "TestCxxToSwift-Swift.h"

using namespace TestCxxToSwift;

int main(int argc, const char * argv[]) {
    std::cout << "Hello, World!\n";

    auto m = MyModule::init();
    auto o = m.getArray();

    return 0;
}

// clang++ -std=c++20 main.cpp -lTestCxxToSwift -lswiftCore -rpath @loader_path/lib
Last login: Mon Feb  5 09:59:03 on ttys000
admin@mbam1 CxxSide % clang++ -std=c++20 main.cpp -lTestCxxToSwift -lswiftCore -rpath @loader_path/lib
In file included from main.cpp:12:
./TestCxxToSwift-Swift.h:5085:35: error: use of undeclared identifier 'MyObject'
  SWIFT_INLINE_THUNK swift::Array<MyObject> getArray() SWIFT_SYMBOL("s:14TestCxxToSwift8MyModuleC8getArraySayAA0E6ObjectCGyF");
                                  ^
1 error generated.
admin@mbam1 CxxSide % 

Expected behavior

compile with no errors.

Note1: If MyObject is a struct instead of a class there is no errors. Calling the method getArray() success. Note2: if the function getArray() is placed at top level instead of inside a class, the call is fine with no errors, regardless MyObject is a class or a struct.

Environment

admin@mbam1 CxxSide % swiftc --version swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) Target: arm64-apple-macosx13.0 admin@mbam1 CxxSide %

Additional information

Tried with current Swift 5.9.2 and DEV SNAPSHOT 5.11, same error.

litewrap commented 4 months ago

I just found something very weird.

If I rename "MyObject" to "MyCar" now the issue is gone, and the C++ code works ok. Regardless MyCar is a struct or a class.

If I rename to "MyOldCar" the issue appear. In fact any class naming beginning with "MyO" will fail ex: "MyOABCDEFGH" will fail.

So.. it seems maybe the emitted C++ header have problem with some class naming.

I hope this can help.