Added first bit of support for the dwarf .file directive. This patch collects
authorKevin Enderby <enderby@apple.com>
Wed, 28 Jul 2010 20:55:35 +0000 (20:55 +0000)
committerKevin Enderby <enderby@apple.com>
Wed, 28 Jul 2010 20:55:35 +0000 (20:55 +0000)
the info from the .file directive and makes file and directory tables that
will eventually be put out as part of the dwarf info in the output file.

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

include/llvm/MC/MCContext.h
include/llvm/MC/MCDwarf.h [new file with mode: 0644]
lib/MC/CMakeLists.txt
lib/MC/MCContext.cpp
lib/MC/MCDwarf.cpp [new file with mode: 0644]
lib/MC/MCParser/AsmParser.cpp

index a57b5bf745d36b4258eb58a2ef176b94166ad3e0..86f83ad240f8d2c12aee0ad105380e2504709a07 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/raw_ostream.h"
+#include <vector> // FIXME: Shouldn't be needed.
 
 namespace llvm {
   class MCAsmInfo;
@@ -22,6 +23,7 @@ namespace llvm {
   class MCSection;
   class MCSymbol;
   class MCLabel;
+  class MCDwarfFile;
   class StringRef;
   class Twine;
   class MCSectionMachO;
@@ -66,6 +68,10 @@ namespace llvm {
     /// .secure_log_reset appearing between them.
     bool SecureLogUsed;
 
+    /// The dwarf file and directory tables from the dwarf .file directive.
+    std::vector<MCDwarfFile *> MCDwarfFiles;
+    std::vector<std::string *> MCDwarfDirs;
+
     /// Allocator - Allocator object used for creating machine code objects.
     ///
     /// We use a bump pointer allocator to avoid the need to track all allocated
@@ -137,6 +143,18 @@ namespace llvm {
     }
 
     
+    /// @}
+
+    /// @name Dwarf Managment
+    /// @{
+
+    /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
+    unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber);
+
+    const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
+      return MCDwarfFiles;
+    }
+
     /// @}
 
     char *getSecureLogFile() { return SecureLogFile; }
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
new file mode 100644 (file)
index 0000000..4ba401a
--- /dev/null
@@ -0,0 +1,61 @@
+//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCDwarfFile to support the dwarf
+// .file directive.
+// TODO: add the support needed for the .loc directive.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDWARF_H
+#define LLVM_MC_MCDWARF_H
+
+#include <string>
+
+namespace llvm {
+  class MCContext;
+  class raw_ostream;
+
+  /// MCDwarfFile - Instances of this class represent the name of the dwarf
+  /// .file directive and its associated dwarf file number in the MC file,
+  /// and MCDwarfFile's are created and unique'd by the MCContext class where
+  /// the file number for each is its index into the vector of DwarfFiles (note
+  /// index 0 is not used and not a valid dwarf file number).
+  class MCDwarfFile {
+    // Name - the base name of the file without its directory path.
+    std::string Name;
+
+    // DirIndex - the index into the list of directory names for this file name.
+    unsigned DirIndex;
+
+  private:  // MCContext creates and uniques these.
+    friend class MCContext;
+    MCDwarfFile(std::string name, unsigned dirIndex)
+      : Name(name), DirIndex(dirIndex) {}
+
+    MCDwarfFile(const MCDwarfFile&);       // DO NOT IMPLEMENT
+    void operator=(const MCDwarfFile&); // DO NOT IMPLEMENT
+  public:
+    /// getName - Get the base name of this MCDwarfFile.
+    std::string getName() const { return Name; }
+
+    /// print - Print the value to the stream \arg OS.
+    void print(raw_ostream &OS) const;
+
+    /// dump - Print the value to stderr.
+    void dump() const;
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
+    DwarfFile.print(OS);
+    return OS;
+  }
+} // end namespace llvm
+
+#endif
index fc4f3c69482ac6c0ca974c22f03275f132566278..7b9b355339a10bb8b3ee4cee1b3434135b119bc7 100644 (file)
@@ -11,6 +11,7 @@ add_llvm_library(LLVMMC
   MCInst.cpp
   MCInstPrinter.cpp
   MCLabel.cpp
+  MCDwarf.cpp
   MCLoggingStreamer.cpp
   MCMachOStreamer.cpp
   MCNullStreamer.cpp
index 11370642530a1947e8a8ca127dae9540b62cacfe..7470e8d0031c39e9c478441aaf55492ca849d13c 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCLabel.h"
+#include "llvm/MC/MCDwarf.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
 using namespace llvm;
@@ -181,3 +182,63 @@ const MCSection *MCContext::getCOFFSection(StringRef Section,
   Entry.setValue(Result);
   return Result;
 }
+
+//===----------------------------------------------------------------------===//
+// Dwarf Management
+//===----------------------------------------------------------------------===//
+
+/// GetDwarfFile - takes a file name an number to place in the dwarf file and
+/// directory tables.  If the file number has already been allocated it is an
+/// error and zero is returned and the client reports the error, else the
+/// allocated file number is returned.  The file numbers may be in any order.
+unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
+  // TODO: a FileNumber of zero says to use the next available file number.
+  // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
+  // to not be less than one.  This needs to be change to be not less than zero.
+
+  // Make space for this FileNumber in the MCDwarfFiles vector if needed.
+  if (FileNumber >= MCDwarfFiles.size()) {
+    MCDwarfFiles.resize(FileNumber + 1);
+  } else {
+    MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
+    if (ExistingFile)
+      // It is an error to use see the same number more than once.
+      return 0;
+  }
+
+  // Get the new MCDwarfFile slot for this FileNumber.
+  MCDwarfFile *&File = MCDwarfFiles[FileNumber];
+
+  // Separate the directory part from the basename of the FileName.
+  std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');
+
+  // Find or make a entry in the MCDwarfDirs vector for this Directory.
+  StringRef Directory;
+  StringRef Name;
+  unsigned DirIndex;
+  // Capture directory name.
+  if (Slash.second.empty()) {
+    Name = Slash.first;
+    DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used.
+  } else {
+    Directory = Slash.first;
+    Name = Slash.second;
+    for (DirIndex = 1; DirIndex < MCDwarfDirs.size(); DirIndex++) {
+      std::string *&Dir = MCDwarfDirs[DirIndex];
+      if (Directory == *Dir)
+       break;
+    }
+    if (DirIndex >= MCDwarfDirs.size()) {
+      MCDwarfDirs.resize(DirIndex + 1);
+      std::string *&NewDir = MCDwarfDirs[DirIndex];
+      NewDir = new (*this) std::string(Directory);
+    }
+  }
+  
+  // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
+  // vector.
+  File = new (*this) MCDwarfFile(Name, DirIndex);
+
+  // return the allocated FileNumber.
+  return FileNumber;
+}
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
new file mode 100644 (file)
index 0000000..2da71f9
--- /dev/null
@@ -0,0 +1,21 @@
+//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+void MCDwarfFile::print(raw_ostream &OS) const {
+  OS << '"' << getName() << '"';
+}
+
+void MCDwarfFile::dump() const {
+  print(dbgs());
+}
index 61d65b8d015146be25e4577ac14f0805082fcdda..e74952a4cab481ff0773ddce1f822e7a1cbc8d50 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCDwarf.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
@@ -370,6 +371,16 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   if (TheCondState.TheCond != StartingCondState.TheCond ||
       TheCondState.Ignore != StartingCondState.Ignore)
     return TokError("unmatched .ifs or .elses");
+
+  // Check to see there are no empty DwarfFile slots.
+  const std::vector<MCDwarfFile *> &MCDwarfFiles =
+    getContext().getMCDwarfFiles();
+  for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
+    if (!MCDwarfFiles[i]){
+      TokError("unassigned file number: " + Twine(i) + " for .file directives");
+      HadError = true;
+    }
+  }
   
   // Finalize the output stream if there are no errors and if the client wants
   // us to.
@@ -1729,6 +1740,7 @@ bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
 bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
   // FIXME: I'm not sure what this is.
   int64_t FileNumber = -1;
+  SMLoc FileNumberLoc = getLexer().getLoc();
   if (getLexer().is(AsmToken::Integer)) {
     FileNumber = getTok().getIntVal();
     Lex();
@@ -1749,8 +1761,11 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
 
   if (FileNumber == -1)
     getStreamer().EmitFileDirective(Filename);
-  else
+  else {
+     if (getContext().GetDwarfFile(Filename, FileNumber) == 0)
+       Error(FileNumberLoc, "file number already allocated");
     getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
+  }
 
   return false;
 }