blob: 8bbb47d3e24521a0f55e50c27ba9bcd5e381f549 [file] [log] [blame]
//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===//
//
// Copyright (C) 2006 to 2013 Jim Laskey, Duncan Sands et al.
//
// This file is part of DragonEgg.
//
// DragonEgg is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2, or (at your option) any later version.
//
// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// DragonEgg; see the file COPYING. If not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
//
//===----------------------------------------------------------------------===//
// This file declares the debug interfaces shared among the dragonegg files.
//===----------------------------------------------------------------------===//
#ifndef DRAGONEGG_DEBUG_H
#define DRAGONEGG_DEBUG_H
// Plugin headers
#include "dragonegg/Internals.h"
// LLVM headers
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"
// System headers
#include <map>
// Forward declarations
namespace llvm {
class AllocaInst;
class BasicBlock;
class CallInst;
class Function;
class Module;
}
/// DebugInfo - This class gathers all debug information during compilation and
/// is responsible for emitting to llvm globals or pass directly to the backend.
class DebugInfo {
private:
llvm::SmallVector<llvm::WeakVH, 4> RegionStack;
// Stack to track declarative scopes.
std::map<tree_node *, llvm::WeakVH> RegionMap;
llvm::Module &M;
llvm::LLVMContext &VMContext;
llvm::DIBuilder Builder;
llvm::Function *DeclareFn; // llvm.dbg.declare
llvm::Function *ValueFn; // llvm.dbg.value
const char *CurFullPath; // Previous location file encountered.
const char *PrevFullPath; // Previous location file encountered.
int CurLineNo; // Previous location line# encountered.
int PrevLineNo; // Previous location line# encountered.
llvm::BasicBlock *PrevBB; // Last basic block encountered.
std::map<tree_node *, llvm::WeakVH> TypeCache;
// Cache of previously constructed
// Types.
std::map<tree_node *, llvm::WeakVH> SPCache;
// Cache of previously constructed
// Subprograms.
std::map<tree_node *, llvm::WeakVH> NameSpaceCache;
// Cache of previously constructed name
// spaces.
/// FunctionNames - This is a storage for function names that are
/// constructed on demand. For example, C++ destructors, C++ operators etc..
llvm::BumpPtrAllocator FunctionNames;
public:
DebugInfo(llvm::Module *m);
~DebugInfo() { Builder.finalize(); }
/// Initialize - Initialize debug info by creating compile unit for
/// main_input_filename. This must be invoked after language dependent
/// initialization is done.
void Initialize();
// Accessors.
void setLocationFile(const char *FullPath) { CurFullPath = FullPath; }
void setLocationLine(int LineNo) { CurLineNo = LineNo; }
/// EmitFunctionStart - Constructs the debug code for entering a function -
/// "llvm.dbg.func.start."
void EmitFunctionStart(tree_node *FnDecl, llvm::Function *Fn);
/// EmitFunctionEnd - Constructs the debug code for exiting a declarative
/// region - "llvm.dbg.region.end."
void EmitFunctionEnd(bool EndFunction);
/// EmitDeclare - Constructs the debug code for allocation of a new variable.
/// region - "llvm.dbg.declare."
void EmitDeclare(tree_node *decl, unsigned Tag, llvm::StringRef Name,
tree_node *type, llvm::Value *AI, LLVMBuilder &Builder);
/// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
/// source line.
void EmitStopPoint(llvm::BasicBlock *CurBB, LLVMBuilder &Builder);
/// EmitGlobalVariable - Emit information about a global variable.
///
void EmitGlobalVariable(llvm::GlobalVariable *GV, tree_node *decl);
/// getOrCreateType - Get the type from the cache or create a new type if
/// necessary.
llvm::DIType getOrCreateType(tree_node *type);
/// createBasicType - Create BasicType.
llvm::DIType createBasicType(tree_node *type);
/// createMethodType - Create MethodType.
llvm::DIType createMethodType(tree_node *type);
/// createPointerType - Create PointerType.
llvm::DIType createPointerType(tree_node *type);
/// createArrayType - Create ArrayType.
llvm::DIType createArrayType(tree_node *type);
/// createEnumType - Create EnumType.
llvm::DIType createEnumType(tree_node *type);
/// createStructType - Create StructType for struct or union or class.
llvm::DIType createStructType(tree_node *type);
/// createVarinatType - Create variant type or return MainTy.
llvm::DIType createVariantType(tree_node *type, llvm::DIType MainTy);
/// getOrCreateCompileUnit - Create a new compile unit.
void getOrCreateCompileUnit(const char *FullPath, bool isMain = false);
/// getOrCreateFile - Get DIFile descriptor.
llvm::DIFile getOrCreateFile(const char *FullPath);
/// findRegion - Find tree_node N's region.
llvm::DIDescriptor findRegion(tree_node *n);
/// getOrCreateNameSpace - Get name space descriptor for the tree node.
llvm::DINameSpace getOrCreateNameSpace(tree_node *Node,
llvm::DIDescriptor Context);
/// getFunctionName - Get function name for the given FnDecl. If the
/// name is constructred on demand (e.g. C++ destructor) then the name
/// is stored on the side.
llvm::StringRef getFunctionName(tree_node *FnDecl);
private:
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
llvm::DIDerivedType CreateDerivedType(
unsigned Tag, llvm::DIDescriptor Context, llvm::StringRef Name,
llvm::DIFile F, unsigned LineNumber, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
llvm::DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
llvm::DICompositeType CreateCompositeType(
unsigned Tag, llvm::DIDescriptor Context, llvm::StringRef Name,
llvm::DIFile F, unsigned LineNumber, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
llvm::DIType DerivedFrom, llvm::DIArray Elements,
unsigned RunTimeLang = 0, llvm::MDNode *ContainingType = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
llvm::DISubprogram CreateSubprogram(
llvm::DIDescriptor Context, llvm::StringRef Name,
llvm::StringRef DisplayName, llvm::StringRef LinkageName, llvm::DIFile F,
unsigned LineNo, llvm::DIType Ty, bool isLocalToUnit, bool isDefinition,
unsigned VK = 0, unsigned VIndex = 0,
llvm::DIType ContainingType = llvm::DIType(), unsigned Flags = 0,
bool isOptimized = false, llvm::Function *Fn = 0);
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
llvm::DISubprogram
CreateSubprogramDefinition(llvm::DISubprogram &SPDeclaration,
unsigned LineNo, llvm::Function *Fn);
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
llvm::Instruction *
InsertDeclare(llvm::Value *Storage, llvm::DIVariable D,
llvm::BasicBlock *InsertAtEnd);
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
llvm::Instruction *
InsertDeclare(llvm::Value *Storage, llvm::DIVariable D,
llvm::Instruction *InsertBefore);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
llvm::Instruction *
InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset, llvm::DIVariable D,
llvm::BasicBlock *InsertAtEnd);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
llvm::Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
llvm::DIVariable D,
llvm::Instruction *InsertBefore);
};
#endif /* DRAGONEGG_DEBUG_H */