Skip to content

Commit ab6ecda

Browse files
authored
Merge pull request #285 from benlangmuir/gmodules-workaround
[clang] Workaround module format issue with -gmodules
2 parents 9d8a5d4 + 8fdcd16 commit ab6ecda

File tree

7 files changed

+54
-1
lines changed

7 files changed

+54
-1
lines changed

Sources/SourceKit/Clang/ClangLanguageServer.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,22 @@ extension ClangLanguageServerShim {
120120
return "settings for \(uri): \(settingsStr)"
121121
}
122122

123-
if let settings = settings {
123+
if var settings = settings {
124+
if settings.compilerArguments.contains("-fmodules") == true {
125+
// Clangd is not built with support for the 'obj' format.
126+
settings.compilerArguments.append(contentsOf: [
127+
"-Xclang", "-fmodule-format=raw"
128+
])
129+
}
130+
if let workingDirectory = settings.workingDirectory {
131+
// FIXME: this is a workaround for clangd not respecting the compilation
132+
// database's "directory" field for relative -fmodules-cache-path.
133+
// rdar://63984913
134+
settings.compilerArguments.append(contentsOf: [
135+
"-working-directory", workingDirectory
136+
])
137+
}
138+
124139
clangd.send(DidChangeConfigurationNotification(settings: .clangd(
125140
ClangWorkspaceSettings(
126141
compilationDatabaseChanges: [url.path: ClangCompileCommand(settings, clang: clang)]))))
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef ClangModuleA_h
2+
#define ClangModuleA_h
3+
4+
void func_ClangModuleA(void);
5+
6+
#endif /* ClangModuleA_h */
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/*main_file*/
2+
@import ClangModuleA;
3+
4+
void test(void) {
5+
func_ClangModuleA();
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module ClangModuleA {
2+
header "ClangModuleA.h"
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"clang_flags": ["-gmodules"],
3+
"sources": ["ClangModules_main.m"]
4+
}

Tests/SourceKitTests/LocalClangTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,22 @@ final class LocalClangTests: XCTestCase {
164164
fatalError("error \(result) waiting for diagnostics notification")
165165
}
166166
}
167+
168+
func testClangModules() {
169+
guard let ws = try! staticSourceKitTibsWorkspace(name: "ClangModules") else { return }
170+
if ToolchainRegistry.shared.default?.clangd == nil { return }
171+
172+
let loc = ws.testLoc("main_file")
173+
174+
let expectation = self.expectation(description: "diagnostics")
175+
176+
ws.sk.handleNextNotification { (note: Notification<PublishDiagnosticsNotification>) in
177+
XCTAssertEqual(note.params.diagnostics.count, 0)
178+
expectation.fulfill()
179+
}
180+
181+
try! ws.openDocument(loc.url, language: .objective_c)
182+
183+
waitForExpectations(timeout: 15)
184+
}
167185
}

Tests/SourceKitTests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ extension LocalClangTests {
9292
// `swift test --generate-linuxmain`
9393
// to regenerate.
9494
static let __allTests__LocalClangTests = [
95+
("testClangModules", testClangModules),
9596
("testClangStdHeaderCanary", testClangStdHeaderCanary),
9697
("testFoldingRange", testFoldingRange),
9798
("testSymbolInfo", testSymbolInfo),

0 commit comments

Comments
 (0)