Expand nested input elements.

Previously only the toplevel elements were expanded by expandElements().
Now we recursively call getReplacements() to expand input elements even
if they are in, say, in a group.

llvm-svn: 208144
This commit is contained in:
Rui Ueyama 2014-05-06 23:52:19 +00:00
parent dff3ef80bb
commit 3608609339
4 changed files with 41 additions and 25 deletions

View File

@ -70,8 +70,8 @@ public:
/// \brief Adds a node into the InputGraph /// \brief Adds a node into the InputGraph
void addInputElement(std::unique_ptr<InputElement>); void addInputElement(std::unique_ptr<InputElement>);
/// Normalize the InputGraph. It visits all nodes in the tree to replace a /// Normalize the InputGraph. It calls expand() on each node and then replace
/// node with its children if it's shouldExpand() returns true. /// it with getReplacements() results.
void normalize(); void normalize();
range<InputElementIterT> inputElements() { range<InputElementIterT> inputElements() {
@ -133,11 +133,11 @@ public:
virtual void resetNextIndex() = 0; virtual void resetNextIndex() = 0;
/// Returns true if we want to replace this node with children. /// Returns true if we want to replace this node with children.
virtual bool shouldExpand() const { return false; } virtual void expand() {}
/// \brief Get the elements that we want to expand with. /// Get the elements that we want to expand with.
virtual range<InputGraph::InputElementIterT> expandElements() { virtual bool getReplacements(InputGraph::InputElementVectorT &) {
llvm_unreachable("no element to expand"); return false;
} }
protected: protected:
@ -194,6 +194,18 @@ public:
ErrorOr<File &> getNextFile() override; 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);
}
protected: protected:
InputGraph::InputElementVectorT _elements; InputGraph::InputElementVectorT _elements;
uint32_t _currentElementIndex; uint32_t _currentElementIndex;

View File

@ -127,18 +127,17 @@ public:
error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) override; error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) override;
bool shouldExpand() const override { return true; } bool getReplacements(InputGraph::InputElementVectorT &result) override {
for (std::unique_ptr<InputElement> &elt : _expandElements)
result.push_back(std::move(elt));
return true;
}
/// Unused functions for ELFGNULdScript Nodes. /// Unused functions for ELFGNULdScript Nodes.
ErrorOr<File &> getNextFile() override { ErrorOr<File &> getNextFile() override {
return make_error_code(InputGraphError::no_more_files); return make_error_code(InputGraphError::no_more_files);
} }
/// Return the elements that we would want to expand with.
range<InputGraph::InputElementIterT> expandElements() override {
return make_range(_expandElements.begin(), _expandElements.end());
}
// Linker Script will be expanded and replaced with other elements // Linker Script will be expanded and replaced with other elements
// by InputGraph::normalize(), so at link time it does not exist in // by InputGraph::normalize(), so at link time it does not exist in
// the tree. No need to handle this message. // the tree. No need to handle this message.

View File

@ -74,15 +74,13 @@ ErrorOr<InputElement *> InputGraph::getNextInputElement() {
} }
void InputGraph::normalize() { void InputGraph::normalize() {
for (std::unique_ptr<InputElement> &elt : _inputArgs)
elt->expand();
std::vector<std::unique_ptr<InputElement>> vec; std::vector<std::unique_ptr<InputElement>> vec;
for (std::unique_ptr<InputElement> &ie : _inputArgs) { for (std::unique_ptr<InputElement> &elt : _inputArgs) {
if (!ie->shouldExpand()) { if (elt->getReplacements(vec))
vec.push_back(std::move(ie));
continue; continue;
} vec.push_back(std::move(elt));
range<InputElementIterT> expanded = ie->expandElements();
vec.insert(vec.end(), std::make_move_iterator(expanded.begin()),
std::make_move_iterator(expanded.end()));
} }
_inputArgs = std::move(vec); _inputArgs = std::move(vec);
} }

View File

@ -38,12 +38,11 @@ class TestExpandFileNode : public SimpleFileNode {
public: public:
TestExpandFileNode(StringRef path) : SimpleFileNode(path) {} TestExpandFileNode(StringRef path) : SimpleFileNode(path) {}
/// Returns true as we want to expand this file
bool shouldExpand() const override { return true; }
/// Returns the elements replacing this node /// Returns the elements replacing this node
range<InputGraph::InputElementIterT> expandElements() override { bool getReplacements(InputGraph::InputElementVectorT &result) override {
return make_range(_expandElements.begin(), _expandElements.end()); for (std::unique_ptr<InputElement> &elt : _expandElements)
result.push_back(std::move(elt));
return true;
} }
void addElement(std::unique_ptr<InputElement> element) { void addElement(std::unique_ptr<InputElement> element) {
@ -173,7 +172,15 @@ TEST_F(InputGraphTest, Normalize) {
expandFile->addElement(createFile1("file3")); expandFile->addElement(createFile1("file3"));
expandFile->addElement(createFile1("file4")); expandFile->addElement(createFile1("file4"));
_graph->addInputElement(std::move(expandFile)); _graph->addInputElement(std::move(expandFile));
_graph->addInputElement(createFile2("file5", "file6"));
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(); _graph->normalize();
EXPECT_EQ("file1", getNext()); EXPECT_EQ("file1", getNext());