Skip to content

Commit b43d01f

Browse files
authored
[autolink-extract] Support (and ignore) LLVM IR files. (swiftlang#71142)
In Linux, the current implementation of swift-autolink-extract does not support LLVM IR files resulting from using LTO. If one tries to build LLVM using LTO and then try to link one of the targets that use `swiftc` to link, but link against LLVM object files (like `swift-plugin-server`), `swift-autolink-extract` will fail saying that some object files are not valid. To deal with LLVM IR files correctly, create and pass a `llvm::LLVMContext` around, which allows the APIs in `llvm::object` to read LLVM IR files. Additionally, handle the case of `IRObjectFile` when extracting, but perform no action.
1 parent c527b0f commit b43d01f

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

lib/DriverTool/autolink_extract_main.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
#include "llvm/Object/Archive.h"
3333
#include "llvm/Object/ObjectFile.h"
3434
#include "llvm/Object/ELFObjectFile.h"
35+
#include "llvm/Object/IRObjectFile.h"
3536
#include "llvm/Object/Wasm.h"
37+
#include "llvm/IR/LLVMContext.h"
3638
#include "llvm/BinaryFormat/Wasm.h"
3739

3840
using namespace swift;
@@ -161,7 +163,8 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
161163
CompilerInstance &Instance,
162164
StringRef BinaryFileName,
163165
std::vector<std::string> &LinkerFlags,
164-
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries) {
166+
std::unordered_map<std::string, bool> &SwiftRuntimeLibraries,
167+
llvm::LLVMContext *LLVMCtx) {
165168
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
166169
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance);
167170
} else if (auto *ObjectFile =
@@ -170,7 +173,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
170173
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
171174
llvm::Error Error = llvm::Error::success();
172175
for (const auto &Child : Archive->children(Error)) {
173-
auto ChildBinary = Child.getAsBinary();
176+
auto ChildBinary = Child.getAsBinary(LLVMCtx);
174177
// FIXME: BinaryFileName below should instead be ld-style names for
175178
// object files in archives, e.g. "foo.a(bar.o)".
176179
if (!ChildBinary) {
@@ -180,12 +183,15 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
180183
return true;
181184
}
182185
if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName,
183-
LinkerFlags, SwiftRuntimeLibraries)) {
186+
LinkerFlags, SwiftRuntimeLibraries, LLVMCtx)) {
184187
return true;
185188
}
186189
}
187190
return bool(Error);
188-
} else {
191+
} else if (auto *IRObjectFile = llvm::dyn_cast<llvm::object::IRObjectFile>(Bin)) {
192+
// Ignore the LLVM IR files (LTO)
193+
return false;
194+
} else {
189195
Instance.getDiags().diagnose(SourceLoc(), diag::error_open_input_file,
190196
BinaryFileName,
191197
"Don't know how to extract from object file"
@@ -259,8 +265,9 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
259265
}
260266

261267
// Extract the linker flags from the objects.
268+
llvm::LLVMContext LLVMCtx;
262269
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
263-
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
270+
auto BinaryOwner = llvm::object::createBinary(BinaryFileName, &LLVMCtx);
264271
if (!BinaryOwner) {
265272
std::string message;
266273
{
@@ -274,7 +281,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
274281
}
275282

276283
if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
277-
LinkerFlags, SwiftRuntimeLibraries)) {
284+
LinkerFlags, SwiftRuntimeLibraries, &LLVMCtx)) {
278285
return 1;
279286
}
280287
}

test/AutolinkExtract/llvm-ir.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// REQUIRES: autolink-extract
2+
// RUN: %clang -flto=thin -c -o - %s | %target-swift-autolink-extract -o - - 2>&1 | %FileCheck --allow-empty %s
3+
// CHECK-NOT: The file was not recognized as a valid object file
4+
5+
int test() {
6+
return 1;
7+
}

0 commit comments

Comments
 (0)