[lld] r277686 - Make ScriptParser::read* functions more functional style.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 3 19:03:27 PDT 2016


Author: ruiu
Date: Wed Aug  3 21:03:27 2016
New Revision: 277686

URL: http://llvm.org/viewvc/llvm-project?rev=277686&view=rev
Log:
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.

Modified:
    lld/trunk/ELF/LinkerScript.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=277686&r1=277685&r2=277686&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Aug  3 21:03:27 2016
@@ -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::readOutputSectionDesc
   expect(":");
 
   if (skip("ALIGN"))
-    readAlign(Cmd);
+    Cmd->AlignExpr = readAlign();
 
   // Parse constraints.
   if (skip("ONLY_IF_RO"))
@@ -819,15 +819,15 @@ void ScriptParser::readOutputSectionDesc
 
   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::readOutputSectionDesc
   }
   Cmd->Phdrs = readOutputSectionPhdrs();
   Cmd->Filler = readOutputSectionFiller();
+  return Cmd;
 }
 
 std::vector<uint8_t> ScriptParser::readOutputSectionFiller() {
@@ -858,13 +859,14 @@ std::vector<uint8_t> ScriptParser::readO
   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::readAssi
   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




More information about the llvm-commits mailing list