[lld] r223867 - Re-commit r223330: Rewrite InputGraph's Group
Shankar Easwaran
shankare at codeaurora.org
Thu Dec 11 21:28:11 PST 2014
Curious to figure out where the error was in the code that caused
undefined symbols ?
Was there a test added to check the failure which was not caught by any
of the tests ?
Shankar Easwaran
On 12/9/2014 6:33 PM, Rui Ueyama wrote:
> Author: ruiu
> Date: Tue Dec 9 18:33:00 2014
> New Revision: 223867
>
> URL: http://llvm.org/viewvc/llvm-project?rev=223867&view=rev
> Log:
> Re-commit r223330: Rewrite InputGraph's Group
>
> Modified:
> lld/trunk/include/lld/Core/InputGraph.h
> lld/trunk/include/lld/Core/LinkingContext.h
> lld/trunk/include/lld/Core/Resolver.h
> lld/trunk/include/lld/Driver/DarwinInputGraph.h
> lld/trunk/include/lld/Driver/WinLinkInputGraph.h
> lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
> lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
> lld/trunk/lib/Core/InputGraph.cpp
> lld/trunk/lib/Core/Resolver.cpp
> lld/trunk/lib/Driver/DarwinInputGraph.cpp
> lld/trunk/lib/Driver/DarwinLdDriver.cpp
> lld/trunk/lib/Driver/Driver.cpp
> lld/trunk/lib/Driver/GnuLdDriver.cpp
> lld/trunk/lib/Driver/GnuLdInputGraph.cpp
> lld/trunk/lib/Driver/WinLinkDriver.cpp
> lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
> lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
> lld/trunk/unittests/DriverTests/DriverTest.h
> lld/trunk/unittests/DriverTests/InputGraphTest.cpp
> lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
>
> Modified: lld/trunk/include/lld/Core/InputGraph.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputGraph.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/InputGraph.h (original)
> +++ lld/trunk/include/lld/Core/InputGraph.h Tue Dec 9 18:33:00 2014
> @@ -59,12 +59,6 @@ public:
> /// assigned in the way files are resolved.
> virtual ErrorOr<File &> getNextFile();
>
> - /// Notifies the current input element of Resolver made some progress on
> - /// resolving undefined symbols using the current file. Group (representing
> - /// --start-group and --end-group) uses that notification to make a decision
> - /// whether it should iterate over again or terminate or not.
> - virtual void notifyProgress();
> -
> /// Adds an observer of getNextFile(). Each time a new file is about to be
> /// returned from getNextFile(), registered observers are called with the file
> /// being returned.
> @@ -76,14 +70,18 @@ public:
> /// \brief Adds a node at the beginning of the InputGraph
> void addInputElementFront(std::unique_ptr<InputElement>);
>
> - /// Normalize the InputGraph. It calls expand() on each node and then replace
> - /// it with getReplacements() results.
> + /// Normalize the InputGraph. It calls getReplacements() on each element.
> void normalize();
>
> - range<InputElementIterT> inputElements() {
> - return make_range(_inputArgs.begin(), _inputArgs.end());
> + InputElementVectorT &inputElements() {
> + return _inputArgs;
> }
>
> + // Returns the current group size if we are at an --end-group.
> + // Otherwise returns 0.
> + int getGroupSize();
> + void skipGroup();
> +
> // \brief Returns the number of input files.
> size_t size() const { return _inputArgs.size(); }
>
> @@ -108,8 +106,8 @@ class InputElement {
> public:
> /// Each input element in the graph can be a File or a control
> enum class Kind : uint8_t {
> - Group, // Represents a type associated with Group
> - File // Represents a type associated with File Nodes
> + File, // Represents a type associated with File Nodes
> + GroupEnd,
> };
>
> InputElement(Kind type) : _kind(type) {}
> @@ -129,16 +127,9 @@ public:
> /// Get the next file to be processed by the resolver
> virtual ErrorOr<File &> getNextFile() = 0;
>
> - /// Refer InputGraph::notifyProgress(). By default, it does nothing. Only
> - /// Group is interested in this message.
> - virtual void notifyProgress() {};
> -
> /// \brief Reset the next index
> virtual void resetNextIndex() = 0;
>
> - /// Returns true if we want to replace this node with children.
> - virtual void expand() {}
> -
> /// Get the elements that we want to expand with.
> virtual bool getReplacements(InputGraph::InputElementVectorT &) {
> return false;
> @@ -148,73 +139,31 @@ protected:
> Kind _kind; // The type of the Element
> };
>
> -/// \brief A Control node which contains a group of InputElements
> -/// This affects the resolver so that it resolves undefined symbols
> -/// in the group completely before looking at other input files that
> -/// follow the group
> -class Group : public InputElement {
> +// This is a marker for --end-group. getSize() returns the number of
> +// files between the corresponding --start-group and this marker.
> +class GroupEnd : public InputElement {
> public:
> - Group()
> - : InputElement(InputElement::Kind::Group), _currentElementIndex(0),
> - _nextElementIndex(0), _madeProgress(false) {}
> + GroupEnd(int size) : InputElement(Kind::GroupEnd), _size(size) {}
>
> - static inline bool classof(const InputElement *a) {
> - return a->kind() == InputElement::Kind::Group;
> - }
> -
> - /// \brief Process input element and add it to the group
> - bool addFile(std::unique_ptr<InputElement> element) {
> - _elements.push_back(std::move(element));
> - return true;
> - }
> + int getSize() const { return _size; }
>
> - range<InputGraph::InputElementIterT> elements() {
> - return make_range(_elements.begin(), _elements.end());
> - }
> -
> - void resetNextIndex() override {
> - _madeProgress = false;
> - _currentElementIndex = 0;
> - _nextElementIndex = 0;
> - for (std::unique_ptr<InputElement> &elem : _elements)
> - elem->resetNextIndex();
> + static inline bool classof(const InputElement *a) {
> + return a->kind() == Kind::GroupEnd;
> }
>
> /// \brief Parse the group members.
> std::error_code parse(const LinkingContext &ctx, raw_ostream &diag) override {
> - for (std::unique_ptr<InputElement> &ei : _elements)
> - if (std::error_code ec = ei->parse(ctx, diag))
> - return ec;
> return std::error_code();
> }
>
> - /// If Resolver made a progress using the current file, it's ok to revisit
> - /// files in this group in future.
> - void notifyProgress() override {
> - for (std::unique_ptr<InputElement> &elem : _elements)
> - elem->notifyProgress();
> - _madeProgress = true;
> - }
> -
> - ErrorOr<File &> getNextFile() override;
> -
> - void expand() override {
> - for (std::unique_ptr<InputElement> &elt : _elements)
> - elt->expand();
> - std::vector<std::unique_ptr<InputElement>> result;
> - for (std::unique_ptr<InputElement> &elt : _elements) {
> - if (elt->getReplacements(result))
> - continue;
> - result.push_back(std::move(elt));
> - }
> - _elements.swap(result);
> + ErrorOr<File &> getNextFile() override {
> + llvm_unreachable("shouldn't be here.");
> }
>
> -protected:
> - InputGraph::InputElementVectorT _elements;
> - uint32_t _currentElementIndex;
> - uint32_t _nextElementIndex;
> - bool _madeProgress;
> + void resetNextIndex() override {}
> +
> +private:
> + int _size;
> };
>
> /// \brief Represents an Input file in the graph
> @@ -252,6 +201,8 @@ public:
>
> /// \brief add a file to the list of files
> virtual void addFiles(InputGraph::FileVectorT files) {
> + assert(files.size() == 1);
> + assert(_files.empty());
> for (std::unique_ptr<File> &ai : files)
> _files.push_back(std::move(ai));
> }
> @@ -260,6 +211,8 @@ public:
> /// the node again.
> void resetNextIndex() override { _nextFileIndex = 0; }
>
> + bool getReplacements(InputGraph::InputElementVectorT &result) override;
> +
> protected:
> /// \brief Read the file into _buffer.
> std::error_code getBuffer(StringRef filePath);
> @@ -276,6 +229,10 @@ protected:
> class SimpleFileNode : public FileNode {
> public:
> SimpleFileNode(StringRef path) : FileNode(path) {}
> + SimpleFileNode(StringRef path, std::unique_ptr<File> f)
> + : FileNode(path) {
> + _files.push_back(std::move(f));
> + }
>
> virtual ~SimpleFileNode() {}
>
>
> Modified: lld/trunk/include/lld/Core/LinkingContext.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/LinkingContext.h (original)
> +++ lld/trunk/include/lld/Core/LinkingContext.h Tue Dec 9 18:33:00 2014
> @@ -322,6 +322,10 @@ public:
> bool runRoundTripPass() const { return _runRoundTripPasses; }
> #endif
>
> + // This function is called just before the Resolver kicks in.
> + // Derived classes may use that chance to rearrange the input files.
> + virtual void maybeSortInputFiles() {}
> +
> /// @}
> protected:
> LinkingContext(); // Must be subclassed
>
> Modified: lld/trunk/include/lld/Core/Resolver.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/Resolver.h (original)
> +++ lld/trunk/include/lld/Core/Resolver.h Tue Dec 9 18:33:00 2014
> @@ -28,7 +28,8 @@ class LinkingContext;
> class Resolver {
> public:
> Resolver(LinkingContext &context)
> - : _context(context), _symbolTable(context), _result(new MergedFile()) {}
> + : _context(context), _symbolTable(context), _result(new MergedFile()),
> + _fileIndex(0) {}
>
> // InputFiles::Handler methods
> void doDefinedAtom(const DefinedAtom&);
> @@ -38,10 +39,10 @@ public:
>
> // Handle files, this adds atoms from the current file thats
> // being processed by the resolver
> - void handleFile(const File &);
> + bool handleFile(const File &);
>
> // Handle an archive library file.
> - void handleArchiveFile(const File &);
> + bool handleArchiveFile(const File &);
>
> // Handle a shared library file.
> void handleSharedLibrary(const File &);
> @@ -54,6 +55,9 @@ public:
> private:
> typedef std::function<void(StringRef, bool)> UndefCallback;
>
> + bool undefinesAdded(int count);
> + ErrorOr<File &> nextFile(bool &inGroup);
> +
> /// \brief Add section group/.gnu.linkonce if it does not exist previously.
> void maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom);
>
> @@ -110,6 +114,11 @@ private:
> llvm::DenseSet<const Atom *> _deadAtoms;
> std::unique_ptr<MergedFile> _result;
> llvm::DenseMap<const Atom *, llvm::DenseSet<const Atom *>> _reverseRef;
> +
> + // --start-group and --end-group
> + std::vector<File *> _files;
> + std::map<File *, bool> _newUndefinesAdded;
> + size_t _fileIndex;
> };
>
> } // namespace lld
>
> Modified: lld/trunk/include/lld/Driver/DarwinInputGraph.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/DarwinInputGraph.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Driver/DarwinInputGraph.h (original)
> +++ lld/trunk/include/lld/Driver/DarwinInputGraph.h Tue Dec 9 18:33:00 2014
> @@ -23,18 +23,6 @@
>
> namespace lld {
>
> -
> -class DarwinInputGraph : public InputGraph {
> -public:
> - DarwinInputGraph() : _librariesPhase(false), _repeatLibraries(false) { }
> - ErrorOr<File &> getNextFile() override;
> - void notifyProgress() override;
> -private:
> - bool _librariesPhase;
> - bool _repeatLibraries;
> -};
> -
> -
> /// \brief Represents a MachO File
> class MachOFileNode : public FileNode {
> public:
>
> Modified: lld/trunk/include/lld/Driver/WinLinkInputGraph.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkInputGraph.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Driver/WinLinkInputGraph.h (original)
> +++ lld/trunk/include/lld/Driver/WinLinkInputGraph.h Tue Dec 9 18:33:00 2014
> @@ -55,21 +55,6 @@ public:
> ErrorOr<StringRef> getPath(const LinkingContext &ctx) const override;
> };
>
> -/// \brief Represents a ELF control node
> -class PECOFFGroup : public Group {
> -public:
> - PECOFFGroup(PECOFFLinkingContext &ctx) : Group(), _ctx(ctx) {}
> -
> - /// \brief Parse the group members.
> - std::error_code parse(const LinkingContext &ctx, raw_ostream &diag) override {
> - std::lock_guard<std::recursive_mutex> lock(_ctx.getMutex());
> - return Group::parse(ctx, diag);
> - }
> -
> -private:
> - PECOFFLinkingContext &_ctx;
> -};
> -
> } // namespace lld
>
> #endif
>
> Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
> +++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Dec 9 18:33:00 2014
> @@ -283,6 +283,8 @@ public:
> /// bits are xxxx.yy.zz. Largest number is 65535.255.255
> static bool parsePackedVersion(StringRef str, uint32_t &result);
>
> + void maybeSortInputFiles() override;
> +
> private:
> Writer &writer() const override;
> mach_o::MachODylibFile* loadIndirectDylib(StringRef path);
>
> Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
> +++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Dec 9 18:33:00 2014
> @@ -29,7 +29,6 @@ using llvm::COFF::WindowsSubsystem;
> static const uint8_t DEFAULT_DOS_STUB[128] = {'M', 'Z'};
>
> namespace lld {
> -class Group;
>
> class PECOFFLinkingContext : public LinkingContext {
> public:
> @@ -318,8 +317,7 @@ public:
> void setEntryNode(SimpleFileNode *node) { _entryNode = node; }
> SimpleFileNode *getEntryNode() const { return _entryNode; }
>
> - void setLibraryGroup(Group *group) { _libraryGroup = group; }
> - Group *getLibraryGroup() const { return _libraryGroup; }
> + void addLibraryFile(std::unique_ptr<FileNode> file);
>
> void setModuleDefinitionFile(const std::string val) {
> _moduleDefinitionFile = val;
> @@ -441,9 +439,6 @@ private:
> // The node containing the entry point file.
> SimpleFileNode *_entryNode;
>
> - // The PECOFFGroup that contains all the .lib files.
> - Group *_libraryGroup;
> -
> // Name of the temporary file for lib.exe subcommand. For debugging
> // only.
> std::string _moduleDefinitionFile;
>
> Modified: lld/trunk/lib/Core/InputGraph.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputGraph.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/InputGraph.cpp (original)
> +++ lld/trunk/lib/Core/InputGraph.cpp Tue Dec 9 18:33:00 2014
> @@ -36,8 +36,6 @@ ErrorOr<File &> InputGraph::getNextFile(
> }
> }
>
> -void InputGraph::notifyProgress() { _currentInputElement->notifyProgress(); }
> -
> void InputGraph::registerObserver(std::function<void(File *)> fn) {
> _observers.push_back(fn);
> }
> @@ -61,12 +59,13 @@ bool InputGraph::dump(raw_ostream &diagn
> ErrorOr<InputElement *> InputGraph::getNextInputElement() {
> if (_nextElementIndex >= _inputArgs.size())
> return make_error_code(InputGraphError::no_more_elements);
> - return _inputArgs[_nextElementIndex++].get();
> + InputElement *elem = _inputArgs[_nextElementIndex++].get();
> + if (isa<GroupEnd>(elem))
> + return getNextInputElement();
> + return elem;
> }
>
> void InputGraph::normalize() {
> - for (std::unique_ptr<InputElement> &elt : _inputArgs)
> - elt->expand();
> std::vector<std::unique_ptr<InputElement>> vec;
> for (std::unique_ptr<InputElement> &elt : _inputArgs) {
> if (elt->getReplacements(vec))
> @@ -76,6 +75,25 @@ void InputGraph::normalize() {
> _inputArgs = std::move(vec);
> }
>
> +// If we are at the end of a group, return its size (which indicates
> +// how many files we need to go back in the command line).
> +// Returns 0 if we are not at the end of a group.
> +int InputGraph::getGroupSize() {
> + if (_nextElementIndex >= _inputArgs.size())
> + return 0;
> + InputElement *elem = _inputArgs[_nextElementIndex].get();
> + if (const GroupEnd *group = dyn_cast<GroupEnd>(elem))
> + return group->getSize();
> + return 0;
> +}
> +
> +void InputGraph::skipGroup() {
> + if (_nextElementIndex >= _inputArgs.size())
> + return;
> + if (isa<GroupEnd>(_inputArgs[_nextElementIndex].get()))
> + _nextElementIndex++;
> +}
> +
> /// \brief Read the file into _buffer.
> std::error_code FileNode::getBuffer(StringRef filePath) {
> // Create a memory buffer
> @@ -87,32 +105,10 @@ std::error_code FileNode::getBuffer(Stri
> return std::error_code();
> }
>
> -/// \brief Return the next file that need to be processed by the resolver.
> -/// This also processes input elements depending on the resolve status
> -/// of the input elements contained in the group.
> -ErrorOr<File &> Group::getNextFile() {
> - // If there are no elements, move on to the next input element
> - if (_elements.empty())
> - return make_error_code(InputGraphError::no_more_files);
> -
> - for (;;) {
> - // If we have processed all the elements, and have made no progress on
> - // linking, we cannot resolve any symbol from this group. Continue to the
> - // next one by returning no_more_files.
> - if (_nextElementIndex == _elements.size()) {
> - if (!_madeProgress)
> - return make_error_code(InputGraphError::no_more_files);
> - resetNextIndex();
> - }
> -
> - _currentElementIndex = _nextElementIndex;
> - auto file = _elements[_nextElementIndex]->getNextFile();
> - // Move on to the next element if we have finished processing all
> - // the files in the input element
> - if (file.getError() == InputGraphError::no_more_files) {
> - _nextElementIndex++;
> - continue;
> - }
> - return *file;
> - }
> +bool FileNode::getReplacements(InputGraph::InputElementVectorT &result) {
> + if (_files.size() < 2)
> + return false;
> + for (std::unique_ptr<File> &file : _files)
> + result.push_back(llvm::make_unique<SimpleFileNode>(_path, std::move(file)));
> + return true;
> }
>
> Modified: lld/trunk/lib/Core/Resolver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/Resolver.cpp (original)
> +++ lld/trunk/lib/Core/Resolver.cpp Tue Dec 9 18:33:00 2014
> @@ -27,7 +27,7 @@
>
> namespace lld {
>
> -void Resolver::handleFile(const File &file) {
> +bool Resolver::handleFile(const File &file) {
> bool undefAdded = false;
> for (const DefinedAtom *atom : file.defined())
> doDefinedAtom(*atom);
> @@ -38,13 +38,7 @@ void Resolver::handleFile(const File &fi
> doSharedLibraryAtom(*atom);
> for (const AbsoluteAtom *atom : file.absolute())
> doAbsoluteAtom(*atom);
> -
> - // Notify the input file manager of the fact that we have made some progress
> - // on linking using the current input file. It may want to know the fact for
> - // --start-group/--end-group.
> - if (undefAdded) {
> - _context.getInputGraph().notifyProgress();
> - }
> + return undefAdded;
> }
>
> void Resolver::forEachUndefines(bool searchForOverrides,
> @@ -76,17 +70,19 @@ void Resolver::forEachUndefines(bool sea
> } while (undefineGenCount != _symbolTable.size());
> }
>
> -void Resolver::handleArchiveFile(const File &file) {
> +bool Resolver::handleArchiveFile(const File &file) {
> const ArchiveLibraryFile *archiveFile = cast<ArchiveLibraryFile>(&file);
> bool searchForOverrides =
> _context.searchArchivesToOverrideTentativeDefinitions();
> + bool undefAdded = false;
> forEachUndefines(searchForOverrides,
> [&](StringRef undefName, bool dataSymbolOnly) {
> if (const File *member = archiveFile->find(undefName, dataSymbolOnly)) {
> member->setOrdinal(_context.getNextOrdinalAndIncrement());
> - handleFile(*member);
> + undefAdded = handleFile(*member) || undefAdded;
> }
> });
> + return undefAdded;
> }
>
> void Resolver::handleSharedLibrary(const File &file) {
> @@ -233,31 +229,66 @@ void Resolver::addAtoms(const std::vecto
> doDefinedAtom(*newAtom);
> }
>
> +// Returns true if at least one of N previous files has created an
> +// undefined symbol.
> +bool Resolver::undefinesAdded(int n) {
> + for (size_t i = _fileIndex - n; i < _fileIndex; ++i)
> + if (_newUndefinesAdded[_files[i]])
> + return true;
> + return false;
> +}
> +
> +ErrorOr<File &> Resolver::nextFile(bool &inGroup) {
> + if (size_t groupSize = _context.getInputGraph().getGroupSize()) {
> + // We are at the end of the current group. If one or more new
> + // undefined atom has been added in the last groupSize files, we
> + // reiterate over the files.
> + if (undefinesAdded(groupSize))
> + _fileIndex -= groupSize;
> + _context.getInputGraph().skipGroup();
> + return nextFile(inGroup);
> + }
> + if (_fileIndex < _files.size()) {
> + // We are still in the current group.
> + inGroup = true;
> + return *_files[_fileIndex++];
> + }
> + // We are not in a group. Get a new file.
> + ErrorOr<File &> file = _context.getInputGraph().getNextFile();
> + if (std::error_code ec = file.getError()) {
> + if (ec != InputGraphError::no_more_files)
> + llvm::errs() << "Error occurred in getNextFile: " << ec.message() << "\n";
> + return ec;
> + }
> + _files.push_back(&*file);
> + ++_fileIndex;
> + inGroup = false;
> + return *file;
> +}
> +
> // Keep adding atoms until _context.getNextFile() returns an error. This
> // function is where undefined atoms are resolved.
> bool Resolver::resolveUndefines() {
> ScopedTask task(getDefaultDomain(), "resolveUndefines");
>
> for (;;) {
> - ErrorOr<File &> file = _context.getInputGraph().getNextFile();
> - std::error_code ec = file.getError();
> - if (ec == InputGraphError::no_more_files)
> - return true;
> - if (!file) {
> - llvm::errs() << "Error occurred in getNextFile: " << ec.message() << "\n";
> - return false;
> - }
> -
> + bool inGroup = false;
> + bool undefAdded = false;
> + ErrorOr<File &> file = nextFile(inGroup);
> + if (std::error_code ec = file.getError())
> + return ec == InputGraphError::no_more_files;
> switch (file->kind()) {
> case File::kindObject:
> + if (inGroup)
> + break;
> assert(!file->hasOrdinal());
> file->setOrdinal(_context.getNextOrdinalAndIncrement());
> - handleFile(*file);
> + undefAdded = handleFile(*file);
> break;
> case File::kindArchiveLibrary:
> if (!file->hasOrdinal())
> file->setOrdinal(_context.getNextOrdinalAndIncrement());
> - handleArchiveFile(*file);
> + undefAdded = handleArchiveFile(*file);
> break;
> case File::kindSharedLibrary:
> if (!file->hasOrdinal())
> @@ -265,6 +296,7 @@ bool Resolver::resolveUndefines() {
> handleSharedLibrary(*file);
> break;
> }
> + _newUndefinesAdded[&*file] = undefAdded;
> }
> }
>
>
> Modified: lld/trunk/lib/Driver/DarwinInputGraph.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinInputGraph.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/DarwinInputGraph.cpp (original)
> +++ lld/trunk/lib/Driver/DarwinInputGraph.cpp Tue Dec 9 18:33:00 2014
> @@ -18,48 +18,6 @@
> namespace lld {
>
>
> -ErrorOr<File &> DarwinInputGraph::getNextFile() {
> - // The darwin linker processes input files in two phases. The first phase
> - // links in all object (.o) files in command line order. The second phase
> - // links in libraries in command line order. If there are still UndefinedAtoms
> - // the second phase is repeated until notifyProgress() is not called by
> - // resolver.
> - for (;;) {
> - if (_currentInputElement) {
> - for(;;) {
> - ErrorOr<File &> next = _currentInputElement->getNextFile();
> - if (next.getError())
> - break;
> - File *file = &next.get();
> - bool fileIsLibrary = isa<SharedLibraryFile>(file) ||
> - isa<ArchiveLibraryFile>(file);
> - if (fileIsLibrary == _librariesPhase) {
> - // Return library in library phase and object files in non-lib mode.
> - return *file;
> - }
> - }
> - }
> -
> - if (_nextElementIndex >= _inputArgs.size()) {
> - // If no more elements, done unless we need to repeat library scan.
> - if (_librariesPhase && !_repeatLibraries)
> - return make_error_code(InputGraphError::no_more_files);
> - // Clear iterations and only look for libraries.
> - _librariesPhase = true;
> - _repeatLibraries = false;
> - _nextElementIndex = 0;
> - for (auto &ie : _inputArgs) {
> - ie->resetNextIndex();
> - }
> - }
> - _currentInputElement = _inputArgs[_nextElementIndex++].get();
> - }
> -}
> -
> -void DarwinInputGraph::notifyProgress() {
> - _repeatLibraries = true;
> -}
> -
> /// \brief Parse the input file to lld::File.
> std::error_code MachOFileNode::parse(const LinkingContext &ctx,
> raw_ostream &diagnostics) {
>
> Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
> +++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Tue Dec 9 18:33:00 2014
> @@ -83,7 +83,7 @@ static std::string canonicalizePath(Stri
> }
> }
>
> -static void addFile(StringRef path, std::unique_ptr<DarwinInputGraph> &inputGraph,
> +static void addFile(StringRef path, std::unique_ptr<InputGraph> &inputGraph,
> MachOLinkingContext &ctx, bool loadWholeArchive,
> bool upwardDylib) {
> auto node = llvm::make_unique<MachOFileNode>(path, ctx);
> @@ -185,7 +185,7 @@ static std::error_code parseOrderFile(St
> // per line. The <dir> prefix is prepended to each partial path.
> //
> static std::error_code parseFileList(StringRef fileListPath,
> - std::unique_ptr<DarwinInputGraph> &inputGraph,
> + std::unique_ptr<InputGraph> &inputGraph,
> MachOLinkingContext &ctx, bool forceLoad,
> raw_ostream &diagnostics) {
> // If there is a comma, split off <dir>.
> @@ -521,7 +521,7 @@ bool DarwinLdDriver::parse(int argc, con
> }
> }
>
> - std::unique_ptr<DarwinInputGraph> inputGraph(new DarwinInputGraph());
> + std::unique_ptr<InputGraph> inputGraph(new InputGraph());
>
> // Now construct the set of library search directories, following ld64's
> // baroque set of accumulated hacks. Mostly, the algorithm constructs
>
> Modified: lld/trunk/lib/Driver/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/Driver.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/Driver.cpp (original)
> +++ lld/trunk/lib/Driver/Driver.cpp Tue Dec 9 18:33:00 2014
> @@ -62,9 +62,6 @@ bool Driver::link(LinkingContext &contex
> if (std::error_code ec = ie->parse(context, stream)) {
> if (FileNode *fileNode = dyn_cast<FileNode>(ie.get()))
> stream << fileNode->errStr(ec) << "\n";
> - else if (dyn_cast<Group>(ie.get()))
> - // FIXME: We need a better diagnostics here
> - stream << "Cannot parse group input element\n";
> else
> llvm_unreachable("Unknown type of input element");
> fail = true;
> @@ -83,21 +80,24 @@ bool Driver::link(LinkingContext &contex
> if (fail)
> return false;
>
> - std::unique_ptr<SimpleFileNode> fileNode(
> - new SimpleFileNode("Internal Files"));
> -
> InputGraph::FileVectorT internalFiles;
> context.createInternalFiles(internalFiles);
> -
> - if (internalFiles.size())
> - fileNode->addFiles(std::move(internalFiles));
> + for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
> + context.getInputGraph().addInputElementFront(
> + llvm::make_unique<SimpleFileNode>("internal", std::move(*i)));
> + }
>
> // Give target a chance to add files.
> InputGraph::FileVectorT implicitFiles;
> context.createImplicitFiles(implicitFiles);
> - if (implicitFiles.size())
> - fileNode->addFiles(std::move(implicitFiles));
> - context.getInputGraph().addInputElementFront(std::move(fileNode));
> + for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
> + context.getInputGraph().addInputElementFront(
> + llvm::make_unique<SimpleFileNode>("implicit", std::move(*i)));
> + }
> +
> + // Give target a chance to sort the input files.
> + // Mach-O uses this chance to move all object files before library files.
> + context.maybeSortInputFiles();
>
> // Do core linking.
> ScopedTask resolveTask(getDefaultDomain(), "Resolve");
>
> Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
> +++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Dec 9 18:33:00 2014
> @@ -295,7 +295,8 @@ bool GnuLdDriver::parse(int argc, const
> }
>
> std::unique_ptr<InputGraph> inputGraph(new InputGraph());
> - std::stack<Group *> groupStack;
> + std::stack<int> groupStack;
> + int numfiles = 0;
>
> ELFFileNode::Attributes attributes;
>
> @@ -468,16 +469,21 @@ bool GnuLdDriver::parse(int argc, const
> break;
> }
>
> - case OPT_start_group: {
> - std::unique_ptr<Group> group(new Group());
> - groupStack.push(group.get());
> - inputGraph->addInputElement(std::move(group));
> + case OPT_start_group:
> + groupStack.push(numfiles);
> break;
> - }
>
> - case OPT_end_group:
> + case OPT_end_group: {
> + if (groupStack.empty()) {
> + diagnostics << "stray --end-group\n";
> + return false;
> + }
> + int startGroupPos = groupStack.top();
> + inputGraph->addInputElement(
> + llvm::make_unique<GroupEnd>(numfiles - startGroupPos));
> groupStack.pop();
> break;
> + }
>
> case OPT_z: {
> StringRef extOpt = inputArg->getValue();
> @@ -552,11 +558,8 @@ bool GnuLdDriver::parse(int argc, const
> }
> }
> std::unique_ptr<InputElement> inputFile(inputNode);
> - if (groupStack.empty()) {
> - inputGraph->addInputElement(std::move(inputFile));
> - } else {
> - groupStack.top()->addFile(std::move(inputFile));
> - }
> + ++numfiles;
> + inputGraph->addInputElement(std::move(inputFile));
> break;
> }
>
>
> Modified: lld/trunk/lib/Driver/GnuLdInputGraph.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdInputGraph.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdInputGraph.cpp (original)
> +++ lld/trunk/lib/Driver/GnuLdInputGraph.cpp Tue Dec 9 18:33:00 2014
> @@ -91,7 +91,7 @@ std::error_code ELFGNULdScript::parse(co
> auto *group = dyn_cast<script::Group>(c);
> if (!group)
> continue;
> - std::unique_ptr<Group> groupStart(new Group());
> + size_t numfiles = 0;
> for (const script::Path &path : group->getPaths()) {
> // TODO : Propagate Set WholeArchive/dashlPrefix
> attributes.setAsNeeded(path._asNeeded);
> @@ -100,9 +100,10 @@ std::error_code ELFGNULdScript::parse(co
> _elfLinkingContext, _elfLinkingContext.allocateString(path._path),
> attributes);
> std::unique_ptr<InputElement> inputFile(inputNode);
> - groupStart.get()->addFile(std::move(inputFile));
> + _expandElements.push_back(std::move(inputFile));
> + ++numfiles;
> }
> - _expandElements.push_back(std::move(groupStart));
> + _expandElements.push_back(llvm::make_unique<GroupEnd>(numfiles));
> }
> return std::error_code();
> }
>
> Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
> +++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Dec 9 18:33:00 2014
> @@ -781,7 +781,7 @@ static bool hasLibrary(const PECOFFLinki
> ErrorOr<StringRef> path = fileNode->getPath(ctx);
> if (!path)
> return false;
> - for (std::unique_ptr<InputElement> &p : ctx.getLibraryGroup()->elements())
> + for (std::unique_ptr<InputElement> &p : ctx.getInputGraph().inputElements())
> if (auto *f = dyn_cast<FileNode>(p.get()))
> if (*path == *f->getPath(ctx))
> return true;
> @@ -1397,10 +1397,8 @@ bool WinLinkDriver::parse(int argc, cons
> ctx.setEntryNode(entry.get());
> ctx.getInputGraph().addInputElement(std::move(entry));
>
> - // The container for all library files.
> - std::unique_ptr<Group> group(new PECOFFGroup(ctx));
> - ctx.setLibraryGroup(group.get());
> - ctx.getInputGraph().addInputElement(std::move(group));
> + // Add a group-end marker.
> + ctx.getInputGraph().addInputElement(llvm::make_unique<GroupEnd>(0));
> }
>
> // Add the library files to the library group.
> @@ -1409,7 +1407,7 @@ bool WinLinkDriver::parse(int argc, cons
> if (isReadingDirectiveSection)
> if (lib->parse(ctx, diag))
> return false;
> - ctx.getLibraryGroup()->addFile(std::move(lib));
> + ctx.addLibraryFile(std::move(lib));
> }
> }
>
>
> Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Dec 9 18:33:00 2014
> @@ -22,6 +22,7 @@
> #include "llvm/ADT/Triple.h"
> #include "llvm/Config/config.h"
> #include "llvm/Support/Errc.h"
> +#include "llvm/Support/Debug.h"
> #include "llvm/Support/Host.h"
> #include "llvm/Support/MachO.h"
> #include "llvm/Support/Path.h"
> @@ -923,4 +924,35 @@ bool MachOLinkingContext::customAtomOrde
> return true;
> }
>
> +static File *getFirstFile(const std::unique_ptr<InputElement> &elem) {
> + FileNode *e = dyn_cast<FileNode>(const_cast<InputElement *>(elem.get()));
> + if (!e || e->files().empty())
> + return nullptr;
> + return e->files()[0].get();
> +}
> +
> +static bool isLibrary(const std::unique_ptr<InputElement> &elem) {
> + File *f = getFirstFile(elem);
> + return f && (isa<SharedLibraryFile>(f) || isa<ArchiveLibraryFile>(f));
> +}
> +
> +// The darwin linker processes input files in two phases. The first phase
> +// links in all object (.o) files in command line order. The second phase
> +// links in libraries in command line order.
> +// In this function we reorder the input files so that all the object files
> +// comes before any library file. We also make a group for the library files
> +// so that the Resolver will reiterate over the libraries as long as we find
> +// new undefines from libraries.
> +void MachOLinkingContext::maybeSortInputFiles() {
> + std::vector<std::unique_ptr<InputElement>> &elements
> + = getInputGraph().inputElements();
> + std::stable_sort(elements.begin(), elements.end(),
> + [](const std::unique_ptr<InputElement> &a,
> + const std::unique_ptr<InputElement> &b) {
> + return !isLibrary(a) && isLibrary(b);
> + });
> + size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
> + elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
> +}
> +
> } // end namespace lld
>
> Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Dec 9 18:33:00 2014
> @@ -87,6 +87,23 @@ std::unique_ptr<File> PECOFFLinkingConte
> "<command line option /include>");
> }
>
> +void PECOFFLinkingContext::addLibraryFile(std::unique_ptr<FileNode> file) {
> + GroupEnd *currentGroupEnd;
> + int pos = -1;
> + std::vector<std::unique_ptr<InputElement>> &elements
> + = getInputGraph().inputElements();
> + for (int i = 0, e = elements.size(); i < e; ++i) {
> + if ((currentGroupEnd = dyn_cast<GroupEnd>(elements[i].get()))) {
> + pos = i;
> + break;
> + }
> + }
> + assert(pos >= 0);
> + elements.insert(elements.begin() + pos, std::move(file));
> + elements[pos + 1] = llvm::make_unique<GroupEnd>(
> + currentGroupEnd->getSize() + 1);
> +}
> +
> bool PECOFFLinkingContext::createImplicitFiles(
> std::vector<std::unique_ptr<File>> &) {
> // Create a file for __ImageBase.
> @@ -109,7 +126,7 @@ bool PECOFFLinkingContext::createImplici
> auto exportNode = llvm::make_unique<SimpleFileNode>("<export>");
> exportNode->appendInputFile(
> llvm::make_unique<pecoff::ExportedSymbolRenameFile>(*this, syms));
> - getLibraryGroup()->addFile(std::move(exportNode));
> + addLibraryFile(std::move(exportNode));
>
> // Create a file for the entry point function.
> getEntryNode()->appendInputFile(
>
> Modified: lld/trunk/unittests/DriverTests/DriverTest.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/DriverTest.h?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/unittests/DriverTests/DriverTest.h (original)
> +++ lld/trunk/unittests/DriverTests/DriverTest.h Tue Dec 9 18:33:00 2014
> @@ -37,18 +37,6 @@ protected:
> llvm_unreachable("not handling other types of input files");
> }
>
> - // Convenience method for getting i'th input files name.
> - std::string inputFile(int index1, int index2) {
> - Group *group = dyn_cast<Group>(
> - linkingContext()->getInputGraph().inputElements()[index1].get());
> - if (!group)
> - llvm_unreachable("not handling other types of input files");
> - FileNode *file = dyn_cast<FileNode>(group->elements()[index2].get());
> - if (!file)
> - llvm_unreachable("not handling other types of input files");
> - return *file->getPath(*linkingContext());
> - }
> -
> // For unit tests to call driver with various command lines.
> bool parse(const char *args, ...) {
> // Construct command line options from varargs.
>
> Modified: lld/trunk/unittests/DriverTests/InputGraphTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/InputGraphTest.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/unittests/DriverTests/InputGraphTest.cpp (original)
> +++ lld/trunk/unittests/DriverTests/InputGraphTest.cpp Tue Dec 9 18:33:00 2014
> @@ -77,7 +77,7 @@ protected:
>
> } // end anonymous namespace
>
> -static std::unique_ptr<TestFileNode> createFile1(StringRef name) {
> +static std::unique_ptr<TestFileNode> createFile(StringRef name) {
> std::vector<std::unique_ptr<File>> files;
> files.push_back(std::unique_ptr<SimpleFile>(new SimpleFile(name)));
> std::unique_ptr<TestFileNode> file(new TestFileNode("filenode"));
> @@ -85,109 +85,30 @@ static std::unique_ptr<TestFileNode> cre
> return file;
> }
>
> -static std::unique_ptr<TestFileNode> createFile2(StringRef name1,
> - StringRef name2) {
> - std::vector<std::unique_ptr<File>> files;
> - files.push_back(std::unique_ptr<SimpleFile>(new SimpleFile(name1)));
> - files.push_back(std::unique_ptr<SimpleFile>(new SimpleFile(name2)));
> - std::unique_ptr<TestFileNode> file(new TestFileNode("filenode"));
> - file->addFiles(std::move(files));
> - return file;
> -}
> -
> TEST_F(InputGraphTest, Empty) {
> expectEnd();
> }
>
> TEST_F(InputGraphTest, File) {
> - _graph->addInputElement(createFile1("file1"));
> - EXPECT_EQ("file1", getNext());
> - expectEnd();
> -}
> -
> -TEST_F(InputGraphTest, Files) {
> - _graph->addInputElement(createFile2("file1", "file2"));
> - EXPECT_EQ("file1", getNext());
> - EXPECT_EQ("file2", getNext());
> - expectEnd();
> -}
> -
> -TEST_F(InputGraphTest, Group) {
> - _graph->addInputElement(createFile2("file1", "file2"));
> -
> - std::unique_ptr<Group> group(new Group());
> - group->addFile(createFile2("file3", "file4"));
> - group->addFile(createFile1("file5"));
> - group->addFile(createFile1("file6"));
> - _graph->addInputElement(std::move(group));
> -
> + _graph->addInputElement(createFile("file1"));
> EXPECT_EQ("file1", getNext());
> - EXPECT_EQ("file2", getNext());
> - EXPECT_EQ("file3", getNext());
> - EXPECT_EQ("file4", getNext());
> - EXPECT_EQ("file5", getNext());
> - EXPECT_EQ("file6", getNext());
> - expectEnd();
> -}
> -
> -// Iterate through the group
> -TEST_F(InputGraphTest, GroupIteration) {
> - _graph->addInputElement(createFile2("file1", "file2"));
> -
> - std::unique_ptr<Group> group(new Group());
> - group->addFile(createFile2("file3", "file4"));
> - group->addFile(createFile1("file5"));
> - group->addFile(createFile1("file6"));
> - _graph->addInputElement(std::move(group));
> -
> - EXPECT_EQ("file1", getNext());
> - EXPECT_EQ("file2", getNext());
> -
> - EXPECT_EQ("file3", getNext());
> - EXPECT_EQ("file4", getNext());
> - EXPECT_EQ("file5", getNext());
> - EXPECT_EQ("file6", getNext());
> - _graph->notifyProgress();
> -
> - EXPECT_EQ("file3", getNext());
> - EXPECT_EQ("file4", getNext());
> - _graph->notifyProgress();
> - EXPECT_EQ("file5", getNext());
> - EXPECT_EQ("file6", getNext());
> -
> - EXPECT_EQ("file3", getNext());
> - EXPECT_EQ("file4", getNext());
> - EXPECT_EQ("file5", getNext());
> - EXPECT_EQ("file6", getNext());
> expectEnd();
> }
>
> // Node expansion tests
> TEST_F(InputGraphTest, Normalize) {
> - _graph->addInputElement(createFile2("file1", "file2"));
> + _graph->addInputElement(createFile("file1"));
>
> std::unique_ptr<TestExpandFileNode> expandFile(
> new TestExpandFileNode("node"));
> - expandFile->addElement(createFile1("file3"));
> - expandFile->addElement(createFile1("file4"));
> + expandFile->addElement(createFile("file2"));
> + expandFile->addElement(createFile("file3"));
> _graph->addInputElement(std::move(expandFile));
> -
> - std::unique_ptr<Group> group(new Group());
> - std::unique_ptr<TestExpandFileNode> expandFile2(
> - new TestExpandFileNode("node"));
> - expandFile2->addElement(createFile1("file5"));
> - group->addFile(std::move(expandFile2));
> - _graph->addInputElement(std::move(group));
> -
> - _graph->addInputElement(createFile1("file6"));
> _graph->normalize();
>
> EXPECT_EQ("file1", getNext());
> EXPECT_EQ("file2", getNext());
> EXPECT_EQ("file3", getNext());
> - EXPECT_EQ("file4", getNext());
> - EXPECT_EQ("file5", getNext());
> - EXPECT_EQ("file6", getNext());
> expectEnd();
> }
>
> @@ -195,8 +116,8 @@ TEST_F(InputGraphTest, Observer) {
> std::vector<std::string> files;
> _graph->registerObserver([&](File *file) { files.push_back(file->path()); });
>
> - _graph->addInputElement(createFile1("file1"));
> - _graph->addInputElement(createFile1("file2"));
> + _graph->addInputElement(createFile("file1"));
> + _graph->addInputElement(createFile("file2"));
> EXPECT_EQ("file1", getNext());
> EXPECT_EQ("file2", getNext());
> expectEnd();
>
> Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=223867&r1=223866&r2=223867&view=diff
> ==============================================================================
> --- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
> +++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Dec 9 18:33:00 2014
> @@ -137,11 +137,11 @@ TEST_F(WinLinkParserTest, Libpath) {
> TEST_F(WinLinkParserTest, InputOrder) {
> EXPECT_TRUE(parse("link.exe", "a.lib", "b.obj", "c.obj", "a.lib", "d.obj",
> nullptr));
> - EXPECT_EQ(5, inputFileCount());
> + EXPECT_EQ(6, inputFileCount());
> EXPECT_EQ("b.obj", inputFile(0));
> EXPECT_EQ("c.obj", inputFile(1));
> EXPECT_EQ("d.obj", inputFile(2));
> - EXPECT_EQ("a.lib", inputFile(4, 0));
> + EXPECT_EQ("a.lib", inputFile(4));
> }
>
> //
> @@ -393,36 +393,36 @@ TEST_F(WinLinkParserTest, SectionMultipl
> TEST_F(WinLinkParserTest, DefaultLib) {
> EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
> "/defaultlib:kernel32", "a.obj", nullptr));
> - EXPECT_EQ(3, inputFileCount());
> + EXPECT_EQ(5, inputFileCount());
> EXPECT_EQ("a.obj", inputFile(0));
> - EXPECT_EQ("user32.lib", inputFile(2, 0));
> - EXPECT_EQ("kernel32.lib", inputFile(2, 1));
> + EXPECT_EQ("user32.lib", inputFile(2));
> + EXPECT_EQ("kernel32.lib", inputFile(3));
> }
>
> TEST_F(WinLinkParserTest, DefaultLibDuplicates) {
> EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
> "/defaultlib:user32.lib", "a.obj", nullptr));
> - EXPECT_EQ(3, inputFileCount());
> + EXPECT_EQ(4, inputFileCount());
> EXPECT_EQ("a.obj", inputFile(0));
> - EXPECT_EQ("user32.lib", inputFile(2, 0));
> + EXPECT_EQ("user32.lib", inputFile(2));
> }
>
> TEST_F(WinLinkParserTest, NoDefaultLib) {
> EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
> "/defaultlib:kernel32", "/nodefaultlib:user32.lib", "a.obj",
> nullptr));
> - EXPECT_EQ(3, inputFileCount());
> + EXPECT_EQ(4, inputFileCount());
> EXPECT_EQ("a.obj", inputFile(0));
> - EXPECT_EQ("kernel32.lib", inputFile(2, 0));
> + EXPECT_EQ("kernel32.lib", inputFile(2));
> }
>
> TEST_F(WinLinkParserTest, NoDefaultLibCase) {
> EXPECT_TRUE(parse("link.exe", "/defaultlib:user32",
> "/defaultlib:kernel32", "/nodefaultlib:USER32.LIB", "a.obj",
> nullptr));
> - EXPECT_EQ(3, inputFileCount());
> + EXPECT_EQ(4, inputFileCount());
> EXPECT_EQ("a.obj", inputFile(0));
> - EXPECT_EQ("kernel32.lib", inputFile(2, 0));
> + EXPECT_EQ("kernel32.lib", inputFile(2));
> }
>
> TEST_F(WinLinkParserTest, NoDefaultLibAll) {
> @@ -436,9 +436,9 @@ TEST_F(WinLinkParserTest, DisallowLib) {
> EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
> "/defaultlib:kernel32", "/disallowlib:user32.lib", "a.obj",
> nullptr));
> - EXPECT_EQ(3, inputFileCount());
> + EXPECT_EQ(4, inputFileCount());
> EXPECT_EQ("a.obj", inputFile(0));
> - EXPECT_EQ("kernel32.lib", inputFile(2, 0));
> + EXPECT_EQ("kernel32.lib", inputFile(2));
> }
>
> //
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation
More information about the llvm-commits
mailing list