<div dir="ltr">I guess that the use of llvm::Optional isn't safe in this context. It has a user-defined desctructor. Could you use 0 or -1 to represent "not set" status?</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 14, 2018 at 2:00 PM, Sam Clegg <span dir="ltr"><<a href="mailto:sbc@google.com" target="_blank">sbc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Works for me too.  I added this assert to the other backends yesterday<br>
without issue.  Strange...<br>
<div class="HOEnZb"><div class="h5"><br>
On Wed, Feb 14, 2018 at 1:15 PM, Rui Ueyama <<a href="mailto:ruiu@google.com">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">llvm-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>> This doesn't build for me.<br>
>><br>
>> /home/michael/llvm-project/<wbr>lld/wasm/Symbols.h:240:3: error: static<br>
>> assertion failed: Symbol types must be trivially destructible<br>
>> │<br>
>>    static_assert(std::is_<wbr>trivially_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">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-<wbr>project?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/<wbr>D43112</a><br>
>>><br>
>>> Modified:<br>
>>>     lld/trunk/wasm/InputFiles.cpp<br>
>>>     lld/trunk/wasm/InputFiles.h<br>
>>>     lld/trunk/wasm/SymbolTable.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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>InputFiles.cpp?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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::<wbr>relocateVirtualAddress(uint32_<wbr>t GlobalIndex) const {<br>
>>> -  return getGlobalSymbol(GlobalIndex)-><wbr>getVirtualAddress();<br>
>>> +  if (auto *DG = dyn_cast<DefinedGlobal>(<wbr>getGlobalSymbol(GlobalIndex)))<br>
>>> +    return DG->getVirtualAddress();<br>
>>> +  else<br>
>>> +    return 0;<br>
>>>  }<br>
>>><br>
>>>  uint32_t ObjFile::<wbr>relocateFunctionIndex(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(<wbr>uint<br>
>>>  }<br>
>>><br>
>>>  uint32_t ObjFile::relocateTableIndex(<wbr>uint32_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::<wbr>FUNCTION_EXPORT: {<br>
>>>        InputFunction *Function = getFunction(WasmSym);<br>
>>>        if (!isExcludedByComdat(Function)<wbr>) {<br>
>>> -        S = createDefined(WasmSym, Symbol::Kind::<wbr>DefinedFunctionKind,<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::<wbr>GLOBAL_EXPORT: {<br>
>>>        InputSegment *Segment = getSegment(WasmSym);<br>
>>>        if (!isExcludedByComdat(Segment)) {<br>
>>> -        S = createDefined(WasmSym, Symbol::Kind::<wbr>DefinedGlobalKind,<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(<wbr>const W<br>
>>>    return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this,<br>
>>> Signature);<br>
>>>  }<br>
>>><br>
>>> -Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind 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::<wbr>createDefinedFunction(const WasmSymbol &Sym,<br>
>>> +                                       InputChunk *Chunk) {<br>
>>> +  if (Sym.isBindingLocal())<br>
>>> +    return make<DefinedFunction>(Sym.<wbr>Name, 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, 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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>InputFiles.h?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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>(<wbr>FunctionSymbols[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>(<wbr>GlobalSymbols[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 *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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>SymbolTable.cpp?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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(<wbr>Name)];<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(<wbr>Symbol<br>
>>>  // Check the type of new symbol matches that of the symbol is replacing.<br>
>>>  // For functions this can also involve verifying that the signatures<br>
>>> match.<br>
>>>  static void checkSymbolTypes(const Symbol &Existing, const InputFile &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::<wbr>UndefinedFunctionKind ||<br>
>>> -                       Kind == Symbol::Kind::<wbr>DefinedFunctionKind;<br>
>>> -<br>
>>>    // First check the symbol types match (i.e. either both are 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>(&<wbr>Existing);<br>
>>> +  if (!ExistingFunc || !Config->CheckSignatures)<br>
>>>      return;<br>
>>> +<br>
>>>    // Skip the signature check if the existing function has no signature<br>
>>> (e.g.<br>
>>>    // if it is an undefined symbol generated by --undefined command line<br>
>>> flag).<br>
>>> -  if (!Existing.hasFunctionType())<br>
>>> +  if (!ExistingFunc-><wbr>hasFunctionType())<br>
>>>      return;<br>
>>><br>
>>> -  DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\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-><wbr>getFile()) + "\n>>> defined as " +<br>
>>> +        toString(*NewSig) + " in " + F.getName());<br>
>>>  }<br>
>>><br>
>>>  static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,<br>
>>> -                             Symbol::Kind Kind, const InputChunk *Chunk)<br>
>>> {<br>
>>> +                             bool IsFunction, const InputChunk *Chunk) {<br>
>>>    const WasmSignature *Sig = nullptr;<br>
>>>    if (auto *F = dyn_cast_or_null<<wbr>InputFunction>(Chunk))<br>
>>>      Sig = &F->Signature;<br>
>>> -  return checkSymbolTypes(Existing, F, Kind, Sig);<br>
>>> +  return checkSymbolTypes(Existing, F, IsFunction, Sig);<br>
>>>  }<br>
>>><br>
>>> -Symbol *SymbolTable::<wbr>addSyntheticFunction(StringRef Name,<br>
>>> -                                          const WasmSignature *Type,<br>
>>> -                                          uint32_t Flags) {<br>
>>> +DefinedFunction *SymbolTable::<wbr>addSyntheticFunction(StringRef Name,<br>
>>> +                                                   const 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::<wbr>DefinedFunctionKind, nullptr, Flags);<br>
>>> -  S->setFunctionType(Type);<br>
>>> -  return S;<br>
>>> +  return replaceSymbol<DefinedFunction><wbr>(S, Name, Flags, Type);<br>
>>>  }<br>
>>><br>
>>> -Symbol *SymbolTable::<wbr>addSyntheticGlobal(StringRef Name) {<br>
>>> +DefinedGlobal *SymbolTable::<wbr>addSyntheticGlobal(StringRef Name, 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::<wbr>DefinedGlobalKind);<br>
>>> -  return S;<br>
>>> +  return replaceSymbol<DefinedGlobal>(<wbr>S, Name, Flags);<br>
>>>  }<br>
>>><br>
>>> -Symbol *SymbolTable::addDefined(<wbr>StringRef Name, Symbol::Kind Kind,<br>
>>> -                                uint32_t Flags, InputFile *F, 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:" << 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 since<br>
>>>      // lazy symbols don't have any type information.<br>
>>>      DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\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>
>>> "\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::<wbr>addUndefinedFunction(StringRef Name,<br>
>>> -                                          const WasmSignature *Type) {<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::<wbr>UndefinedFunctionKind);<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>(<wbr>S, Name, Flags, F, Chunk, Address);<br>
>>>    }<br>
>>>    return S;<br>
>>>  }<br>
>>> @@ -208,17 +202,19 @@ Symbol *SymbolTable::addUndefined(<wbr>String<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<<wbr>UndefinedFunction>(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-><wbr>getArchiveSymbol());<br>
>>> +    auto *AF = cast<ArchiveFile>(LazySym-><wbr>getFile());<br>
>>> +    AF->addMember(&LazySym-><wbr>getArchiveSymbol());<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(<wbr>ArchiveFile *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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>SymbolTable.h?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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 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(<wbr>StringRef Name, const WasmSignature<br>
>>> *Type,<br>
>>> -                               uint32_t Flags);<br>
>>> +  DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags = 0);<br>
>>> +  DefinedFunction *addSyntheticFunction(<wbr>StringRef 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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>Symbols.cpp?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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<<wbr>InputFunction>(Chunk))<br>
>>> @@ -61,12 +40,6 @@ uint32_t Symbol::getOutputIndex() const<br>
>>>    return OutputIndex.getValue();<br>
>>>  }<br>
>>><br>
>>> -void Symbol::setVirtualAddress(<wbr>uint32_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 << "\n");<br>
>>>    assert(!dyn_cast_or_null<<wbr>InputFunction>(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) == 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 << "\n");<br>
>>> +  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;<br>
>>> +  if (IsHidden)<br>
>>> +    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>>> +  else<br>
>>> +    Flags |= WASM_SYMBOL_VISIBILITY_<wbr>DEFAULT;<br>
>>> +}<br>
>>> +<br>
>>> +const WasmSignature &FunctionSymbol::<wbr>getFunctionType() const {<br>
>>> +  if (auto *F = dyn_cast_or_null<<wbr>InputFunction>(Chunk))<br>
>>> +    return F->Signature;<br>
>>> +<br>
>>> +  assert(FunctionType != nullptr);<br>
>>> +  return *FunctionType;<br>
>>> +}<br>
>>> +<br>
>>> +void FunctionSymbol::<wbr>setFunctionType(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<<wbr>InputFunction>(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<<wbr>InputFunction>(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 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) == 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::<wbr>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>
>>><br>
>>> -void Symbol::setHidden(bool IsHidden) {<br>
>>> -  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");<br>
>>> -  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;<br>
>>> -  if (IsHidden)<br>
>>> -    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;<br>
>>> -  else<br>
>>> -    Flags |= WASM_SYMBOL_VISIBILITY_<wbr>DEFAULT;<br>
>>> +void DefinedGlobal::<wbr>setVirtualAddress(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>
>>> <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-<wbr>project/lld/trunk/wasm/<wbr>Symbols.h?rev=325150&r1=<wbr>325149&r2=325150&view=diff</a><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>
>>> -  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 *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 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 = 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>
>>> +  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>
>>> +  static bool classof(const Symbol *S) { return S->kind() == 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 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_<wbr>trivially_destructible<T>(),<br>
>>> +                "Symbol types must be trivially destructible");<br>
>>> +  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");<br>
>>> +  static_assert(alignof(T) <= alignof(SymbolUnion),<br>
>>> +                "SymbolUnion not aligned enough");<br>
>>> +  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&<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>
>>> <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-<wbr>project/lld/trunk/wasm/Writer.<wbr>cpp?rev=325150&r1=325149&r2=<wbr>325150&view=diff</a><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() && !Config->Relocatable))<br>
>>>        continue;<br>
>>><br>
>>> -    if (Sym->isFunction()) {<br>
>>> -      Sym->setOutputIndex(<wbr>ImportedFunctions.size());<br>
>>> -      ImportedFunctions.push_back(<wbr>Sym);<br>
>>> -    } else {<br>
>>> -      Sym->setOutputIndex(<wbr>ImportedGlobals.size());<br>
>>> -      ImportedGlobals.push_back(Sym)<wbr>;<br>
>>> +    if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {<br>
>>> +      F->setOutputIndex(<wbr>ImportedFunctions.size());<br>
>>> +      ImportedFunctions.push_back(F)<wbr>;<br>
>>> +    } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {<br>
>>> +      G->setOutputIndex(<wbr>ImportedGlobals.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-><wbr>getFunctionType());<br>
>>><br>
>>>    for (const InputFunction *F : DefinedFunctions)<br>
>>> @@ -723,7 +723,7 @@ void Writer::assignIndexes() {<br>
>>>    uint32_t GlobalIndex = ImportedGlobals.size() + 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(<wbr>Sym);<br>
>>>        Sym->setOutputIndex(<wbr>GlobalIndex++);<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_<wbr>SLEB) {<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">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">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>
</div></div></blockquote></div><br></div>