summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-08-04 02:03:27 +0000
committerRui Ueyama <ruiu@google.com>2016-08-04 02:03:27 +0000
commit104165643ee017aa38b620d96ee2bb808293ab45 (patch)
treef3a65165bbb63601731849d1209a8e4187984ca9
parent70ffe6523f1b94c134fcc8d285ee58eeb574dd9f (diff)
downloadbcm5719-llvm-104165643ee017aa38b620d96ee2bb808293ab45.tar.gz
bcm5719-llvm-104165643ee017aa38b620d96ee2bb808293ab45.zip
Make ScriptParser::read* functions more functional style.
Previously, many read* functions created new command objects and add them directly to the top-level data structure. This is not work for some commands because some commands, such as the assignment, can appear inside and outside of the output section description. This patch is to not append objects to the top-level data structure. Callers are now responsible to do that. llvm-svn: 277686
-rw-r--r--lld/ELF/LinkerScript.cpp106
1 files changed, 53 insertions, 53 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 808d62433e6..194f4b76166 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -477,15 +477,15 @@ private:
void readSections();
SymbolAssignment *readAssignment(StringRef Name);
- void readOutputSectionDescription(StringRef OutSec);
+ OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
std::vector<uint8_t> readOutputSectionFiller();
std::vector<StringRef> readOutputSectionPhdrs();
- std::unique_ptr<InputSectionDescription> readInputSectionDescription();
- void readInputFilePattern(InputSectionDescription *InCmd, bool Keep);
- void readInputSectionRules(InputSectionDescription *InCmd, bool Keep);
+ InputSectionDescription *readInputSectionDescription();
+ std::vector<StringRef> readInputFilePatterns();
+ InputSectionDescription *readInputSectionRules();
unsigned readPhdrType();
- void readProvide(bool Hidden);
- void readAlign(OutputSectionCommand *Cmd);
+ SymbolAssignment *readProvide(bool Hidden);
+ Expr readAlign();
void readSort();
Expr readExpr();
@@ -685,16 +685,18 @@ void ScriptParser::readSections() {
expect("{");
while (!Error && !skip("}")) {
StringRef Tok = next();
+ BaseCommand *Cmd;
if (peek() == "=" || peek() == "+=") {
- readAssignment(Tok);
+ Cmd = readAssignment(Tok);
expect(";");
} else if (Tok == "PROVIDE") {
- readProvide(false);
+ Cmd = readProvide(false);
} else if (Tok == "PROVIDE_HIDDEN") {
- readProvide(true);
+ Cmd = readProvide(true);
} else {
- readOutputSectionDescription(Tok);
+ Cmd = readOutputSectionDescription(Tok);
}
+ Opt.Commands.emplace_back(Cmd);
}
}
@@ -714,80 +716,78 @@ static int precedence(StringRef Op) {
.Default(-1);
}
-void ScriptParser::readInputFilePattern(InputSectionDescription *InCmd,
- bool Keep) {
- while (!Error && !skip(")")) {
- if (Keep)
- Opt.KeptSections.push_back(peek());
- InCmd->SectionPatterns.push_back(next());
- }
+std::vector<StringRef> ScriptParser::readInputFilePatterns() {
+ std::vector<StringRef> V;
+ while (!Error && !skip(")"))
+ V.push_back(next());
+ return V;
}
-void ScriptParser::readInputSectionRules(InputSectionDescription *InCmd,
- bool Keep) {
- InCmd->FilePattern = next();
+InputSectionDescription *ScriptParser::readInputSectionRules() {
+ auto *Cmd = new InputSectionDescription;
+ Cmd->FilePattern = next();
expect("(");
if (skip("EXCLUDE_FILE")) {
expect("(");
while (!Error && !skip(")"))
- InCmd->ExcludedFiles.push_back(next());
+ Cmd->ExcludedFiles.push_back(next());
}
if (skip("SORT") || skip("SORT_BY_NAME")) {
expect("(");
if (skip("SORT_BY_ALIGNMENT")) {
- InCmd->Sort = SortKind::NameAlign;
+ Cmd->Sort = SortKind::NameAlign;
expect("(");
- readInputFilePattern(InCmd, Keep);
+ Cmd->SectionPatterns = readInputFilePatterns();
expect(")");
} else {
- InCmd->Sort = SortKind::Name;
- readInputFilePattern(InCmd, Keep);
+ Cmd->Sort = SortKind::Name;
+ Cmd->SectionPatterns = readInputFilePatterns();
}
expect(")");
- return;
+ return Cmd;
}
if (skip("SORT_BY_ALIGNMENT")) {
expect("(");
if (skip("SORT") || skip("SORT_BY_NAME")) {
- InCmd->Sort = SortKind::AlignName;
+ Cmd->Sort = SortKind::AlignName;
expect("(");
- readInputFilePattern(InCmd, Keep);
+ Cmd->SectionPatterns = readInputFilePatterns();
expect(")");
} else {
- InCmd->Sort = SortKind::Align;
- readInputFilePattern(InCmd, Keep);
+ Cmd->Sort = SortKind::Align;
+ Cmd->SectionPatterns = readInputFilePatterns();
}
expect(")");
- return;
+ return Cmd;
}
- readInputFilePattern(InCmd, Keep);
+ Cmd->SectionPatterns = readInputFilePatterns();
+ return Cmd;
}
-std::unique_ptr<InputSectionDescription>
-ScriptParser::readInputSectionDescription() {
- auto InCmd = llvm::make_unique<InputSectionDescription>();
-
+InputSectionDescription *ScriptParser::readInputSectionDescription() {
// Input section wildcard can be surrounded by KEEP.
// https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
if (skip("KEEP")) {
expect("(");
- readInputSectionRules(InCmd.get(), true);
+ InputSectionDescription *Cmd = readInputSectionRules();
expect(")");
- } else {
- readInputSectionRules(InCmd.get(), false);
+ Opt.KeptSections.insert(Opt.KeptSections.end(),
+ Cmd->SectionPatterns.begin(),
+ Cmd->SectionPatterns.end());
+ return Cmd;
}
-
- return InCmd;
+ return readInputSectionRules();
}
-void ScriptParser::readAlign(OutputSectionCommand *Cmd) {
+Expr ScriptParser::readAlign() {
expect("(");
- Cmd->AlignExpr = readExpr();
+ Expr E = readExpr();
expect(")");
+ return E;
}
void ScriptParser::readSort() {
@@ -796,9 +796,9 @@ void ScriptParser::readSort() {
expect(")");
}
-void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
+OutputSectionCommand *
+ScriptParser::readOutputSectionDescription(StringRef OutSec) {
OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
- Opt.Commands.emplace_back(Cmd);
// Read an address expression.
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
@@ -808,7 +808,7 @@ void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
expect(":");
if (skip("ALIGN"))
- readAlign(Cmd);
+ Cmd->AlignExpr = readAlign();
// Parse constraints.
if (skip("ONLY_IF_RO"))
@@ -819,15 +819,15 @@ void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
while (!Error && !skip("}")) {
if (peek().startswith("*") || peek() == "KEEP") {
- Cmd->Commands.push_back(readInputSectionDescription());
+ Cmd->Commands.emplace_back(readInputSectionDescription());
continue;
}
StringRef Tok = next();
if (Tok == "PROVIDE") {
- readProvide(false);
+ Opt.Commands.emplace_back(readProvide(false));
} else if (Tok == "PROVIDE_HIDDEN") {
- readProvide(true);
+ Opt.Commands.emplace_back(readProvide(true));
} else if (Tok == "SORT") {
readSort();
} else {
@@ -836,6 +836,7 @@ void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
}
Cmd->Phdrs = readOutputSectionPhdrs();
Cmd->Filler = readOutputSectionFiller();
+ return Cmd;
}
std::vector<uint8_t> ScriptParser::readOutputSectionFiller() {
@@ -858,13 +859,14 @@ std::vector<uint8_t> ScriptParser::readOutputSectionFiller() {
return { uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V) };
}
-void ScriptParser::readProvide(bool Hidden) {
+SymbolAssignment *ScriptParser::readProvide(bool Hidden) {
expect("(");
SymbolAssignment *Cmd = readAssignment(next());
Cmd->Provide = true;
Cmd->Hidden = Hidden;
expect(")");
expect(";");
+ return Cmd;
}
static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
@@ -917,9 +919,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
Expr E = readExpr();
if (Op == "+=")
E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
- auto *Cmd = new SymbolAssignment(Name, E);
- Opt.Commands.emplace_back(Cmd);
- return Cmd;
+ return new SymbolAssignment(Name, E);
}
// This is an operator-precedence parser to parse a linker
OpenPOWER on IntegriCloud