Linker script: support VERSION command.

Summary:
VERSION commands define symbol versions. The grammar of the
commnad is as follows

  VERSION { version-script-commands }

where version-script-commands is

  [ name ] { version-definitions }.

Note that we already support version-script-commands because
it is being used for version script command.

This patch is based on George's patch https://reviews.llvm.org/D23609

Reviewers: grimar

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D24089

llvm-svn: 280284
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9403233..b3a1c45 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -653,6 +653,8 @@
   void readPhdrs();
   void readSearchDir();
   void readSections();
+  void readVersion();
+  void readVersionScriptCommand();
 
   SymbolAssignment *readAssignment(StringRef Name);
   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
@@ -676,7 +678,7 @@
 
   // For parsing version script.
   void readExtern(std::vector<SymbolVersion> *Globals);
-  void readVersion(StringRef VerStr);
+  void readVersionDeclaration(StringRef VerStr);
   void readGlobal(StringRef VerStr);
   void readLocal();
 
@@ -698,29 +700,39 @@
     {"PHDRS", &ScriptParser::readPhdrs},
     {"SEARCH_DIR", &ScriptParser::readSearchDir},
     {"SECTIONS", &ScriptParser::readSections},
+    {"VERSION", &ScriptParser::readVersion},
     {";", &ScriptParser::readNothing}};
 
 void ScriptParser::readVersionScript() {
-  StringRef Msg = "anonymous version definition is used in "
-                  "combination with other version definitions";
+  readVersionScriptCommand();
+  if (!atEOF())
+    setError("EOF expected, but got " + next());
+}
+
+void ScriptParser::readVersionScriptCommand() {
   if (skip("{")) {
-    readVersion("");
-    if (!atEOF())
-      setError(Msg);
+    readVersionDeclaration("");
     return;
   }
 
-  while (!atEOF() && !Error) {
+  while (!atEOF() && !Error && peek() != "}") {
     StringRef VerStr = next();
     if (VerStr == "{") {
-      setError(Msg);
+      setError("anonymous version definition is used in "
+               "combination with other version definitions");
       return;
     }
     expect("{");
-    readVersion(VerStr);
+    readVersionDeclaration(VerStr);
   }
 }
 
+void ScriptParser::readVersion() {
+  expect("{");
+  readVersionScriptCommand();
+  expect("}");
+}
+
 void ScriptParser::readLinkerScript() {
   while (!atEOF()) {
     StringRef Tok = next();
@@ -1377,7 +1389,7 @@
   return Ret;
 }
 
-void ScriptParser::readVersion(StringRef VerStr) {
+void ScriptParser::readVersionDeclaration(StringRef VerStr) {
   // Identifiers start at 2 because 0 and 1 are reserved
   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
   size_t VersionId = Config->VersionDefinitions.size() + 2;