================
@@ -187,13 +161,174 @@ void ModuleSymbolTable::CollectAsmSymbols(
   }
 }
 
+static void
+addSymbols(RecordStreamer &Streamer,
+           function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+  Streamer.flushSymverDirectives();
+
+  for (const auto &[Name, State] : Streamer) {
+    // FIXME: For now we just assume that all asm symbols are executable.
+    uint32_t Res = BasicSymbolRef::SF_Executable;
+    switch (State) {
+    case RecordStreamer::NeverSeen:
+      llvm_unreachable("NeverSeen should have been replaced earlier");
+    case RecordStreamer::DefinedGlobal:
+      Res |= BasicSymbolRef::SF_Global;
+      break;
+    case RecordStreamer::Defined:
+      break;
+    case RecordStreamer::Global:
+    case RecordStreamer::Used:
+      Res |= BasicSymbolRef::SF_Undefined;
+      Res |= BasicSymbolRef::SF_Global;
+      break;
+    case RecordStreamer::DefinedWeak:
+      Res |= BasicSymbolRef::SF_Weak;
+      Res |= BasicSymbolRef::SF_Global;
+      break;
+    case RecordStreamer::UndefinedWeak:
+      Res |= BasicSymbolRef::SF_Weak;
+      Res |= BasicSymbolRef::SF_Undefined;
+    }
+    AsmSymbol(Name, BasicSymbolRef::Flags(Res));
+  }
+}
+
+void ModuleSymbolTable::CollectAsmSymbols(
+    const Module &M,
+    function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+
+  MDTuple *SymbolsMD =
+      dyn_cast_if_present<MDTuple>(M.getModuleFlag("global-asm-symbols"));
+
+  if (SymbolsMD) {
+    for (const Metadata *MD : SymbolsMD->operands()) {
+      const MDTuple *SymMD = cast<MDTuple>(MD);
+      const MDString *Name = cast<MDString>(SymMD->getOperand(0));
+      const ConstantInt *Flags =
+          mdconst::extract<ConstantInt>(SymMD->getOperand(1));
+      AsmSymbol(Name->getString(),
+                static_cast<BasicSymbolRef::Flags>(Flags->getZExtValue()));
+    }
+    addSpecialSymbols(M, AsmSymbol);
+    return;
+  }
+
+  initializeRecordStreamer(
+      M, /*CPU=*/"", /*Features=*/"",
+      [&](RecordStreamer &Streamer) { addSymbols(Streamer, AsmSymbol); },
+      /*DiagHandler=*/nullptr);
+
+  addSpecialSymbols(M, AsmSymbol);
+}
+
+static void addSymvers(RecordStreamer &Streamer,
+                       function_ref<void(StringRef, StringRef)> AsmSymver) {
+  for (const auto &[Name, Aliases] : Streamer.symverAliases())
+    for (StringRef Alias : Aliases)
+      AsmSymver(Name->getName(), Alias);
+}
+
 void ModuleSymbolTable::CollectAsmSymvers(
     const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) {
-  initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
-    for (auto &KV : Streamer.symverAliases())
-      for (auto &Alias : KV.second)
-        AsmSymver(KV.first->getName(), Alias);
-  });
+
+  MDTuple *SymversMD =
+      dyn_cast_if_present<MDTuple>(M.getModuleFlag("global-asm-symvers"));
+
+  if (SymversMD) {
+    for (const Metadata *MD : SymversMD->operands()) {
+      const MDTuple *SymverMD = cast<MDTuple>(MD);
+      StringRef Name = cast<MDString>(SymverMD->getOperand(0))->getString();
+      for (size_t i = 1, End = SymverMD->getNumOperands(); i < End; ++i) {
----------------
asavonic wrote:

Sorry, I check all `if`s, but missed all `for`s. Now it should be OK.

https://github.com/llvm/llvm-project/pull/174995
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to