Extend the AsmWriter to print unnamed numbered types as "%0 = type ..."
authorDan Gohman <gohman@apple.com>
Wed, 12 Aug 2009 23:32:33 +0000 (23:32 +0000)
committerDan Gohman <gohman@apple.com>
Wed, 12 Aug 2009 23:32:33 +0000 (23:32 +0000)
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

lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h
lib/VMCore/AsmWriter.cpp
test/Assembler/unnamed.ll [new file with mode: 0644]

index b5699ff361a67e7a7924ec999636e77f31581e37..ab686ced9b07952abafdb5acc49e128ddaea3445 100644 (file)
@@ -117,8 +117,10 @@ bool LLParser::ParseTopLevelEntities() {
     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 @@ bool LLParser::ParseDepLibs() {
   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 @@ bool LLParser::ParseUnnamedType() {
   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 @@ bool LLParser::ParseGlobalType(bool &IsConstant) {
   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
index 40848cfe77c5118c036cac1ef83d73b44e2b003d..4bdbbfeab2193ec8692a0ff139316550d43b0f57 100644 (file)
@@ -143,6 +143,7 @@ namespace llvm {
     bool ParseDefine();
 
     bool ParseGlobalType(bool &IsConstant);
+    bool ParseUnnamedGlobal();
     bool ParseNamedGlobal();
     bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
                      bool HasLinkage, unsigned Visibility);
index 602047e106ad1cbb5710670f11b47147bf72df7b..c2a121a2b69e68552e77e0289ff49edc78b9928d 100644 (file)
@@ -1442,10 +1442,8 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
 }
 
 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::printAlias(const GlobalAlias *GA) {
 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 @@ void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
   // 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::printInfoComment(const Value &V) {
 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 (file)
index 0000000..31f1b58
--- /dev/null
@@ -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
+}