Skip to content

Commit ffe8a2b

Browse files
authored
Merge pull request swiftlang#30650 from nkcsgexi/60857172
PrintAsObjC: use header path relative to usr/include when importing non-framework headers
2 parents 5010483 + ebe0a45 commit ffe8a2b

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,42 @@ static void writeImports(raw_ostream &out,
332332
allPaths.append(module->getTopLevelModuleName());
333333
llvm::sys::path::append(allPaths, Buffer.str());
334334
} else {
335-
// Otherwise, import the header directly.
336-
allPaths.append(header.NameAsWritten);
335+
auto DirPath = header.Entry->getDir()->getName();
336+
auto I = llvm::sys::path::begin(DirPath),
337+
E = llvm::sys::path::end(DirPath);
338+
llvm::SmallVector<StringRef, 4> Comps;
339+
// Check if the path of the header contains `/usr/include/` in it.
340+
// If so, we print the header include path starting from the next component.
341+
// e.g. for .../usr/include/dispatch/dispatch.h, we print
342+
// #include "dispatch/dispatch.h" because we could assume /usr/include/ is
343+
// in the header search paths.
344+
while (true) {
345+
StringRef Parts[2] = {*I, StringRef()};
346+
++ I;
347+
if (I == E)
348+
break;
349+
Parts[1] = *I;
350+
if (Parts[0] == "usr" && Parts[1] == "include") {
351+
++ I;
352+
for (;I != E; ++ I) {
353+
Comps.push_back(*I);
354+
}
355+
break;
356+
}
357+
};
358+
if (!Comps.empty()) {
359+
// The header is in a deeper location inside /usr/include/, add the
360+
// additional path components before adding the header name.
361+
allPaths.append(Comps.front());
362+
for (auto c: llvm::makeArrayRef(Comps).slice(1)) {
363+
llvm::sys::path::append(allPaths, c);
364+
}
365+
llvm::sys::path::append(allPaths,
366+
llvm::sys::path::filename(header.NameAsWritten));
367+
} else {
368+
// Otherwise, import the header directly.
369+
allPaths.append(header.NameAsWritten);
370+
}
337371
}
338372
headerImports.insert(allPaths.str().substr(startIdx));
339373
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module CTypesCore [system] [extern_c] {
2+
umbrella header "values.h"
3+
export *
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
typedef int DWORD_CORE;
2+
3+
#define MY_INT 123

test/PrintAsObjC/imports.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// CHECK-NEXT: @import Base.ExplicitSub;
1414
// CHECK-NEXT: @import Base.ExplicitSub.ExSub;
1515
// CHECK-NEXT: @import Base.ImplicitSub.ExSub;
16+
// CHECK-NEXT: @import CTypesCore;
1617
// CHECK-NEXT: @import Foundation;
1718
// CHECK-NEXT: @import MostlyPrivate1;
1819
// CHECK-NEXT: @import MostlyPrivate1_Private;
@@ -24,6 +25,7 @@
2425
// CHECK-NEXT: #import <Base.ExplicitSub.h>
2526
// CHECK-NEXT: #import <Base.ExplicitSub.ExSub.h>
2627
// CHECK-NEXT: #import <Base.ImplicitSub.ExSub.h>
28+
// CHECK-NEXT: #import <CTypesCore/values.h>
2729
// CHECK-NEXT: #import <Foundation.h>
2830
// CHECK-NEXT: #import <MostlyPrivate1/MostlyPrivate1.h>
2931
// CHECK-NEXT: #import <MostlyPrivate1_Private/MostlyPrivate1_Private.h>
@@ -38,6 +40,7 @@
3840

3941
// NEGATIVE-NOT: secretMethod
4042

43+
import CTypesCore
4144
import ctypes.bits
4245
import Foundation
4346

@@ -58,6 +61,7 @@ import MostlyPrivate2_Private
5861

5962
@objc class Test {
6063
@objc let word: DWORD = 0
64+
@objc let word_core: DWORD_CORE = 0
6165
@objc let number: TimeInterval = 0.0
6266

6367
@objc let baseI: BaseI = 0

0 commit comments

Comments
 (0)