//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the helper classes used to build and interpret debug
// information in LLVM IR form.
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Support/Streams.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// DIDescriptor
//===----------------------------------------------------------------------===//
DIDescriptor::DIDescriptor(GlobalVariable *gv, unsigned RequiredTag) {
GV = gv;
// If this is non-null, check to see if the Tag matches. If not, set to null.
if (GV && getTag() != RequiredTag)
GV = 0;
}
std::string DIDescriptor::getStringField(unsigned Elt) const {
if (GV == 0) return "";
Constant *C = GV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return "";
std::string Result;
// Fills in the string if it succeeds
if (!GetConstantStringInfo(C->getOperand(Elt), Result))
Result.clear();
return Result;
}
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
if (GV == 0) return 0;
Constant *C = GV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return 0;
if (ConstantInt *CI = dyn_cast<ConstantInt>(C->getOperand(Elt)))
return CI->getZExtValue();
return 0;
}
DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
if (GV == 0) return DIDescriptor();
Constant *C = GV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return DIDescriptor();
C = C->getOperand(Elt);
return DIDescriptor(dyn_cast<GlobalVariable>(C->stripPointerCasts()));
}
GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
if (GV == 0) return 0;
Constant *C = GV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return 0;
C = C->getOperand(Elt);
return dyn_cast<GlobalVariable>(C->stripPointerCasts());
}
//===----------------------------------------------------------------------===//
// Simple Descriptor Constructors and other Methods
//===----------------------------------------------------------------------===//
DIAnchor::DIAnchor(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_anchor) {}
DIEnumerator::DIEnumerator(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_enumerator) {}
DISubrange::DISubrange(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_subrange_type) {}
DICompileUnit::DICompileUnit(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_compile_unit) {}
DIBasicType::DIBasicType(GlobalVariable *GV)
: DIType(GV, dwarf::DW_TAG_base_type) {}
DISubprogram::DISubprogram(GlobalVariable *GV)
: DIGlobal(GV, dwarf::DW_TAG_subprogram) {}
DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV)
: DIGlobal(GV, dwarf::DW_TAG_variable) {}
DIBlock::DIBlock(GlobalVariable *GV)
: DIDescriptor(GV, dwarf::DW_TAG_lexical_block) {}
// needed by DIVariable::getType()
DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) {
if (!gv) return;
unsigned tag = getTag();
if (tag != dwarf::DW_TAG_base_type && !DIDerivedType::isDerivedType(tag) &&
!DICompositeType::isCompositeType(tag))
GV = 0;
}
/// isDerivedType - Return true if the specified tag is legal for
/// DIDerivedType.
bool DIType::isDerivedType(unsigned Tag) {
switch (Tag) {
case dwarf::DW_TAG_typedef:
case dwarf::DW_TAG_pointer_type:
case dwarf::DW_TAG_reference_type:
case dwarf::DW_TAG_const_type:
case dwarf::<