================
@@ -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

Reply via email to