<div dir="ltr">The assertion was (temporarily) removed in r325181.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 14, 2018 at 2:30 PM, Vitaly Buka <span dir="ltr"><<a href="mailto:vitalybuka@google.com" target="_blank">vitalybuka@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Some bots are red for hours.</div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/8532/steps/check-asan%20in%20gcc%20build/logs/stdio" target="_blank">http://lab.llvm.org:8011/<wbr>builders/sanitizer-x86_64-<wbr>linux/builds/8532/steps/check-<wbr>asan%20in%20gcc%20build/logs/<wbr>stdio</a><br></div>Could you please revert or commit the fix?</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 14, 2018 at 2:26 PM, Sam Clegg via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><a href="https://reviews.llvm.org/D43317" rel="noreferrer" target="_blank">https://reviews.llvm.org/D4331<wbr>7</a><br>
<div class="m_6506724463395761542HOEnZb"><div class="m_6506724463395761542h5"><br>
On Wed, Feb 14, 2018 at 2:04 PM, Rui Ueyama <<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>> wrote:<br>
> I guess that the use of llvm::Optional isn't safe in this context. It has a<br>
> user-defined desctructor. Could you use 0 or -1 to represent "not set"<br>
> status?<br>
><br>
> On Wed, Feb 14, 2018 at 2:00 PM, Sam Clegg <<a href="mailto:sbc@google.com" target="_blank">sbc@google.com</a>> wrote:<br>
>><br>
>> Works for me too.  I added this assert to the other backends yesterday<br>
>> without issue.  Strange...<br>
>><br>
>> On Wed, Feb 14, 2018 at 1:15 PM, Rui Ueyama <<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>> wrote:<br>
>> > It compiles on my machine. What is "T" when it fails on the assertion?<br>
>> ><br>
>> > On Wed, Feb 14, 2018 at 1:10 PM, Michael Spencer via llvm-commits<br>
>> > <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
>> >><br>
>> >> This doesn't build for me.<br>
>> >><br>
>> >> /home/michael/llvm-project/lld<wbr>/wasm/Symbols.h:240:3: error: static<br>
>> >> assertion failed: Symbol types must be trivially destructible<br>
>> >> │<br>
>> >>    static_assert(std::is_triviall<wbr>y_destructible<T>(),<br>
>> >> │<br>
>> >>    ^~~~~~~~~~~~~<br>
>> >><br>
>> >> - Michael Spencer<br>
>> >><br>
>> >> On Wed, Feb 14, 2018 at 10:27 AM, Sam Clegg via llvm-commits<br>
>> >> <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
>> >>><br>
>> >>> Author: sbc<br>
>> >>> Date: Wed Feb 14 10:27:59 2018<br>
>> >>> New Revision: 325150<br>
>> >>><br>
>> >>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=325150&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=325150&view=rev</a><br>
>> >>> Log:<br>
>> >>> [WebAssembly] Use a Symbol class heirarchy. NFC.<br>
>> >>><br>
>> >>> This brings wasm into line with ELF and COFF in terms of<br>
>> >>> symbol types are represented.<br>
>> >>><br>
>> >>> Differential Revision: <a href="https://reviews.llvm.org/D43112" rel="noreferrer" target="_blank">https://reviews.llvm.org/D4311<wbr>2</a><br>
>> >>><br>
>> >>> Modified:<br>
>> >>>     lld/trunk/wasm/InputFiles.cpp<br>
>> >>>     lld/trunk/wasm/InputFiles.h<br>
>> >>>     lld/trunk/wasm/SymbolTable.<wbr>cpp<br>
>> >>>     lld/trunk/wasm/SymbolTable.h<br>
>> >>>     lld/trunk/wasm/Symbols.cpp<br>
>> >>>     lld/trunk/wasm/Symbols.h<br>
>> >>>     lld/trunk/wasm/Writer.cpp<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/InputFiles.cpp<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/InputFile<wbr>s.cpp?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/InputFiles.cpp (original)<br>
>> >>> +++ lld/trunk/wasm/InputFiles.cpp Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -51,11 +51,14 @@ void ObjFile::dumpInfo() const {<br>
>> >>>  }<br>
>> >>><br>
>> >>>  uint32_t ObjFile::relocateVirtualAddres<wbr>s(uint32_t GlobalIndex) const<br>
>> >>> {<br>
>> >>> -  return getGlobalSymbol(GlobalIndex)-><wbr>getVirtualAddress();<br>
>> >>> +  if (auto *DG =<br>
>> >>> dyn_cast<DefinedGlobal>(getGlo<wbr>balSymbol(GlobalIndex)))<br>
>> >>> +    return DG->getVirtualAddress();<br>
>> >>> +  else<br>
>> >>> +    return 0;<br>
>> >>>  }<br>
>> >>><br>
>> >>>  uint32_t ObjFile::relocateFunctionIndex<wbr>(uint32_t Original) const {<br>
>> >>> -  const Symbol *Sym = getFunctionSymbol(Original);<br>
>> >>> +  const FunctionSymbol *Sym = getFunctionSymbol(Original);<br>
>> >>>    uint32_t Index = Sym->getOutputIndex();<br>
>> >>>    DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "<br>
>> >>>                 << Original << " -> " << Index << "\n");<br>
>> >>> @@ -68,7 +71,7 @@ uint32_t ObjFile::relocateTypeIndex(uin<wbr>t<br>
>> >>>  }<br>
>> >>><br>
>> >>>  uint32_t ObjFile::relocateTableIndex(ui<wbr>nt32_t Original) const {<br>
>> >>> -  const Symbol *Sym = getFunctionSymbol(Original);<br>
>> >>> +  const FunctionSymbol *Sym = getFunctionSymbol(Original);<br>
>> >>>    uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;<br>
>> >>>    DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " <<<br>
>> >>> Original<br>
>> >>>                 << " -> " << Index << "\n");<br>
>> >>> @@ -249,7 +252,7 @@ void ObjFile::initializeSymbols() {<br>
>> >>>      case WasmSymbol::SymbolType::FUNCTI<wbr>ON_EXPORT: {<br>
>> >>>        InputFunction *Function = getFunction(WasmSym);<br>
>> >>>        if (!isExcludedByComdat(Function)<wbr>) {<br>
>> >>> -        S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionK<wbr>ind,<br>
>> >>> Function);<br>
>> >>> +        S = createDefinedFunction(WasmSym, Function);<br>
>> >>>          break;<br>
>> >>>        } else {<br>
>> >>>          Function->Live = false;<br>
>> >>> @@ -263,8 +266,7 @@ void ObjFile::initializeSymbols() {<br>
>> >>>      case WasmSymbol::SymbolType::GLOBAL<wbr>_EXPORT: {<br>
>> >>>        InputSegment *Segment = getSegment(WasmSym);<br>
>> >>>        if (!isExcludedByComdat(Segment)) {<br>
>> >>> -        S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKin<wbr>d,<br>
>> >>> Segment,<br>
>> >>> -                          getGlobalValue(WasmSym));<br>
>> >>> +        S = createDefinedGlobal(WasmSym, Segment,<br>
>> >>> getGlobalValue(WasmSym));<br>
>> >>>          break;<br>
>> >>>        } else {<br>
>> >>>          Segment->Live = false;<br>
>> >>> @@ -302,15 +304,18 @@ Symbol *ObjFile::createUndefined(cons<wbr>t W<br>
>> >>>    return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this,<br>
>> >>> Signature);<br>
>> >>>  }<br>
>> >>><br>
>> >>> -Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind<br>
>> >>> Kind,<br>
>> >>> -                               InputChunk *Chunk, uint32_t Address) {<br>
>> >>> -  Symbol *S;<br>
>> >>> -  if (Sym.isBindingLocal()) {<br>
>> >>> -    S = make<Symbol>(Sym.Name, true);<br>
>> >>> -    S->update(Kind, this, Sym.Flags, Chunk, Address);<br>
>> >>> -    return S;<br>
>> >>> -  }<br>
>> >>> -  return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk,<br>
>> >>> Address);<br>
>> >>> +Symbol *ObjFile::createDefinedFunctio<wbr>n(const WasmSymbol &Sym,<br>
>> >>> +                                       InputChunk *Chunk) {<br>
>> >>> +  if (Sym.isBindingLocal())<br>
>> >>> +    return make<DefinedFunction>(Sym.Name<wbr>, Sym.Flags, this, Chunk);<br>
>> >>> +  return Symtab->addDefined(true, Sym.Name, Sym.Flags, this, Chunk);<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +Symbol *ObjFile::createDefinedGlobal(<wbr>const WasmSymbol &Sym,<br>
>> >>> InputChunk<br>
>> >>> *Chunk,<br>
>> >>> +                                     uint32_t Address) {<br>
>> >>> +  if (Sym.isBindingLocal())<br>
>> >>> +    return make<DefinedGlobal>(Sym.Name, Sym.Flags, this, Chunk,<br>
>> >>> Address);<br>
>> >>> +  return Symtab->addDefined(false, Sym.Name, Sym.Flags, this, Chunk,<br>
>> >>> Address);<br>
>> >>>  }<br>
>> >>><br>
>> >>>  void ArchiveFile::parse() {<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/InputFiles.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/InputFile<wbr>s.h?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/InputFiles.h (original)<br>
>> >>> +++ lld/trunk/wasm/InputFiles.h Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -107,11 +107,13 @@ public:<br>
>> >>><br>
>> >>>    ArrayRef<Symbol *> getSymbols() const { return Symbols; }<br>
>> >>><br>
>> >>> -  Symbol *getFunctionSymbol(uint32_t Index) const {<br>
>> >>> -    return FunctionSymbols[Index];<br>
>> >>> +  FunctionSymbol *getFunctionSymbol(uint32_t Index) const {<br>
>> >>> +    return cast<FunctionSymbol>(FunctionS<wbr>ymbols[Index]);<br>
>> >>>    }<br>
>> >>><br>
>> >>> -  Symbol *getGlobalSymbol(uint32_t Index) const { return<br>
>> >>> GlobalSymbols[Index]; }<br>
>> >>> +  GlobalSymbol *getGlobalSymbol(uint32_t Index) const {<br>
>> >>> +    return cast<GlobalSymbol>(GlobalSymbo<wbr>ls[Index]);<br>
>> >>> +  }<br>
>> >>><br>
>> >>>  private:<br>
>> >>>    uint32_t relocateVirtualAddress(uint32_<wbr>t Index) const;<br>
>> >>> @@ -119,9 +121,9 @@ private:<br>
>> >>>    uint32_t relocateGlobalIndex(uint32_t Original) const;<br>
>> >>>    uint32_t relocateTableIndex(uint32_t Original) const;<br>
>> >>><br>
>> >>> -  Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,<br>
>> >>> -                        InputChunk *Chunk = nullptr,<br>
>> >>> -                        uint32_t Address = UINT32_MAX);<br>
>> >>> +  Symbol *createDefinedGlobal(const WasmSymbol &Sym, InputChunk<br>
>> >>> *Chunk,<br>
>> >>> +                              uint32_t Address);<br>
>> >>> +  Symbol *createDefinedFunction(const WasmSymbol &Sym, InputChunk<br>
>> >>> *Chunk);<br>
>> >>>    Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,<br>
>> >>>                            const WasmSignature *Signature = nullptr);<br>
>> >>>    void initializeSymbols();<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/SymbolTable.cpp<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/SymbolTab<wbr>le.cpp?rev=325150&r1=325149&<wbr>r2=325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/SymbolTable.cpp (original)<br>
>> >>> +++ lld/trunk/wasm/SymbolTable.cpp Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -66,7 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::i<br>
>> >>>    Symbol *&Sym = SymMap[CachedHashStringRef(Nam<wbr>e)];<br>
>> >>>    if (Sym)<br>
>> >>>      return {Sym, false};<br>
>> >>> -  Sym = make<Symbol>(Name, false);<br>
>> >>> +  Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());<br>
>> >>>    SymVector.emplace_back(Sym);<br>
>> >>>    return {Sym, true};<br>
>> >>>  }<br>
>> >>> @@ -80,13 +80,10 @@ void SymbolTable::reportDuplicate(S<wbr>ymbol<br>
>> >>>  // Check the type of new symbol matches that of the symbol is<br>
>> >>> replacing.<br>
>> >>>  // For functions this can also involve verifying that the signatures<br>
>> >>> match.<br>
>> >>>  static void checkSymbolTypes(const Symbol &Existing, const InputFile<br>
>> >>> &F,<br>
>> >>> -                             Symbol::Kind Kind, const WasmSignature<br>
>> >>> *NewSig) {<br>
>> >>> +                             bool NewIsFunction, const WasmSignature<br>
>> >>> *NewSig) {<br>
>> >>>    if (Existing.isLazy())<br>
>> >>>      return;<br>
>> >>><br>
>> >>> -  bool NewIsFunction = Kind == Symbol::Kind::UndefinedFunctio<wbr>nKind ||<br>
>> >>> -                       Kind == Symbol::Kind::DefinedFunctionK<wbr>ind;<br>
>> >>> -<br>
>> >>>    // First check the symbol types match (i.e. either both are<br>
>> >>> function<br>
>> >>>    // symbols or both are data symbols).<br>
>> >>>    if (Existing.isFunction() != NewIsFunction) {<br>
>> >>> @@ -98,105 +95,102 @@ static void checkSymbolTypes(const Symbo<br>
>> >>>    }<br>
>> >>><br>
>> >>>    // For function symbols, optionally check the function signature<br>
>> >>> matches too.<br>
>> >>> -  if (!NewIsFunction || !Config->CheckSignatures)<br>
>> >>> +  auto *ExistingFunc = dyn_cast<FunctionSymbol>(&Exis<wbr>ting);<br>
>> >>> +  if (!ExistingFunc || !Config->CheckSignatures)<br>
>> >>>      return;<br>
>> >>> +<br>
>> >>>    // Skip the signature check if the existing function has no<br>
>> >>> signature<br>
>> >>> (e.g.<br>
>> >>>    // if it is an undefined symbol generated by --undefined command<br>
>> >>> line<br>
>> >>> flag).<br>
>> >>> -  if (!Existing.hasFunctionType())<br>
>> >>> +  if (!ExistingFunc->hasFunctionTyp<wbr>e())<br>
>> >>>      return;<br>
>> >>><br>
>> >>> -  DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() <<<br>
>> >>> "\n");<br>
>> >>> +  DEBUG(dbgs() << "checkSymbolTypes: " << ExistingFunc->getName() <<<br>
>> >>> "\n");<br>
>> >>>    assert(NewSig);<br>
>> >>><br>
>> >>> -  const WasmSignature &OldSig = Existing.getFunctionType();<br>
>> >>> +  const WasmSignature &OldSig = ExistingFunc->getFunctionType(<wbr>);<br>
>> >>>    if (*NewSig == OldSig)<br>
>> >>>      return;<br>
>> >>><br>
>> >>> -  error("function signature mismatch: " + Existing.getName() +<br>
>> >>> +  error("function signature mismatch: " + ExistingFunc->getName() +<br>
>> >>>          "\n>>> defined as " + toString(OldSig) + " in " +<br>
>> >>> -        toString(Existing.getFile()) + "\n>>> defined as " +<br>
>> >>> toString(*NewSig) +<br>
>> >>> -        " in " + F.getName());<br>
>> >>> +        toString(ExistingFunc->getFile<wbr>()) + "\n>>> defined as " +<br>
>> >>> +        toString(*NewSig) + " in " + F.getName());<br>
>> >>>  }<br>
>> >>><br>
>> >>>  static void checkSymbolTypes(const Symbol &Existing, const InputFile<br>
>> >>> &F,<br>
>> >>> -                             Symbol::Kind Kind, const InputChunk<br>
>> >>> *Chunk)<br>
>> >>> {<br>
>> >>> +                             bool IsFunction, const InputChunk<br>
>> >>> *Chunk) {<br>
>> >>>    const WasmSignature *Sig = nullptr;<br>
>> >>>    if (auto *F = dyn_cast_or_null<InputFunction<wbr>>(Chunk))<br>
>> >>>      Sig = &F->Signature;<br>
>> >>> -  return checkSymbolTypes(Existing, F, Kind, Sig);<br>
>> >>> +  return checkSymbolTypes(Existing, F, IsFunction, Sig);<br>
>> >>>  }<br>
>> >>><br>
>> >>> -Symbol *SymbolTable::addSyntheticFunc<wbr>tion(StringRef Name,<br>
>> >>> -                                          const WasmSignature *Type,<br>
>> >>> -                                          uint32_t Flags) {<br>
>> >>> +DefinedFunction *SymbolTable::addSyntheticFunc<wbr>tion(StringRef Name,<br>
>> >>> +                                                   const<br>
>> >>> WasmSignature<br>
>> >>> *Type,<br>
>> >>> +                                                   uint32_t Flags) {<br>
>> >>>    DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");<br>
>> >>>    Symbol *S;<br>
>> >>>    bool WasInserted;<br>
>> >>>    std::tie(S, WasInserted) = insert(Name);<br>
>> >>>    assert(WasInserted);<br>
>> >>> -  S->update(Symbol::DefinedFunct<wbr>ionKind, nullptr, Flags);<br>
>> >>> -  S->setFunctionType(Type);<br>
>> >>> -  return S;<br>
>> >>> +  return replaceSymbol<DefinedFunction><wbr>(S, Name, Flags, Type);<br>
>> >>>  }<br>
>> >>><br>
>> >>> -Symbol *SymbolTable::addSyntheticGlob<wbr>al(StringRef Name) {<br>
>> >>> +DefinedGlobal *SymbolTable::addSyntheticGlob<wbr>al(StringRef Name,<br>
>> >>> uint32_t<br>
>> >>> Flags) {<br>
>> >>>    DEBUG(dbgs() << "addSyntheticGlobal: " << Name << "\n");<br>
>> >>>    Symbol *S;<br>
>> >>>    bool WasInserted;<br>
>> >>>    std::tie(S, WasInserted) = insert(Name);<br>
>> >>>    assert(WasInserted);<br>
>> >>> -  S->update(Symbol::DefinedGloba<wbr>lKind);<br>
>> >>> -  return S;<br>
>> >>> +  return replaceSymbol<DefinedGlobal>(S<wbr>, Name, Flags);<br>
>> >>>  }<br>
>> >>><br>
>> >>> -Symbol *SymbolTable::addDefined(Strin<wbr>gRef Name, Symbol::Kind Kind,<br>
>> >>> -                                uint32_t Flags, InputFile *F,<br>
>> >>> InputChunk<br>
>> >>> *Chunk,<br>
>> >>> +Symbol *SymbolTable::addDefined(bool IsFunction, StringRef Name,<br>
>> >>> uint32_t Flags,<br>
>> >>> +                                InputFile *F, InputChunk *Chunk,<br>
>> >>>                                  uint32_t Address) {<br>
>> >>> -  DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address <<<br>
>> >>> "\n");<br>
>> >>> +  if (IsFunction)<br>
>> >>> +    DEBUG(dbgs() << "addDefined: func:" << Name << "\n");<br>
>> >>> +  else<br>
>> >>> +    DEBUG(dbgs() << "addDefined: global:" << Name << " addr:" <<<br>
>> >>> Address<br>
>> >>> +                 << "\n");<br>
>> >>>    Symbol *S;<br>
>> >>>    bool WasInserted;<br>
>> >>> +  bool Replace = false;<br>
>> >>> +  bool CheckTypes = false;<br>
>> >>><br>
>> >>>    std::tie(S, WasInserted) = insert(Name);<br>
>> >>>    if (WasInserted) {<br>
>> >>> -    S->update(Kind, F, Flags, Chunk, Address);<br>
>> >>> +    Replace = true;<br>
>> >>>    } else if (S->isLazy()) {<br>
>> >>> -    // The existing symbol is lazy. Replace it without checking types<br>
>> >>> since<br>
>> >>> +    // Existing symbol is lazy. Replace it without checking types<br>
>> >>> since<br>
>> >>>      // lazy symbols don't have any type information.<br>
>> >>>      DEBUG(dbgs() << "replacing existing lazy symbol: " << Name <<<br>
>> >>> "\n");<br>
>> >>> -    S->update(Kind, F, Flags, Chunk, Address);<br>
>> >>> +    Replace = true;<br>
>> >>>    } else if (!S->isDefined()) {<br>
>> >>> -    // The existing symbol table entry is undefined. The new symbol<br>
>> >>> replaces<br>
>> >>> -    // it, after checking the type matches<br>
>> >>> +    // Existing symbol is undefined: replace it, while check types.<br>
>> >>>      DEBUG(dbgs() << "resolving existing undefined symbol: " << Name<br>
>> >>> <<<br>
>> >>> "\n");<br>
>> >>> -    checkSymbolTypes(*S, *F, Kind, Chunk);<br>
>> >>> -    S->update(Kind, F, Flags, Chunk, Address);<br>
>> >>> +    Replace = true;<br>
>> >>> +    CheckTypes = true;<br>
>> >>>    } else if ((Flags & WASM_SYMBOL_BINDING_MASK) ==<br>
>> >>> WASM_SYMBOL_BINDING_WEAK) {<br>
>> >>>      // the new symbol is weak we can ignore it<br>
>> >>>      DEBUG(dbgs() << "existing symbol takes precedence\n");<br>
>> >>>    } else if (S->isWeak()) {<br>
>> >>> -    // the new symbol is not weak and the existing symbol is, so we<br>
>> >>> replace<br>
>> >>> -    // it<br>
>> >>> +    // the existing symbol is, so we replace it<br>
>> >>>      DEBUG(dbgs() << "replacing existing weak symbol\n");<br>
>> >>> -    checkSymbolTypes(*S, *F, Kind, Chunk);<br>
>> >>> -    S->update(Kind, F, Flags, Chunk, Address);<br>
>> >>> +    Replace = true;<br>
>> >>> +    CheckTypes = true;<br>
>> >>>    } else {<br>
>> >>>      // neither symbol is week. They conflict.<br>
>> >>>      reportDuplicate(S, F);<br>
>> >>>    }<br>
>> >>> -  return S;<br>
>> >>> -}<br>
>> >>><br>
>> >>> -Symbol *SymbolTable::addUndefinedFunc<wbr>tion(StringRef Name,<br>
>> >>> -                                          const WasmSignature *Type)<br>
>> >>> {<br>
>> >>> -  DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");<br>
>> >>> -  Symbol *S;<br>
>> >>> -  bool WasInserted;<br>
>> >>> -  std::tie(S, WasInserted) = insert(Name);<br>
>> >>> -  if (WasInserted) {<br>
>> >>> -    S->update(Symbol::UndefinedFun<wbr>ctionKind);<br>
>> >>> -    S->setFunctionType(Type);<br>
>> >>> -  } else if (!S->isFunction()) {<br>
>> >>> -    error("symbol type mismatch: " + Name);<br>
>> >>> +  if (Replace) {<br>
>> >>> +    if (CheckTypes)<br>
>> >>> +      checkSymbolTypes(*S, *F, IsFunction, Chunk);<br>
>> >>> +    if (IsFunction)<br>
>> >>> +      replaceSymbol<DefinedFunction><wbr>(S, Name, Flags, F, Chunk);<br>
>> >>> +    else<br>
>> >>> +      replaceSymbol<DefinedGlobal>(S<wbr>, Name, Flags, F, Chunk,<br>
>> >>> Address);<br>
>> >>>    }<br>
>> >>>    return S;<br>
>> >>>  }<br>
>> >>> @@ -208,17 +202,19 @@ Symbol *SymbolTable::addUndefined(Str<wbr>ing<br>
>> >>>    Symbol *S;<br>
>> >>>    bool WasInserted;<br>
>> >>>    std::tie(S, WasInserted) = insert(Name);<br>
>> >>> +  bool IsFunction = Kind == Symbol::UndefinedFunctionKind;<br>
>> >>>    if (WasInserted) {<br>
>> >>> -    S->update(Kind, F, Flags);<br>
>> >>> -    if (Type)<br>
>> >>> -      S->setFunctionType(Type);<br>
>> >>> -  } else if (S->isLazy()) {<br>
>> >>> +    if (IsFunction)<br>
>> >>> +      replaceSymbol<UndefinedFunctio<wbr>n>(S, Name, Flags, F, Type);<br>
>> >>> +    else<br>
>> >>> +      replaceSymbol<UndefinedGlobal><wbr>(S, Name, Flags, F);<br>
>> >>> +  } else if (auto *LazySym = dyn_cast<LazySymbol>(S)) {<br>
>> >>>      DEBUG(dbgs() << "resolved by existing lazy\n");<br>
>> >>> -    auto *AF = cast<ArchiveFile>(S->getFile()<wbr>);<br>
>> >>> -    AF->addMember(&S->getArchiveSy<wbr>mbol());<br>
>> >>> +    auto *AF = cast<ArchiveFile>(LazySym->get<wbr>File());<br>
>> >>> +    AF->addMember(&LazySym->getArc<wbr>hiveSymbol());<br>
>> >>>    } else if (S->isDefined()) {<br>
>> >>>      DEBUG(dbgs() << "resolved by existing\n");<br>
>> >>> -    checkSymbolTypes(*S, *F, Kind, Type);<br>
>> >>> +    checkSymbolTypes(*S, *F, IsFunction, Type);<br>
>> >>>    }<br>
>> >>>    return S;<br>
>> >>>  }<br>
>> >>> @@ -230,8 +226,7 @@ void SymbolTable::addLazy(ArchiveFi<wbr>le *F<br>
>> >>>    bool WasInserted;<br>
>> >>>    std::tie(S, WasInserted) = insert(Name);<br>
>> >>>    if (WasInserted) {<br>
>> >>> -    S->update(Symbol::LazyKind, F);<br>
>> >>> -    S->setArchiveSymbol(*Sym);<br>
>> >>> +    replaceSymbol<LazySymbol>(S, Name, F, *Sym);<br>
>> >>>    } else if (S->isUndefined()) {<br>
>> >>>      // There is an existing undefined symbol.  The can load from the<br>
>> >>>      // archive.<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/SymbolTable.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/SymbolTab<wbr>le.h?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/SymbolTable.h (original)<br>
>> >>> +++ lld/trunk/wasm/SymbolTable.h Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -49,7 +49,7 @@ public:<br>
>> >>>    Symbol *find(StringRef Name);<br>
>> >>>    ObjFile *findComdat(StringRef Name) const;<br>
>> >>><br>
>> >>> -  Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t<br>
>> >>> Flags,<br>
>> >>> +  Symbol *addDefined(bool IsFunction, StringRef Name, uint32_t Flags,<br>
>> >>>                       InputFile *F, InputChunk *Chunk = nullptr,<br>
>> >>>                       uint32_t Address = 0);<br>
>> >>>    Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t<br>
>> >>> Flags,<br>
>> >>> @@ -58,9 +58,10 @@ public:<br>
>> >>>    void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);<br>
>> >>>    bool addComdat(StringRef Name, ObjFile *);<br>
>> >>><br>
>> >>> -  Symbol *addSyntheticGlobal(StringRef Name);<br>
>> >>> -  Symbol *addSyntheticFunction(StringRe<wbr>f Name, const WasmSignature<br>
>> >>> *Type,<br>
>> >>> -                               uint32_t Flags);<br>
>> >>> +  DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags =<br>
>> >>> 0);<br>
>> >>> +  DefinedFunction *addSyntheticFunction(StringRe<wbr>f Name,<br>
>> >>> +                                        const WasmSignature *Type,<br>
>> >>> +                                        uint32_t Flags = 0);<br>
>> >>>  private:<br>
>> >>>    std::pair<Symbol *, bool> insert(StringRef Name);<br>
>> >>><br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/Symbols.cpp<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/Symbols.<wbr>cpp?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/Symbols.cpp (original)<br>
>> >>> +++ lld/trunk/wasm/Symbols.cpp Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -22,32 +22,11 @@ using namespace llvm::wasm;<br>
>> >>>  using namespace lld;<br>
>> >>>  using namespace lld::wasm;<br>
>> >>><br>
>> >>> -Symbol *WasmSym::CallCtors;<br>
>> >>> -Symbol *WasmSym::DsoHandle;<br>
>> >>> -Symbol *WasmSym::DataEnd;<br>
>> >>> -Symbol *WasmSym::HeapBase;<br>
>> >>> -Symbol *WasmSym::StackPointer;<br>
>> >>> -<br>
>> >>> -const WasmSignature &Symbol::getFunctionType() const {<br>
>> >>> -  if (Chunk != nullptr)<br>
>> >>> -    return dyn_cast<InputFunction>(Chunk)<wbr>->Signature;<br>
>> >>> -<br>
>> >>> -  assert(FunctionType != nullptr);<br>
>> >>> -  return *FunctionType;<br>
>> >>> -}<br>
>> >>> -<br>
>> >>> -void Symbol::setFunctionType(const WasmSignature *Type) {<br>
>> >>> -  assert(FunctionType == nullptr);<br>
>> >>> -  assert(!Chunk);<br>
>> >>> -  FunctionType = Type;<br>
>> >>> -}<br>
>> >>> -<br>
>> >>> -uint32_t Symbol::getVirtualAddress() const {<br>
>> >>> -  assert(isGlobal());<br>
>> >>> -  DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");<br>
>> >>> -  return Chunk ?<br>
>> >>> dyn_cast<InputSegment>(Chunk)-<wbr>>translateVA(VirtualAddress)<br>
>> >>> -               : VirtualAddress;<br>
>> >>> -}<br>
>> >>> +DefinedFunction *WasmSym::CallCtors;<br>
>> >>> +DefinedGlobal *WasmSym::DsoHandle;<br>
>> >>> +DefinedGlobal *WasmSym::DataEnd;<br>
>> >>> +DefinedGlobal *WasmSym::HeapBase;<br>
>> >>> +DefinedGlobal *WasmSym::StackPointer;<br>
>> >>><br>
>> >>>  bool Symbol::hasOutputIndex() const {<br>
>> >>>    if (auto *F = dyn_cast_or_null<InputFunction<wbr>>(Chunk))<br>
>> >>> @@ -61,12 +40,6 @@ uint32_t Symbol::getOutputIndex() const<br>
>> >>>    return OutputIndex.getValue();<br>
>> >>>  }<br>
>> >>><br>
>> >>> -void Symbol::setVirtualAddress(uint<wbr>32_t Value) {<br>
>> >>> -  DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value <<<br>
>> >>> "\n");<br>
>> >>> -  assert(isGlobal());<br>
>> >>> -  VirtualAddress = Value;<br>
>> >>> -}<br>
>> >>> -<br>
>> >>>  void Symbol::setOutputIndex(uint32_<wbr>t Index) {<br>
>> >>>    DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index <<<br>
>> >>> "\n");<br>
>> >>>    assert(!dyn_cast_or_null<Input<wbr>Function>(Chunk));<br>
>> >>> @@ -74,19 +47,54 @@ void Symbol::setOutputIndex(uint32_<wbr>t Ind<br>
>> >>>    OutputIndex = Index;<br>
>> >>>  }<br>
>> >>><br>
>> >>> -uint32_t Symbol::getTableIndex() const {<br>
>> >>> +bool Symbol::isWeak() const {<br>
>> >>> +  return (Flags & WASM_SYMBOL_BINDING_MASK) ==<br>
>> >>> WASM_SYMBOL_BINDING_WEAK;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +bool Symbol::isLocal() const {<br>
>> >>> +  return (Flags & WASM_SYMBOL_BINDING_MASK) ==<br>
>> >>> WASM_SYMBOL_BINDING_LOCAL;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +bool Symbol::isHidden() const {<br>
>> >>> +  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) ==<br>
>> >>> WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +void Symbol::setHidden(bool IsHidden) {<br>
>> >>> +  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden <<<br>
>> >>> "\n");<br>
>> >>> +  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;<br>
>> >>> +  if (IsHidden)<br>
>> >>> +    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>> >>> +  else<br>
>> >>> +    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT<wbr>;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +const WasmSignature &FunctionSymbol::getFunctionTy<wbr>pe() const {<br>
>> >>> +  if (auto *F = dyn_cast_or_null<InputFunction<wbr>>(Chunk))<br>
>> >>> +    return F->Signature;<br>
>> >>> +<br>
>> >>> +  assert(FunctionType != nullptr);<br>
>> >>> +  return *FunctionType;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +void FunctionSymbol::setFunctionTyp<wbr>e(const WasmSignature *Type) {<br>
>> >>> +  assert(FunctionType == nullptr);<br>
>> >>> +  assert(!Chunk);<br>
>> >>> +  FunctionType = Type;<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +uint32_t FunctionSymbol::getTableIndex(<wbr>) const {<br>
>> >>>    if (auto *F = dyn_cast_or_null<InputFunction<wbr>>(Chunk))<br>
>> >>>      return F->getTableIndex();<br>
>> >>>    return TableIndex.getValue();<br>
>> >>>  }<br>
>> >>><br>
>> >>> -bool Symbol::hasTableIndex() const {<br>
>> >>> +bool FunctionSymbol::hasTableIndex(<wbr>) const {<br>
>> >>>    if (auto *F = dyn_cast_or_null<InputFunction<wbr>>(Chunk))<br>
>> >>>      return F->hasTableIndex();<br>
>> >>>    return TableIndex.hasValue();<br>
>> >>>  }<br>
>> >>><br>
>> >>> -void Symbol::setTableIndex(uint32_t Index) {<br>
>> >>> +void FunctionSymbol::setTableIndex(<wbr>uint32_t Index) {<br>
>> >>>    // For imports, we set the table index here on the Symbol; for<br>
>> >>> defined<br>
>> >>>    // functions we set the index on the InputFunction so that we don't<br>
>> >>> export<br>
>> >>>    // the same thing twice (keeps the table size down).<br>
>> >>> @@ -99,35 +107,17 @@ void Symbol::setTableIndex(uint32_t Inde<br>
>> >>>    TableIndex = Index;<br>
>> >>>  }<br>
>> >>><br>
>> >>> -void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, InputChunk<br>
>> >>> *Chunk_,<br>
>> >>> -                    uint32_t Address) {<br>
>> >>> -  SymbolKind = K;<br>
>> >>> -  File = F;<br>
>> >>> -  Flags = Flags_;<br>
>> >>> -  Chunk = Chunk_;<br>
>> >>> -  if (Address != UINT32_MAX)<br>
>> >>> -    setVirtualAddress(Address);<br>
>> >>> -}<br>
>> >>> -<br>
>> >>> -bool Symbol::isWeak() const {<br>
>> >>> -  return (Flags & WASM_SYMBOL_BINDING_MASK) ==<br>
>> >>> WASM_SYMBOL_BINDING_WEAK;<br>
>> >>> -}<br>
>> >>> -<br>
>> >>> -bool Symbol::isLocal() const {<br>
>> >>> -  return (Flags & WASM_SYMBOL_BINDING_MASK) ==<br>
>> >>> WASM_SYMBOL_BINDING_LOCAL;<br>
>> >>> -}<br>
>> >>> -<br>
>> >>> -bool Symbol::isHidden() const {<br>
>> >>> -  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) ==<br>
>> >>> WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>> >>> +uint32_t DefinedGlobal::getVirtualAddre<wbr>ss() const {<br>
>> >>> +  assert(isGlobal());<br>
>> >>> +  DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");<br>
>> >>> +  return Chunk ?<br>
>> >>> dyn_cast<InputSegment>(Chunk)-<wbr>>translateVA(VirtualAddress)<br>
>> >>> +               : VirtualAddress;<br>
>> >>>  }<br>
>> >>><br>
>> >>> -void Symbol::setHidden(bool IsHidden) {<br>
>> >>> -  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden <<<br>
>> >>> "\n");<br>
>> >>> -  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;<br>
>> >>> -  if (IsHidden)<br>
>> >>> -    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>> >>> -  else<br>
>> >>> -    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT<wbr>;<br>
>> >>> +void DefinedGlobal::setVirtualAddre<wbr>ss(uint32_t Value) {<br>
>> >>> +  DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value <<<br>
>> >>> "\n");<br>
>> >>> +  assert(isGlobal());<br>
>> >>> +  VirtualAddress = Value;<br>
>> >>>  }<br>
>> >>><br>
>> >>>  std::string lld::toString(const wasm::Symbol &Sym) {<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/Symbols.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/Symbols.<wbr>h?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/Symbols.h (original)<br>
>> >>> +++ lld/trunk/wasm/Symbols.h Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -23,6 +23,7 @@ namespace wasm {<br>
>> >>>  class InputFile;<br>
>> >>>  class InputChunk;<br>
>> >>><br>
>> >>> +// The base class for real symbol classes.<br>
>> >>>  class Symbol {<br>
>> >>>  public:<br>
>> >>>    enum Kind {<br>
>> >>> @@ -37,9 +38,7 @@ public:<br>
>> >>>      InvalidKind,<br>
>> >>>    };<br>
>> >>><br>
>> >>> -  Symbol(StringRef Name, uint32_t Flags) : Flags(Flags), Name(Name)<br>
>> >>> {}<br>
>> >>> -<br>
>> >>> -  Kind getKind() const { return SymbolKind; }<br>
>> >>> +  Kind kind() const { return static_cast<Kind>(SymbolKind); }<br>
>> >>><br>
>> >>>    bool isLazy() const { return SymbolKind == LazyKind; }<br>
>> >>>    bool isDefined() const { return SymbolKind <= LastDefinedKind; }<br>
>> >>> @@ -63,9 +62,6 @@ public:<br>
>> >>>    InputFile *getFile() const { return File; }<br>
>> >>>    InputChunk *getChunk() const { return Chunk; }<br>
>> >>><br>
>> >>> -  bool hasFunctionType() const { return FunctionType != nullptr; }<br>
>> >>> -  const WasmSignature &getFunctionType() const;<br>
>> >>> -  void setFunctionType(const WasmSignature *Type);<br>
>> >>>    void setHidden(bool IsHidden);<br>
>> >>><br>
>> >>>    uint32_t getOutputIndex() const;<br>
>> >>> @@ -77,6 +73,28 @@ public:<br>
>> >>>    // space of the output object.<br>
>> >>>    void setOutputIndex(uint32_t Index);<br>
>> >>><br>
>> >>> +protected:<br>
>> >>> +  Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,<br>
>> >>> InputChunk *C)<br>
>> >>> +      : Name(Name), SymbolKind(K), Flags(Flags), File(F), Chunk(C) {}<br>
>> >>> +<br>
>> >>> +  StringRef Name;<br>
>> >>> +  Kind SymbolKind;<br>
>> >>> +  uint32_t Flags;<br>
>> >>> +  InputFile *File;<br>
>> >>> +  InputChunk *Chunk;<br>
>> >>> +  llvm::Optional<uint32_t> OutputIndex;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class FunctionSymbol : public Symbol {<br>
>> >>> +public:<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == DefinedFunctionKind ||<br>
>> >>> +           S->kind() == UndefinedFunctionKind;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  bool hasFunctionType() const { return FunctionType != nullptr; }<br>
>> >>> +  const WasmSignature &getFunctionType() const;<br>
>> >>> +<br>
>> >>>    uint32_t getTableIndex() const;<br>
>> >>><br>
>> >>>    // Returns true if a table index has been set for this symbol<br>
>> >>> @@ -85,30 +103,99 @@ public:<br>
>> >>>    // Set the table index of the symbol<br>
>> >>>    void setTableIndex(uint32_t Index);<br>
>> >>><br>
>> >>> -  // Returns the virtual address of a defined global.<br>
>> >>> -  // Only works for globals, not functions.<br>
>> >>> +protected:<br>
>> >>> +  void setFunctionType(const WasmSignature *Type);<br>
>> >>> +<br>
>> >>> +  FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile<br>
>> >>> *F,<br>
>> >>> +                 InputChunk *C)<br>
>> >>> +      : Symbol(Name, K, Flags, F, C) {}<br>
>> >>> +<br>
>> >>> +  llvm::Optional<uint32_t> TableIndex;<br>
>> >>> +<br>
>> >>> +  // Explict function type, needed for undefined or synthetic<br>
>> >>> functions<br>
>> >>> only.<br>
>> >>> +  const WasmSignature *FunctionType = nullptr;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class DefinedFunction : public FunctionSymbol {<br>
>> >>> +public:<br>
>> >>> +  DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F =<br>
>> >>> nullptr,<br>
>> >>> +                  InputChunk *C = nullptr)<br>
>> >>> +      : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, C) {}<br>
>> >>> +<br>
>> >>> +  DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature<br>
>> >>> *Type)<br>
>> >>> +      : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr,<br>
>> >>> nullptr) {<br>
>> >>> +    setFunctionType(Type);<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == DefinedFunctionKind;<br>
>> >>> +  }<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class UndefinedFunction : public FunctionSymbol {<br>
>> >>> +public:<br>
>> >>> +  UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File =<br>
>> >>> nullptr,<br>
>> >>> +                    const WasmSignature *Type = nullptr)<br>
>> >>> +      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File,<br>
>> >>> nullptr) {<br>
>> >>> +    setFunctionType(Type);<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == UndefinedFunctionKind;<br>
>> >>> +  }<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class GlobalSymbol : public Symbol {<br>
>> >>> +public:<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == DefinedGlobalKind || S->kind() ==<br>
>> >>> UndefinedGlobalKind;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +protected:<br>
>> >>> +  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,<br>
>> >>> +               InputChunk *C)<br>
>> >>> +      : Symbol(Name, K, Flags, F, C) {}<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class DefinedGlobal : public GlobalSymbol {<br>
>> >>> +public:<br>
>> >>> +  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F =<br>
>> >>> nullptr,<br>
>> >>> +                InputChunk *C = nullptr, uint32_t Address = 0)<br>
>> >>> +      : GlobalSymbol(Name, DefinedGlobalKind, Flags, F, C),<br>
>> >>> +        VirtualAddress(Address) {}<br>
>> >>> +<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == DefinedGlobalKind;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>>    uint32_t getVirtualAddress() const;<br>
>> >>><br>
>> >>>    void setVirtualAddress(uint32_t VA);<br>
>> >>><br>
>> >>> -  void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0,<br>
>> >>> -              InputChunk *chunk = nullptr, uint32_t Address =<br>
>> >>> UINT32_MAX);<br>
>> >>> +protected:<br>
>> >>> +  uint32_t VirtualAddress;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class UndefinedGlobal : public GlobalSymbol {<br>
>> >>> +public:<br>
>> >>> +  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File =<br>
>> >>> nullptr)<br>
>> >>> +      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, nullptr)<br>
>> >>> {}<br>
>> >>> +  static bool classof(const Symbol *S) {<br>
>> >>> +    return S->kind() == UndefinedGlobalKind;<br>
>> >>> +  }<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +class LazySymbol : public Symbol {<br>
>> >>> +public:<br>
>> >>> +  LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol<br>
>> >>> &Sym)<br>
>> >>> +      : Symbol(Name, LazyKind, 0, File, nullptr), ArchiveSymbol(Sym)<br>
>> >>> {}<br>
>> >>> +<br>
>> >>> +  static bool classof(const Symbol *S) { return S->kind() ==<br>
>> >>> LazyKind; }<br>
>> >>><br>
>> >>> -  void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol =<br>
>> >>> Sym; }<br>
>> >>>    const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; }<br>
>> >>><br>
>> >>>  protected:<br>
>> >>> -  uint32_t Flags;<br>
>> >>> -  uint32_t VirtualAddress = 0;<br>
>> >>> -<br>
>> >>> -  StringRef Name;<br>
>> >>> -  Archive::Symbol ArchiveSymbol = {nullptr, 0, 0};<br>
>> >>> -  Kind SymbolKind = InvalidKind;<br>
>> >>> -  InputFile *File = nullptr;<br>
>> >>> -  InputChunk *Chunk = nullptr;<br>
>> >>> -  llvm::Optional<uint32_t> OutputIndex;<br>
>> >>> -  llvm::Optional<uint32_t> TableIndex;<br>
>> >>> -  const WasmSignature *FunctionType = nullptr;<br>
>> >>> +  Archive::Symbol ArchiveSymbol;<br>
>> >>>  };<br>
>> >>><br>
>> >>>  // linker-generated symbols<br>
>> >>> @@ -116,27 +203,50 @@ struct WasmSym {<br>
>> >>>    // __stack_pointer<br>
>> >>>    // Global that holds the address of the top of the explicit value<br>
>> >>> stack in<br>
>> >>>    // linear memory.<br>
>> >>> -  static Symbol *StackPointer;<br>
>> >>> +  static DefinedGlobal *StackPointer;<br>
>> >>><br>
>> >>>    // __data_end<br>
>> >>>    // Symbol marking the end of the data and bss.<br>
>> >>> -  static Symbol *DataEnd;<br>
>> >>> +  static DefinedGlobal *DataEnd;<br>
>> >>><br>
>> >>>    // __heap_base<br>
>> >>>    // Symbol marking the end of the data, bss and explicit stack.  Any<br>
>> >>> linear<br>
>> >>>    // memory following this address is not used by the linked code and<br>
>> >>> can<br>
>> >>>    // therefore be used as a backing store for brk()/malloc()<br>
>> >>> implementations.<br>
>> >>> -  static Symbol *HeapBase;<br>
>> >>> +  static DefinedGlobal *HeapBase;<br>
>> >>><br>
>> >>>    // __wasm_call_ctors<br>
>> >>>    // Function that directly calls all ctors in priority order.<br>
>> >>> -  static Symbol *CallCtors;<br>
>> >>> +  static DefinedFunction *CallCtors;<br>
>> >>><br>
>> >>>    // __dso_handle<br>
>> >>>    // Global used in calls to __cxa_atexit to determine current DLL<br>
>> >>> -  static Symbol *DsoHandle;<br>
>> >>> +  static DefinedGlobal *DsoHandle;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +// A buffer class that is large enough to hold any Symbol-derived<br>
>> >>> +// object. We allocate memory using this class and instantiate a<br>
>> >>> symbol<br>
>> >>> +// using the placement new.<br>
>> >>> +union SymbolUnion {<br>
>> >>> +  alignas(DefinedFunction) char A[sizeof(DefinedFunction)];<br>
>> >>> +  alignas(DefinedGlobal) char B[sizeof(DefinedGlobal)];<br>
>> >>> +  alignas(LazySymbol) char C[sizeof(LazySymbol)];<br>
>> >>> +  alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];<br>
>> >>> +  alignas(UndefinedGlobal) char E[sizeof(UndefinedFunction)];<br>
>> >>>  };<br>
>> >>><br>
>> >>> +template <typename T, typename... ArgT><br>
>> >>> +T *replaceSymbol(Symbol *S, ArgT &&... Arg) {<br>
>> >>> +  static_assert(std::is_triviall<wbr>y_destructible<T>(),<br>
>> >>> +                "Symbol types must be trivially destructible");<br>
>> >>> +  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too<br>
>> >>> small");<br>
>> >>> +  static_assert(alignof(T) <= alignof(SymbolUnion),<br>
>> >>> +                "SymbolUnion not aligned enough");<br>
>> >>> +  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr<br>
>> >>> &&<br>
>> >>> +         "Not a Symbol");<br>
>> >>> +  return new (S) T(std::forward<ArgT>(Arg)...);<br>
>> >>> +}<br>
>> >>> +<br>
>> >>>  } // namespace wasm<br>
>> >>><br>
>> >>>  // Returns a symbol name for an error message.<br>
>> >>><br>
>> >>> Modified: lld/trunk/wasm/Writer.cpp<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=325150&r1=325149&r2=325150&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/wasm/Writer.cp<wbr>p?rev=325150&r1=325149&r2=3251<wbr>50&view=diff</a><br>
>> >>><br>
>> >>><br>
>> >>> ==============================<wbr>==============================<wbr>==================<br>
>> >>> --- lld/trunk/wasm/Writer.cpp (original)<br>
>> >>> +++ lld/trunk/wasm/Writer.cpp Wed Feb 14 10:27:59 2018<br>
>> >>> @@ -119,12 +119,12 @@ private:<br>
>> >>><br>
>> >>>    std::vector<const WasmSignature *> Types;<br>
>> >>>    DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo><br>
>> >>> TypeIndices;<br>
>> >>> -  std::vector<const Symbol *> ImportedFunctions;<br>
>> >>> -  std::vector<const Symbol *> ImportedGlobals;<br>
>> >>> +  std::vector<const FunctionSymbol *> ImportedFunctions;<br>
>> >>> +  std::vector<const GlobalSymbol *> ImportedGlobals;<br>
>> >>>    std::vector<WasmExportEntry> ExportedSymbols;<br>
>> >>> -  std::vector<const Symbol *> DefinedGlobals;<br>
>> >>> +  std::vector<const DefinedGlobal *> DefinedGlobals;<br>
>> >>>    std::vector<InputFunction *> DefinedFunctions;<br>
>> >>> -  std::vector<const Symbol *> IndirectFunctions;<br>
>> >>> +  std::vector<const FunctionSymbol *> IndirectFunctions;<br>
>> >>>    std::vector<WasmInitFunc> InitFunctions;<br>
>> >>><br>
>> >>>    // Elements that are used to construct the final output<br>
>> >>> @@ -164,7 +164,7 @@ void Writer::createImportSection() {<br>
>> >>><br>
>> >>>    writeUleb128(OS, NumImports, "import count");<br>
>> >>><br>
>> >>> -  for (const Symbol *Sym : ImportedFunctions) {<br>
>> >>> +  for (const FunctionSymbol *Sym : ImportedFunctions) {<br>
>> >>>      WasmImport Import;<br>
>> >>>      Import.Module = "env";<br>
>> >>>      Import.Field = Sym->getName();<br>
>> >>> @@ -234,7 +234,7 @@ void Writer::createGlobalSection() {<br>
>> >>>    raw_ostream &OS = Section->getStream();<br>
>> >>><br>
>> >>>    writeUleb128(OS, DefinedGlobals.size(), "global count");<br>
>> >>> -  for (const Symbol *Sym : DefinedGlobals) {<br>
>> >>> +  for (const DefinedGlobal *Sym : DefinedGlobals) {<br>
>> >>>      WasmGlobal Global;<br>
>> >>>      Global.Type.Type = WASM_TYPE_I32;<br>
>> >>>      Global.Type.Mutable = Sym == WasmSym::StackPointer;<br>
>> >>> @@ -316,7 +316,7 @@ void Writer::createElemSection() {<br>
>> >>>    writeUleb128(OS, IndirectFunctions.size(), "elem count");<br>
>> >>><br>
>> >>>    uint32_t TableIndex = kInitialTableOffset;<br>
>> >>> -  for (const Symbol *Sym : IndirectFunctions) {<br>
>> >>> +  for (const FunctionSymbol *Sym : IndirectFunctions) {<br>
>> >>>      assert(Sym->getTableIndex() == TableIndex);<br>
>> >>>      writeUleb128(OS, Sym->getOutputIndex(), "function index");<br>
>> >>>      ++TableIndex;<br>
>> >>> @@ -619,12 +619,12 @@ void Writer::calculateImports() {<br>
>> >>>      if (!Sym->isUndefined() || (Sym->isWeak() &&<br>
>> >>> !Config->Relocatable))<br>
>> >>>        continue;<br>
>> >>><br>
>> >>> -    if (Sym->isFunction()) {<br>
>> >>> -      Sym->setOutputIndex(ImportedFu<wbr>nctions.size());<br>
>> >>> -      ImportedFunctions.push_back(Sy<wbr>m);<br>
>> >>> -    } else {<br>
>> >>> -      Sym->setOutputIndex(ImportedGl<wbr>obals.size());<br>
>> >>> -      ImportedGlobals.push_back(Sym)<wbr>;<br>
>> >>> +    if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {<br>
>> >>> +      F->setOutputIndex(ImportedFunc<wbr>tions.size());<br>
>> >>> +      ImportedFunctions.push_back(F)<wbr>;<br>
>> >>> +    } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {<br>
>> >>> +      G->setOutputIndex(ImportedGlob<wbr>als.size());<br>
>> >>> +      ImportedGlobals.push_back(G);<br>
>> >>>      }<br>
>> >>>    }<br>
>> >>>  }<br>
>> >>> @@ -712,7 +712,7 @@ void Writer::calculateTypes() {<br>
>> >>>          File->TypeMap[I] = registerType(Types[I]);<br>
>> >>>    }<br>
>> >>><br>
>> >>> -  for (const Symbol *Sym : ImportedFunctions)<br>
>> >>> +  for (const FunctionSymbol *Sym : ImportedFunctions)<br>
>> >>>      registerType(Sym->getFunctionT<wbr>ype());<br>
>> >>><br>
>> >>>    for (const InputFunction *F : DefinedFunctions)<br>
>> >>> @@ -723,7 +723,7 @@ void Writer::assignIndexes() {<br>
>> >>>    uint32_t GlobalIndex = ImportedGlobals.size() +<br>
>> >>> DefinedGlobals.size();<br>
>> >>>    uint32_t FunctionIndex = ImportedFunctions.size() +<br>
>> >>> DefinedFunctions.size();<br>
>> >>><br>
>> >>> -  auto AddDefinedGlobal = [&](Symbol* Sym) {<br>
>> >>> +  auto AddDefinedGlobal = [&](DefinedGlobal *Sym) {<br>
>> >>>      if (Sym) {<br>
>> >>>        DefinedGlobals.emplace_back(Sy<wbr>m);<br>
>> >>>        Sym->setOutputIndex(GlobalInde<wbr>x++);<br>
>> >>> @@ -743,12 +743,10 @@ void Writer::assignIndexes() {<br>
>> >>>        DEBUG(dbgs() << "Globals: " << File->getName() << "\n");<br>
>> >>>        for (Symbol *Sym : File->getSymbols()) {<br>
>> >>>          // Create wasm globals for data symbols defined in this file<br>
>> >>> -        if (!Sym->isDefined() || File != Sym->getFile())<br>
>> >>> +        if (File != Sym->getFile())<br>
>> >>>            continue;<br>
>> >>> -        if (Sym->isFunction())<br>
>> >>> -          continue;<br>
>> >>> -<br>
>> >>> -        AddDefinedGlobal(Sym);<br>
>> >>> +        if (auto *G = dyn_cast<DefinedGlobal>(Sym))<br>
>> >>> +          AddDefinedGlobal(G);<br>
>> >>>        }<br>
>> >>>      }<br>
>> >>>    }<br>
>> >>> @@ -772,7 +770,7 @@ void Writer::assignIndexes() {<br>
>> >>>        for (const WasmRelocation& Reloc : Chunk->getRelocations()) {<br>
>> >>>          if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||<br>
>> >>>              Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB<wbr>) {<br>
>> >>> -          Symbol *Sym = File->getFunctionSymbol(Reloc.<wbr>Index);<br>
>> >>> +          FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.<wbr>Index);<br>
>> >>>            if (Sym->hasTableIndex() || !Sym->hasOutputIndex())<br>
>> >>>              continue;<br>
>> >>>            Sym->setTableIndex(TableIndex+<wbr>+);<br>
>> >>><br>
>> >>><br>
>> >>> ______________________________<wbr>_________________<br>
>> >>> llvm-commits mailing list<br>
>> >>> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
>> >>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
>> >><br>
>> >><br>
>> >><br>
>> >> ______________________________<wbr>_________________<br>
>> >> llvm-commits mailing list<br>
>> >> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
>> >> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
>> >><br>
>> ><br>
><br>
><br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>