Index: lib/Object/COFFModuleDefinition.cpp =================================================================== --- lib/Object/COFFModuleDefinition.cpp +++ lib/Object/COFFModuleDefinition.cpp @@ -232,7 +232,14 @@ for (;;) { read(); if (Tok.K == Identifier && Tok.Value[0] == '@') { - Tok.Value.drop_front().getAsInteger(10, E.Ordinal); + if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) { + // Not an ordinal modifier at all, but the next export (fastcall + // decorated) - complete the current one. + unget(); + Info.Exports.push_back(E); + return Error::success(); + break; + } read(); if (Tok.K == KwNoname) { E.Noname = true; Index: lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp =================================================================== --- lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -155,6 +155,22 @@ if (Path.empty()) Path = getImplibPath(Def->OutputFile); + if (Machine == IMAGE_FILE_MACHINE_I386 && Args.getLastArg(OPT_k)) { + for (COFFShortExport& E : Def->Exports) { + if (E.isWeak()) + continue; + E.SymbolName = E.Name; + // Trim off the trailing decoration. Symbols will always have a + // starting prefix here (either _ for cdecl/stdcall, @ for fastcall + // or ? for C++ functions). (Vectorcall functions also will end up having + // a prefix here, even if they shouldn't.) + E.Name = E.Name.substr(0, E.Name.find('@', 1)); + // By making sure E.SymbolName != E.Name for decorated symbols, + // writeImportLibrary writes these symbols with the type + // IMPORT_NAME_UNDECORATE. + } + } + if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine)) return 1; return 0; Index: lib/ToolDrivers/llvm-dlltool/Options.td =================================================================== --- lib/ToolDrivers/llvm-dlltool/Options.td +++ lib/ToolDrivers/llvm-dlltool/Options.td @@ -12,13 +12,13 @@ def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">; def d_long : JoinedOrSeparate<["--"], "input-def">, Alias; +def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">; +def k_alias: Flag<["--"], "kill-at">, Alias; + //============================================================================== // The flags below do nothing. They are defined only for dlltool compatibility. //============================================================================== -def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">; -def k_alias: Flag<["--"], "kill-at">, Alias; - def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">; def S_alias: JoinedOrSeparate<["--"], "as">, Alias; Index: test/DllTool/coff-decorated.def =================================================================== --- /dev/null +++ test/DllTool/coff-decorated.def @@ -0,0 +1,22 @@ +; RUN: llvm-dlltool -k -m i386 --input-def %s --output-lib %t.a +; RUN: llvm-readobj %t.a | FileCheck %s +; RUN: llvm-nm %t.a | FileCheck %s -check-prefix=CHECK-NM + +LIBRARY test.dll +EXPORTS +CdeclFunction +StdcallFunction@4 +@FastcallFunction@4 +StdcallAlias@4=StdcallFunction@4 + +; CHECK: Name type: noprefix +; CHECK: Symbol: __imp__CdeclFunction +; CHECK: Symbol: _CdeclFunction +; CHECK: Name type: undecorate +; CHECK: Symbol: __imp__StdcallFunction@4 +; CHECK: Symbol: _StdcallFunction@4 +; CHECK: Name type: undecorate +; CHECK: Symbol: __imp_@FastcallFunction@4 +; CHECK: Symbol: @FastcallFunction@4 +; CHECK-NM: w _StdcallAlias@4 +; CHECK-NM: U _StdcallFunction@4