diff --git a/lld/include/lld/Driver/WinLinkModuleDef.h b/lld/include/lld/Driver/WinLinkModuleDef.h index 030305717e23..5779901de61d 100644 --- a/lld/include/lld/Driver/WinLinkModuleDef.h +++ b/lld/include/lld/Driver/WinLinkModuleDef.h @@ -35,6 +35,7 @@ enum class Kind { kw_heapsize, kw_name, kw_noname, + kw_stacksize, kw_version, }; @@ -63,7 +64,7 @@ private: class Directive { public: - enum class Kind { exports, heapsize, name, version }; + enum class Kind { exports, heapsize, name, stacksize, version }; Kind getKind() const { return _kind; } virtual ~Directive() {} @@ -92,13 +93,14 @@ private: const std::vector _exports; }; -class Heapsize : public Directive { +template +class MemorySize : public Directive { public: - explicit Heapsize(uint64_t reserve, uint64_t commit) - : Directive(Kind::heapsize), _reserve(reserve), _commit(commit) {} + explicit MemorySize(uint64_t reserve, uint64_t commit) + : Directive(kind), _reserve(reserve), _commit(commit) {} static bool classof(const Directive *dir) { - return dir->getKind() == Kind::heapsize; + return dir->getKind() == kind; } uint64_t getReserve() const { return _reserve; } @@ -109,6 +111,9 @@ private: const uint64_t _commit; }; +typedef MemorySize Heapsize; +typedef MemorySize Stacksize; + class Name : public Directive { public: explicit Name(StringRef outputPath, uint64_t baseaddr) @@ -159,7 +164,7 @@ private: void error(const Token &tok, Twine msg); bool parseExport(PECOFFLinkingContext::ExportDesc &result); - bool parseHeapsize(uint64_t &reserve, uint64_t &commit); + bool parseMemorySize(uint64_t &reserve, uint64_t &commit); bool parseName(std::string &outfile, uint64_t &baseaddr); bool parseVersion(int &major, int &minor); diff --git a/lld/lib/Driver/WinLinkModuleDef.cpp b/lld/lib/Driver/WinLinkModuleDef.cpp index bc18609b821a..62eed1f0fcca 100644 --- a/lld/lib/Driver/WinLinkModuleDef.cpp +++ b/lld/lib/Driver/WinLinkModuleDef.cpp @@ -54,6 +54,7 @@ Token Lexer::lex() { .Case("HEAPSIZE", Kind::kw_heapsize) .Case("NAME", Kind::kw_name) .Case("NONAME", Kind::kw_noname) + .Case("STACKSIZE", Kind::kw_stacksize) .Case("VERSION", Kind::kw_version) .Default(Kind::identifier); _buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end); @@ -118,10 +119,17 @@ llvm::Optional Parser::parse() { // HEAPSIZE if (_tok._kind == Kind::kw_heapsize) { uint64_t reserve, commit; - if (!parseHeapsize(reserve, commit)) + if (!parseMemorySize(reserve, commit)) return llvm::None; return new (_alloc) Heapsize(reserve, commit); } + // STACKSIZE + if (_tok._kind == Kind::kw_stacksize) { + uint64_t reserve, commit; + if (!parseMemorySize(reserve, commit)) + return llvm::None; + return new (_alloc) Stacksize(reserve, commit); + } // NAME if (_tok._kind == Kind::kw_name) { std::string outputPath; @@ -170,8 +178,8 @@ bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) { } } -// HEAPSIZE reserve [, commit] -bool Parser::parseHeapsize(uint64_t &reserve, uint64_t &commit) { +// HEAPSIZE/STACKSIZE reserve[,commit] +bool Parser::parseMemorySize(uint64_t &reserve, uint64_t &commit) { if (!consumeTokenAsInt(reserve)) return false; diff --git a/lld/unittests/DriverTests/WinLinkModuleDefTest.cpp b/lld/unittests/DriverTests/WinLinkModuleDefTest.cpp index 2ce1cb478451..53f2c033a182 100644 --- a/lld/unittests/DriverTests/WinLinkModuleDefTest.cpp +++ b/lld/unittests/DriverTests/WinLinkModuleDefTest.cpp @@ -46,6 +46,7 @@ public: }; class HeapsizeTest : public ParserTest {}; +class StacksizeTest : public ParserTest {}; class NameTest : public ParserTest {}; class VersionTest : public ParserTest {}; @@ -78,6 +79,18 @@ TEST_F(HeapsizeTest, WithCommit) { EXPECT_EQ(8192U, heapsize->getCommit()); } +TEST_F(StacksizeTest, Basic) { + moduledef::Stacksize *stacksize = parse("STACKSIZE 65536"); + EXPECT_EQ(65536U, stacksize->getReserve()); + EXPECT_EQ(0U, stacksize->getCommit()); +} + +TEST_F(StacksizeTest, WithCommit) { + moduledef::Stacksize *stacksize = parse("STACKSIZE 65536, 8192"); + EXPECT_EQ(65536U, stacksize->getReserve()); + EXPECT_EQ(8192U, stacksize->getCommit()); +} + TEST_F(NameTest, Basic) { moduledef::Name *name = parse("NAME foo.exe"); EXPECT_EQ("foo.exe", name->getOutputPath());