template <typename T>
static void setImportAttributes(T *existing, Optional<StringRef> importName,
Optional<StringRef> importModule,
- InputFile *file) {
+ uint32_t flags, InputFile *file) {
if (importName) {
if (!existing->importName)
existing->importName = importName;
toString(existing->getFile()) + "\n>>> defined as " +
*importModule + " in " + toString(file));
}
+
+ // Update symbol binding, if the existing symbol is weak
+ uint32_t binding = flags & WASM_SYMBOL_BINDING_MASK;
+ if (existing->isWeak() && binding != WASM_SYMBOL_BINDING_WEAK) {
+ existing->flags = (existing->flags & ~WASM_SYMBOL_BINDING_MASK) | binding;
+ }
}
Symbol *SymbolTable::addUndefinedFunction(StringRef name,
bool isCalledDirectly) {
LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " ["
<< (sig ? toString(*sig) : "none")
- << "] IsCalledDirectly:" << isCalledDirectly << "\n");
+ << "] IsCalledDirectly:" << isCalledDirectly << " flags=0x"
+ << utohexstr(flags) << "\n");
assert(flags & WASM_SYMBOL_UNDEFINED);
Symbol *s;
reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
return s;
}
- auto *existingUndefined = dyn_cast<UndefinedFunction>(existingFunction);
if (!existingFunction->signature && sig)
existingFunction->signature = sig;
+ auto *existingUndefined = dyn_cast<UndefinedFunction>(existingFunction);
if (isCalledDirectly && !signatureMatches(existingFunction, sig)) {
- // If the existing undefined functions is not called direcltly then let
+ // If the existing undefined functions is not called directly then let
// this one take precedence. Otherwise the existing function is either
- // direclty called or defined, in which case we need a function variant.
+ // directly called or defined, in which case we need a function variant.
if (existingUndefined && !existingUndefined->isCalledDirectly)
replaceSym();
else if (getFunctionVariant(s, sig, file, &s))
replaceSym();
}
if (existingUndefined)
- setImportAttributes(existingUndefined, importName, importModule, file);
+ setImportAttributes(existingUndefined, importName, importModule, flags,
+ file);
}
return s;
auto *func = make<SyntheticFunction>(sig, sym->getName(), debugName);
func->setBody(unreachableFn);
syntheticFunctions.emplace_back(func);
- replaceSymbol<DefinedFunction>(sym, sym->getName(), sym->getFlags(), nullptr,
+ replaceSymbol<DefinedFunction>(sym, sym->getName(), sym->flags, nullptr,
func);
return func;
}
// Returns the file from which this symbol was created.
InputFile *getFile() const { return file; }
- uint32_t getFlags() const { return flags; }
-
InputChunk *getChunk() const;
// Indicates that the section or import for this symbol will be included in
protected:
Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f)
- : name(name), file(f), flags(flags), symbolKind(k),
- referenced(!config->gcSections), requiresGOT(false),
- isUsedInRegularObj(false), forceExport(false), canInline(false),
- traced(false) {}
+ : name(name), file(f), symbolKind(k), referenced(!config->gcSections),
+ requiresGOT(false), isUsedInRegularObj(false), forceExport(false),
+ canInline(false), traced(false), flags(flags) {}
StringRef name;
InputFile *file;
- uint32_t flags;
uint32_t outputSymbolIndex = INVALID_INDEX;
uint32_t gotIndex = INVALID_INDEX;
Kind symbolKind;
// True if this symbol is specified by --trace-symbol option.
bool traced : 1;
+
+ uint32_t flags;
};
class FunctionSymbol : public Symbol {