Implement part of review feedback for address spaces.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44933 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/docs/LangRef.html b/docs/LangRef.html
index fd40c92..df6baa7 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -671,7 +671,8 @@
 <p>A global variable may be declared to reside in a target-specifc numbered 
 address space. For targets that support them, address spaces may affect how
 optimizations are performed and/or what target instructions are used to access 
-the variable. The default address space is zero.</p>
+the variable. The default address space is zero. The address space qualifier 
+must precede any other attributes.</p>
 
 <p>LLVM allows an explicit section to be specified for globals.  If the target
 supports it, it will emit globals to the section specified.</p>
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 8d95c87..3b026ef 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -194,6 +194,7 @@
     FUNC_CODE_INST_FREE        = 18, // FREE:       [opty, op]
     FUNC_CODE_INST_ALLOCA      = 19, // ALLOCA:     [instty, op, align]
     FUNC_CODE_INST_LOAD        = 20, // LOAD:       [opty, op, align, vol]
+    // FIXME: Remove STORE in favor of STORE2 in LLVM 3.0
     FUNC_CODE_INST_STORE       = 21, // STORE:      [valty,val,ptr, align, vol]
     FUNC_CODE_INST_CALL        = 22, // CALL:       [attr, fnty, fnid, args...]
     FUNC_CODE_INST_VAARG       = 23, // VAARG:      [valistty, valist, instty]
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index cd3a7ed..c1f52a2 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -1050,7 +1050,7 @@
 %type <StrVal> GlobalName OptGlobalAssign GlobalAssign
 %type <StrVal> OptSection SectionString OptGC
 
-%type <UIntVal> OptAlign OptCAlign
+%type <UIntVal> OptAlign OptCAlign OptAddrSpace
 
 %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
@@ -1137,6 +1137,9 @@
 LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
 OptLocalName : LocalName | /*empty*/ { $$ = 0; };
 
+OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; }
+             | /*empty*/                    { $$=0; };
+
 /// OptLocalAssign - Value producing statements have an optional assignment
 /// component.
 OptLocalAssign : LocalName '=' {
@@ -1316,17 +1319,10 @@
     $$ = new PATypeHolder($1);
     CHECK_FOR_ERROR
   }
-  | Types '*' {                             // Pointer type?
+  | Types OptAddrSpace '*' {                             // Pointer type?
     if (*$1 == Type::LabelTy)
       GEN_ERROR("Cannot form a pointer to a basic block");
-    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1)));
-    delete $1;
-    CHECK_FOR_ERROR
-  }
-  | Types ADDRSPACE '(' EUINT64VAL ')' '*' {             // Pointer type?
-    if (*$1 == Type::LabelTy)
-      GEN_ERROR("Cannot form a pointer to a basic block");
-    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $4)));
+    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2)));
     delete $1;
     CHECK_FOR_ERROR
   }
@@ -2073,41 +2069,31 @@
     }
     CHECK_FOR_ERROR
   }
-  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal { 
+  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal 
+    OptAddrSpace { 
     /* "Externally Visible" Linkage */
     if ($5 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
     CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
-                                $2, $4, $5->getType(), $5, $3);
-    CHECK_FOR_ERROR
-  } GlobalVarAttributes {
-    CurGV = 0;
-  }
-  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal
-    ADDRSPACE '(' EUINT64VAL ')' { 
-    /* "Externally Visible" Linkage with address space qualifier */
-    if ($5 == 0) 
-      GEN_ERROR("Global value initializer is not a constant");
-    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
-                                $2, $4, $5->getType(), $5, $3, $8);
+                                $2, $4, $5->getType(), $5, $3, $6);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType
-    ConstVal {
+    ConstVal OptAddrSpace {
     if ($6 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
-    CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType
-    Types {
+    Types OptAddrSpace {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
-    CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7);
     CHECK_FOR_ERROR
     delete $6;
   } GlobalVarAttributes {
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 3abac06..abe1933 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -141,6 +141,7 @@
   Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                             Log2_32_Ceil(VE.getTypes().size()+1)));
+  Abbv->Add(BitCodeAbbrevOp(0));  // Addrspace = 0
   unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
   
   // Abbrev for TYPE_CODE_FUNCTION.
@@ -198,16 +199,14 @@
       break;
     case Type::PointerTyID: {
       const PointerType *PTy = cast<PointerType>(T);
-      // POINTER: [pointee type] or [pointee type, address space]
+      // POINTER: [pointee type, address space]
       Code = bitc::TYPE_CODE_POINTER;
       TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
-      if (unsigned AddressSpace = PTy->getAddressSpace())
-        TypeVals.push_back(AddressSpace);
-      else
-        AbbrevToUse = PtrAbbrev;
+      unsigned AddressSpace = PTy->getAddressSpace();
+      TypeVals.push_back(AddressSpace);
+      if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
       break;
     }
-
     case Type::FunctionTyID: {
       const FunctionType *FT = cast<FunctionType>(T);
       // FUNCTION: [isvararg, attrid, retty, paramty x N]
diff --git a/test/Assembler/2007-12-11-AddressSpaces.ll b/test/Assembler/2007-12-11-AddressSpaces.ll
index 91f6d93..e3cd262 100644
--- a/test/Assembler/2007-12-11-AddressSpaces.ll
+++ b/test/Assembler/2007-12-11-AddressSpaces.ll
@@ -5,9 +5,9 @@
 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(22)} | count 5
 
 	%struct.mystruct = type { i32, i32 addrspace(33)*, i32, i32 addrspace(33)* }
-@input = global %struct.mystruct zeroinitializer addrspace(42) 		; <%struct.mystruct addrspace(42)*> [#uses=1]
+@input = weak global %struct.mystruct zeroinitializer addrspace(42) 		; <%struct.mystruct addrspace(42)*> [#uses=1]
 @output = global %struct.mystruct zeroinitializer addrspace(66) 		; <%struct.mystruct addrspace(66)*> [#uses=1]
-@y = global i32 addrspace(11)* addrspace(22)* null addrspace(33) 		; <i32 addrspace(11)* addrspace(22)* addrspace(33)*> [#uses=1]
+@y = external global i32 addrspace(11)* addrspace(22)* addrspace(33) 		; <i32 addrspace(11)* addrspace(22)* addrspace(33)*> [#uses=1]
 
 define void @foo() {
 entry: