It could come about that we parse the inline ASM before we get a potential
authorBill Wendling <isanbard@gmail.com>
Mon, 2 Apr 2012 03:33:31 +0000 (03:33 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 2 Apr 2012 03:33:31 +0000 (03:33 +0000)
definition for it. In that case, we want to wait for the potential definition
before we create a symbol for it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153859 91177308-0d34-0410-b5e6-96231b3b80d8

tools/lto/LTOModule.cpp
tools/lto/LTOModule.h

index fb66973357d5ba1732c07bd1bd7f20c3207c4225..3bd764cb76a1ba9a0d7a904d333980d6bf1f68c5 100644 (file)
@@ -399,6 +399,18 @@ void LTOModule::addAsmGlobalSymbol(const char *name,
 
   NameAndAttributes &info = _undefines[entry.getKey().data()];
 
+  if (info.symbol == 0) {
+    // If we haven't seen this symbol before, save it and we may see it again.
+    StringMap<NameAndAttributes>::value_type
+      &asm_entry = _asm_defines.GetOrCreateValue(name);
+    NameAndAttributes &asm_info = _asm_defines[asm_entry.getKey().data()];
+    asm_info.name = name;
+    asm_info.attributes = scope;
+    asm_info.isFunction = false;
+    asm_info.symbol = 0;
+    return;
+  }
+
   if (info.isFunction)
     addDefinedFunctionSymbol(cast<Function>(info.symbol));
   else
@@ -452,6 +464,20 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, bool isFunc) {
   if (entry.getValue().name)
     return;
 
+  StringMap<NameAndAttributes>::value_type &asm_entry =
+    _asm_defines.GetOrCreateValue(name);
+
+  if (asm_entry.getValue().name != 0) {
+    if (isFunc)
+      addDefinedFunctionSymbol(cast<Function>(decl));
+    else
+      addDefinedDataSymbol(decl);
+
+    _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
+    _symbols.back().attributes |= asm_entry.getValue().attributes;
+    return;
+  }
+
   NameAndAttributes info;
 
   info.name = entry.getKey().data();
index cafb927abfb1210a2b46a22932e919358ed1eaec..6280c6770d2da5cd465a189259d93a60fe535820 100644 (file)
@@ -53,6 +53,7 @@ private:
   // _defines and _undefines only needed to disambiguate tentative definitions
   StringSet                               _defines;
   llvm::StringMap<NameAndAttributes>      _undefines;
+  llvm::StringMap<NameAndAttributes>      _asm_defines;
   std::vector<const char*>                _asm_undefines;
   llvm::MCContext                         _context;