Extend the AsmWriter to print unnamed numbered types as "%0 = type ..."
and unnamed numbered global variables as "@0 = global ...". Extend the
AsmParser to recognize these forms.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78859 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index b5699ff..ab686ce 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -117,8 +117,10 @@
     case lltok::kw_target:  if (ParseTargetDefinition()) return true; break;
     case lltok::kw_deplibs: if (ParseDepLibs()) return true; break;
     case lltok::kw_type:    if (ParseUnnamedType()) return true; break;
+    case lltok::LocalVarID: if (ParseUnnamedType()) return true; break;
     case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0
     case lltok::LocalVar:   if (ParseNamedType()) return true; break;
+    case lltok::GlobalID:   if (ParseUnnamedGlobal()) return true; break;
     case lltok::GlobalVar:  if (ParseNamedGlobal()) return true; break;
     case lltok::Metadata:   if (ParseStandaloneMetadata()) return true; break;
     case lltok::NamedMD:    if (ParseNamedMetadata()) return true; break;
@@ -236,9 +238,23 @@
   return ParseToken(lltok::rsquare, "expected ']' at end of list");
 }
 
-/// toplevelentity
+/// ParseUnnamedType:
 ///   ::= 'type' type
+///   ::= LocalVarID '=' 'type' type
 bool LLParser::ParseUnnamedType() {
+  unsigned TypeID = NumberedTypes.size();
+
+  // Handle the LocalVarID form.
+  if (Lex.getKind() == lltok::LocalVarID) {
+    if (Lex.getUIntVal() != TypeID)
+      return Error(Lex.getLoc(), "type expected to be numbered '%" +
+                   utostr(TypeID) + "'");
+    Lex.Lex(); // eat LocalVarID;
+
+    if (ParseToken(lltok::equal, "expected '=' after name"))
+      return true;
+  }
+
   assert(Lex.getKind() == lltok::kw_type);
   LocTy TypeLoc = Lex.getLoc();
   Lex.Lex(); // eat kw_type
@@ -246,8 +262,6 @@
   PATypeHolder Ty(Type::VoidTy);
   if (ParseType(Ty)) return true;
  
-  unsigned TypeID = NumberedTypes.size();
-  
   // See if this type was previously referenced.
   std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
     FI = ForwardRefTypeIDs.find(TypeID);
@@ -348,6 +362,38 @@
   return false;
 }
 
+/// ParseUnnamedGlobal:
+///   OptionalVisibility ALIAS ...
+///   OptionalLinkage OptionalVisibility ...   -> global variable
+///   GlobalID '=' OptionalVisibility ALIAS ...
+///   GlobalID '=' OptionalLinkage OptionalVisibility ...   -> global variable
+bool LLParser::ParseUnnamedGlobal() {
+  unsigned VarID = NumberedVals.size();
+  std::string Name;
+  LocTy NameLoc = Lex.getLoc();
+
+  // Handle the GlobalID form.
+  if (Lex.getKind() == lltok::GlobalID) {
+    if (Lex.getUIntVal() != VarID)
+      return Error(Lex.getLoc(), "variable expected to be numbered '%" +
+                   utostr(VarID) + "'");
+    Lex.Lex(); // eat GlobalID;
+
+    if (ParseToken(lltok::equal, "expected '=' after name"))
+      return true;
+  }
+
+  bool HasLinkage;
+  unsigned Linkage, Visibility;
+  if (ParseOptionalLinkage(Linkage, HasLinkage) ||
+      ParseOptionalVisibility(Visibility))
+    return true;
+  
+  if (HasLinkage || Lex.getKind() != lltok::kw_alias)
+    return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
+  return ParseAlias(Name, NameLoc, Visibility);
+}
+
 /// ParseNamedGlobal:
 ///   GlobalVar '=' OptionalVisibility ALIAS ...
 ///   GlobalVar '=' OptionalLinkage OptionalVisibility ...   -> global variable
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 40848cf..4bdbbfe 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -143,6 +143,7 @@
     bool ParseDefine();
 
     bool ParseGlobalType(bool &IsConstant);
+    bool ParseUnnamedGlobal();
     bool ParseNamedGlobal();
     bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
                      bool HasLinkage, unsigned Visibility);
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 602047e..c2a121a 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -1442,10 +1442,8 @@
 }
 
 void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
-  if (GV->hasName()) {
-    PrintLLVMName(Out, GV);
-    Out << " = ";
-  }
+  WriteAsOperandInternal(Out, GV, TypePrinter, &Machine);
+  Out << " = ";
 
   if (!GV->hasInitializer() && GV->hasExternalLinkage())
     Out << "external ";
@@ -1518,7 +1516,7 @@
 void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
   // Emit all numbered types.
   for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) {
-    Out << "\ttype ";
+    Out << '%' << i << " = type ";
     
     // Make sure we print out at least one level of the type structure, so
     // that we do not get %2 = type %2
@@ -1530,7 +1528,6 @@
   // Print the named types.
   for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
        TI != TE; ++TI) {
-    Out << '\t';
     PrintLLVMName(Out, TI->first, LocalPrefix);
     Out << " = type ";
 
@@ -1737,6 +1734,7 @@
 void AssemblyWriter::printInstruction(const Instruction &I) {
   if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);
 
+  // Print out indentation for an instruction.
   Out << '\t';
 
   // Print out name if it exists...
diff --git a/test/Assembler/unnamed.ll b/test/Assembler/unnamed.ll
new file mode 100644
index 0000000..31f1b58
--- /dev/null
+++ b/test/Assembler/unnamed.ll
@@ -0,0 +1,42 @@
+; RUN: llvm-as < %s | llvm-dis
+
+%0 = type { %1, %2 }                              ; type %0
+%1 = type { i32 }                                 ; type %1
+%2 = type { float, double }                       ; type %2
+
+@0 = global i32 0
+@1 = global float 3.0
+@2 = global i8* null
+
+define float @foo(%0* %p) nounwind {
+  %t = load %0* %p                                ; <%0> [#uses=2]
+  %s = extractvalue %0 %t, 1, 0                   ; <float> [#uses=1]
+  %r = insertvalue %0 %t, double 2.000000e+00, 1, 1; <%0> [#uses=1]
+  store %0 %r, %0* %p
+  ret float %s
+}
+
+define float @bar(%0* %p) nounwind {
+  store %0 { %1 { i32 4 }, %2 { float 4.000000e+00, double 2.000000e+01 } }, %0* %p
+  ret float 7.000000e+00
+}
+
+define float @car(%0* %p) nounwind {
+  store %0 { %1 undef, %2 { float undef, double 2.000000e+01 } }, %0* %p
+  ret float undef
+}
+
+define float @dar(%0* %p) nounwind {
+  store %0 { %1 zeroinitializer, %2 { float 0.000000e+00, double 2.000000e+01 } }, %0* %p
+  ret float 0.000000e+00
+}
+
+define i32* @qqq() {
+  ret i32* @0
+}
+define float* @rrr() {
+  ret float* @1
+}
+define i8** @sss() {
+  ret i8** @2
+}