[DWARF] Fix mixing assembler -g with DWARF .file directives.
authorPaul Robinson <paul.robinson@sony.com>
Thu, 22 Mar 2018 15:48:01 +0000 (15:48 +0000)
committerPaul Robinson <paul.robinson@sony.com>
Thu, 22 Mar 2018 15:48:01 +0000 (15:48 +0000)
We were effectively overriding an explicit '.file' directive with info
for the assembler source.  That shouldn't happen.

Fixes PR36636, really, even for .s files emitted by Clang.

Differential Revision: https://reviews.llvm.org/D44265

llvm-svn: 328208

llvm/lib/MC/MCParser/AsmParser.cpp
llvm/test/MC/AsmParser/directive_file-2.s

index 54a76732bbea7a5f8b21eff1898f2f23d9df7b1f..3042f9964ff19459997193c50d614e18ad9ac3c3 100644 (file)
@@ -311,6 +311,11 @@ private:
   }
   static void DiagHandler(const SMDiagnostic &Diag, void *Context);
 
+  /// Should we emit DWARF describing this assembler source?  (Returns false if
+  /// the source has .file directives, which means we don't want to generate
+  /// info describing the assembler source itself.)
+  bool enabledGenDwarfForAssembly();
+
   /// \brief Enter the specified file. This returns true on failure.
   bool enterIncludeFile(const std::string &Filename);
 
@@ -824,6 +829,19 @@ const AsmToken &AsmParser::Lex() {
   return *tok;
 }
 
+bool AsmParser::enabledGenDwarfForAssembly() {
+  // Check whether the user specified -g.
+  if (!getContext().getGenDwarfForAssembly())
+    return false;
+  // If we haven't encountered any .file directives (which would imply that
+  // the assembler source was produced with debug info already) then emit one
+  // describing the assembler source file itself.
+  if (getContext().getGenDwarfFileNumber() == 0)
+    getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
+        0, StringRef(), getContext().getMainFileName()));
+  return true;
+}
+
 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   // Create the initial section, if requested.
   if (!NoInitialTextSection)
@@ -837,7 +855,9 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   SmallVector<AsmRewrite, 4> AsmStrRewrites;
 
   // If we are generating dwarf for assembly source files save the initial text
-  // section and generate a .file directive.
+  // section.  (Don't use enabledGenDwarfForAssembly() here, as we aren't
+  // emitting any actual debug info yet and haven't had a chance to parse any
+  // embedded .file directives.)
   if (getContext().getGenDwarfForAssembly()) {
     MCSection *Sec = getStreamer().getCurrentSectionOnly();
     if (!Sec->getBeginSymbol()) {
@@ -848,8 +868,6 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
     bool InsertResult = getContext().addGenDwarfSection(Sec);
     assert(InsertResult && ".text section should not have debug info yet");
     (void)InsertResult;
-    getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
-        0, StringRef(), getContext().getMainFileName()));
   }
 
   // While we have input, parse each statement.
@@ -1784,7 +1802,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
 
     // If we are generating dwarf for assembly source files then gather the
     // info to make a dwarf label entry for this label if needed.
-    if (getContext().getGenDwarfForAssembly())
+    if (enabledGenDwarfForAssembly())
       MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
                                  IDLoc);
 
@@ -2153,7 +2171,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
 
   // If we are generating dwarf for the current section then generate a .loc
   // directive for the instruction.
-  if (!ParseHadError && getContext().getGenDwarfForAssembly() &&
+  if (!ParseHadError && enabledGenDwarfForAssembly() &&
       getContext().getGenDwarfSectionSyms().count(
           getStreamer().getCurrentSectionOnly())) {
     unsigned Line;
@@ -3318,6 +3336,10 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
     }
   }
 
+  // In case there is a -g option as well as debug info from directive .file,
+  // we turn off the -g option, directly use the existing debug info instead.
+  getContext().setGenDwarfForAssembly(false);
+
   if (FileNumber == -1)
     getStreamer().EmitFileDirective(Filename);
   else {
@@ -3334,17 +3356,11 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
       memcpy(SourceBuf, SourceString.data(), SourceString.size());
       Source = StringRef(SourceBuf, SourceString.size());
     }
-    // If there is -g option as well as debug info from directive file,
-    // we turn off -g option, directly use the existing debug info instead.
-    if (getContext().getGenDwarfForAssembly())
-      getContext().setGenDwarfForAssembly(false);
-    else {
-      Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
-          FileNumber, Directory, Filename, CKMem, Source);
-      if (!FileNumOrErr)
-        return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
-      FileNumber = FileNumOrErr.get();
-    }
+    Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
+        FileNumber, Directory, Filename, CKMem, Source);
+    if (!FileNumOrErr)
+      return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
+    FileNumber = FileNumOrErr.get();
   }
 
   return false;
index ff6df5116ad5a60ade8ebc4e0eb6d0b3aa65dd7f..ad3904ada0e26285120c96f39582eb9f14a97d31 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+// RUN: llvm-mc -g -triple i386-unknown-unknown %s | FileCheck %s
 // Test for Bug 11740
 // This testcase has two directive files,
 // when compiled with -g, this testcase will not report error,