This is an archive of the discontinued LLVM Phabricator instance.

[clang][Sema] Better support for ObjC++ in Sema::LookupName
AbandonedPublic

Authored by bulbazord on Mar 15 2022, 3:40 PM.

Details

Reviewers
arphaman
Summary

Sema::LookupName essentially has two possible code paths based on what
language is currently being used. The predicate selecting the code path
is whether or not C++ is being used. In this scenario, the Scope
argument that is being passed needs to be not nullptr in order to
succeed. In the C/ObjC case, the Scope argument can potentially be
nullptr and still succeed. In the case where the Scope argument is
nullptr and you are dealing with Objective-C++ while looking up an
Objective-C name, you will fail where you otherwise should succeed.

This was surfaced when working on Swift/C++ interop. Swift passes
nullptr for the Scope when looking up some Objective-C name with the
experimental C++ interop option enabled resulting in a failure.

Diff Detail

Event Timeline

bulbazord created this revision.Mar 15 2022, 3:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 15 2022, 3:40 PM
bulbazord requested review of this revision.Mar 15 2022, 3:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 15 2022, 3:40 PM

I'm not quite sure the best way to test this. Looks like Sema::LookupName isn't currently directly tested. I've run the test suite and did not find any new failing tests.

arphaman added a comment.EditedMar 15 2022, 4:53 PM

Is there a Swift-based test case you have that demonstrates the original problem from Swift's clang importer side? I'm curious to see where it manifests in Swift.

Is there a Swift-based test case you have that demonstrates the original problem from Swift's clang importer side? I'm curious to see where it manifests in Swift.

% cat Test.h
@protocol Foo
@end
@interface Foo <Foo>
@end

% cat test.swift
import Test

public protocol Thing: FooProtocol {
}

% cat module.modulemap
module Test [extern_c] {
  header "Test.h"
}

% $SWIFT_BUILD_DIR/bin/swiftc -frontend -c -enable-cxx-interop -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/ -I. -o /tmp/foo.o test.swift
test.swift:3:24: error: cannot find type 'FooProtocol' in scope
public protocol Thing: FooProtocol {
                       ^~~~~~~~~~~

There's a call to Sema::LookupName that fails for the reason I outlined in the description when building the SwiftLookupTable during PCM creation time. The renaming of @protocol Foo to protocol FooProtocol doesn't occur because it thinks there is no naming conflict.

I see, thanks! Let me think a bit more about this change and test it on our codebase to see if this is a viable Sema change.

I don't think this patch is sound. I found this problem with this change when the following file is compiled in Objective-C++ mode:

template <class T, bool umax = true>
T umax(T a, T b) {
  return a;
}

produces this error:

test.mm:3:3: error: declaration of 'umax' shadows template parameter
T umax(T a, T b) {
  ^
test.mm:2:25: note: template parameter is declared here
template <class T, bool umax = true>
                        ^

which is unexpected and isn't produced in C++ mode.

I don't think this patch is sound. I found this problem with this change when the following file is compiled in Objective-C++ mode:

template <class T, bool umax = true>
T umax(T a, T b) {
  return a;
}

produces this error:

test.mm:3:3: error: declaration of 'umax' shadows template parameter
T umax(T a, T b) {
  ^
test.mm:2:25: note: template parameter is declared here
template <class T, bool umax = true>
                        ^

which is unexpected and isn't produced in C++ mode.

Could you tell me what flags you gave to clang to compile the test? I'd like to test a few things.

clang -x objective-c++ -Weverything -std=c++14 -c test.mm

bulbazord abandoned this revision.Mar 24 2022, 11:39 AM