Index: include/llvm/MC/MCSymbolWasm.h =================================================================== --- include/llvm/MC/MCSymbolWasm.h +++ include/llvm/MC/MCSymbolWasm.h @@ -19,6 +19,7 @@ bool IsHidden = false; bool IsComdat = false; std::string ModuleName; + std::string FieldName; wasm::WasmSignature *Signature = nullptr; Optional GlobalType; Optional EventType; @@ -31,7 +32,8 @@ // Use a module name of "env" for now, for compatibility with existing tools. // This is temporary, and may change, as the ABI is not yet stable. MCSymbolWasm(const StringMapEntry *Name, bool isTemporary) - : MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env") {} + : MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env"), + FieldName(getName().str()) {} static bool classof(const MCSymbol *S) { return S->isWasm(); } const MCExpr *getSize() const { return SymbolSize; } @@ -57,6 +59,9 @@ const StringRef getModuleName() const { return ModuleName; } void setModuleName(StringRef Name) { ModuleName = Name; } + const StringRef getFieldName() const { return FieldName; } + void setFieldName(StringRef Name) { FieldName = Name; } + const wasm::WasmSignature *getSignature() const { return Signature; } void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; } Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -45,6 +45,9 @@ /// .import_module virtual void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) = 0; + /// .import_field + virtual void emitImportField(const MCSymbolWasm *Sym, + StringRef ModuleName) = 0; protected: void emitValueType(wasm::ValType Type); @@ -67,6 +70,7 @@ void emitGlobalType(const MCSymbolWasm *Sym) override; void emitEventType(const MCSymbolWasm *Sym) override; void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) override; + void emitImportField(const MCSymbolWasm *Sym, StringRef ModuleName) override; }; /// This part is for Wasm object output @@ -82,6 +86,8 @@ void emitEventType(const MCSymbolWasm *Sym) override {} void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) override {} + void emitImportField(const MCSymbolWasm *Sym, + StringRef ModuleName) override {} }; /// This part is for null output @@ -97,6 +103,7 @@ void emitGlobalType(const MCSymbolWasm *) override {} void emitEventType(const MCSymbolWasm *) override {} void emitImportModule(const MCSymbolWasm *, StringRef) override {} + void emitImportField(const MCSymbolWasm *, StringRef) override {} }; } // end namespace llvm Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -116,6 +116,11 @@ OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n'; } +void WebAssemblyTargetAsmStreamer::emitImportField(const MCSymbolWasm *Sym, + StringRef FieldName) { + OS << "\t.import_field\t" << Sym->getName() << ", " << FieldName << '\n'; +} + void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { OS << "\t.indidx \t" << *Value << '\n'; } Index: lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -117,6 +117,13 @@ Sym->setModuleName(Name); getTargetStreamer()->emitImportModule(Sym, Name); } + if (TM.getTargetTriple().isOSBinFormatWasm() && + F.hasFnAttribute("wasm-import-field")) { + StringRef Name = + F.getFnAttribute("wasm-import-field").getValueAsString(); + Sym->setFieldName(Name); + getTargetStreamer()->emitImportField(Sym, Name); + } } } Index: test/CodeGen/WebAssembly/import-module.ll =================================================================== --- test/CodeGen/WebAssembly/import-module.ll +++ test/CodeGen/WebAssembly/import-module.ll @@ -12,8 +12,9 @@ declare void @foo() #0 declare void @plain() -attributes #0 = { "wasm-import-module"="bar" } +attributes #0 = { "wasm-import-module"="bar", "wasm-import-field"="qux" } ; CHECK-NOT: .import_module plain ; CHECK: .import_module foo, bar +; CHECK: .import_field foo, qux ; CHECK-NOT: .import_module plain Index: test/MC/WebAssembly/external-func-address.ll =================================================================== --- test/MC/WebAssembly/external-func-address.ll +++ test/MC/WebAssembly/external-func-address.ll @@ -8,7 +8,7 @@ declare void @f0(i32) #0 @ptr_to_f0 = hidden global void (i32)* @f0, align 4 -attributes #0 = { "wasm-import-module"="somewhere" } +attributes #0 = { "wasm-import-module"="somewhere", "wasm-import-field"="something" } declare void @f1(i32) #1 @ptr_to_f1 = hidden global void (i32)* @f1, align 4 @@ -47,7 +47,7 @@ ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 1 ; CHECK: - Module: somewhere -; CHECK-NEXT: Field: f0 +; CHECK-NEXT: Field: something ; CHECK: - Module: env ; CHECK-NEXT: Field: f1 ; CHECK-NEXT: Kind: FUNCTION