mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[LLVM-C] Expose functions to create debug locations via DIBuilder.
These include: * Several functions for creating an LLVMDIBuilder, * LLVMDIBuilderCreateCompileUnit, * LLVMDIBuilderCreateFile, * LLVMDIBuilderCreateDebugLocation. Patch by Harlan Haskins. Differential Revision: https://reviews.llvm.org/D32368 llvm-svn: 317135
This commit is contained in:
parent
e214cacb92
commit
ee01810f86
202
include/llvm-c/DebugInfo.h
Normal file
202
include/llvm-c/DebugInfo.h
Normal file
@ -0,0 +1,202 @@
|
||||
//===------------ DebugInfo.h - LLVM C API Debug Info API -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// This file declares the C API endpoints for generating DWARF Debug Info
|
||||
///
|
||||
/// Note: This interface is experimental. It is *NOT* stable, and may be
|
||||
/// changed without warning.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Debug info flags.
|
||||
typedef enum {
|
||||
LLVMDIFlagZero = 0,
|
||||
LLVMDIFlagPrivate = 1,
|
||||
LLVMDIFlagProtected = 2,
|
||||
LLVMDIFlagPublic = 3,
|
||||
LLVMDIFlagFwdDecl = 1 << 2,
|
||||
LLVMDIFlagAppleBlock = 1 << 3,
|
||||
LLVMDIFlagBlockByrefStruct = 1 << 4,
|
||||
LLVMDIFlagVirtual = 1 << 5,
|
||||
LLVMDIFlagArtificial = 1 << 6,
|
||||
LLVMDIFlagExplicit = 1 << 7,
|
||||
LLVMDIFlagPrototyped = 1 << 8,
|
||||
LLVMDIFlagObjcClassComplete = 1 << 9,
|
||||
LLVMDIFlagObjectPointer = 1 << 10,
|
||||
LLVMDIFlagVector = 1 << 11,
|
||||
LLVMDIFlagStaticMember = 1 << 12,
|
||||
LLVMDIFlagLValueReference = 1 << 13,
|
||||
LLVMDIFlagRValueReference = 1 << 14,
|
||||
LLVMDIFlagReserved = 1 << 15,
|
||||
LLVMDIFlagSingleInheritance = 1 << 16,
|
||||
LLVMDIFlagMultipleInheritance = 2 << 16,
|
||||
LLVMDIFlagVirtualInheritance = 3 << 16,
|
||||
LLVMDIFlagIntroducedVirtual = 1 << 18,
|
||||
LLVMDIFlagBitField = 1 << 19,
|
||||
LLVMDIFlagNoReturn = 1 << 20,
|
||||
LLVMDIFlagMainSubprogram = 1 << 21,
|
||||
LLVMDIFlagIndirectVirtualBase = (1 << 2) | (1 << 5),
|
||||
LLVMDIFlagAccessibility = LLVMDIFlagPrivate | LLVMDIFlagProtected |
|
||||
LLVMDIFlagPublic,
|
||||
LLVMDIFlagPtrToMemberRep = LLVMDIFlagSingleInheritance |
|
||||
LLVMDIFlagMultipleInheritance |
|
||||
LLVMDIFlagVirtualInheritance
|
||||
} LLVMDIFlags;
|
||||
|
||||
/// Source languages known by DWARF.
|
||||
typedef enum {
|
||||
LLVMDWARFSourceLanguageC89,
|
||||
LLVMDWARFSourceLanguageC,
|
||||
LLVMDWARFSourceLanguageAda83,
|
||||
LLVMDWARFSourceLanguageC_plus_plus,
|
||||
LLVMDWARFSourceLanguageCobol74,
|
||||
LLVMDWARFSourceLanguageCobol85,
|
||||
LLVMDWARFSourceLanguageFortran77,
|
||||
LLVMDWARFSourceLanguageFortran90,
|
||||
LLVMDWARFSourceLanguagePascal83,
|
||||
LLVMDWARFSourceLanguageModula2,
|
||||
// New in DWARF v3:
|
||||
LLVMDWARFSourceLanguageJava,
|
||||
LLVMDWARFSourceLanguageC99,
|
||||
LLVMDWARFSourceLanguageAda95,
|
||||
LLVMDWARFSourceLanguageFortran95,
|
||||
LLVMDWARFSourceLanguagePLI,
|
||||
LLVMDWARFSourceLanguageObjC,
|
||||
LLVMDWARFSourceLanguageObjC_plus_plus,
|
||||
LLVMDWARFSourceLanguageUPC,
|
||||
LLVMDWARFSourceLanguageD,
|
||||
// New in DWARF v4:
|
||||
LLVMDWARFSourceLanguagePython,
|
||||
// New in DWARF v5:
|
||||
LLVMDWARFSourceLanguageOpenCL,
|
||||
LLVMDWARFSourceLanguageGo,
|
||||
LLVMDWARFSourceLanguageModula3,
|
||||
LLVMDWARFSourceLanguageHaskell,
|
||||
LLVMDWARFSourceLanguageC_plus_plus_03,
|
||||
LLVMDWARFSourceLanguageC_plus_plus_11,
|
||||
LLVMDWARFSourceLanguageOCaml,
|
||||
LLVMDWARFSourceLanguageRust,
|
||||
LLVMDWARFSourceLanguageC11,
|
||||
LLVMDWARFSourceLanguageSwift,
|
||||
LLVMDWARFSourceLanguageJulia,
|
||||
LLVMDWARFSourceLanguageDylan,
|
||||
LLVMDWARFSourceLanguageC_plus_plus_14,
|
||||
LLVMDWARFSourceLanguageFortran03,
|
||||
LLVMDWARFSourceLanguageFortran08,
|
||||
LLVMDWARFSourceLanguageRenderScript,
|
||||
LLVMDWARFSourceLanguageBLISS,
|
||||
// Vendor extensions:
|
||||
LLVMDWARFSourceLanguageMips_Assembler,
|
||||
LLVMDWARFSourceLanguageGOOGLE_RenderScript,
|
||||
LLVMDWARFSourceLanguageBORLAND_Delphi
|
||||
} LLVMDWARFSourceLanguage;
|
||||
|
||||
/// The amount of debug information to emit.
|
||||
typedef enum {
|
||||
LLVMDWARFEmissionNone = 0,
|
||||
LLVMDWARFEmissionFull,
|
||||
LLVMDWARFEmissionLineTablesOnly
|
||||
} LLVMDWARFEmissionKind;
|
||||
|
||||
/// The current debug metadata version number.
|
||||
unsigned LLVMDebugMetadataVersion(void);
|
||||
|
||||
/// The version of debug metadata that's present in the provided \c Module.
|
||||
unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef Module);
|
||||
|
||||
/// Strip debug info in the module if it exists.
|
||||
///
|
||||
/// To do this, we remove all calls to the debugger intrinsics and any named
|
||||
/// metadata for debugging. We also remove debug locations for instructions.
|
||||
/// Return true if module is modified.
|
||||
LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef Module);
|
||||
|
||||
/// Construct a builder for a module, and do not allow for unresolved nodes
|
||||
/// attached to the module.
|
||||
LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M);
|
||||
|
||||
/// Construct a builder for a module and collect unresolved nodes attached
|
||||
/// to the module in order to resolve cycles during a call to
|
||||
/// \c LLVMDIBuilderFinalize.
|
||||
LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M);
|
||||
|
||||
/// Deallocates the DIBuilder and everything it owns.
|
||||
/// @note You must call \c LLVMDIBuilderFinalize before this
|
||||
void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder);
|
||||
|
||||
/// Construct any deferred debug info descriptors.
|
||||
void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder);
|
||||
|
||||
/// A CompileUnit provides an anchor for all debugging
|
||||
/// information generated during this instance of compilation.
|
||||
/// \param Lang Source programming language, eg.
|
||||
/// \c LLVMDWARFSourceLanguageC99
|
||||
/// \param File File info.
|
||||
/// \param Producer Identify the producer of debugging information
|
||||
/// and code. Usually this is a compiler
|
||||
/// version string.
|
||||
/// \param ProducerLen The length of the C string passed to \c Producer.
|
||||
/// \param isOptimized A boolean flag which indicates whether optimization
|
||||
/// is enabled or not.
|
||||
/// \param Flags This string lists command line options. This
|
||||
/// string is directly embedded in debug info
|
||||
/// output which may be used by a tool
|
||||
/// analyzing generated debugging information.
|
||||
/// \param FlagsLen The length of the C string passed to \c Flags.
|
||||
/// \param RuntimeVer This indicates runtime version for languages like
|
||||
/// Objective-C.
|
||||
/// \param SplitName The name of the file that we'll split debug info
|
||||
/// out into.
|
||||
/// \param SplitNameLen The length of the C string passed to \c SplitName.
|
||||
/// \param Kind The kind of debug information to generate.
|
||||
/// \param DWOId The DWOId if this is a split skeleton compile unit.
|
||||
/// \param SplitDebugInlining Whether to emit inline debug info.
|
||||
/// \param DebugInfoForProfiling Whether to emit extra debug info for
|
||||
/// profile collection.
|
||||
LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
|
||||
LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,
|
||||
LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,
|
||||
LLVMBool isOptimized, const char *Flags, size_t FlagsLen,
|
||||
unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
|
||||
LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
|
||||
LLVMBool DebugInfoForProfiling);
|
||||
|
||||
/// Create a file descriptor to hold debugging information for a file.
|
||||
/// \param Builder The DIBuilder.
|
||||
/// \param Filename File name.
|
||||
/// \param FilenameLen The length of the C string passed to \c Filename.
|
||||
/// \param Directory Directory.
|
||||
/// \param DirectoryLen The length of the C string passed to \c Directory.
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
|
||||
size_t FilenameLen, const char *Directory,
|
||||
size_t DirectoryLen);
|
||||
|
||||
/// Creates a new DebugLocation that describes a source location.
|
||||
/// \param Line The line in the source file.
|
||||
/// \param Column The column in the source file.
|
||||
/// \param Scope The scope in which the location resides.
|
||||
/// \param InlinedAt The scope where this location was inlined, if at all.
|
||||
/// (optional).
|
||||
/// \note If the item to which this location is attached cannot be
|
||||
/// attributed to a source line, pass 0 for the line and column.
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
|
||||
unsigned Column, LLVMMetadataRef Scope,
|
||||
LLVMMetadataRef InlinedAt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end extern "C"
|
||||
#endif
|
@ -12,10 +12,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm-c/DebugInfo.h"
|
||||
#include "LLVMContextImpl.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -23,6 +25,8 @@
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GVMaterializer.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
@ -692,3 +696,79 @@ void Instruction::applyMergedLocation(const DILocation *LocA,
|
||||
setDebugLoc(DILocation::get(
|
||||
Result->getContext(), 0, 0, Result->getScope(), Result->getInlinedAt()));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LLVM C API implementations.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static unsigned map_from_llvmDWARFsourcelanguage(LLVMDWARFSourceLanguage lang) {
|
||||
switch (lang) {
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||
case LLVMDWARFSourceLanguage##NAME: return ID;
|
||||
#include "llvm/BinaryFormat/Dwarf.def"
|
||||
#undef HANDLE_DW_LANG
|
||||
}
|
||||
llvm_unreachable("Unhandled Tag");
|
||||
}
|
||||
|
||||
unsigned LLVMDebugMetadataVersion() {
|
||||
return DEBUG_METADATA_VERSION;
|
||||
}
|
||||
|
||||
LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M) {
|
||||
return wrap(new DIBuilder(*unwrap(M), false));
|
||||
}
|
||||
|
||||
LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M) {
|
||||
return wrap(new DIBuilder(*unwrap(M)));
|
||||
}
|
||||
|
||||
unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef M) {
|
||||
return getDebugMetadataVersionFromModule(*unwrap(M));
|
||||
}
|
||||
|
||||
LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef M) {
|
||||
return StripDebugInfo(*unwrap(M));
|
||||
}
|
||||
|
||||
void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder) {
|
||||
delete unwrap(Builder);
|
||||
}
|
||||
|
||||
void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder) {
|
||||
unwrap(Builder)->finalize();
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
|
||||
LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,
|
||||
LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,
|
||||
LLVMBool isOptimized, const char *Flags, size_t FlagsLen,
|
||||
unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
|
||||
LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
|
||||
LLVMBool DebugInfoForProfiling) {
|
||||
auto File = unwrap<DIFile>(FileRef);
|
||||
|
||||
return wrap(unwrap(Builder)->createCompileUnit(
|
||||
map_from_llvmDWARFsourcelanguage(Lang), File,
|
||||
StringRef(Producer, ProducerLen), isOptimized,
|
||||
StringRef(Flags, FlagsLen), RuntimeVer,
|
||||
StringRef(SplitName, SplitNameLen),
|
||||
static_cast<DICompileUnit::DebugEmissionKind>(Kind), DWOId,
|
||||
SplitDebugInlining, DebugInfoForProfiling));
|
||||
}
|
||||
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
|
||||
size_t FilenameLen, const char *Directory,
|
||||
size_t DirectoryLen) {
|
||||
return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),
|
||||
StringRef(Directory, DirectoryLen)));
|
||||
}
|
||||
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
|
||||
unsigned Column, LLVMMetadataRef Scope,
|
||||
LLVMMetadataRef InlinedAt) {
|
||||
return wrap(DILocation::get(*unwrap(Ctx), Line, Column, unwrap(Scope),
|
||||
unwrap(InlinedAt)));
|
||||
}
|
||||
|
8
test/Bindings/llvm-c/debug_info.ll
Normal file
8
test/Bindings/llvm-c/debug_info.ll
Normal file
@ -0,0 +1,8 @@
|
||||
; RUN: llvm-c-test --test-dibuilder | FileCheck %s
|
||||
|
||||
; CHECK: ; ModuleID = 'debuginfo.c'
|
||||
; CHECK-NEXT: source_filename = "debuginfo.c"
|
||||
|
||||
; CHECK: !llvm.dbg.cu = !{!0}
|
||||
; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
|
||||
; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c\00", directory: ".")
|
@ -38,6 +38,7 @@ endif ()
|
||||
add_llvm_tool(llvm-c-test
|
||||
attributes.c
|
||||
calc.c
|
||||
debuginfo.c
|
||||
diagnostic.c
|
||||
disassemble.c
|
||||
echo.cpp
|
||||
|
38
tools/llvm-c-test/debuginfo.c
Normal file
38
tools/llvm-c-test/debuginfo.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*===-- debuginfo.c - tool for testing libLLVM and llvm-c API -------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* Tests for the LLVM C DebugInfo API *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/DebugInfo.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int llvm_test_dibuilder() {
|
||||
LLVMModuleRef M = LLVMModuleCreateWithName("debuginfo.c");
|
||||
LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
|
||||
|
||||
LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, "debuginfo.c", 12,
|
||||
".", 1);
|
||||
|
||||
LLVMDIBuilderCreateCompileUnit(DIB,
|
||||
LLVMDWARFSourceLanguageC, File,"llvm-c-test", 11, 0, NULL, 0, 0,
|
||||
NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0);
|
||||
|
||||
char *MStr = LLVMPrintModuleToString(M);
|
||||
puts(MStr);
|
||||
LLVMDisposeMessage(MStr);
|
||||
|
||||
LLVMDisposeDIBuilder(DIB);
|
||||
LLVMDisposeModule(M);
|
||||
|
||||
return 0;
|
||||
}
|
@ -35,6 +35,9 @@ int llvm_calc(void);
|
||||
// disassemble.c
|
||||
int llvm_disassemble(void);
|
||||
|
||||
// debuginfo.c
|
||||
int llvm_test_dibuilder(void);
|
||||
|
||||
// metadata.c
|
||||
int llvm_add_named_metadata_operand(void);
|
||||
int llvm_set_metadata(void);
|
||||
|
@ -55,6 +55,9 @@ static void print_usage(void) {
|
||||
fprintf(stderr, " * --test-diagnostic-handler\n");
|
||||
fprintf(stderr,
|
||||
" Read bitcode file form stdin with a diagnostic handler set\n\n");
|
||||
fprintf(stderr, " * --test-dibuilder\n");
|
||||
fprintf(stderr,
|
||||
" Run tests for the DIBuilder C API - print generated module\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@ -96,6 +99,8 @@ int main(int argc, char **argv) {
|
||||
return llvm_echo();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) {
|
||||
return llvm_test_diagnostic_handler();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--test-dibuilder")) {
|
||||
return llvm_test_dibuilder();
|
||||
} else {
|
||||
print_usage();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user