[cxx-interop] Use the locations imported from C++

A recent PR (#77204) started to import C++ source locations into Swift.
This PR flips a switch so these locations are actually used more widely.
Now some of the diagnostic locations are changed, but they generally
improved the quality of the diagnostics, pointing out conformances
imported from Obj-C code right when they are declared.
This commit is contained in:
Gabor Horvath
2024-10-31 15:59:00 +00:00
parent 09c89fb983
commit 6d24c52b80
13 changed files with 33 additions and 36 deletions

View File

@@ -1011,6 +1011,7 @@ static_assert(sizeof(checkSourceLocType(&ID##Decl::getLoc)) == 2, \
return getLocFromSource(); return getLocFromSource();
switch(File->getKind()) { switch(File->getKind()) {
case FileUnitKind::Source: case FileUnitKind::Source:
case FileUnitKind::ClangModule:
return getLocFromSource(); return getLocFromSource();
case FileUnitKind::SerializedAST: { case FileUnitKind::SerializedAST: {
if (!SerializedOK) if (!SerializedOK)
@@ -1019,7 +1020,6 @@ static_assert(sizeof(checkSourceLocType(&ID##Decl::getLoc)) == 2, \
} }
case FileUnitKind::Builtin: case FileUnitKind::Builtin:
case FileUnitKind::Synthesized: case FileUnitKind::Synthesized:
case FileUnitKind::ClangModule:
case FileUnitKind::DWARFModule: case FileUnitKind::DWARFModule:
return SourceLoc(); return SourceLoc();
} }

View File

@@ -1351,12 +1351,11 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
if (!attrSourceFile) if (!attrSourceFile)
return nullptr; return nullptr;
// If the declaration has no source location and comes from a Clang module, // If the declaration comes from a Clang module,
// pretty-print the declaration and use that location. // pretty-print the declaration and use that location.
SourceLoc attachedToLoc = attachedTo->getLoc(); SourceLoc attachedToLoc = attachedTo->getLoc();
bool isPrettyPrintedDecl = false; bool isPrettyPrintedDecl = false;
if (attachedToLoc.isInvalid() && if (isa<ClangModuleUnit>(dc->getModuleScopeContext())) {
isa<ClangModuleUnit>(dc->getModuleScopeContext())) {
isPrettyPrintedDecl = true; isPrettyPrintedDecl = true;
attachedToLoc = evaluateOrDefault( attachedToLoc = evaluateOrDefault(
ctx.evaluator, PrettyPrintDeclRequest{attachedTo}, SourceLoc()); ctx.evaluator, PrettyPrintDeclRequest{attachedTo}, SourceLoc());

View File

@@ -8,10 +8,7 @@ func testLocalVsFileScope() {
theFunctionInQuestion() theFunctionInQuestion()
// CHECK: :[[@LINE-1]]:25: error: missing argument // CHECK: :[[@LINE-1]]:25: error: missing argument
// CHECK: LocalVsFileScope.theFunctionInQuestion:1:{{[0-9]+}}: note: // CHECK: LocalVsFileScope.h:{{[0-9]+}}:{{[0-9]+}}: note:
// This is not a wonderful test because it's relying on the diagnostic
// engine's synthesis of fake declarations to figure out what module the
// importer assigned the function to. But, well, that's what we get.
aFunctionInBase() // just make sure it's imported aFunctionInBase() // just make sure it's imported
// CHECK-NOT: :[[@LINE-1]]:{{[0-9]+}}: // CHECK-NOT: :[[@LINE-1]]:{{[0-9]+}}:

View File

@@ -108,4 +108,4 @@ import Module100
obsoleted() obsoleted()
// CHECK: [[@LINE-1]]:1: error: // CHECK: [[@LINE-1]]:1: error:
// CHECK: explicitly marked unavailable here // CHECK: explicitly marked unavailable here
// CHECK: func obsoleted() // CHECK: void obsoleted() __attribute__((unavailable));

View File

@@ -60,12 +60,12 @@ s.c = 5
// CHECK-NEXT: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: built-in type 'Complex' not supported // CHECK-NEXT: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: built-in type 'Complex' not supported
// CHECK-NEXT: int _Complex c; // CHECK-NEXT: int _Complex c;
// CHECK-NEXT: ^ // CHECK-NEXT: ^
// CHECK-NEXT: ctypes.PartialImport.a:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'a'? // CHECK-NEXT: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'a'?
// CHECK-NEXT: public var a: Int32 // CHECK-NEXT: int a;
// CHECK-NEXT: ^ // CHECK-NEXT: ^
// CHECK-NEXT: ctypes.PartialImport.b:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'b'? // CHECK-NEXT: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'b'?
// CHECK-NEXT: public var b: Int32 // CHECK-NEXT: int b;
// CHECK-NEXT: ^ // CHECK-NEXT: ^
// CHECK-NOT: note // CHECK-NOT: note
// CHECK-NOT: warning // CHECK-NOT: warning

View File

@@ -19,8 +19,8 @@ _ = bar.methodReturningForwardDeclaredInterface()
let s: PartialImport let s: PartialImport
s.c = 5 s.c = 5
// CHECK: experimental_diagnostics_opt_out.swift:{{[0-9]+}}:{{[0-9]+}}: error: value of type 'PartialImport' has no member 'c' // CHECK: experimental_diagnostics_opt_out.swift:{{[0-9]+}}:{{[0-9]+}}: error: value of type 'PartialImport' has no member 'c'
// CHECK: ctypes.PartialImport.a:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'a'? // CHECK: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'a'?
// CHECK: ctypes.PartialImport.b:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'b'? // CHECK: ctypes.h:{{[0-9]+}}:{{[0-9]+}}: note: did you mean 'b'?
// CHECK-NOT: warning // CHECK-NOT: warning
// CHECK-NOT: error // CHECK-NOT: error
// CHECK-NOT: note // CHECK-NOT: note

View File

@@ -11,12 +11,12 @@ import ObjCIRExtras
func foo(_: SwiftConstrGenericNameAlias<String>) { func foo(_: SwiftConstrGenericNameAlias<String>) {
// expected-error@-1 {{'SwiftConstrGenericNameAlias' requires that 'String' inherit from 'NSNumber'}} // expected-error@-1 {{'SwiftConstrGenericNameAlias' requires that 'String' inherit from 'NSNumber'}}
// expected-note@-2 {{requirement specified as 'T' : 'NSNumber' [with T = String]}} // TODO: validate node in imported Obj-C header.
} }
func faz(_: SwiftGenericNameAlias<Int>) { func faz(_: SwiftGenericNameAlias<Int>) {
// expected-error@-1 {{'SwiftGenericNameAlias' requires that 'Int' be a class type}} // expected-error@-1 {{'SwiftGenericNameAlias' requires that 'Int' be a class type}}
// expected-note@-2 {{requirement specified as 'T' : 'AnyObject' [with T = Int]}} // TODO: validate node in imported Obj-C header.
} }
func bar(_: SwiftGenericNameAlias<NSNumber>) {} // Ok func bar(_: SwiftGenericNameAlias<NSNumber>) {} // Ok

View File

@@ -88,12 +88,12 @@ func testImportedTypeParamRequirements() {
let _ = PettableContainer<Rock>() let _ = PettableContainer<Rock>()
let _ = PettableContainer<Porcupine>() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}} let _ = PettableContainer<Porcupine>() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}}
let _ = PettableContainer<Cat>() let _ = PettableContainer<Cat>()
let _ = AnimalContainer<Desk>() // expected-error{{'AnimalContainer' requires that 'Desk' inherit from 'Animal'}} expected-note{{requirement specified as 'T' : 'Animal' [with T = Desk]}} let _ = AnimalContainer<Desk>() // expected-error{{'AnimalContainer' requires that 'Desk' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header.
let _ = AnimalContainer<Rock>() // expected-error{{'AnimalContainer' requires that 'Rock' inherit from 'Animal'}} expected-note{{requirement specified as 'T' : 'Animal' [with T = Rock]}} let _ = AnimalContainer<Rock>() // expected-error{{'AnimalContainer' requires that 'Rock' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header.
let _ = AnimalContainer<Porcupine>() let _ = AnimalContainer<Porcupine>()
let _ = AnimalContainer<Cat>() let _ = AnimalContainer<Cat>()
let _ = PettableAnimalContainer<Desk>() // expected-error{{'PettableAnimalContainer' requires that 'Desk' inherit from 'Animal'}} expected-note{{requirement specified as 'T' : 'Animal' [with T = Desk]}} let _ = PettableAnimalContainer<Desk>() // expected-error{{'PettableAnimalContainer' requires that 'Desk' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header.
let _ = PettableAnimalContainer<Rock>() // expected-error{{'PettableAnimalContainer' requires that 'Rock' inherit from 'Animal'}} expected-note{{requirement specified as 'T' : 'Animal' [with T = Rock]}} let _ = PettableAnimalContainer<Rock>() // expected-error{{'PettableAnimalContainer' requires that 'Rock' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header.
let _ = PettableAnimalContainer<Porcupine>() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}} let _ = PettableAnimalContainer<Porcupine>() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}}
let _ = PettableAnimalContainer<Cat>() let _ = PettableAnimalContainer<Cat>()
} }

View File

@@ -26,9 +26,9 @@ class MyObject : NSObject {
// directly. // directly.
// IMPORT-CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[OVERLAY]] // IMPORT-CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[OVERLAY]]
// ALLOCCTOR-CHECK: ![[F:.*]] = !DIFile(filename: "<compiler-generated>",
// ALLOCCTOR-CHECK: distinct !DISubprogram(name: "init", linkageName: "$sSo7NSArrayCABycfC" // ALLOCCTOR-CHECK: distinct !DISubprogram(name: "init", linkageName: "$sSo7NSArrayCABycfC"
// ALLOCCTOR-CHECK-SAME: file: ![[F]], // ALLOCCTOR-CHECK-SAME: file: ![[F:[0-9]+]],
// ALLOCCTOR-CHECK: ![[F]] = !DIFile(filename: "{{.*}}/NSArray.h",
@objc func foo(_ obj: MyObject) { @objc func foo(_ obj: MyObject) {
return obj.foo(obj) return obj.foo(obj)
} }

View File

@@ -179,7 +179,7 @@ typedef void ( ^ObjCErrorHandler )( NSError * _Nullable inError );
- (void) myMethod:(NSInteger)value1 foo:(NSInteger)value2; - (void) myMethod:(NSInteger)value1 foo:(NSInteger)value2;
@end @end
@interface GenericObject<T> : NSObject @interface GenericObject<T> : NSObject // expected-note {{generic class 'GenericObject' does not conform to the 'Sendable' protocol}}
- (void)doSomethingWithCompletionHandler:(void (^)(T _Nullable_result, NSError * _Nullable))completionHandler; - (void)doSomethingWithCompletionHandler:(void (^)(T _Nullable_result, NSError * _Nullable))completionHandler;
- (void)doAnotherThingWithCompletionHandler:(void (^)(GenericObject<T> *_Nullable))completionHandler; - (void)doAnotherThingWithCompletionHandler:(void (^)(GenericObject<T> *_Nullable))completionHandler;
@end @end
@@ -218,7 +218,7 @@ MAIN_ACTOR MAIN_ACTOR __attribute__((__swift_attr__("@MainActor"))) @protocol Tr
SENDABLE @interface SendableClass : NSObject @end SENDABLE @interface SendableClass : NSObject @end
NONSENDABLE @interface NonSendableClass : NSObject @end NONSENDABLE @interface NonSendableClass : NSObject @end // expected-note {{class 'NonSendableClass' does not conform to the 'Sendable' protocol}}
ASSUME_NONSENDABLE_BEGIN ASSUME_NONSENDABLE_BEGIN
@@ -232,14 +232,14 @@ SENDABLE @protocol SendableProtocol @end
typedef NS_ENUM(unsigned, SendableEnum) { typedef NS_ENUM(unsigned, SendableEnum) {
SendableEnumFoo, SendableEnumBar SendableEnumFoo, SendableEnumBar
}; };
typedef NS_ENUM(unsigned, NonSendableEnum) { typedef NS_ENUM(unsigned, NonSendableEnum) { // expected-note {{enum 'NonSendableEnum' does not conform to the 'Sendable' protocol}}
NonSendableEnumFoo, NonSendableEnumBar NonSendableEnumFoo, NonSendableEnumBar
} NONSENDABLE; } NONSENDABLE;
typedef NS_OPTIONS(unsigned, SendableOptions) { typedef NS_OPTIONS(unsigned, SendableOptions) {
SendableOptionsFoo = 1 << 0, SendableOptionsBar = 1 << 1 SendableOptionsFoo = 1 << 0, SendableOptionsBar = 1 << 1
}; };
typedef NS_OPTIONS(unsigned, NonSendableOptions) { typedef NS_OPTIONS(unsigned, NonSendableOptions) { // expected-note {{struct 'NonSendableOptions' does not conform to the 'Sendable' protocol}}
NonSendableOptionsFoo = 1 << 0, NonSendableOptionsBar = 1 << 1 NonSendableOptionsFoo = 1 << 0, NonSendableOptionsBar = 1 << 1
} NONSENDABLE; } NONSENDABLE;
@@ -264,10 +264,10 @@ UI_ACTOR
@end @end
typedef NSString *SendableStringEnum NS_STRING_ENUM; typedef NSString *SendableStringEnum NS_STRING_ENUM;
typedef NSString *NonSendableStringEnum NS_STRING_ENUM NONSENDABLE; typedef NSString *NonSendableStringEnum NS_STRING_ENUM NONSENDABLE; // expected-note {{struct 'NonSendableStringEnum' does not conform to the 'Sendable' protocol}}
typedef NSString *SendableStringStruct NS_EXTENSIBLE_STRING_ENUM; typedef NSString *SendableStringStruct NS_EXTENSIBLE_STRING_ENUM;
typedef NSString *NonSendableStringStruct NS_EXTENSIBLE_STRING_ENUM NONSENDABLE; typedef NSString *NonSendableStringStruct NS_EXTENSIBLE_STRING_ENUM NONSENDABLE; // expected-note {{struct 'NonSendableStringStruct' does not conform to the 'Sendable' protocol}}
SENDABLE SENDABLE
typedef struct { typedef struct {

View File

@@ -48,6 +48,7 @@ public func noAnnotations() -> View {
// CHECK-NOT: nonescapable.h:19 // CHECK-NOT: nonescapable.h:19
f2(nil, nil) f2(nil, nil)
// CHECK: nonescapable.h:23:6: warning: the returned type 'View' is annotated as non-escapable; its lifetime dependencies must be annotated // CHECK: nonescapable.h:23:6: warning: the returned type 'View' is annotated as non-escapable; its lifetime dependencies must be annotated
// CHECKL nonescapable.h:23:6: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
g(nil) g(nil)
return View() return View()
} }

View File

@@ -368,7 +368,7 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
// CHECK13: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>testDefaultParam</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>arg1</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type> = 0</decl.var.parameter>)</decl.function.free> // CHECK13: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>testDefaultParam</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>arg1</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type> = 0</decl.var.parameter>)</decl.function.free>
// RUN: %sourcekitd-test -req=cursor -pos=34:4 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %s | %FileCheck -check-prefix=CHECK14 %s // RUN: %sourcekitd-test -req=cursor -pos=34:4 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %s | %FileCheck -check-prefix=CHECK14 %s
// CHECK14: source.lang.swift.ref.function.free ({{.*}}Foo.framework/Frameworks/FooSub.framework/Headers/FooSub.h:4:5-4:16) // CHECK14: source.lang.swift.ref.function.free ({{.*}}Foo.framework/Frameworks/FooSub.framework/Headers/FooSub.h:4:5-4:22)
// CHECK14: fooSubFunc1 // CHECK14: fooSubFunc1
// CHECK14: c:@F@fooSubFunc1 // CHECK14: c:@F@fooSubFunc1
// CHECK14: source.lang.objc // CHECK14: source.lang.objc

View File

@@ -87,8 +87,8 @@ do {
// DEMANGLE-DECL: $sSo7NSCacheCySo8NSNumberCSo8NSStringCG // DEMANGLE-DECL: $sSo7NSCacheCySo8NSNumberCSo8NSStringCG
// DEMANGLE-DECL: $sSo26NSPropertyListWriteOptionsa // DEMANGLE-DECL: $sSo26NSPropertyListWriteOptionsa
// CHECK-DECL: Foundation.(file).NSSet // CHECK-DECL: Foundation.(file).NSSet@{{.*}}NSSet.h:{{[0-9]+}}:{{[0-9]+}}
// CHECK-DECL: Foundation.(file).NSFastEnumeration // CHECK-DECL: Foundation.(file).NSFastEnumeration@{{.*}}NSEnumerator.h:{{[0-9]+}}:{{[0-9]+}}
// CHECK-DECL: objc_classes.(file).OurObjCProtocol // CHECK-DECL: objc_classes.(file).OurObjCProtocol
// CHECK-DECL: Foundation.(file).NSCache // CHECK-DECL: Foundation.(file).NSCache@{{.*}}NSCache.h:{{[0-9]+}}:{{[0-9]+}}
// CHECK-DECL: Foundation.(file).PropertyListSerialization extension.WriteOptions // CHECK-DECL: Foundation.(file).PropertyListSerialization extension.WriteOptions@{{.*}}NSPropertyList.h:{{[0-9]+}}:{{[0-9]+}}