X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FDebugInfo.cpp;h=aeb039ce71c19f57c4e1ea66cb8caf7d675b4023;hb=865375ca7f68e60c0234916dd6bb365bb674bddb;hp=b42e946f2ffa22941b05b97441470bc2226cf9e0;hpb=1a81d48bde36ccb4499695629b966e80cb85e260;p=oota-llvm.git diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index b42e946f2ff..aeb039ce71c 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -111,9 +111,17 @@ Function *DIDescriptor::getFunctionField(unsigned Elt) const { unsigned DIVariable::getNumAddrElements() const { if (getVersion() <= llvm::LLVMDebugVersion8) return DbgNode->getNumOperands()-6; - return DbgNode->getNumOperands()-7; + if (getVersion() == llvm::LLVMDebugVersion9) + return DbgNode->getNumOperands()-7; + return DbgNode->getNumOperands()-8; } +/// getInlinedAt - If this variable is inlined then return inline location. +MDNode *DIVariable::getInlinedAt() const { + if (getVersion() <= llvm::LLVMDebugVersion9) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(7)); +} //===----------------------------------------------------------------------===// // Predicates @@ -122,7 +130,14 @@ unsigned DIVariable::getNumAddrElements() const { /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { - return DbgNode && getTag() == dwarf::DW_TAG_base_type; + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_base_type: + case dwarf::DW_TAG_unspecified_type: + return true; + default: + return false; + } } /// isDerivedType - Return true if the specified tag is legal for DIDerivedType. @@ -320,6 +335,22 @@ void DIType::replaceAllUsesWith(MDNode *D) { } } +/// isUnsignedDIType - Return true if type encoding is unsigned. +bool DIType::isUnsignedDIType() { + DIDerivedType DTy(DbgNode); + if (DTy.Verify()) + return DTy.getTypeDerivedFrom().isUnsignedDIType(); + + DIBasicType BTy(DbgNode); + if (BTy.Verify()) { + unsigned Encoding = BTy.getEncoding(); + if (Encoding == dwarf::DW_ATE_unsigned || + Encoding == dwarf::DW_ATE_unsigned_char) + return true; + } + return false; +} + /// Verify - Verify that a compile unit is well formed. bool DICompileUnit::Verify() const { if (!DbgNode) @@ -335,7 +366,7 @@ bool DICompileUnit::Verify() const { bool DIType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; unsigned Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && @@ -343,6 +374,7 @@ bool DIType::Verify() const { Tag != dwarf::DW_TAG_reference_type && Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type && Tag != dwarf::DW_TAG_array_type && Tag != dwarf::DW_TAG_enumeration_type + && Tag != dwarf::DW_TAG_subroutine_type && getFilename().empty()) return false; return true; @@ -362,12 +394,9 @@ bool DIDerivedType::Verify() const { bool DICompositeType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) - return false; return true; } @@ -376,11 +405,7 @@ bool DISubprogram::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DICompositeType Ty = getType(); @@ -397,11 +422,7 @@ bool DIGlobalVariable::Verify() const { if (getDisplayName().empty()) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -419,10 +440,7 @@ bool DIVariable::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - if (!getCompileUnit().Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -446,8 +464,6 @@ bool DINameSpace::Verify() const { return false; if (getName().empty()) return false; - if (!getCompileUnit().Verify()) - return false; return true; } @@ -504,6 +520,23 @@ unsigned DISubprogram::isOptimized() const { return 0; } +MDNode *DISubprogram::getVariablesNodes() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return NULL; + if (MDNode *Temp = dyn_cast_or_null(DbgNode->getOperand(19))) + return dyn_cast_or_null(Temp->getOperand(0)); + return NULL; +} + +DIArray DISubprogram::getVariables() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return DIArray(); + if (MDNode *T = dyn_cast_or_null(DbgNode->getOperand(19))) + if (MDNode *A = dyn_cast_or_null(T->getOperand(0))) + return DIArray(A); + return DIArray(); +} + StringRef DIScope::getFilename() const { if (!DbgNode) return StringRef(); @@ -542,6 +575,47 @@ StringRef DIScope::getDirectory() const { return StringRef(); } +DIArray DICompileUnit::getEnumTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(10))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getRetainedTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(11))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getSubprograms() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(12))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + + +DIArray DICompileUnit::getGlobalVariables() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(13))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// @@ -573,7 +647,6 @@ void DIType::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << "line " << getLineNumber() << ", " << getSizeInBits() << " bits, " @@ -629,7 +702,6 @@ void DISubprogram::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -652,7 +724,6 @@ void DIGlobalVariable::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -666,13 +737,48 @@ void DIGlobalVariable::print(raw_ostream &OS) const { OS << "]\n"; } +static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, + const LLVMContext &Ctx) { + if (!DL.isUnknown()) { // Print source line info. + DIScope Scope(DL.getScope(Ctx)); + // Omit the directory, because it's likely to be long and uninteresting. + if (Scope.Verify()) + CommentOS << Scope.getFilename(); + else + CommentOS << ""; + CommentOS << ':' << DL.getLine(); + if (DL.getCol() != 0) + CommentOS << ':' << DL.getCol(); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); + if (!InlinedAtDL.isUnknown()) { + CommentOS << " @[ "; + printDebugLoc(InlinedAtDL, CommentOS, Ctx); + CommentOS << " ]"; + } + } +} + +void DIVariable::printExtendedName(raw_ostream &OS) const { + const LLVMContext &Ctx = DbgNode->getContext(); + StringRef Res = getName(); + if (!Res.empty()) + OS << Res << "," << getLineNumber(); + if (MDNode *InlinedAt = getInlinedAt()) { + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); + if (!InlinedAtDL.isUnknown()) { + OS << " @["; + printDebugLoc(InlinedAtDL, OS, Ctx); + OS << "]"; + } + } +} + /// print - Print variable. void DIVariable::print(raw_ostream &OS) const { StringRef Res = getName(); if (!Res.empty()) OS << " [" << Res << "] "; - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; getType().print(OS); OS << "\n"; @@ -744,22 +850,61 @@ static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) { /// getFnSpecificMDNode - Return a NameMDNode, if available, that is /// suitable to hold function specific information. -NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, StringRef FuncName) { +NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) { SmallString<32> Name = StringRef("llvm.dbg.lv."); - fixupObjcLikeName(FuncName, Name); - + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); return M.getNamedMetadata(Name.str()); } /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable /// to hold function specific information. -NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, StringRef FuncName) { +NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) { SmallString<32> Name = StringRef("llvm.dbg.lv."); - fixupObjcLikeName(FuncName, Name); - + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); + return M.getOrInsertNamedMetadata(Name.str()); } +/// createInlinedVariable - Create a new inlined variable based on current +/// variable. +/// @param DV Current Variable. +/// @param InlinedScope Location at current variable is inlined. +DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, + LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? Elts.push_back(InlinedScope) : + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} + +/// cleanseInlinedVariable - Remove inlined scope from the variable. +DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))): + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. @@ -767,6 +912,10 @@ NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, StringRef FuncName) { /// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { + if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) + addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i))); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; @@ -796,7 +945,8 @@ void DebugInfoFinder::processModule(Module &M) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIGlobalVariable DIG(cast(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { - addCompileUnit(DIG.getCompileUnit()); + if (DIG.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); } } @@ -824,8 +974,8 @@ void DebugInfoFinder::processLocation(DILocation Loc) { void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; - - addCompileUnit(DT.getCompileUnit()); + if (DT.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DT.getCompileUnit()); if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom()); @@ -856,7 +1006,8 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; - addCompileUnit(SP.getCompileUnit()); + if (SP.getVersion() <= LLVMDebugVersion10) + addCompileUnit(SP.getCompileUnit()); processType(SP.getType()); } @@ -871,8 +1022,8 @@ void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) { if (!NodesSeen.insert(DV)) return; - - addCompileUnit(DIVariable(N).getCompileUnit()); + if (DIVariable(N).getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIVariable(N).getCompileUnit()); processType(DIVariable(N).getType()); } @@ -946,3 +1097,17 @@ DICompositeType llvm::getDICompositeType(DIType T) { return DICompositeType(); } + +/// isSubprogramContext - Return true if Context is either a subprogram +/// or another context nested inside a subprogram. +bool llvm::isSubprogramContext(const MDNode *Context) { + if (!Context) + return false; + DIDescriptor D(Context); + if (D.isSubprogram()) + return true; + if (D.isType()) + return isSubprogramContext(DIType(Context).getContext()); + return false; +} +