sbc100 updated this revision to Diff 507802.
sbc100 added a comment.
Herald added a reviewer: aaron.ballman.
Herald added subscribers: llvm-commits, pmatos, asb, wingo, ecnelises.
Herald added projects: LLVM, All.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76547/new/

https://reviews.llvm.org/D76547

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/wasm-export.c
  llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
  llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
  llvm/test/CodeGen/WebAssembly/export.ll

Index: llvm/test/CodeGen/WebAssembly/export.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/export.ll
@@ -0,0 +1,17 @@
+; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @test() #0 {
+  ret void
+}
+
+declare void @test2() #1
+
+
+attributes #0 = { "wasm-exported" }
+attributes #1 = { "wasm-exported" }
+
+; CHECK: .export test
+; CHECK: .export test2
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -376,6 +376,12 @@
       getTargetStreamer()->emitImportName(Sym, Name);
     }
 
+    if (F.hasFnAttribute("wasm-exported")) {
+      auto *Sym = cast<MCSymbolWasm>(getSymbol(&F));
+      Sym->setExported();
+      getTargetStreamer()->emitExport(Sym);
+    }
+
     if (F.hasFnAttribute("wasm-export-name")) {
       auto *Sym = cast<MCSymbolWasm>(getSymbol(&F));
       StringRef Name = F.getFnAttribute("wasm-export-name").getValueAsString();
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
@@ -51,6 +51,8 @@
   /// .export_name
   virtual void emitExportName(const MCSymbolWasm *Sym,
                               StringRef ExportName) = 0;
+  /// .export
+  virtual void emitExport(const MCSymbolWasm *Sym) = 0;
 
 protected:
   void emitValueType(wasm::ValType Type);
@@ -72,6 +74,7 @@
   void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override;
   void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName) override;
   void emitExportName(const MCSymbolWasm *Sym, StringRef ExportName) override;
+  void emitExport(const MCSymbolWasm *Sym) override;
 };
 
 /// This part is for Wasm object output
@@ -91,6 +94,7 @@
                       StringRef ImportName) override {}
   void emitExportName(const MCSymbolWasm *Sym,
                       StringRef ExportName) override {}
+  void emitExport(const MCSymbolWasm *Sym) override {}
 };
 
 /// This part is for null output
@@ -108,6 +112,7 @@
   void emitImportModule(const MCSymbolWasm *, StringRef) override {}
   void emitImportName(const MCSymbolWasm *, StringRef) override {}
   void emitExportName(const MCSymbolWasm *, StringRef) override {}
+  void emitExport(const MCSymbolWasm *) override {}
 };
 
 } // end namespace llvm
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -114,6 +114,10 @@
                            << ExportName << '\n';
 }
 
+void WebAssemblyTargetAsmStreamer::emitExport(const MCSymbolWasm *Sym) {
+  OS << "\t.export\t" << Sym->getName() << '\n';
+}
+
 void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
   OS << "\t.indidx  \t" << *Value << '\n';
 }
Index: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -897,6 +897,15 @@
       return expect(AsmToken::EndOfStatement, "EOL");
     }
 
+    if (DirectiveID.getString() == ".export") {
+      auto SymName = expectIdent();
+      if (SymName.empty())
+        return true;
+      auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
+      WasmSym->setExported();
+      TOut.emitExport(WasmSym);
+    }
+
     if (DirectiveID.getString() == ".export_name") {
       auto SymName = expectIdent();
       if (SymName.empty())
Index: clang/test/CodeGen/wasm-export.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/wasm-export.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s
+
+int __attribute__((exported)) foo(void);
+
+int foo(void) {
+  return 43;
+}
+
+// CHECK: @llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @foo to i8*)]
+
+// CHECK: define i32 @foo() [[A:#[0-9]+]]
+
+// CHECK: attributes [[A]] = {{{.*}} "wasm-export" {{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -7557,6 +7557,23 @@
   D->addAttr(UsedAttr::CreateImplicit(S.Context));
 }
 
+static void handleWebAssemblyExportedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!isFunctionOrMethod(D)) {
+    S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+        << "'exported'" << ExpectedFunction;
+    return;
+  }
+
+  auto *FD = cast<FunctionDecl>(D);
+  if (FD->isThisDeclarationADefinition()) {
+    S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) WebAssemblyExportedAttr(S.Context, AL));
+  D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
 WebAssemblyImportModuleAttr *
 Sema::mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL) {
   auto *FD = cast<FunctionDecl>(D);
@@ -8736,6 +8753,9 @@
   case ParsedAttr::AT_WebAssemblyExportName:
     handleWebAssemblyExportNameAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_WebAssemblyExported:
+    handleWebAssemblyExportedAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_WebAssemblyImportModule:
     handleWebAssemblyImportModuleAttr(S, D, AL);
     break;
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -873,24 +873,25 @@
                            CodeGen::CodeGenModule &CGM) const override {
     TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
     if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+      llvm::Function *Fn = cast<llvm::Function>(GV);
       if (const auto *Attr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
-        llvm::Function *Fn = cast<llvm::Function>(GV);
         llvm::AttrBuilder B(GV->getContext());
         B.addAttribute("wasm-import-module", Attr->getImportModule());
         Fn->addFnAttrs(B);
       }
       if (const auto *Attr = FD->getAttr<WebAssemblyImportNameAttr>()) {
-        llvm::Function *Fn = cast<llvm::Function>(GV);
         llvm::AttrBuilder B(GV->getContext());
         B.addAttribute("wasm-import-name", Attr->getImportName());
         Fn->addFnAttrs(B);
       }
       if (const auto *Attr = FD->getAttr<WebAssemblyExportNameAttr>()) {
-        llvm::Function *Fn = cast<llvm::Function>(GV);
         llvm::AttrBuilder B(GV->getContext());
         B.addAttribute("wasm-export-name", Attr->getExportName());
         Fn->addFnAttrs(B);
       }
+      if (const auto *Attr = FD->getAttr<WebAssemblyExportedAttr>()) {
+        Fn->addFnAttr("wasm-exported");
+      }
     }
 
     if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -5527,6 +5527,16 @@
   }];
 }
 
+def WebAssemblyExportedDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the ``__attribute__((exported))``
+attribute for the WebAssembly target. This attribute may be attached to a
+function declaration, where it causes the symbol to be exported from the
+linked WebAssembly module.
+  }];
+}
+
 def WebAssemblyImportModuleDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1946,6 +1946,13 @@
   let Subjects = SubjectList<[Function], ErrorDiag>;
 }
 
+def WebAssemblyExported : InheritableAttr,
+                          TargetSpecificAttr<TargetWebAssembly> {
+  let Spellings = [Clang<"exported">];
+  let Documentation = [WebAssemblyExportedDocs];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+}
+
 def WebAssemblyImportModule : InheritableAttr,
                               TargetSpecificAttr<TargetWebAssembly> {
   let Spellings = [Clang<"import_module">];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D76547: [WebAssembly] Ad... Sam Clegg via Phabricator via cfe-commits

Reply via email to