From 086f8a6ef5459ea30a688e82ca471d9a863ae898 Mon Sep 17 00:00:00 2001 From: Shankar Easwaran Date: Wed, 2 Apr 2014 03:57:39 +0000 Subject: [PATCH] [ELF] Create Attribute class associated with Input files. The attribute class holds positional attributes for Input files specified on the command line for the Gnu flavor. llvm-svn: 205392 --- lld/include/lld/Driver/GnuLdInputGraph.h | 41 +++++++++++++++++------- lld/lib/Driver/GnuLdDriver.cpp | 22 ++++++------- lld/lib/Driver/GnuLdInputGraph.cpp | 6 ++-- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/lld/include/lld/Driver/GnuLdInputGraph.h b/lld/include/lld/Driver/GnuLdInputGraph.h index 522af99079c0..c10edda7e8c4 100644 --- a/lld/include/lld/Driver/GnuLdInputGraph.h +++ b/lld/include/lld/Driver/GnuLdInputGraph.h @@ -28,12 +28,30 @@ namespace lld { /// \brief Represents a ELF File class ELFFileNode : public FileNode { public: - ELFFileNode(ELFLinkingContext &ctx, StringRef path, int64_t ordinal = -1, - bool isWholeArchive = false, bool asNeeded = false, - bool dashlPrefix = false) + /// \brief The attributes class provides a way for a input file to look into + /// all the positional attributes that were specified in the command line. + /// There are few positional operators and the number of arguments to the + /// ELFFileNode class keeps growing. This achieves code to be clean as well. + class Attributes { + public: + Attributes() + : _isWholeArchive(false), _asNeeded(false), _isDashlPrefix(false) {} + void setWholeArchive(bool isWholeArchive) { + _isWholeArchive = isWholeArchive; + } + void setAsNeeded(bool asNeeded) { _asNeeded = asNeeded; } + void setDashlPrefix(bool isDashlPrefix) { _isDashlPrefix = isDashlPrefix; } + + public: + bool _isWholeArchive; + bool _asNeeded; + bool _isDashlPrefix; + }; + + ELFFileNode(ELFLinkingContext &ctx, StringRef path, int64_t ordinal, + Attributes &attributes) : FileNode(path, ordinal), _elfLinkingContext(ctx), - _isWholeArchive(isWholeArchive), _asNeeded(asNeeded), - _isDashlPrefix(dashlPrefix) {} + _attributes(attributes) {} ErrorOr getPath(const LinkingContext &ctx) const override; @@ -50,9 +68,9 @@ public: << "Attributes : " << "\n" << " - wholeArchive : " - << ((_isWholeArchive) ? "true" : "false") << "\n" - << " - asNeeded : " << ((_asNeeded) ? "true" : "false") - << "\n"; + << ((_attributes._isWholeArchive) ? "true" : "false") << "\n" + << " - asNeeded : " + << ((_attributes._asNeeded) ? "true" : "false") << "\n"; return true; } @@ -66,7 +84,8 @@ public: /// reset the next file index to 0 only if the node is an archive library or /// a shared library void resetNextIndex() override { - if ((!_isWholeArchive && (_files[0]->kind() == File::kindArchiveLibrary)) || + if ((!_attributes._isWholeArchive && + (_files[0]->kind() == File::kindArchiveLibrary)) || (_files[0]->kind() == File::kindSharedLibrary)) { _nextFileIndex = 0; } @@ -86,10 +105,8 @@ public: private: llvm::BumpPtrAllocator _alloc; const ELFLinkingContext &_elfLinkingContext; - bool _isWholeArchive; - bool _asNeeded; - bool _isDashlPrefix; std::unique_ptr _archiveFile; + const Attributes _attributes; }; /// \brief Parse GNU Linker scripts. diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 9d380e83d66e..687e34aed2d1 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -143,14 +143,14 @@ static bool parseDefsymOption(StringRef opt, StringRef &sym, uint64_t &addr) { } llvm::ErrorOr ELFFileNode::getPath(const LinkingContext &) const { - if (!_isDashlPrefix) + if (!_attributes._isDashlPrefix) return _path; return _elfLinkingContext.searchLibrary(_path); } std::string ELFFileNode::errStr(error_code errc) { if (errc == llvm::errc::no_such_file_or_directory) { - if (_isDashlPrefix) + if (_attributes._isDashlPrefix) return (Twine("Unable to find library -l") + _path).str(); return (Twine("Unable to find file ") + _path).str(); } @@ -268,12 +268,10 @@ bool GnuLdDriver::parse(int argc, const char *argv[], std::unique_ptr inputGraph(new InputGraph()); std::stack groupStack; - // Positional options for an Input File - bool isWholeArchive = false; - bool asNeeded = false; - bool _outputOptionSet = false; + ELFFileNode::Attributes attributes; int index = 0; + bool _outputOptionSet = false; // Ignore unknown arguments. for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN), @@ -403,19 +401,19 @@ bool GnuLdDriver::parse(int argc, const char *argv[], break; case OPT_no_whole_archive: - isWholeArchive = false; + attributes.setWholeArchive(false); break; case OPT_whole_archive: - isWholeArchive = true; + attributes.setWholeArchive(true); break; case OPT_as_needed: - asNeeded = true; + attributes.setAsNeeded(true); break; case OPT_no_as_needed: - asNeeded = false; + attributes.setAsNeeded(false); break; case OPT_defsym: { @@ -453,6 +451,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[], case OPT_INPUT: case OPT_l: { bool isDashlPrefix = (inputArg->getOption().getID() == OPT_l); + attributes.setDashlPrefix(isDashlPrefix); bool isELFFileNode = true; StringRef userPath = inputArg->getValue(); std::string resolvedInputPath = userPath; @@ -481,8 +480,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[], isELFFileNode = false; FileNode *inputNode = nullptr; if (isELFFileNode) - inputNode = new ELFFileNode(*ctx, userPath, index++, isWholeArchive, - asNeeded, isDashlPrefix); + inputNode = new ELFFileNode(*ctx, userPath, index++, attributes); else { inputNode = new ELFGNULdScript(*ctx, resolvedInputPath, index++); ec = inputNode->parse(*ctx, diagnostics); diff --git a/lld/lib/Driver/GnuLdInputGraph.cpp b/lld/lib/Driver/GnuLdInputGraph.cpp index cd3eb8787f20..f1c8b4e8ae06 100644 --- a/lld/lib/Driver/GnuLdInputGraph.cpp +++ b/lld/lib/Driver/GnuLdInputGraph.cpp @@ -25,7 +25,7 @@ error_code ELFFileNode::parse(const LinkingContext &ctx, if (ctx.logInputFiles()) diagnostics << *filePath << "\n"; - if (_isWholeArchive) { + if (_attributes._isWholeArchive) { std::vector> parsedFiles; error_code ec = ctx.registry().parseFile(_buffer, parsedFiles); if (ec) @@ -75,6 +75,7 @@ error_code GNULdScript::parse(const LinkingContext &ctx, error_code ELFGNULdScript::parse(const LinkingContext &ctx, raw_ostream &diagnostics) { int64_t index = 0; + ELFFileNode::Attributes attributes; if (error_code ec = GNULdScript::parse(ctx, diagnostics)) return ec; for (const auto &c : _linkerScript->_commands) { @@ -82,9 +83,10 @@ error_code ELFGNULdScript::parse(const LinkingContext &ctx, std::unique_ptr groupStart(new Group(index++)); for (auto &path : group->getPaths()) { // TODO : Propagate Set WholeArchive/dashlPrefix + attributes.setAsNeeded(path._asNeeded); auto inputNode = new ELFFileNode( _elfLinkingContext, _elfLinkingContext.allocateString(path._path), - index++, false, path._asNeeded, false); + index++, attributes); std::unique_ptr inputFile(inputNode); cast(groupStart.get())->addFile( std::move(inputFile));