================
@@ -187,84 +193,339 @@ static Error executeCommands(StringRef ExecutablePath,
return Error::success();
}
-static Expected<SmallVector<std::string>> getInput(const ArgList &Args) {
- // Collect all input bitcode files to be passed to the linking stage.
- SmallVector<std::string> BitcodeFiles;
- auto Inputs = Args.filtered(OPT_INPUT);
- if (Inputs.empty())
- return createStringError("no input files provided");
- for (const opt::Arg *Arg : Inputs) {
- StringRef Filename = Arg->getValue();
- if (!sys::fs::exists(Filename) || sys::fs::is_directory(Filename))
- return createStringError("input file '" + Filename + "' does not exist");
- file_magic Magic;
- if (auto EC = identify_magic(Filename, Magic))
- return createStringError("failed to open file '" + Filename + "'");
- // TODO: Current use case involves LLVM IR bitcode files as input.
- // This will be extended to support SPIR-V IR files.
- if (Magic != file_magic::bitcode)
- return createStringError("unsupported file type for '" + Filename + "'");
- BitcodeFiles.push_back(std::string(Filename));
+namespace {
+/// A minimal symbol interface used to drive archive member extraction. Only
the
+/// flags required by the symbol-resolution fixed-point loop are tracked.
+struct Symbol {
+ enum Flags {
+ None = 0,
+ Undefined = 1 << 0,
+ Weak = 1 << 1,
+ };
+
+ Symbol() : SymFlags(None) {}
+ Symbol(Symbol::Flags F) : SymFlags(F) {}
+ Symbol(const irsymtab::Reader::SymbolRef Sym) : SymFlags(0) {
+ if (Sym.isUndefined())
+ SymFlags |= Undefined;
+ if (Sym.isWeak())
+ SymFlags |= Weak;
}
- return BitcodeFiles;
-}
-/// Handle cases where input file is a LLVM IR bitcode file.
-/// When clang-sycl-linker is called via clang-linker-wrapper tool, input files
-/// are LLVM IR bitcode files.
-// TODO: Support SPIR-V IR files.
-static Expected<std::unique_ptr<Module>> getBitcodeModule(StringRef File,
- LLVMContext &C) {
- SMDiagnostic Err;
+ bool isWeak() const { return SymFlags & Weak; }
+ bool isUndefined() const { return SymFlags & Undefined; }
- auto M = getLazyIRFileModule(File, Err, C);
- if (M)
- return std::move(M);
- return createStringError(Err.getMessage());
-}
+ uint32_t SymFlags;
+};
+
+/// Description of a single input (positional file or -l library).
+struct InputDesc {
+ enum class Kind { File, Library };
+
+ StringRef Value; // File path, or library name for -l (the value after -l).
+ Kind InputKind = Kind::File;
+ bool WholeArchive = false; // --whole-archive state in effect at this input.
+};
+
+/// An input buffer pending archive-member resolution, together with its parsed
+/// IR symbol table. The symbol table is parsed once and reused across all
+/// fixed-point passes so members are not re-parsed on every pass.
+struct PendingInput {
+ std::unique_ptr<MemoryBuffer> Buffer;
+ bool IsLazy = false;
+ bool FromArchive = false;
+ IRSymtabFile Symtab;
+};
+
+/// Resolved input buffers and their target triple.
+struct ResolvedInputs {
+ SmallVector<std::unique_ptr<MemoryBuffer>> Buffers;
+ llvm::Triple TargetTriple;
+ StringRef TripleSource; // Source of the triple (--triple= or filename)
+};
+} // namespace
static std::optional<std::string> findFile(StringRef Dir, const Twine &Name) {
- SmallString<128> Path(Dir);
- llvm::sys::path::append(Path, Name);
+ SmallString<128> Path;
+ sys::path::append(Path, Dir, Name);
+ // Skip directories so a directory whose name matches the requested library
+ // does not stop the search; a later -L path may hold the real archive.
if (sys::fs::exists(Path) && !sys::fs::is_directory(Path))
- return std::string(Path);
+ return static_cast<std::string>(Path);
return std::nullopt;
}
static std::optional<std::string>
-searchLibrary(StringRef Name, ArrayRef<StringRef> SearchPaths) {
- // An absolute path is taken as-is; -L paths are only consulted for relative
- // names.
- if (sys::path::is_absolute(Name)) {
- if (sys::fs::exists(Name) && !sys::fs::is_directory(Name))
- return std::string(Name);
- return std::nullopt;
- }
+findFromSearchPaths(StringRef Name, ArrayRef<StringRef> SearchPaths) {
for (StringRef Dir : SearchPaths)
if (std::optional<std::string> File = findFile(Dir, Name))
return File;
return std::nullopt;
}
-/// Gather all library files. The list of files and its location are passed
from
-/// driver.
-static Expected<SmallVector<std::string>>
-getBCLibraryNames(const ArgList &Args) {
+/// Search for static libraries in the linker's library path given input like
+/// `-lfoo`, `-l:libfoo.a`, or `-l/absolute/path/to/lib.a`.
+static std::optional<std::string>
+searchLibrary(StringRef Input, ArrayRef<StringRef> SearchPaths) {
+ // An absolute path is taken as-is; -L paths are only consulted for relative
+ // names.
+ if (sys::path::is_absolute(Input)) {
+ if (sys::fs::exists(Input) && !sys::fs::is_directory(Input))
+ return Input.str();
+ return std::nullopt;
+ }
+
+ if (Input.starts_with(":"))
+ return findFromSearchPaths(Input.drop_front(), SearchPaths);
+ SmallString<128> LibName("lib");
+ LibName += Input;
+ LibName += ".a";
+ return findFromSearchPaths(LibName, SearchPaths);
+}
+
+/// Scan a member's pre-parsed IR symbol table against \p LinkerSymtab and
+/// return true if the member should be extracted: it is non-lazy, or it
defines
+/// a symbol that resolves a currently-undefined reference. Mirrors a linker's
+/// archive member selection.
+static bool scanSymbols(const IRSymtabFile &MemberSymtab,
+ StringMap<Symbol> &LinkerSymtab, bool IsLazy) {
+ bool Extracted = !IsLazy;
+ StringMap<Symbol> PendingSymbols;
+ for (unsigned I = 0; I != MemberSymtab.Mods.size(); ++I) {
----------------
sarnex wrote:
nit
```suggestion
for (unsigned ModIdx = 0; ModIdx != MemberSymtab.Mods.size(); ++ModIdx) {
```
https://github.com/llvm/llvm-project/pull/202829
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits