Index: ELF/LinkerScript.h
===================================================================
--- ELF/LinkerScript.h
+++ ELF/LinkerScript.h
@@ -24,8 +24,6 @@
 template <class ELFT> class OutputSectionBase;
 template <class ELFT> class OutputSectionFactory;
 
-typedef std::function<uint64_t(uint64_t)> Expr;
-
 // Parses a linker script. Calling this function updates
 // Config and ScriptConfig.
 void readLinkerScript(MemoryBufferRef MB);
@@ -49,11 +47,11 @@
 };
 
 struct SymbolAssignment : BaseCommand {
-  SymbolAssignment(StringRef Name, Expr E)
-      : BaseCommand(AssignmentKind), Name(Name), Expression(E) {}
+  SymbolAssignment(StringRef Name, std::function<uint64_t()> Expr)
+      : BaseCommand(AssignmentKind), Name(Name), Expr(Expr) {}
   static bool classof(const BaseCommand *C);
   StringRef Name;
-  Expr Expression;
+  std::function<uint64_t()> Expr;
   bool Provide = false;
   // Hidden and Ignore can be true, only if Provide is true
   bool Hidden = false;
@@ -107,6 +105,9 @@
   // List of section patterns specified with KEEP commands. They will
   // be kept even if they are unused and --gc-sections is specified.
   std::vector<StringRef> KeptSections;
+
+  // The current value of the special variable ".".
+  uint64_t Dot = 0;
 };
 
 extern ScriptConfiguration *ScriptConfig;
@@ -136,8 +137,6 @@
   int getSectionIndex(StringRef Name);
   std::vector<size_t> getPhdrIndices(StringRef SectionName);
   void dispatchAssignment(SymbolAssignment *Cmd);
-
-  uintX_t Dot;
 };
 
 // Variable template is a C++14 feature, so we can't template
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -152,12 +152,11 @@
 
 template <class ELFT>
 void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) {
-  uint64_t Val = Cmd->Expression(Dot);
   if (Cmd->Name == ".") {
-    Dot = Val;
+    Opt.Dot = Cmd->Expr();
   } else if (!Cmd->Ignore) {
     auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name));
-    D->Value = Val;
+    D->Value = Cmd->Expr();
   }
 }
 
@@ -176,7 +175,8 @@
   }
 
   // Assign addresses as instructed by linker script SECTIONS sub-commands.
-  Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+  Opt.Dot =
+      Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
   uintX_t ThreadBssOffset = 0;
 
@@ -195,18 +195,18 @@
         continue;
 
       if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
-        uintX_t TVA = Dot + ThreadBssOffset;
+        uintX_t TVA = Opt.Dot + ThreadBssOffset;
         TVA = alignTo(TVA, Sec->getAlignment());
         Sec->setVA(TVA);
-        ThreadBssOffset = TVA - Dot + Sec->getSize();
+        ThreadBssOffset = TVA - Opt.Dot + Sec->getSize();
         continue;
       }
 
       if (Sec->getFlags() & SHF_ALLOC) {
-        Dot = alignTo(Dot, Sec->getAlignment());
-        Sec->setVA(Dot);
-        MinVA = std::min(MinVA, Dot);
-        Dot += Sec->getSize();
+        Opt.Dot = alignTo(Opt.Dot, Sec->getAlignment());
+        Sec->setVA(Opt.Dot);
+        MinVA = std::min(MinVA, (uintX_t)Opt.Dot);
+        Opt.Dot += Sec->getSize();
         continue;
       }
     }
@@ -421,11 +421,13 @@
   unsigned readPhdrType();
   void readProvide(bool Hidden);
 
-  Expr readExpr();
-  Expr readExpr1(Expr Lhs, int MinPrec);
-  Expr readPrimary();
-  Expr readTernary(Expr Cond);
-  Expr combine(StringRef Op, Expr Lhs, Expr Rhs);
+  std::function<uint64_t()> readExpr();
+  std::function<uint64_t()> readExpr1(std::function<uint64_t()> Lhs,
+                                      int MinPrec);
+  std::function<uint64_t()> readPrimary();
+  std::function<uint64_t()> readTernary(std::function<uint64_t()> Cond);
+  std::function<uint64_t()> combine(StringRef Op, std::function<uint64_t()> Lhs,
+                                    std::function<uint64_t()> Rhs);
 
   const static StringMap<Handler> Cmd;
   ScriptConfiguration &Opt = *ScriptConfig;
@@ -710,19 +712,21 @@
 
 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   expect("=");
-  Expr E = readExpr();
-  auto *Cmd = new SymbolAssignment(Name, E);
+  auto *Cmd = new SymbolAssignment(Name, readExpr());
   Opt.Commands.emplace_back(Cmd);
   return Cmd;
 }
 
 // This is an operator-precedence parser to parse a linker
 // script expression.
-Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
+std::function<uint64_t()> ScriptParser::readExpr() {
+  return readExpr1(readPrimary(), 0);
+}
 
 // This is a part of the operator-precedence parser. This function
 // assumes that the remaining token stream starts with an operator.
-Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
+std::function<uint64_t()> ScriptParser::readExpr1(std::function<uint64_t()> Lhs,
+                                                  int MinPrec) {
   while (!atEOF() && !Error) {
     // Read an operator and an expression.
     StringRef Op1 = peek();
@@ -731,7 +735,7 @@
     if (precedence(Op1) < MinPrec)
       break;
     next();
-    Expr Rhs = readPrimary();
+    std::function<uint64_t()> Rhs = readPrimary();
 
     // Evaluate the remaining part of the expression first if the
     // next operator has greater precedence than the previous one.
@@ -756,14 +760,14 @@
   return 0;
 }
 
-Expr ScriptParser::readPrimary() {
+std::function<uint64_t()> ScriptParser::readPrimary() {
   StringRef Tok = next();
 
   if (Tok == ".")
-    return [](uint64_t Dot) { return Dot; };
+    return []() { return ScriptConfig->Dot; };
 
   if (Tok == "(") {
-    Expr E = readExpr();
+    std::function<uint64_t()> E = readExpr();
     expect(")");
     return E;
   }
@@ -772,24 +776,25 @@
   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
   if (Tok == "ALIGN") {
     expect("(");
-    Expr E = readExpr();
+    std::function<uint64_t()> E = readExpr();
     expect(")");
-    return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
+    return [=]() { return alignTo(ScriptConfig->Dot, E()); };
   }
   if (Tok == "CONSTANT") {
     expect("(");
     StringRef Tok = next();
     expect(")");
-    return [=](uint64_t Dot) { return getConstant(Tok); };
+    return [=]() { return getConstant(Tok); };
   }
   if (Tok == "DATA_SEGMENT_ALIGN") {
     expect("(");
-    Expr E = readExpr();
+    std::function<uint64_t()> E = readExpr();
     expect(",");
     readExpr();
     expect(")");
-    return [=](uint64_t Dot) -> uint64_t {
-      uint64_t Val = E(Dot);
+    return [=]() -> uint64_t {
+      uint64_t Val = E();
+      uint64_t Dot = ScriptConfig->Dot;
       return alignTo(Dot, Val) + (Dot & (Val - 1));
     };
   }
@@ -797,55 +802,58 @@
     expect("(");
     expect(".");
     expect(")");
-    return [](uint64_t Dot) { return Dot; };
+    return []() { return ScriptConfig->Dot; };
   }
 
   // Parse a number literal
   uint64_t V = 0;
   if (Tok.getAsInteger(0, V))
     setError("malformed number: " + Tok);
-  return [=](uint64_t Dot) { return V; };
+  return [=]() { return V; };
 }
 
-Expr ScriptParser::readTernary(Expr Cond) {
+std::function<uint64_t()>
+ScriptParser::readTernary(std::function<uint64_t()> Cond) {
   next();
-  Expr L = readExpr();
+  std::function<uint64_t()> L = readExpr();
   expect(":");
-  Expr R = readExpr();
-  return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
+  std::function<uint64_t()> R = readExpr();
+  return [=]() { return Cond() ? L() : R(); };
 }
 
-Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
+std::function<uint64_t()> ScriptParser::combine(StringRef Op,
+                                                std::function<uint64_t()> L,
+                                                std::function<uint64_t()> R) {
   if (Op == "*")
-    return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
+    return [=]() { return L() * R(); };
   if (Op == "/") {
-    return [=](uint64_t Dot) -> uint64_t {
-      uint64_t RHS = R(Dot);
+    return [=]() -> uint64_t {
+      uint64_t RHS = R();
       if (RHS == 0) {
         error("division by zero");
         return 0;
       }
-      return L(Dot) / RHS;
+      return L() / RHS;
     };
   }
   if (Op == "+")
-    return [=](uint64_t Dot) { return L(Dot) + R(Dot); };
+    return [=]() { return L() + R(); };
   if (Op == "-")
-    return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
+    return [=]() { return L() - R(); };
   if (Op == "<")
-    return [=](uint64_t Dot) { return L(Dot) < R(Dot); };
+    return [=]() { return L() < R(); };
   if (Op == ">")
-    return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
+    return [=]() { return L() > R(); };
   if (Op == ">=")
-    return [=](uint64_t Dot) { return L(Dot) >= R(Dot); };
+    return [=]() { return L() >= R(); };
   if (Op == "<=")
-    return [=](uint64_t Dot) { return L(Dot) <= R(Dot); };
+    return [=]() { return L() <= R(); };
   if (Op == "==")
-    return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
+    return [=]() { return L() == R(); };
   if (Op == "!=")
-    return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
+    return [=]() { return L() != R(); };
   if (Op == "&")
-    return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
+    return [=]() { return L() & R(); };
   llvm_unreachable("invalid operator");
 }