Add support for a new extension to the .file directive:

.file filenumber "directory" "filename"

This removes one join+split of the directory+filename in MC internals. Because
bitcode files have independent fields for directory and filenames in debug info,
this patch may change the .o files written by existing .bc files.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2011-10-17 23:05:28 +00:00
parent 3a7572ff61
commit 44d798d976
22 changed files with 143 additions and 65 deletions

View File

@ -204,7 +204,8 @@ namespace llvm {
/// @{
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber);
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber);
bool isValidDwarfFileNumber(unsigned FileNumber);

View File

@ -505,7 +505,8 @@ namespace llvm {
/// EmitDwarfFileDirective - Associate a filename with a specified logical
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
/// directive.
virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename);
/// EmitDwarfLocDirective - This implements the DWARF2
// '.loc fileno lineno ...' assembler directive.
@ -613,6 +614,7 @@ namespace llvm {
bool isVerboseAsm,
bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0,
MCAsmBackend *TAB = 0,

View File

@ -50,6 +50,7 @@ namespace llvm {
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm,
bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
@ -116,6 +117,7 @@ namespace llvm {
bool isVerboseAsm,
bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
@ -426,13 +428,14 @@ namespace llvm {
bool isVerboseAsm,
bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst) const {
// AsmStreamerCtorFn is default to llvm::createAsmStreamer
return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
InstPrint, CE, TAB, ShowInst);
useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
}
/// @}

View File

@ -101,6 +101,7 @@ protected: // Can only create subclasses.
unsigned MCSaveTempLabels : 1;
unsigned MCUseLoc : 1;
unsigned MCUseCFI : 1;
unsigned MCUseDwarfDirectory : 1;
public:
virtual ~TargetMachine();
@ -196,6 +197,14 @@ public:
/// setMCUseCFI - Set whether all we should use dwarf's .cfi_* directives.
void setMCUseCFI(bool Value) { MCUseCFI = Value; }
/// hasMCUseDwarfDirectory - Check whether we should use .file directives with
/// explicit directories.
bool hasMCUseDwarfDirectory() const { return MCUseDwarfDirectory; }
/// setMCUseDwarfDirectory - Set whether all we should use .file directives
/// with explicit directories.
void setMCUseDwarfDirectory(bool Value) { MCUseDwarfDirectory = Value; }
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
Reloc::Model getRelocationModel() const;

View File

@ -442,23 +442,21 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,
if (FileName.empty())
return GetOrCreateSourceID("<stdin>", StringRef());
// MCStream expects full path name as filename.
if (!DirName.empty() && !sys::path::is_absolute(FileName)) {
SmallString<128> FullPathName = DirName;
sys::path::append(FullPathName, FileName);
// Here FullPathName will be copied into StringMap by GetOrCreateSourceID.
return GetOrCreateSourceID(StringRef(FullPathName), StringRef());
}
unsigned SrcId = SourceIdMap.size()+1;
std::pair<std::string, std::string> SourceName =
std::make_pair(FileName, DirName);
std::pair<std::pair<std::string, std::string>, unsigned> Entry =
make_pair(SourceName, SrcId);
StringMapEntry<unsigned> &Entry = SourceIdMap.GetOrCreateValue(FileName);
if (Entry.getValue())
return Entry.getValue();
unsigned SrcId = SourceIdMap.size();
Entry.setValue(SrcId);
std::map<std::pair<std::string, std::string>, unsigned>::iterator I;
bool NewlyInserted;
tie(I, NewlyInserted) = SourceIdMap.insert(Entry);
if (!NewlyInserted)
return I->second;
// Print out a .file directive to specify files for .loc directives.
Asm->OutStreamer.EmitDwarfFileDirective(SrcId, Entry.getKey());
Asm->OutStreamer.EmitDwarfFileDirective(SrcId, Entry.first.second,
Entry.first.first);
return SrcId;
}

View File

@ -26,6 +26,7 @@
#include "llvm/ADT/UniqueVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DebugLoc.h"
#include <map>
namespace llvm {
@ -207,9 +208,9 @@ class DwarfDebug {
///
std::vector<DIEAbbrev *> Abbreviations;
/// SourceIdMap - Source id map, i.e. pair of directory id and source file
/// id mapped to a unique id.
StringMap<unsigned> SourceIdMap;
/// SourceIdMap - Source id map, i.e. pair of source filename and directory
/// mapped to a unique id.
std::map<std::pair<std::string, std::string>, unsigned> SourceIdMap;
/// StringPool - A String->Symbol mapping of strings used by indirect
/// references.

View File

@ -159,6 +159,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
getVerboseAsm(),
hasMCUseLoc(),
hasMCUseCFI(),
hasMCUseDwarfDirectory(),
InstPrinter,
MCE, MAB,
ShowMCInst);

View File

@ -29,6 +29,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/PathV2.h"
#include <cctype>
using namespace llvm;
@ -50,6 +51,7 @@ private:
unsigned ShowInst : 1;
unsigned UseLoc : 1;
unsigned UseCFI : 1;
unsigned UseDwarfDirectory : 1;
enum EHSymbolFlags { EHGlobal = 1,
EHWeakDefinition = 1 << 1,
@ -63,13 +65,15 @@ private:
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend,
bool showInst)
: MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI) {
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream);
}
@ -196,7 +200,8 @@ public:
unsigned char Value = 0);
virtual void EmitFileDirective(StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename);
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
@ -748,13 +753,27 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
EmitEOL();
}
bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){
bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
if (!UseDwarfDirectory && !Directory.empty()) {
if (sys::path::is_absolute(Filename))
return EmitDwarfFileDirective(FileNo, "", Filename);
SmallString<128> FullPathName = Directory;
sys::path::append(FullPathName, Filename);
return EmitDwarfFileDirective(FileNo, "", FullPathName);
}
if (UseLoc) {
OS << "\t.file\t" << FileNo << ' ';
if (!Directory.empty()) {
PrintQuotedString(Directory, OS);
OS << ' ';
}
PrintQuotedString(Filename, OS);
EmitEOL();
}
return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename);
return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
}
void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@ -1271,9 +1290,9 @@ void MCAsmStreamer::Finish() {
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc,
bool useCFI, MCInstPrinter *IP,
MCCodeEmitter *CE, MCAsmBackend *MAB,
bool ShowInst) {
bool useCFI, bool useDwarfDirectory,
MCInstPrinter *IP, MCCodeEmitter *CE,
MCAsmBackend *MAB, bool ShowInst) {
return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
IP, CE, MAB, ShowInst);
useDwarfDirectory, IP, CE, MAB, ShowInst);
}

View File

@ -248,7 +248,8 @@ const MCSection *MCContext::getCOFFSection(StringRef Section,
/// 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) {
unsigned MCContext::GetDwarfFile(StringRef Directory, 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.
@ -266,19 +267,21 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
// 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('/');
if (Directory.empty()) {
// Separate the directory part from the basename of the FileName.
std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');
Directory = Slash.second;
if (!Directory.empty())
FileName = Slash.first;
}
// Find or make a entry in the MCDwarfDirs vector for this 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.
unsigned DirIndex;
if (Directory.empty()) {
// For FileNames with no directories a DirIndex of 0 is used.
DirIndex = 0;
} else {
StringRef Directory = Slash.first;
Name = Slash.second;
DirIndex = 0;
for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
if (Directory == MCDwarfDirs[DirIndex])
@ -291,16 +294,16 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
}
// The DirIndex is one based, as DirIndex of 0 is used for FileNames with
// no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
// directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames are
// stored at MCDwarfFiles[FileNumber].Name .
// directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
// are stored at MCDwarfFiles[FileNumber].Name .
DirIndex++;
}
// Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
// vector.
char *Buf = static_cast<char *>(Allocate(Name.size()));
memcpy(Buf, Name.data(), Name.size());
File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex);
char *Buf = static_cast<char *>(Allocate(FileName.size()));
memcpy(Buf, FileName.data(), FileName.size());
File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex);
// return the allocated FileNumber.
return FileNumber;

View File

@ -208,10 +208,12 @@ public:
return Child->EmitFileDirective(Filename);
}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
LogCall("EmitDwarfFileDirective",
"FileNo:" + Twine(FileNo) + " Filename:" + Filename);
return Child->EmitDwarfFileDirective(FileNo, Filename);
"FileNo:" + Twine(FileNo) + " Directory:" + Directory +
" Filename:" + Filename);
return Child->EmitDwarfFileDirective(FileNo, Directory, Filename);
}
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,

View File

@ -83,7 +83,8 @@ namespace {
unsigned char Value = 0) {}
virtual void EmitFileDirective(StringRef Filename) {}
virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) {
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
return false;
}
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,

View File

@ -2303,7 +2303,8 @@ bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
}
/// ParseDirectiveFile
/// ::= .file [number] string
/// ::= .file [number] filename
/// ::= .file number directory filename
bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
// FIXME: I'm not sure what this is.
int64_t FileNumber = -1;
@ -2319,17 +2320,31 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::String))
return TokError("unexpected token in '.file' directive");
StringRef Filename = getTok().getString();
Filename = Filename.substr(1, Filename.size()-2);
// Usually the directory and filename together, otherwise just the directory.
StringRef Path = getTok().getString();
Path = Path.substr(1, Path.size()-2);
Lex();
StringRef Directory;
StringRef Filename;
if (getLexer().is(AsmToken::String)) {
if (FileNumber == -1)
return TokError("explicit path specified, but no file number");
Filename = getTok().getString();
Filename = Filename.substr(1, Filename.size()-2);
Directory = Path;
Lex();
} else {
Filename = Path;
}
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.file' directive");
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
if (getStreamer().EmitDwarfFileDirective(FileNumber, Filename))
if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename))
Error(FileNumberLoc, "file number already allocated");
}

View File

@ -93,7 +93,8 @@ public:
virtual void EmitFileDirective(StringRef Filename) {
report_fatal_error("unsupported directive in pure streamer");
}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
report_fatal_error("unsupported directive in pure streamer");
return false;
}

View File

@ -142,8 +142,9 @@ void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
}
bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
StringRef Directory,
StringRef Filename) {
return getContext().GetDwarfFile(Filename, FileNo) == 0;
return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0;
}
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,

View File

@ -535,7 +535,7 @@ unsigned PTXAsmPrinter::GetOrCreateSourceID(StringRef FileName,
Entry.setValue(SrcId);
// Print out a .file directive to specify files for .loc directives.
OutStreamer.EmitDwarfFileDirective(SrcId, Entry.getKey());
OutStreamer.EmitDwarfFileDirective(SrcId, "", Entry.getKey());
return SrcId;
}
@ -594,4 +594,3 @@ extern "C" void LLVMInitializePTXAsmPrinter() {
RegisterAsmPrinter<PTXAsmPrinter> X(ThePTX32Target);
RegisterAsmPrinter<PTXAsmPrinter> Y(ThePTX64Target);
}

View File

@ -22,6 +22,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/PathV2.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@ -165,7 +166,8 @@ public:
unsigned char Value = 0);
virtual void EmitFileDirective(StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename);
virtual void EmitInstruction(const MCInst &Inst);
@ -489,11 +491,20 @@ void PTXMCAsmStreamer::EmitFileDirective(StringRef Filename) {
// FIXME: should we inherit from MCAsmStreamer?
bool PTXMCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
StringRef Filename){
StringRef Directory,
StringRef Filename) {
if (!Directory.empty()) {
if (sys::path::is_absolute(Filename))
return EmitDwarfFileDirective(FileNo, "", Filename);
SmallString<128> FullPathName = Directory;
sys::path::append(FullPathName, Filename);
return EmitDwarfFileDirective(FileNo, "", FullPathName);
}
OS << "\t.file\t" << FileNo << ' ';
PrintQuotedString(Filename, OS);
EmitEOL();
return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename);
return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
}
void PTXMCAsmStreamer::AddEncodingComment(const MCInst &Inst) {}
@ -535,6 +546,7 @@ namespace llvm {
MCStreamer *createPTXAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *IP,
MCCodeEmitter *CE, MCAsmBackend *MAB,
bool ShowInst) {

View File

@ -46,7 +46,7 @@ using namespace llvm;
namespace llvm {
MCStreamer *createPTXAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc,
bool useCFI,
bool useCFI, bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *MAB,
@ -157,6 +157,7 @@ bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
true, /* verbose asm */
hasMCUseLoc(),
hasMCUseCFI(),
hasMCUseDwarfDirectory(),
InstPrinter,
MCE, MAB,
false /* show MC encoding */);

View File

@ -197,7 +197,8 @@ TargetMachine::TargetMachine(const Target &T,
MCNoExecStack(false),
MCSaveTempLabels(false),
MCUseLoc(true),
MCUseCFI(true) {
MCUseCFI(true),
MCUseDwarfDirectory(true) {
// Typically it will be subtargets that will adjust FloatABIType from Default
// to Soft or Hard.
if (UseSoftFloat)

View File

@ -1,7 +1,7 @@
; RUN: llc -mtriple x86_64-apple-darwin10.0.0 < %s | FileCheck %s
; Radar 8884898
; CHECK: file 1 "/Users/manav/one/two{{/|\\\\}}simple.c"
; CHECK: file 1 "/Users/manav/one/two" "simple.c"
declare i32 @printf(i8*, ...) nounwind

View File

@ -2,7 +2,8 @@
.file "hello"
.file 1 "world"
.file 2 "directory" "file"
# CHECK: .file "hello"
# CHECK: .file 1 "world"
# CHECK: .file 2 "directory" "file"

View File

@ -133,6 +133,9 @@ cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
cl::desc("Do not use .cfi_* directives"));
cl::opt<bool> DisableDwarfDirectory("disable-dwarf-directory", cl::Hidden,
cl::desc("Do not use file directives with an explicit directory."));
static cl::opt<bool>
DisableRedZone("disable-red-zone",
cl::desc("Do not emit code that uses the red zone."),
@ -316,6 +319,9 @@ int main(int argc, char **argv) {
if (DisableCFI)
Target.setMCUseCFI(false);
if (DisableDwarfDirectory)
Target.setMCUseDwarfDirectory(false);
// Disable .loc support for older OS X versions.
if (TheTriple.isMacOSX() &&
TheTriple.isMacOSXVersionLT(10, 6))

View File

@ -409,8 +409,10 @@ static int AssembleInput(const char *ProgName) {
}
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
/*useLoc*/ true,
/*useCFI*/ true, IP, CE, MAB,
ShowInst));
/*useCFI*/ true,
/*useDwarfDirectory*/ true,
IP, CE, MAB, ShowInst));
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
@ -515,4 +517,3 @@ int main(int argc, char **argv) {
return 0;
}