diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
commit | a16c51cee9225a354c999dd1076d5dba2aa79807 (patch) | |
tree | dba00119388b84f9f44e6ec5e9129f807fd79ca3 /lib/Analysis/DebugInfo.cpp | |
parent | 40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (diff) | |
download | FreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.zip FreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.tar.gz |
Update LLVM to 92395.
Diffstat (limited to 'lib/Analysis/DebugInfo.cpp')
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 706 |
1 files changed, 336 insertions, 370 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 1c9f500..de2d839 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -13,15 +13,16 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/DebugInfo.h" +#include "llvm/Target/TargetMachine.h" // FIXME: LAYERING VIOLATION! #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Support/raw_ostream.h" @@ -34,7 +35,7 @@ using namespace llvm::dwarf; /// ValidDebugInfo - Return true if V represents valid debug info value. /// FIXME : Add DIDescriptor.isValid() -bool DIDescriptor::ValidDebugInfo(MDNode *N, CodeGenOpt::Level OptLevel) { +bool DIDescriptor::ValidDebugInfo(MDNode *N, unsigned OptLevel) { if (!N) return false; @@ -45,8 +46,7 @@ bool DIDescriptor::ValidDebugInfo(MDNode *N, CodeGenOpt::Level OptLevel) { if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6) return false; - unsigned Tag = DI.getTag(); - switch (Tag) { + switch (DI.getTag()) { case DW_TAG_variable: assert(DIVariable(N).Verify() && "Invalid DebugInfo value"); break; @@ -83,8 +83,8 @@ DIDescriptor::getStringField(unsigned Elt) const { if (DbgNode == 0) return StringRef(); - if (Elt < DbgNode->getNumElements()) - if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getElement(Elt))) + if (Elt < DbgNode->getNumOperands()) + if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getOperand(Elt))) return MDS->getString(); return StringRef(); @@ -94,8 +94,8 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { if (DbgNode == 0) return 0; - if (Elt < DbgNode->getNumElements()) - if (ConstantInt *CI = dyn_cast<ConstantInt>(DbgNode->getElement(Elt))) + if (Elt < DbgNode->getNumOperands()) + if (ConstantInt *CI = dyn_cast<ConstantInt>(DbgNode->getOperand(Elt))) return CI->getZExtValue(); return 0; @@ -105,8 +105,8 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { if (DbgNode == 0) return DIDescriptor(); - if (Elt < DbgNode->getNumElements() && DbgNode->getElement(Elt)) - return DIDescriptor(dyn_cast<MDNode>(DbgNode->getElement(Elt))); + if (Elt < DbgNode->getNumOperands() && DbgNode->getOperand(Elt)) + return DIDescriptor(dyn_cast<MDNode>(DbgNode->getOperand(Elt))); return DIDescriptor(); } @@ -115,11 +115,16 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { if (DbgNode == 0) return 0; - if (Elt < DbgNode->getNumElements()) - return dyn_cast_or_null<GlobalVariable>(DbgNode->getElement(Elt)); + if (Elt < DbgNode->getNumOperands()) + return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); return 0; } +unsigned DIVariable::getNumAddrElements() const { + return DbgNode->getNumOperands()-6; +} + + //===----------------------------------------------------------------------===// // Predicates //===----------------------------------------------------------------------===// @@ -127,18 +132,14 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_base_type; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_base_type; } /// isDerivedType - Return true if the specified tag is legal for DIDerivedType. bool DIDescriptor::isDerivedType() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - switch (Tag) { + assert(!isNull() && "Invalid descriptor!"); + switch (getTag()) { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: case dwarf::DW_TAG_reference_type: @@ -157,10 +158,8 @@ bool DIDescriptor::isDerivedType() const { /// isCompositeType - Return true if the specified tag is legal for /// DICompositeType. bool DIDescriptor::isCompositeType() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - switch (Tag) { + assert(!isNull() && "Invalid descriptor!"); + switch (getTag()) { case dwarf::DW_TAG_array_type: case dwarf::DW_TAG_structure_type: case dwarf::DW_TAG_union_type: @@ -176,10 +175,8 @@ bool DIDescriptor::isCompositeType() const { /// isVariable - Return true if the specified tag is legal for DIVariable. bool DIDescriptor::isVariable() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - switch (Tag) { + assert(!isNull() && "Invalid descriptor!"); + switch (getTag()) { case dwarf::DW_TAG_auto_variable: case dwarf::DW_TAG_arg_variable: case dwarf::DW_TAG_return_variable: @@ -197,19 +194,15 @@ bool DIDescriptor::isType() const { /// isSubprogram - Return true if the specified tag is legal for /// DISubprogram. bool DIDescriptor::isSubprogram() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_subprogram; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_subprogram; } /// isGlobalVariable - Return true if the specified tag is legal for /// DIGlobalVariable. bool DIDescriptor::isGlobalVariable() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_variable; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_variable; } /// isGlobal - Return true if the specified tag is legal for DIGlobal. @@ -220,50 +213,47 @@ bool DIDescriptor::isGlobal() const { /// isScope - Return true if the specified tag is one of the scope /// related tag. bool DIDescriptor::isScope() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - switch (Tag) { - case dwarf::DW_TAG_compile_unit: - case dwarf::DW_TAG_lexical_block: - case dwarf::DW_TAG_subprogram: - return true; - default: - break; + assert(!isNull() && "Invalid descriptor!"); + switch (getTag()) { + case dwarf::DW_TAG_compile_unit: + case dwarf::DW_TAG_lexical_block: + case dwarf::DW_TAG_subprogram: + case dwarf::DW_TAG_namespace: + return true; + default: + break; } return false; } /// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit. bool DIDescriptor::isCompileUnit() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_compile_unit; +} - return Tag == dwarf::DW_TAG_compile_unit; +/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. +bool DIDescriptor::isNameSpace() const { + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_namespace; } /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_lexical_block; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_lexical_block; } /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. bool DIDescriptor::isSubrange() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_subrange_type; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_subrange_type; } /// isEnumerator - Return true if the specified tag is DW_TAG_enumerator. bool DIDescriptor::isEnumerator() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_enumerator; + assert(!isNull() && "Invalid descriptor!"); + return getTag() == dwarf::DW_TAG_enumerator; } //===----------------------------------------------------------------------===// @@ -278,8 +268,8 @@ DIType::DIType(MDNode *N) : DIDescriptor(N) { } unsigned DIArray::getNumElements() const { - assert (DbgNode && "Invalid DIArray"); - return DbgNode->getNumElements(); + assert(DbgNode && "Invalid DIArray"); + return DbgNode->getNumOperands(); } /// replaceAllUsesWith - Replace all uses of debug info referenced by @@ -289,7 +279,7 @@ void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) { if (isNull()) return; - assert (!D.isNull() && "Can not replace with null"); + assert(!D.isNull() && "Can not replace with null"); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something @@ -299,7 +289,7 @@ void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) { if (getNode() != D.getNode()) { MDNode *Node = DbgNode; Node->replaceAllUsesWith(D.getNode()); - delete Node; + Node->destroy(); } } @@ -422,7 +412,7 @@ uint64_t DIDerivedType::getOriginalTypeSize() const { /// describes - Return true if this subprogram provides debugging /// information for the function F. bool DISubprogram::describes(const Function *F) { - assert (F && "Invalid function"); + assert(F && "Invalid function"); StringRef Name = getLinkageName(); if (Name.empty()) Name = getName(); @@ -434,24 +424,26 @@ bool DISubprogram::describes(const Function *F) { StringRef DIScope::getFilename() const { if (isLexicalBlock()) return DILexicalBlock(DbgNode).getFilename(); - else if (isSubprogram()) + if (isSubprogram()) return DISubprogram(DbgNode).getFilename(); - else if (isCompileUnit()) + if (isCompileUnit()) return DICompileUnit(DbgNode).getFilename(); - else - assert (0 && "Invalid DIScope!"); + if (isNameSpace()) + return DINameSpace(DbgNode).getFilename(); + assert(0 && "Invalid DIScope!"); return StringRef(); } StringRef DIScope::getDirectory() const { if (isLexicalBlock()) return DILexicalBlock(DbgNode).getDirectory(); - else if (isSubprogram()) + if (isSubprogram()) return DISubprogram(DbgNode).getDirectory(); - else if (isCompileUnit()) + if (isCompileUnit()) return DICompileUnit(DbgNode).getDirectory(); - else - assert (0 && "Invalid DIScope!"); + if (isNameSpace()) + return DINameSpace(DbgNode).getDirectory(); + assert(0 && "Invalid DIScope!"); return StringRef(); } @@ -462,16 +454,16 @@ StringRef DIScope::getDirectory() const { /// dump - Print descriptor. void DIDescriptor::dump() const { - errs() << "[" << dwarf::TagString(getTag()) << "] "; - errs().write_hex((intptr_t) &*DbgNode) << ']'; + dbgs() << "[" << dwarf::TagString(getTag()) << "] "; + dbgs().write_hex((intptr_t) &*DbgNode) << ']'; } /// dump - Print compile unit. void DICompileUnit::dump() const { if (getLanguage()) - errs() << " [" << dwarf::LanguageString(getLanguage()) << "] "; + dbgs() << " [" << dwarf::LanguageString(getLanguage()) << "] "; - errs() << " [" << getDirectory() << "/" << getFilename() << " ]"; + dbgs() << " [" << getDirectory() << "/" << getFilename() << " ]"; } /// dump - Print type. @@ -480,14 +472,14 @@ void DIType::dump() const { StringRef Res = getName(); if (!Res.empty()) - errs() << " [" << Res << "] "; + dbgs() << " [" << Res << "] "; unsigned Tag = getTag(); - errs() << " [" << dwarf::TagString(Tag) << "] "; + dbgs() << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context getCompileUnit().dump(); - errs() << " [" + dbgs() << " [" << getLineNumber() << ", " << getSizeInBits() << ", " << getAlignInBits() << ", " @@ -495,12 +487,12 @@ void DIType::dump() const { << "] "; if (isPrivate()) - errs() << " [private] "; + dbgs() << " [private] "; else if (isProtected()) - errs() << " [protected] "; + dbgs() << " [protected] "; if (isForwardDecl()) - errs() << " [fwd] "; + dbgs() << " [fwd] "; if (isBasicType()) DIBasicType(DbgNode).dump(); @@ -509,21 +501,21 @@ void DIType::dump() const { else if (isCompositeType()) DICompositeType(DbgNode).dump(); else { - errs() << "Invalid DIType\n"; + dbgs() << "Invalid DIType\n"; return; } - errs() << "\n"; + dbgs() << "\n"; } /// dump - Print basic type. void DIBasicType::dump() const { - errs() << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; + dbgs() << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; } /// dump - Print derived type. void DIDerivedType::dump() const { - errs() << "\n\t Derived From: "; getTypeDerivedFrom().dump(); + dbgs() << "\n\t Derived From: "; getTypeDerivedFrom().dump(); } /// dump - Print composite type. @@ -531,73 +523,73 @@ void DICompositeType::dump() const { DIArray A = getTypeArray(); if (A.isNull()) return; - errs() << " [" << A.getNumElements() << " elements]"; + dbgs() << " [" << A.getNumElements() << " elements]"; } /// dump - Print global. void DIGlobal::dump() const { StringRef Res = getName(); if (!Res.empty()) - errs() << " [" << Res << "] "; + dbgs() << " [" << Res << "] "; unsigned Tag = getTag(); - errs() << " [" << dwarf::TagString(Tag) << "] "; + dbgs() << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context getCompileUnit().dump(); - errs() << " [" << getLineNumber() << "] "; + dbgs() << " [" << getLineNumber() << "] "; if (isLocalToUnit()) - errs() << " [local] "; + dbgs() << " [local] "; if (isDefinition()) - errs() << " [def] "; + dbgs() << " [def] "; if (isGlobalVariable()) DIGlobalVariable(DbgNode).dump(); - errs() << "\n"; + dbgs() << "\n"; } /// dump - Print subprogram. void DISubprogram::dump() const { StringRef Res = getName(); if (!Res.empty()) - errs() << " [" << Res << "] "; + dbgs() << " [" << Res << "] "; unsigned Tag = getTag(); - errs() << " [" << dwarf::TagString(Tag) << "] "; + dbgs() << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context getCompileUnit().dump(); - errs() << " [" << getLineNumber() << "] "; + dbgs() << " [" << getLineNumber() << "] "; if (isLocalToUnit()) - errs() << " [local] "; + dbgs() << " [local] "; if (isDefinition()) - errs() << " [def] "; + dbgs() << " [def] "; - errs() << "\n"; + dbgs() << "\n"; } /// dump - Print global variable. void DIGlobalVariable::dump() const { - errs() << " ["; + dbgs() << " ["; getGlobal()->dump(); - errs() << "] "; + dbgs() << "] "; } /// dump - Print variable. void DIVariable::dump() const { StringRef Res = getName(); if (!Res.empty()) - errs() << " [" << Res << "] "; + dbgs() << " [" << Res << "] "; getCompileUnit().dump(); - errs() << " [" << getLineNumber() << "] "; + dbgs() << " [" << getLineNumber() << "] "; getType().dump(); - errs() << "\n"; + dbgs() << "\n"; // FIXME: Dump complex addresses } @@ -899,18 +891,18 @@ DISubprogram DIFactory::CreateSubprogramDefinition(DISubprogram &SPDeclaration) Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_subprogram), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - DeclNode->getElement(2), // Context - DeclNode->getElement(3), // Name - DeclNode->getElement(4), // DisplayName - DeclNode->getElement(5), // LinkageName - DeclNode->getElement(6), // CompileUnit - DeclNode->getElement(7), // LineNo - DeclNode->getElement(8), // Type - DeclNode->getElement(9), // isLocalToUnit + DeclNode->getOperand(2), // Context + DeclNode->getOperand(3), // Name + DeclNode->getOperand(4), // DisplayName + DeclNode->getOperand(5), // LinkageName + DeclNode->getOperand(6), // CompileUnit + DeclNode->getOperand(7), // LineNo + DeclNode->getOperand(8), // Type + DeclNode->getOperand(9), // isLocalToUnit ConstantInt::get(Type::getInt1Ty(VMContext), true), - DeclNode->getElement(11), // Virtuality - DeclNode->getElement(12), // VIndex - DeclNode->getElement(13) // Containting Type + DeclNode->getOperand(11), // Virtuality + DeclNode->getOperand(12), // VIndex + DeclNode->getOperand(13) // Containting Type }; return DISubprogram(MDNode::get(VMContext, &Elts[0], 14)); } @@ -943,7 +935,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name, // Create a named metadata so that we do not lose this mdnode. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); - NMD->addElement(Node); + NMD->addOperand(Node); return DIGlobalVariable(Node); } @@ -996,6 +988,21 @@ DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) { return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); } +/// CreateNameSpace - This creates new descriptor for a namespace +/// with the specified parent context. +DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNo) { + Value *Elts[] = { + GetTagConstant(dwarf::DW_TAG_namespace), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) + }; + return DINameSpace(MDNode::get(VMContext, &Elts[0], 5)); +} + /// CreateLocation - Creates a debug info location. DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc) { @@ -1088,9 +1095,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, /// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { - - MetadataContext &TheMetadata = M.getContext().getMetadata(); - unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); + unsigned MDDbgKind = M.getMDKindID("dbg"); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) @@ -1098,17 +1103,16 @@ void DebugInfoFinder::processModule(Module &M) { ++BI) { if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) processDeclare(DDI); - else if (MDDbgKind) - if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI)) - processLocation(DILocation(L)); + else if (MDNode *L = BI->getMetadata(MDDbgKind)) + processLocation(DILocation(L)); } NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv"); if (!NMD) return; - for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { - DIGlobalVariable DIG(cast<MDNode>(NMD->getElement(i))); + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); @@ -1238,275 +1242,237 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) { return true; } -namespace llvm { - /// findStopPoint - Find the stoppoint coressponding to this instruction, that - /// is the stoppoint that dominates this instruction. - const DbgStopPointInst *findStopPoint(const Instruction *Inst) { - if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst)) - return DSI; - - const BasicBlock *BB = Inst->getParent(); - BasicBlock::const_iterator I = Inst, B; - while (BB) { - B = BB->begin(); - - // A BB consisting only of a terminator can't have a stoppoint. - while (I != B) { - --I; - if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I)) - return DSI; - } - - // This BB didn't have a stoppoint: if there is only one predecessor, look - // for a stoppoint there. We could use getIDom(), but that would require - // dominator info. - BB = I->getParent()->getUniquePredecessor(); - if (BB) - I = BB->getTerminator(); - } +/// findStopPoint - Find the stoppoint coressponding to this instruction, that +/// is the stoppoint that dominates this instruction. +const DbgStopPointInst *llvm::findStopPoint(const Instruction *Inst) { + if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst)) + return DSI; - return 0; - } + const BasicBlock *BB = Inst->getParent(); + BasicBlock::const_iterator I = Inst, B; + while (BB) { + B = BB->begin(); - /// findBBStopPoint - Find the stoppoint corresponding to first real - /// (non-debug intrinsic) instruction in this Basic Block, and return the - /// stoppoint for it. - const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB) { - for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) + // A BB consisting only of a terminator can't have a stoppoint. + while (I != B) { + --I; if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I)) return DSI; + } - // Fallback to looking for stoppoint of unique predecessor. Useful if this - // BB contains no stoppoints, but unique predecessor does. - BB = BB->getUniquePredecessor(); + // This BB didn't have a stoppoint: if there is only one predecessor, look + // for a stoppoint there. We could use getIDom(), but that would require + // dominator info. + BB = I->getParent()->getUniquePredecessor(); if (BB) - return findStopPoint(BB->getTerminator()); - - return 0; + I = BB->getTerminator(); } - Value *findDbgGlobalDeclare(GlobalVariable *V) { - const Module *M = V->getParent(); - NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); - if (!NMD) - return 0; - - for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { - DIGlobalVariable DIG(cast_or_null<MDNode>(NMD->getElement(i))); - if (DIG.isNull()) - continue; - if (DIG.getGlobal() == V) - return DIG.getNode(); - } - return 0; - } - - /// Finds the llvm.dbg.declare intrinsic corresponding to this value if any. - /// It looks through pointer casts too. - const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts) { - if (stripCasts) { - V = V->stripPointerCasts(); - - // Look for the bitcast. - for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); - I != E; ++I) - if (isa<BitCastInst>(I)) { - const DbgDeclareInst *DDI = findDbgDeclare(*I, false); - if (DDI) return DDI; - } - return 0; - } + return 0; +} - // Find llvm.dbg.declare among uses of the instruction. - for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); - I != E; ++I) - if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) - return DDI; +/// findBBStopPoint - Find the stoppoint corresponding to first real +/// (non-debug intrinsic) instruction in this Basic Block, and return the +/// stoppoint for it. +const DbgStopPointInst *llvm::findBBStopPoint(const BasicBlock *BB) { + for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) + if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I)) + return DSI; - return 0; - } + // Fallback to looking for stoppoint of unique predecessor. Useful if this + // BB contains no stoppoints, but unique predecessor does. + BB = BB->getUniquePredecessor(); + if (BB) + return findStopPoint(BB->getTerminator()); -bool getLocationInfo(const Value *V, std::string &DisplayName, - std::string &Type, unsigned &LineNo, std::string &File, - std::string &Dir) { - DICompileUnit Unit; - DIType TypeD; - - if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) { - Value *DIGV = findDbgGlobalDeclare(GV); - if (!DIGV) return false; - DIGlobalVariable Var(cast<MDNode>(DIGV)); - - StringRef D = Var.getDisplayName(); - if (!D.empty()) - DisplayName = D; - LineNo = Var.getLineNumber(); - Unit = Var.getCompileUnit(); - TypeD = Var.getType(); - } else { - const DbgDeclareInst *DDI = findDbgDeclare(V); - if (!DDI) return false; - DIVariable Var(cast<MDNode>(DDI->getVariable())); - - StringRef D = Var.getName(); - if (!D.empty()) - DisplayName = D; - LineNo = Var.getLineNumber(); - Unit = Var.getCompileUnit(); - TypeD = Var.getType(); - } + return 0; +} - StringRef T = TypeD.getName(); - if (!T.empty()) - Type = T; - StringRef F = Unit.getFilename(); - if (!F.empty()) - File = F; - StringRef D = Unit.getDirectory(); - if (!D.empty()) - Dir = D; - return true; - } +Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) { + const Module *M = V->getParent(); + NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); + if (!NMD) + return 0; - /// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI, - CodeGenOpt::Level OptLev) { - return DIDescriptor::ValidDebugInfo(SPI.getContext(), OptLev); + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + DIGlobalVariable DIG(cast_or_null<MDNode>(NMD->getOperand(i))); + if (DIG.isNull()) + continue; + if (DIG.getGlobal() == V) + return DIG.getNode(); } + return 0; +} - /// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgFuncStartInst &FSI, - CodeGenOpt::Level OptLev) { - return DIDescriptor::ValidDebugInfo(FSI.getSubprogram(), OptLev); - } +/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any. +/// It looks through pointer casts too. +const DbgDeclareInst *llvm::findDbgDeclare(const Value *V, bool stripCasts) { + if (stripCasts) { + V = V->stripPointerCasts(); - /// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgRegionStartInst &RSI, - CodeGenOpt::Level OptLev) { - return DIDescriptor::ValidDebugInfo(RSI.getContext(), OptLev); + // Look for the bitcast. + for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); + I != E; ++I) + if (isa<BitCastInst>(I)) { + const DbgDeclareInst *DDI = findDbgDeclare(*I, false); + if (DDI) return DDI; + } + return 0; } - /// isValidDebugInfoIntrinsic - Return true if REI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgRegionEndInst &REI, - CodeGenOpt::Level OptLev) { - return DIDescriptor::ValidDebugInfo(REI.getContext(), OptLev); - } + // Find llvm.dbg.declare among uses of the instruction. + for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); + I != E; ++I) + if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) + return DDI; + return 0; +} - /// isValidDebugInfoIntrinsic - Return true if DI is a valid debug - /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI, - CodeGenOpt::Level OptLev) { - return DIDescriptor::ValidDebugInfo(DI.getVariable(), OptLev); - } +bool llvm::getLocationInfo(const Value *V, std::string &DisplayName, + std::string &Type, unsigned &LineNo, + std::string &File, std::string &Dir) { + DICompileUnit Unit; + DIType TypeD; - /// ExtractDebugLocation - Extract debug location information - /// from llvm.dbg.stoppoint intrinsic. - DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI, - DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - Value *Context = SPI.getContext(); - - // If this location is already tracked then use it. - DebugLocTuple Tuple(cast<MDNode>(Context), NULL, SPI.getLine(), - SPI.getColumn()); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); - if (II != DebugLocInfo.DebugIdMap.end()) - return DebugLoc::get(II->second); - - // Add a new location entry. - unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; - - return DebugLoc::get(Id); - } + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) { + Value *DIGV = findDbgGlobalDeclare(GV); + if (!DIGV) return false; + DIGlobalVariable Var(cast<MDNode>(DIGV)); - /// ExtractDebugLocation - Extract debug location information - /// from DILocation. - DebugLoc ExtractDebugLocation(DILocation &Loc, - DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - MDNode *Context = Loc.getScope().getNode(); - MDNode *InlinedLoc = NULL; - if (!Loc.getOrigLocation().isNull()) - InlinedLoc = Loc.getOrigLocation().getNode(); - // If this location is already tracked then use it. - DebugLocTuple Tuple(Context, InlinedLoc, Loc.getLineNumber(), - Loc.getColumnNumber()); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); - if (II != DebugLocInfo.DebugIdMap.end()) - return DebugLoc::get(II->second); - - // Add a new location entry. - unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; - - return DebugLoc::get(Id); + StringRef D = Var.getDisplayName(); + if (!D.empty()) + DisplayName = D; + LineNo = Var.getLineNumber(); + Unit = Var.getCompileUnit(); + TypeD = Var.getType(); + } else { + const DbgDeclareInst *DDI = findDbgDeclare(V); + if (!DDI) return false; + DIVariable Var(cast<MDNode>(DDI->getVariable())); + + StringRef D = Var.getName(); + if (!D.empty()) + DisplayName = D; + LineNo = Var.getLineNumber(); + Unit = Var.getCompileUnit(); + TypeD = Var.getType(); } - /// ExtractDebugLocation - Extract debug location information - /// from llvm.dbg.func_start intrinsic. - DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI, - DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - Value *SP = FSI.getSubprogram(); - - DISubprogram Subprogram(cast<MDNode>(SP)); - unsigned Line = Subprogram.getLineNumber(); - DICompileUnit CU(Subprogram.getCompileUnit()); - - // If this location is already tracked then use it. - DebugLocTuple Tuple(CU.getNode(), NULL, Line, /* Column */ 0); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); - if (II != DebugLocInfo.DebugIdMap.end()) - return DebugLoc::get(II->second); - - // Add a new location entry. - unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; - - return DebugLoc::get(Id); - } + StringRef T = TypeD.getName(); + if (!T.empty()) + Type = T; + StringRef F = Unit.getFilename(); + if (!F.empty()) + File = F; + StringRef D = Unit.getDirectory(); + if (!D.empty()) + Dir = D; + return true; +} - /// getDISubprogram - Find subprogram that is enclosing this scope. - DISubprogram getDISubprogram(MDNode *Scope) { - DIDescriptor D(Scope); - if (D.isNull()) - return DISubprogram(); - - if (D.isCompileUnit()) - return DISubprogram(); - - if (D.isSubprogram()) - return DISubprogram(Scope); - - if (D.isLexicalBlock()) - return getDISubprogram(DILexicalBlock(Scope).getContext().getNode()); - +/// ExtractDebugLocation - Extract debug location information +/// from llvm.dbg.stoppoint intrinsic. +DebugLoc llvm::ExtractDebugLocation(DbgStopPointInst &SPI, + DebugLocTracker &DebugLocInfo) { + DebugLoc DL; + Value *Context = SPI.getContext(); + + // If this location is already tracked then use it. + DebugLocTuple Tuple(cast<MDNode>(Context), NULL, SPI.getLine(), + SPI.getColumn()); + DenseMap<DebugLocTuple, unsigned>::iterator II + = DebugLocInfo.DebugIdMap.find(Tuple); + if (II != DebugLocInfo.DebugIdMap.end()) + return DebugLoc::get(II->second); + + // Add a new location entry. + unsigned Id = DebugLocInfo.DebugLocations.size(); + DebugLocInfo.DebugLocations.push_back(Tuple); + DebugLocInfo.DebugIdMap[Tuple] = Id; + + return DebugLoc::get(Id); +} + +/// ExtractDebugLocation - Extract debug location information +/// from DILocation. +DebugLoc llvm::ExtractDebugLocation(DILocation &Loc, + DebugLocTracker &DebugLocInfo) { + DebugLoc DL; + MDNode *Context = Loc.getScope().getNode(); + MDNode *InlinedLoc = NULL; + if (!Loc.getOrigLocation().isNull()) + InlinedLoc = Loc.getOrigLocation().getNode(); + // If this location is already tracked then use it. + DebugLocTuple Tuple(Context, InlinedLoc, Loc.getLineNumber(), + Loc.getColumnNumber()); + DenseMap<DebugLocTuple, unsigned>::iterator II + = DebugLocInfo.DebugIdMap.find(Tuple); + if (II != DebugLocInfo.DebugIdMap.end()) + return DebugLoc::get(II->second); + + // Add a new location entry. + unsigned Id = DebugLocInfo.DebugLocations.size(); + DebugLocInfo.DebugLocations.push_back(Tuple); + DebugLocInfo.DebugIdMap[Tuple] = Id; + + return DebugLoc::get(Id); +} + +/// ExtractDebugLocation - Extract debug location information +/// from llvm.dbg.func_start intrinsic. +DebugLoc llvm::ExtractDebugLocation(DbgFuncStartInst &FSI, + DebugLocTracker &DebugLocInfo) { + DebugLoc DL; + Value *SP = FSI.getSubprogram(); + + DISubprogram Subprogram(cast<MDNode>(SP)); + unsigned Line = Subprogram.getLineNumber(); + DICompileUnit CU(Subprogram.getCompileUnit()); + + // If this location is already tracked then use it. + DebugLocTuple Tuple(CU.getNode(), NULL, Line, /* Column */ 0); + DenseMap<DebugLocTuple, unsigned>::iterator II + = DebugLocInfo.DebugIdMap.find(Tuple); + if (II != DebugLocInfo.DebugIdMap.end()) + return DebugLoc::get(II->second); + + // Add a new location entry. + unsigned Id = DebugLocInfo.DebugLocations.size(); + DebugLocInfo.DebugLocations.push_back(Tuple); + DebugLocInfo.DebugIdMap[Tuple] = Id; + + return DebugLoc::get(Id); +} + +/// getDISubprogram - Find subprogram that is enclosing this scope. +DISubprogram llvm::getDISubprogram(MDNode *Scope) { + DIDescriptor D(Scope); + if (D.isNull()) return DISubprogram(); - } - - /// getDICompositeType - Find underlying composite type. - DICompositeType getDICompositeType(DIType T) { - if (T.isNull()) - return DICompositeType(); - - if (T.isCompositeType()) - return DICompositeType(T.getNode()); - - if (T.isDerivedType()) - return getDICompositeType(DIDerivedType(T.getNode()).getTypeDerivedFrom()); - + + if (D.isCompileUnit()) + return DISubprogram(); + + if (D.isSubprogram()) + return DISubprogram(Scope); + + if (D.isLexicalBlock()) + return getDISubprogram(DILexicalBlock(Scope).getContext().getNode()); + + return DISubprogram(); +} + +/// getDICompositeType - Find underlying composite type. +DICompositeType llvm::getDICompositeType(DIType T) { + if (T.isNull()) return DICompositeType(); - } + + if (T.isCompositeType()) + return DICompositeType(T.getNode()); + + if (T.isDerivedType()) + return getDICompositeType(DIDerivedType(T.getNode()).getTypeDerivedFrom()); + + return DICompositeType(); } |