summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCContext.h18
-rw-r--r--include/llvm/MC/MCDwarf.h61
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/MCContext.cpp61
-rw-r--r--lib/MC/MCDwarf.cpp21
-rw-r--r--lib/MC/MCParser/AsmParser.cpp17
6 files changed, 178 insertions, 1 deletions
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index a57b5bf745..86f83ad240 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -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
@@ -139,6 +145,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; }
raw_ostream *getSecureLog() { return SecureLog; }
bool getSecureLogUsed() { return SecureLogUsed; }
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
new file mode 100644
index 0000000000..4ba401a49a
--- /dev/null
+++ b/include/llvm/MC/MCDwarf.h
@@ -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
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index fc4f3c6948..7b9b355339 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_library(LLVMMC
MCInst.cpp
MCInstPrinter.cpp
MCLabel.cpp
+ MCDwarf.cpp
MCLoggingStreamer.cpp
MCMachOStreamer.cpp
MCNullStreamer.cpp
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 1137064253..7470e8d003 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -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
index 0000000000..2da71f96c6
--- /dev/null
+++ b/lib/MC/MCDwarf.cpp
@@ -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());
+}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 61d65b8d01..e74952a4ca 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -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;
}