Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -747,6 +747,15 @@ public: explicit WebAssemblyTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) : TargetCodeGenInfo(new WebAssemblyABIInfo(CGT)) {} + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + if (auto *FD = dyn_cast_or_null(D)) { + llvm::Function *Fn = cast(GV); + if (!FD->doesThisDeclarationHaveABody() && !FD->hasPrototype()) + Fn->addFnAttr("no-prototype"); + } + } }; /// Classify argument of given type \p Ty. Index: cfe/trunk/test/CodeGen/no-prototype.c =================================================================== --- cfe/trunk/test/CodeGen/no-prototype.c +++ cfe/trunk/test/CodeGen/no-prototype.c @@ -0,0 +1,20 @@ +// REQUIRES: webassembly-registered-target +// RUN: %clang_cc1 -triple wasm32 -emit-llvm %s -o - | FileCheck %s + +int foo(); + +int bar(int a) { + return foo(); +} + +int baz() { + return foo(); +} + +// CHECK: define i32 @bar(i32 %a) [[BAR_ATTR:#[0-9]+]] { +// CHECK: declare i32 @foo(...) [[FOO_ATTR:#[0-9]+]] +// CHECK: define i32 @baz() [[BAZ_ATTR:#[0-9]+]] { + +// CHECK: attributes [[FOO_ATTR]] = { {{.*}}"no-prototype"{{.*}} } +// CHECK-NOT: attributes [[BAR_ATTR]] = { {{.*}}"no-prototype"{{.*}} } +// CHECK-NOT: attributes [[BAZ_ATTR]] = { {{.*}}"no-prototype"{{.*}} }