First part of support for generating dwarf for assembly source files with the
authorKevin Enderby <enderby@apple.com>
Tue, 1 Nov 2011 22:27:22 +0000 (22:27 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 1 Nov 2011 22:27:22 +0000 (22:27 +0000)
-g flag.  In this part we generate the .file for the source being assembled and
the .loc's for the assembled instructions.

The next part will be to generate the dwarf Compile Unit DIE and a dwarf
subprogram DIE for each non-temporary label.

Once the next part is done test cases will be added.  rdar://9275556

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

include/llvm/MC/MCContext.h
lib/MC/MCContext.cpp
lib/MC/MCParser/AsmParser.cpp
tools/llvm-mc/llvm-mc.cpp

index 44bfb39c64499a0c39fb33c27ab93db7b712c0fd..d45b0c8ca61567a9db8bf183c76aebc146215e5b 100644 (file)
@@ -98,6 +98,17 @@ namespace llvm {
     MCDwarfLoc CurrentDwarfLoc;
     bool DwarfLocSeen;
 
+    /// Generate dwarf debugging info for assembly source files.
+    bool GenDwarfForAssembly;
+
+    /// The current dwarf file number when generate dwarf debugging info for
+    /// assembly source files.
+    unsigned GenDwarfFileNumber;
+
+    /// The default initial text section that we generate dwarf debugging line
+    /// info for when generating dwarf assembly source files.
+    const MCSection *GenDwarfSection;
+
     /// Honor temporary labels, this is useful for debugging semantic
     /// differences between temporary and non-temporary labels (primarily on
     /// Darwin).
@@ -252,6 +263,13 @@ namespace llvm {
     bool getDwarfLocSeen() { return DwarfLocSeen; }
     const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
 
+    bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
+    void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
+    unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
+    unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
+    const MCSection *getGenDwarfSection() { return GenDwarfSection; }
+    void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
+
     /// @}
 
     char *getSecureLogFile() { return SecureLogFile; }
index 9e28b8f41c6e307dc39c0eabf581f830dd18b01c..814726ebd8c0f54615be75624f78515ab03181f3 100644 (file)
@@ -43,6 +43,8 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
   SecureLogUsed = false;
 
   DwarfLocSeen = false;
+  GenDwarfForAssembly = false;
+  GenDwarfFileNumber = 0;
 }
 
 MCContext::~MCContext() {
index d7ee1c4ca3e76cda9c7ed1e39dd5906dd6695daf..990fd17f5987e7a349df880f803c42abaa236149 100644 (file)
@@ -464,6 +464,14 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   HadError = false;
   AsmCond StartingCondState = TheCondState;
 
+  // If we are generating dwarf for assembly source files save the initial text
+  // section and generate a .file directive.
+  if (getContext().getGenDwarfForAssembly()) {
+    getContext().setGenDwarfSection(getStreamer().getCurrentSection());
+    getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(),
+      StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier());
+  }
+
   // While we have input, parse each statement.
   while (Lexer.isNot(AsmToken::Eof)) {
     if (!ParseStatement()) continue;
@@ -1211,6 +1219,18 @@ bool AsmParser::ParseStatement() {
     PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str());
   }
 
+  // If we are generating dwarf for assembly source files and the current
+  // section is the initial text section then generate a .loc directive for
+  // the instruction.
+  if (!HadError && getContext().getGenDwarfForAssembly() &&
+      getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) {
+    getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(),
+                                        SrcMgr.FindLineNumber(IDLoc, CurBuffer),
+                                        0, DWARF2_LINE_DEFAULT_IS_STMT ?
+                                       DWARF2_FLAG_IS_STMT : 0, 0, 0,
+                                        StringRef());
+  }
+
   // If parsing succeeded, match the instruction.
   if (!HadError)
     HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands,
@@ -2342,6 +2362,10 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in '.file' directive");
 
+  if (getContext().getGenDwarfForAssembly() == true)
+    Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
+                        "used to generate dwarf debug info for assembly code");
+
   if (FileNumber == -1)
     getStreamer().EmitFileDirective(Filename);
   else {
index c188a76f5479a12b4f5c4179e73d0d77fafae2a4..8718b10ec210279c8c2c643bbd2ef227189a7092 100644 (file)
@@ -152,6 +152,10 @@ NoInitialTextSection("n", cl::desc("Don't assume assembly file starts "
 static cl::opt<bool>
 SaveTempLabels("L", cl::desc("Don't discard temporary labels"));
 
+static cl::opt<bool>
+GenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly "
+                                  "source files"));
+
 enum ActionType {
   AC_AsLex,
   AC_Assemble,
@@ -377,6 +381,8 @@ static int AssembleInput(const char *ProgName) {
   if (SaveTempLabels)
     Ctx.setAllowTemporaryLabels(false);
 
+  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
+
   // Package up features to be passed to target/subtarget
   std::string FeaturesStr;
   if (MAttrs.size()) {