For PR950:
Remove all grammar conflicts from assembly parsing.  This change involves:
1. Making the "type" keyword not a primitive type (removes several
   reduce/reduce conflicts)
2. Being more specific about which linkage types are allowed for functions
   and global variables. In particular "appending" can no longer be
   specified for a function. A differentiation was made between the various
   internal and external linkage types.
3. Introduced the "define" keyword which is now required when defining a
   function. This disambiguates several cases where a named function return
   type could get confused with the definition of a new type. Using the
   keyword eliminates all shift/reduce conflicts and the remaining
   reduce/reduce conflicts.

These changes are necessary to implement the function parameter attributes
that will be introduced soon. Adding the function parameter attributes in
the presence of the shift/reduce and reduce/reduce conflicts led to severe
ambiguities that caused the parser to report syntax errors that needed to
be resolved. This patch resolves them.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32770 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l
index 478bfb8..2f681a6 100644
--- a/lib/AsmParser/Lexer.l
+++ b/lib/AsmParser/Lexer.l
@@ -192,6 +192,7 @@
 true            { return TRUETOK;  }
 false           { return FALSETOK; }
 declare         { return DECLARE; }
+define          { return DEFINE; }
 global          { return GLOBAL; }
 constant        { return CONSTANT; }
 internal        { return INTERNAL; }
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index fa87821..8f2df71 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -895,7 +895,7 @@
   llvm::FCmpInst::Predicate         FPredicate;
 }
 
-%type <ModuleVal>     Module FunctionList
+%type <ModuleVal>     Module
 %type <FunctionVal>   Function FunctionProto FunctionHeader BasicBlockList
 %type <BasicBlockVal> BasicBlock InstructionList
 %type <TermInstVal>   BBTerminatorInst
@@ -913,7 +913,7 @@
 %type <BoolVal>       OptVolatile                 // 'volatile' or not
 %type <BoolVal>       OptTailCall                 // TAIL CALL or plain CALL.
 %type <BoolVal>       OptSideEffect               // 'sideeffect' or not.
-%type <Linkage>       OptLinkage
+%type <Linkage>       FunctionLinkage GVInternalLinkage GVExternalLinkage
 %type <Endianness>    BigOrLittle
 
 // ValueRef - Unresolved reference to a definition or BB
@@ -936,7 +936,8 @@
 %type  <TypeVal> Types TypesV UpRTypes UpRTypesV
 %type  <PrimType> SIntType UIntType IntType FPType PrimType   // Classifications
 %token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
-%token <PrimType> FLOAT DOUBLE TYPE LABEL
+%token <PrimType> FLOAT DOUBLE LABEL
+%token TYPE
 
 %token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
 %type  <StrVal> Name OptName OptAssign
@@ -944,7 +945,7 @@
 %type <StrVal> OptSection SectionString
 
 %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
-%token DECLARE GLOBAL CONSTANT SECTION VOLATILE
+%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE
 %token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
 %token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
@@ -1038,14 +1039,33 @@
     CHECK_FOR_ERROR
   };
 
-OptLinkage : INTERNAL    { $$ = GlobalValue::InternalLinkage; } |
-             LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } |
-             WEAK        { $$ = GlobalValue::WeakLinkage; } |
-             APPENDING   { $$ = GlobalValue::AppendingLinkage; } |
-             DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } |
-             DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } |
-             EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
-             /*empty*/   { $$ = GlobalValue::ExternalLinkage; };
+GVInternalLinkage 
+  : INTERNAL    { $$ = GlobalValue::InternalLinkage; } 
+  | WEAK        { $$ = GlobalValue::WeakLinkage; } 
+  | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; }
+  | APPENDING   { $$ = GlobalValue::AppendingLinkage; }
+  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } 
+  ;
+
+GVExternalLinkage
+  : DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; }
+  | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
+  | EXTERNAL    { $$ = GlobalValue::ExternalLinkage; }
+  ;
+
+FnDeclareLinkage
+  : /*empty*/   { /*default*/ }
+  | DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage; } 
+  | EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; }
+  ;
+  
+FunctionLinkage 
+  : INTERNAL    { $$ = GlobalValue::InternalLinkage; }
+  | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; }
+  | WEAK        { $$ = GlobalValue::WeakLinkage; }
+  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } 
+  | /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
+  ; 
 
 OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                  CCC_TOK            { $$ = CallingConv::C; } |
@@ -1128,7 +1148,7 @@
 // Derived types are added later...
 //
 PrimType : BOOL | SBYTE | UBYTE | SHORT  | USHORT | INT   | UINT ;
-PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE   | LABEL;
+PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL ;
 UpRTypes : OPAQUE {
     $$ = new PATypeHolder(OpaqueType::get());
     CHECK_FOR_ERROR
@@ -1634,33 +1654,36 @@
 // Module rule: Capture the result of parsing the whole file into a result
 // variable...
 //
-Module : FunctionList {
-  $$ = ParserResult = $1;
-  CurModule.ModuleDone();
-  CHECK_FOR_ERROR;
-};
+Module 
+  : DefinitionList {
+    $$ = ParserResult = CurModule.CurrentModule;
+    CurModule.ModuleDone();
+    CHECK_FOR_ERROR;
+  }
+  | /*empty*/ {
+    $$ = ParserResult = CurModule.CurrentModule;
+    CurModule.ModuleDone();
+    CHECK_FOR_ERROR;
+  }
+  ;
 
-// FunctionList - A list of functions, preceeded by a constant pool.
-//
-FunctionList : FunctionList Function {
-    $$ = $1;
+DefinitionList
+  : Definition
+  | DefinitionList Definition
+  ;
+
+Definition 
+  : DEFINE { CurFun.isDeclare = false } Function {
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
-  } 
-  | FunctionList FunctionProto {
-    $$ = $1;
+  }
+  | DECLARE { CurFun.isDeclare = true; } FunctionProto {
     CHECK_FOR_ERROR
   }
-  | FunctionList MODULE ASM_TOK AsmBlock {
-    $$ = $1;
+  | MODULE ASM_TOK AsmBlock {
     CHECK_FOR_ERROR
   }  
-  | FunctionList IMPLEMENTATION {
-    $$ = $1;
-    CHECK_FOR_ERROR
-  }
-  | ConstPool {
-    $$ = CurModule.CurrentModule;
+  | IMPLEMENTATION {
     // Emit an error if there are any unresolved types left.
     if (!CurModule.LateResolveTypes.empty()) {
       const ValID &DID = CurModule.LateResolveTypes.begin()->first;
@@ -1671,10 +1694,8 @@
       }
     }
     CHECK_FOR_ERROR
-  };
-
-// ConstPool - Constants with optional names assigned to them.
-ConstPool : ConstPool OptAssign TYPE TypesV {
+  }
+  | OptAssign TYPE TypesV {
     // Eagerly resolve types.  This is not an optimization, this is a
     // requirement that is due to the fact that we could have this:
     //
@@ -1684,65 +1705,50 @@
     // If types are not resolved eagerly, then the two types will not be
     // determined to be the same type!
     //
-    ResolveTypeTo($2, *$4);
+    ResolveTypeTo($1, *$3);
 
-    if (!setTypeName(*$4, $2) && !$2) {
+    if (!setTypeName(*$3, $1) && !$1) {
       CHECK_FOR_ERROR
       // If this is a named type that is not a redefinition, add it to the slot
       // table.
-      CurModule.Types.push_back(*$4);
+      CurModule.Types.push_back(*$3);
     }
 
-    delete $4;
+    delete $3;
     CHECK_FOR_ERROR
   }
-  | ConstPool FunctionProto {       // Function prototypes can be in const pool
-    CHECK_FOR_ERROR
-  }
-  | ConstPool MODULE ASM_TOK AsmBlock {  // Asm blocks can be in the const pool
-    CHECK_FOR_ERROR
-  }
-  | ConstPool OptAssign OptLinkage GlobalType ConstVal {
-    if ($5 == 0) 
+  | OptAssign GlobalType ConstVal { /* "Externally Visible" Linkage */
+    if ($3 == 0) 
       GEN_ERROR("Global value initializer is not a constant!");
-    CurGV = ParseGlobalVariable($2, $3, $4, $5->getType(), $5);
+    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, $2, 
+                                $3->getType(), $3);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
-  | ConstPool OptAssign EXTERNAL GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0);
+  | OptAssign GVInternalLinkage GlobalType ConstVal {
+    if ($4 == 0) 
+      GEN_ERROR("Global value initializer is not a constant!");
+    CurGV = ParseGlobalVariable($1, $2, $3, $4->getType(), $4);
     CHECK_FOR_ERROR
-    delete $5;
+  } GlobalVarAttributes {
+    CurGV = 0;
+  }
+  | OptAssign GVExternalLinkage GlobalType Types {
+    CurGV = ParseGlobalVariable($1, $2, $3, *$4, 0);
+    CHECK_FOR_ERROR
+    delete $4;
   } GlobalVarAttributes {
     CurGV = 0;
     CHECK_FOR_ERROR
   }
-  | ConstPool OptAssign DLLIMPORT GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, *$5, 0);
-    CHECK_FOR_ERROR
-    delete $5;
-  } GlobalVarAttributes {
-    CurGV = 0;
+  | TARGET TargetDefinition { 
     CHECK_FOR_ERROR
   }
-  | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
-    CurGV = 
-      ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
-    CHECK_FOR_ERROR
-    delete $5;
-  } GlobalVarAttributes {
-    CurGV = 0;
+  | DEPLIBS '=' LibrariesDefinition {
     CHECK_FOR_ERROR
   }
-  | ConstPool TARGET TargetDefinition { 
-    CHECK_FOR_ERROR
-  }
-  | ConstPool DEPLIBS '=' LibrariesDefinition {
-    CHECK_FOR_ERROR
-  }
-  | /* empty: end of list */ { 
-  };
+  ;
 
 
 AsmBlock : STRINGCONSTANT {
@@ -1944,7 +1950,7 @@
 
 BEGIN : BEGINTOK | '{';                // Allow BEGIN or '{' to start a function
 
-FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
+FunctionHeader : FunctionLinkage FunctionHeaderH BEGIN {
   $$ = CurFun.CurrentFunction;
 
   // Make sure that we keep track of the linkage type even if there was a
@@ -1959,11 +1965,7 @@
   CHECK_FOR_ERROR
 };
 
-FnDeclareLinkage: /*default*/ |
-                  DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage; } |
-                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; };
-  
-FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+FunctionProto : FnDeclareLinkage FunctionHeaderH {
     $$ = CurFun.CurrentFunction;
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 268d3f5..eb2f3fd 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -921,7 +921,8 @@
     case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
     default: Out << "declare ";
     }
-  else
+  else {
+    Out << "define ";
     switch (F->getLinkage()) {
     case GlobalValue::InternalLinkage:     Out << "internal "; break;
     case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
@@ -935,6 +936,7 @@
       cerr << "GhostLinkage not allowed in AsmWriter!\n";
       abort();
     }
+  }
 
   // Print the calling convention.
   switch (F->getCallingConv()) {