OSDN Git Service

First bit of support for the dwarf .loc directive. This patch updates the
authorKevin Enderby <enderby@apple.com>
Tue, 24 Aug 2010 20:32:42 +0000 (20:32 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 24 Aug 2010 20:32:42 +0000 (20:32 +0000)
needed parsing for the .loc directive and saves the current info from that
into the context.  The next patch will take the current loc info after an
instruction is assembled and save that info into a vector for each section for
use to build the line number tables.  The patch after that will encode the info
from those vectors into the output file as the dwarf line tables.

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

include/llvm/MC/MCContext.h
include/llvm/MC/MCDwarf.h
lib/MC/MCContext.cpp
lib/MC/MCParser/AsmParser.cpp

index 17e79fb..6686950 100644 (file)
@@ -11,6 +11,7 @@
 #define LLVM_MC_MCCONTEXT_H
 
 #include "llvm/MC/SectionKind.h"
+#include "llvm/MC/MCDwarf.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Allocator.h"
@@ -24,6 +25,7 @@ namespace llvm {
   class MCSymbol;
   class MCLabel;
   class MCDwarfFile;
+  class MCDwarfLoc;
   class StringRef;
   class Twine;
   class MCSectionMachO;
@@ -69,6 +71,10 @@ namespace llvm {
     std::vector<MCDwarfFile *> MCDwarfFiles;
     std::vector<StringRef> MCDwarfDirs;
 
+    /// The current dwarf line information from the last dwarf .loc directive.
+    MCDwarfLoc CurrentDwarfLoc;
+    bool DwarfLocSeen;
+
     /// Allocator - Allocator object used for creating machine code objects.
     ///
     /// We use a bump pointer allocator to avoid the need to track all allocated
@@ -149,6 +155,8 @@ namespace llvm {
     /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
     unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber);
 
+    bool ValidateDwarfFileNumber(unsigned FileNumber);
+
     const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
       return MCDwarfFiles;
     }
@@ -156,6 +164,19 @@ namespace llvm {
       return MCDwarfDirs;
     }
 
+    /// setCurrentDwarfLoc - saves the information from the currently parsed
+    /// dwarf .loc directive and sets DwarfLocSeen.  When the next instruction      /// is assembled an entry in the line number table with this information and
+    /// the address of the instruction will be created.
+    void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
+                            unsigned Flags, unsigned Isa) {
+      CurrentDwarfLoc.setFileNum(FileNum);
+      CurrentDwarfLoc.setLine(Line);
+      CurrentDwarfLoc.setColumn(Column);
+      CurrentDwarfLoc.setFlags(Flags);
+      CurrentDwarfLoc.setIsa(Isa);
+      DwarfLocSeen = true;
+    }
+
     /// @}
 
     char *getSecureLogFile() { return SecureLogFile; }
index e21b42f..4f39f79 100644 (file)
@@ -57,6 +57,50 @@ namespace llvm {
     void dump() const;
   };
 
+  /// MCDwarfLoc - Instances of this class represent the information from a
+  /// dwarf .loc directive.
+  class MCDwarfLoc {
+    // FileNum - the file number.
+    unsigned FileNum;
+    // Line - the line number.
+    unsigned Line;
+    // Column - the column position.
+    unsigned Column;
+    // Flags (see #define's below)
+    unsigned Flags;
+    // Isa
+    unsigned Isa;
+
+#define DWARF2_FLAG_IS_STMT        (1 << 0)
+#define DWARF2_FLAG_BASIC_BLOCK    (1 << 1)
+#define DWARF2_FLAG_PROLOGUE_END   (1 << 2)
+#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
+
+  private:  // MCContext manages these
+    friend class MCContext;
+    MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
+               unsigned isa)
+      : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa) {}
+
+    MCDwarfLoc(const MCDwarfLoc&);       // DO NOT IMPLEMENT
+    void operator=(const MCDwarfLoc&); // DO NOT IMPLEMENT
+  public:
+    /// setFileNum - Set the FileNum of this MCDwarfLoc.
+    void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+    /// setLine - Set the Line of this MCDwarfLoc.
+    void setLine(unsigned line) { Line = line; }
+
+    /// setColumn - Set the Column of this MCDwarfLoc.
+    void setColumn(unsigned column) { Column = column; }
+
+    /// setFlags - Set the Flags of this MCDwarfLoc.
+    void setFlags(unsigned flags) { Flags = flags; }
+
+    /// setIsa - Set the Isa of this MCDwarfLoc.
+    void setIsa(unsigned isa) { Isa = isa; }
+  };
+
   inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
     DwarfFile.print(OS);
     return OS;
index adf476c..13cf9a8 100644 (file)
@@ -24,7 +24,8 @@ typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
 typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
 
 
-MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
+MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0),
+                     CurrentDwarfLoc(0,0,0,0,0) {
   MachOUniquingMap = 0;
   ELFUniquingMap = 0;
   COFFUniquingMap = 0;
@@ -32,6 +33,8 @@ MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
   SecureLogFile = getenv("AS_SECURE_LOG_FILE");
   SecureLog = 0;
   SecureLogUsed = false;
+
+  DwarfLocSeen = false;
 }
 
 MCContext::~MCContext() {
@@ -247,3 +250,16 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
   // return the allocated FileNumber.
   return FileNumber;
 }
+
+/// ValidateDwarfFileNumber - takes a dwarf file number and returns true if it
+/// currently is assigned and false otherwise.
+bool MCContext::ValidateDwarfFileNumber(unsigned FileNumber) {
+  if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
+    return false;
+
+  MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
+  if (ExistingFile)
+    return true;
+  else
+    return false;
+}
index 747b009..c65becf 100644 (file)
@@ -1838,39 +1838,101 @@ bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
 
 
 /// ParseDirectiveLoc
-/// ::= .loc number [number [number]]
+/// ::= .loc FileNumber LineNumber [ColumnPos] [basic_block] [prologue_end]
+///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
+/// The first number is a file number, must have been previously assigned with
+/// a .file directive, the second number is the line number and optionally the
+/// third number is a column position (zero if not specified).  The remaining
+/// optional items are .loc sub-directives.
 bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
+
   if (getLexer().isNot(AsmToken::Integer))
     return TokError("unexpected token in '.loc' directive");
-
-  // FIXME: What are these fields?
   int64_t FileNumber = getTok().getIntVal();
-  (void) FileNumber;
-  // FIXME: Validate file.
+  if (FileNumber < 1)
+    return TokError("file number less than one in '.loc' directive");
+  if (!getContext().ValidateDwarfFileNumber(FileNumber))
+    return TokError("unassigned file number in '.loc' directive");
+  Lex();
 
+  if (getLexer().isNot(AsmToken::Integer))
+    return TokError("unexpected token in '.loc' directive");
+  int64_t LineNumber = getTok().getIntVal();
+  if (LineNumber < 1)
+    return TokError("line number less than one in '.loc' directive");
   Lex();
-  if (getLexer().isNot(AsmToken::EndOfStatement)) {
-    if (getLexer().isNot(AsmToken::Integer))
-      return TokError("unexpected token in '.loc' directive");
 
-    int64_t Param2 = getTok().getIntVal();
-    (void) Param2;
+  int64_t ColumnPos = 0;
+  if (getLexer().is(AsmToken::Integer)) {
+    ColumnPos = getTok().getIntVal();
+    if (ColumnPos < 0)
+      return TokError("column position less than zero in '.loc' directive");
     Lex();
+  }
 
-    if (getLexer().isNot(AsmToken::EndOfStatement)) {
-      if (getLexer().isNot(AsmToken::Integer))
+  unsigned Flags = 0;
+  unsigned Isa = 0;
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    for (;;) {
+      if (getLexer().is(AsmToken::EndOfStatement))
+        break;
+
+      StringRef Name;
+      SMLoc Loc = getTok().getLoc();
+      if (getParser().ParseIdentifier(Name))
         return TokError("unexpected token in '.loc' directive");
 
-      int64_t Param3 = getTok().getIntVal();
-      (void) Param3;
-      Lex();
+      if (Name == "basic_block")
+        Flags |= DWARF2_FLAG_BASIC_BLOCK;
+      else if (Name == "prologue_end")
+        Flags |= DWARF2_FLAG_PROLOGUE_END;
+      else if (Name == "epilogue_begin")
+        Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
+      else if (Name == "is_stmt") {
+        SMLoc Loc = getTok().getLoc();
+        const MCExpr *Value;
+        if (getParser().ParseExpression(Value))
+          return true;
+        // The expression must be the constant 0 or 1.
+        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+          int Value = MCE->getValue();
+          if (Value == 0)
+            Flags &= ~DWARF2_FLAG_IS_STMT;
+          else if (Value == 1)
+            Flags |= DWARF2_FLAG_IS_STMT;
+          else
+            return Error(Loc, "is_stmt value not 0 or 1");
+       }
+        else {
+          return Error(Loc, "is_stmt value not the constant value of 0 or 1");
+        }
+      }
+      else if (Name == "isa") {
+        SMLoc Loc = getTok().getLoc();
+        const MCExpr *Value;
+        if (getParser().ParseExpression(Value))
+          return true;
+        // The expression must be a constant greater or equal to 0.
+        if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+          int Value = MCE->getValue();
+          if (Value < 0)
+            return Error(Loc, "isa number less than zero");
+          Isa = Value;
+       }
+        else {
+          return Error(Loc, "isa number not a constant value");
+        }
+      }
+      else {
+        return Error(Loc, "unknown sub-directive in '.loc' directive");
+      }
 
-      // FIXME: Do something with the .loc.
+      if (getLexer().is(AsmToken::EndOfStatement))
+        break;
     }
   }
 
-  if (getLexer().isNot(AsmToken::EndOfStatement))
-    return TokError("unexpected token in '.file' directive");
+  getContext().setCurrentDwarfLoc(FileNumber, LineNumber, ColumnPos, Flags,Isa);
 
   return false;
 }