mcstreamerize .file and .file. This also fixes an issue where the
authorChris Lattner <sabre@nondot.org>
Mon, 25 Jan 2010 18:58:59 +0000 (18:58 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 25 Jan 2010 18:58:59 +0000 (18:58 +0000)
normal form of .file would fail if the filename had a weird character
in it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94437 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCMachOStreamer.cpp
lib/MC/MCNullStreamer.cpp
lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp

index 377096c4d38369dc14d21a14919db90fdc5cbba8..8959c755c1e7a5be0fbbef20a2765c62c8a5c920 100644 (file)
@@ -265,9 +265,6 @@ namespace llvm {
     ///
     void EmitInt64(uint64_t Value) const;
 
-    /// EmitFile - Emit a .file directive.
-    void EmitFile(unsigned Number, StringRef Name) const;
-
     //===------------------------------------------------------------------===//
 
     /// EmitAlignment - Emit an alignment directive to the specified power of
index 09df6fa8061a899f3fccde4bb174cc1c25b1d589..cb8196e29826de68212ce45923b67b1b387fcd07 100644 (file)
@@ -233,6 +233,15 @@ namespace llvm {
                                    unsigned char Value = 0) = 0;
     
     /// @}
+    
+    /// EmitFileDirective - Switch to a new logical file.  This is used to
+    /// implement the '.file "foo.c"' assembler directive.
+    virtual void EmitFileDirective(StringRef Filename) = 0;
+    
+    /// EmitDwarfFileDirective - Associate a filename with a specified logical
+    /// file number.  This implements the DWARF2 '.file 4 "foo.c"' assembler
+    /// directive.
+    virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0;
 
     /// EmitInstruction - Emit the given @param Instruction into the current
     /// section.
index 8935445ade5571310915395c369f8d3cc853bbeb..fe2ef7adebb45fa5bd40a03f3be9b3d8376104a6 100644 (file)
@@ -115,11 +115,11 @@ bool AsmPrinter::doInitialization(Module &M) {
   // Allow the target to emit any magic that it wants at the start of the file.
   EmitStartOfAsmFile(M);
 
+  // Very minimal debug info. It is ignored if we emit actual debug info. If we
+  // don't, this at least helps the user find where a global came from.
   if (MAI->hasSingleParameterDotFile()) {
-    // Very minimal debug info. It is ignored if we emit actual
-    // debug info. If we don't, this at least helps the user find where
-    // a function came from.
-    O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
+    // .file "foo.c"
+    OutStreamer.EmitFileDirective(M.getModuleIdentifier());
   }
 
   GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
@@ -236,6 +236,9 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
       // .globl _foo
       OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+      // FIXME: linkonce should be a section attribute, handled by COFF Section
+      // assignment.
+      // http://sourceware.org/binutils/docs-2.20/as/Linkonce.html#Linkonce
       // .linkonce same_size
       O << LinkOnce;
     } else {
@@ -679,48 +682,6 @@ void AsmPrinter::EmitInt64(uint64_t Value) const {
   OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
 }
 
-
-/// toOctal - Convert the low order bits of X into an octal digit.
-///
-static inline char toOctal(int X) {
-  return (X&7)+'0';
-}
-
-/// printStringChar - Print a char, escaped if necessary.
-///
-static void printStringChar(formatted_raw_ostream &O, unsigned char C) {
-  if (C == '"') {
-    O << "\\\"";
-  } else if (C == '\\') {
-    O << "\\\\";
-  } else if (isprint((unsigned char)C)) {
-    O << C;
-  } else {
-    switch(C) {
-    case '\b': O << "\\b"; break;
-    case '\f': O << "\\f"; break;
-    case '\n': O << "\\n"; break;
-    case '\r': O << "\\r"; break;
-    case '\t': O << "\\t"; break;
-    default:
-      O << '\\';
-      O << toOctal(C >> 6);
-      O << toOctal(C >> 3);
-      O << toOctal(C >> 0);
-      break;
-    }
-  }
-}
-
-/// EmitFile - Emit a .file directive.
-void AsmPrinter::EmitFile(unsigned Number, StringRef Name) const {
-  O << "\t.file\t" << Number << " \"";
-  for (unsigned i = 0, N = Name.size(); i < N; ++i)
-    printStringChar(O, Name[i]);
-  O << '\"';
-}
-
-
 //===----------------------------------------------------------------------===//
 
 // EmitAlignment - Emit an alignment directive to the specified power of
index 6a93cc6578db223b4b1e9f4f17ddcd0fb6e17d0e..532a68f5eaafb92bddb6aeaef50d933a8bf1cd77 100644 (file)
@@ -1779,8 +1779,7 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
         FullPath.appendComponent(getSourceFileName(Id.second));
       assert(AppendOk && "Could not append filename to directory!");
       AppendOk = false;
-      Asm->EmitFile(i, FullPath.str());
-      Asm->O << '\n';
+      Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
     }
   }
 
index 9d9f46a37861d98460058ae8a4f169998a092943..f9a3128f90af4bc7c30122c2329f8b7921933bfc 100644 (file)
@@ -120,9 +120,12 @@ public:
 
   virtual void EmitValueToOffset(const MCExpr *Offset,
                                  unsigned char Value = 0);
-  
-  virtual void EmitInstruction(const MCInst &Inst);
 
+  virtual void EmitFileDirective(StringRef Filename);
+  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename);
+
+  virtual void EmitInstruction(const MCInst &Inst);
+  
   virtual void Finish();
   
   /// @}
@@ -320,6 +323,40 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
 
 static inline char toOctal(int X) { return (X&7)+'0'; }
 
+static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
+  OS << '"';
+  
+  for (unsigned i = 0, e = Data.size(); i != e; ++i) {
+    unsigned char C = Data[i];
+    if (C == '"' || C == '\\') {
+      OS << '\\' << (char)C;
+      continue;
+    }
+    
+    if (isprint((unsigned char)C)) {
+      OS << (char)C;
+      continue;
+    }
+    
+    switch (C) {
+      case '\b': OS << "\\b"; break;
+      case '\f': OS << "\\f"; break;
+      case '\n': OS << "\\n"; break;
+      case '\r': OS << "\\r"; break;
+      case '\t': OS << "\\t"; break;
+      default:
+        OS << '\\';
+        OS << toOctal(C >> 6);
+        OS << toOctal(C >> 3);
+        OS << toOctal(C >> 0);
+        break;
+    }
+  }
+  
+  OS << '"';
+}
+
+
 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
   assert(CurSection && "Cannot emit contents before setting section!");
   if (Data.empty()) return;
@@ -340,34 +377,8 @@ void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
     OS << MAI.getAsciiDirective();
   }
 
-  OS << " \"";
-  for (unsigned i = 0, e = Data.size(); i != e; ++i) {
-    unsigned char C = Data[i];
-    if (C == '"' || C == '\\') {
-      OS << '\\' << (char)C;
-      continue;
-    }
-    
-    if (isprint((unsigned char)C)) {
-      OS << (char)C;
-      continue;
-    }
-    
-    switch (C) {
-    case '\b': OS << "\\b"; break;
-    case '\f': OS << "\\f"; break;
-    case '\n': OS << "\\n"; break;
-    case '\r': OS << "\\r"; break;
-    case '\t': OS << "\\t"; break;
-    default:
-      OS << '\\';
-      OS << toOctal(C >> 6);
-      OS << toOctal(C >> 3);
-      OS << toOctal(C >> 0);
-      break;
-    }
-  }
-  OS << '"';
+  OS << ' ';
+  PrintQuotedString(Data, OS);
   EmitEOL();
 }
 
@@ -492,6 +503,21 @@ void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
   EmitEOL();
 }
 
+
+void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
+  assert(MAI.hasSingleParameterDotFile());
+  OS << "\t.file\t";
+  PrintQuotedString(Filename, OS);
+  EmitEOL();
+}
+
+void MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){
+  OS << "\t.file\t" << FileNo << ' ';
+  PrintQuotedString(Filename, OS);
+  EmitEOL();
+}
+
+
 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
   assert(CurSection && "Cannot emit contents before setting section!");
 
index acfda32cdaa9e12da50b1d06d5e4d5d7c3785376..545f8d094525dcb26fed78e8aa28b56318d8d17e 100644 (file)
@@ -139,6 +139,14 @@ public:
                                     unsigned MaxBytesToEmit = 0);
   virtual void EmitValueToOffset(const MCExpr *Offset,
                                  unsigned char Value = 0);
+  
+  virtual void EmitFileDirective(StringRef Filename) {
+    errs() << "FIXME: MCMachoStreamer:EmitFileDirective not implemented\n";
+  }
+  virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
+    errs() << "FIXME: MCMachoStreamer:EmitDwarfFileDirective not implemented\n";
+  }
+  
   virtual void EmitInstruction(const MCInst &Inst);
   virtual void Finish();
 
index 1d2b778ffcbcfcfae170b2f5715266bc79488602..151cf2832264c38881534c1a2644b7211a115bf3 100644 (file)
@@ -58,6 +58,8 @@ namespace {
     virtual void EmitValueToOffset(const MCExpr *Offset,
                                    unsigned char Value = 0) {}
     
+    virtual void EmitFileDirective(StringRef Filename) {}
+    virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) {}
     virtual void EmitInstruction(const MCInst &Inst) {}
 
     virtual void Finish() {}
index 85ff09a3be546bc9f267a5bbf9397b05a8bde07a..b3654971a520eb17b9dbd9bdf88ff80e6b88efb9 100644 (file)
@@ -96,6 +96,9 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
       O << MAI->getWeakDefDirective() << *CurrentFnSym << '\n';
     } else if (Subtarget->isTargetCygMing()) {
       OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
+      // FIXME: linkonce should be a section attribute, handled by COFF Section
+      // assignment.
+      // http://sourceware.org/binutils/docs-2.20/as/Linkonce.html#Linkonce
       O << "\t.linkonce discard\n";
     } else {
       O << "\t.weak\t" << *CurrentFnSym << '\n';
@@ -105,7 +108,7 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
 
   printVisibility(CurrentFnSym, F->getVisibility());
 
-  if (Subtarget->isTargetELF()) {
+  if (MAI->hasDotTypeDotSizeDirective()) {
     OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
   } else if (Subtarget->isTargetCygMing()) {
     O << "\t.def\t " << *CurrentFnSym;