diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Object/COFFModuleDefinition.cpp | |
parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) |
Notes
Diffstat (limited to 'lib/Object/COFFModuleDefinition.cpp')
-rw-r--r-- | lib/Object/COFFModuleDefinition.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/Object/COFFModuleDefinition.cpp b/lib/Object/COFFModuleDefinition.cpp index 510eac8b239ba..a571354648d65 100644 --- a/lib/Object/COFFModuleDefinition.cpp +++ b/lib/Object/COFFModuleDefinition.cpp @@ -57,9 +57,27 @@ struct Token { }; static bool isDecorated(StringRef Sym, bool MingwDef) { - // mingw does not prepend "_". - return (!MingwDef && Sym.startswith("_")) || Sym.startswith("@") || - Sym.startswith("?"); + // In def files, the symbols can either be listed decorated or undecorated. + // + // - For cdecl symbols, only the undecorated form is allowed. + // - For fastcall and vectorcall symbols, both fully decorated or + // undecorated forms can be present. + // - For stdcall symbols in non-MinGW environments, the decorated form is + // fully decorated with leading underscore and trailing stack argument + // size - like "_Func@0". + // - In MinGW def files, a decorated stdcall symbol does not include the + // leading underscore though, like "Func@0". + + // This function controls whether a leading underscore should be added to + // the given symbol name or not. For MinGW, treat a stdcall symbol name such + // as "Func@0" as undecorated, i.e. a leading underscore must be added. + // For non-MinGW, look for '@' in the whole string and consider "_Func@0" + // as decorated, i.e. don't add any more leading underscores. + // We can't check for a leading underscore here, since function names + // themselves can start with an underscore, while a second one still needs + // to be added. + return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") || + (!MingwDef && Sym.contains('@')); } static Error createError(const Twine &Err) { @@ -99,7 +117,7 @@ public: return Token(Identifier, S); } default: { - size_t End = Buf.find_first_of("=,\r\n \t\v"); + size_t End = Buf.find_first_of("=,;\r\n \t\v"); StringRef Word = Buf.substr(0, End); Kind K = llvm::StringSwitch<Kind>(Word) .Case("BASE", KwBase) @@ -232,13 +250,18 @@ private: for (;;) { read(); if (Tok.K == Identifier && Tok.Value[0] == '@') { - 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. + if (Tok.Value == "@") { + // "foo @ 10" + read(); + Tok.Value.getAsInteger(10, E.Ordinal); + } else if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) { + // "foo \n @bar" - 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(); } + // "foo @10" read(); if (Tok.K == KwNoname) { E.Noname = true; |