X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FDebugInfo.cpp;h=00a2eaadba350212f253028cd5bfe8a9587348e4;hb=494f8c6cfaa7443bc708f6006c70f37ca30ac765;hp=b050227bc8400e33f57f395b609ba81db496033a;hpb=b71541a2db814019c4c7a54fa3700b54b263489e;p=oota-llvm.git diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index b050227bc84..00a2eaadba3 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -39,6 +39,9 @@ DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) { DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) { } +DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) { +} + DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) { } @@ -65,7 +68,7 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = dyn_cast(DbgNode->getOperand(Elt))) + if (ConstantInt *CI = dyn_cast_or_null(DbgNode->getOperand(Elt))) return CI->getZExtValue(); return 0; @@ -130,7 +133,14 @@ MDNode *DIVariable::getInlinedAt() 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. @@ -140,6 +150,7 @@ bool DIDescriptor::isDerivedType() const { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: case dwarf::DW_TAG_reference_type: + case dwarf::DW_TAG_rvalue_reference_type: case dwarf::DW_TAG_const_type: case dwarf::DW_TAG_volatile_type: case dwarf::DW_TAG_restrict_type: @@ -256,9 +267,17 @@ bool DIDescriptor::isNameSpace() const { return DbgNode && getTag() == dwarf::DW_TAG_namespace; } +/// isLexicalBlockFile - Return true if the specified descriptor is a +/// lexical block with an extra file. +bool DIDescriptor::isLexicalBlockFile() const { + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() == 3); +} + /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { - return DbgNode && getTag() == dwarf::DW_TAG_lexical_block; + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() > 3); } /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. @@ -271,6 +290,10 @@ bool DIDescriptor::isEnumerator() const { return DbgNode && getTag() == dwarf::DW_TAG_enumerator; } +/// isObjCProperty - Return true if the specified tag is DW_TAG +bool DIDescriptor::isObjCProperty() const { + return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property; +} //===----------------------------------------------------------------------===// // Simple Descriptor Constructors and other Methods //===----------------------------------------------------------------------===// @@ -355,6 +378,19 @@ bool DICompileUnit::Verify() const { return true; } +/// Verify - Verify that an ObjC property is well formed. +bool DIObjCProperty::Verify() const { + if (!DbgNode) + return false; + unsigned Tag = getTag(); + if (Tag != dwarf::DW_TAG_APPLE_property) return false; + DIType Ty = getType(); + if (!Ty.Verify()) return false; + + // Don't worry about the rest of the strings for now. + return true; +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!DbgNode) @@ -364,11 +400,13 @@ bool DIType::Verify() const { unsigned Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type && - 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()) + Tag != dwarf::DW_TAG_reference_type && + Tag != dwarf::DW_TAG_rvalue_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; } @@ -464,6 +502,7 @@ bool DINameSpace::Verify() const { /// return base type size. uint64_t DIDerivedType::getOriginalTypeSize() const { unsigned Tag = getTag(); + if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || Tag == dwarf::DW_TAG_restrict_type) { @@ -472,7 +511,14 @@ uint64_t DIDerivedType::getOriginalTypeSize() const { // approach. if (!BaseType.isValid()) return getSizeInBits(); - if (BaseType.isDerivedType()) + // If this is a derived type, go ahead and get the base type, unless + // it's a reference then it's just the size of the field. Pointer types + // have no need of this since they're a different type of qualification + // on the type. + if (BaseType.getTag() == dwarf::DW_TAG_reference_type || + BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) + return getSizeInBits(); + else if (BaseType.isDerivedType()) return DIDerivedType(BaseType).getOriginalTypeSize(); else return BaseType.getSizeInBits(); @@ -481,6 +527,13 @@ uint64_t DIDerivedType::getOriginalTypeSize() const { return getSizeInBits(); } +/// getObjCProperty - Return property node, if this ivar is associated with one. +MDNode *DIDerivedType::getObjCProperty() const { + if (getVersion() <= LLVMDebugVersion11 || DbgNode->getNumOperands() <= 10) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(10)); +} + /// isInlinedFnArgument - Return true if this variable provides debugging /// information for an inlined function arguments. bool DIVariable::isInlinedFnArgument(const Function *CurFn) { @@ -533,6 +586,8 @@ DIArray DISubprogram::getVariables() const { StringRef DIScope::getFilename() const { if (!DbgNode) return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getFilename(); if (isLexicalBlock()) return DILexicalBlock(DbgNode).getFilename(); if (isSubprogram()) @@ -545,13 +600,14 @@ StringRef DIScope::getFilename() const { return DIType(DbgNode).getFilename(); if (isFile()) return DIFile(DbgNode).getFilename(); - assert(0 && "Invalid DIScope!"); - return StringRef(); + llvm_unreachable("Invalid DIScope!"); } StringRef DIScope::getDirectory() const { if (!DbgNode) return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getDirectory(); if (isLexicalBlock()) return DILexicalBlock(DbgNode).getDirectory(); if (isSubprogram()) @@ -564,8 +620,7 @@ StringRef DIScope::getDirectory() const { return DIType(DbgNode).getDirectory(); if (isFile()) return DIFile(DbgNode).getDirectory(); - assert(0 && "Invalid DIScope!"); - return StringRef(); + llvm_unreachable("Invalid DIScope!"); } DIArray DICompileUnit::getEnumTypes() const { @@ -609,125 +664,169 @@ DIArray DICompileUnit::getGlobalVariables() const { return DIArray(); } +//===----------------------------------------------------------------------===// +// DIDescriptor: vtable anchors for all descriptors. +//===----------------------------------------------------------------------===// + +void DIScope::anchor() { } + +void DICompileUnit::anchor() { } + +void DIFile::anchor() { } + +void DIType::anchor() { } + +void DIBasicType::anchor() { } + +void DIDerivedType::anchor() { } + +void DICompositeType::anchor() { } + +void DISubprogram::anchor() { } + +void DILexicalBlock::anchor() { } + +void DINameSpace::anchor() { } + +void DILexicalBlockFile::anchor() { } + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// +/// dump - Print descriptor to dbgs() with a newline. +void DIDescriptor::dump() const { + print(dbgs()); dbgs() << '\n'; +} /// print - Print descriptor. void DIDescriptor::print(raw_ostream &OS) const { - OS << "[" << dwarf::TagString(getTag()) << "] "; - OS.write_hex((intptr_t) &*DbgNode) << ']'; + if (!DbgNode) return; + + OS << "[" << dwarf::TagString(getTag()) << ']'; + + if (this->isSubrange()) { + DISubrange(DbgNode).printInternal(OS); + } else if (this->isScope()) { + DIScope(DbgNode).printInternal(OS); + } else if (this->isCompileUnit()) { + DICompileUnit(DbgNode).printInternal(OS); + } else if (this->isFile()) { + DIFile(DbgNode).printInternal(OS); + } else if (this->isEnumerator()) { + DIEnumerator(DbgNode).printInternal(OS); + } else if (this->isBasicType()) { + DIType(DbgNode).printInternal(OS); + } else if (this->isDerivedType()) { + DIDerivedType(DbgNode).printInternal(OS); + } else if (this->isCompositeType()) { + DICompositeType(DbgNode).printInternal(OS); + } else if (this->isSubprogram()) { + DISubprogram(DbgNode).printInternal(OS); + } else if (this->isGlobalVariable()) { + DIGlobalVariable(DbgNode).printInternal(OS); + } else if (this->isVariable()) { + DIVariable(DbgNode).printInternal(OS); + } +} + +void DISubrange::printInternal(raw_ostream &OS) const { + OS << " [" << getLo() << ", " << getHi() << ']'; +} + +void DIScope::printInternal(raw_ostream &OS) const { + OS << " [" << getDirectory() << "/" << getFilename() << ']'; } -/// print - Print compile unit. -void DICompileUnit::print(raw_ostream &OS) const { - if (getLanguage()) - OS << " [" << dwarf::LanguageString(getLanguage()) << "] "; +void DICompileUnit::printInternal(raw_ostream &OS) const { + DIScope::printInternal(OS); + if (unsigned Lang = getLanguage()) + OS << " [" << dwarf::LanguageString(Lang) << ']'; +} - OS << " [" << getDirectory() << "/" << getFilename() << "]"; +void DIEnumerator::printInternal(raw_ostream &OS) const { + OS << " [" << getName() << " :: " << getEnumValue() << ']'; } -/// print - Print type. -void DIType::print(raw_ostream &OS) const { +void DIType::printInternal(raw_ostream &OS) const { if (!DbgNode) return; StringRef Res = getName(); if (!Res.empty()) - OS << " [" << Res << "] "; + OS << " [" << Res << "]"; - unsigned Tag = getTag(); - OS << " [" << dwarf::TagString(Tag) << "] "; + // TODO: Print context? - // TODO : Print context - OS << " [" - << "line " << getLineNumber() << ", " - << getSizeInBits() << " bits, " - << getAlignInBits() << " bit alignment, " - << getOffsetInBits() << " bit offset" - << "] "; + OS << " [line " << getLineNumber() + << ", size " << getSizeInBits() + << ", align " << getAlignInBits() + << ", offset " << getOffsetInBits(); + if (isBasicType()) + OS << ", enc " + << dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()); + OS << "]"; if (isPrivate()) - OS << " [private] "; + OS << " [private]"; else if (isProtected()) - OS << " [protected] "; + OS << " [protected]"; if (isForwardDecl()) - OS << " [fwd] "; - - if (isBasicType()) - DIBasicType(DbgNode).print(OS); - else if (isDerivedType()) - DIDerivedType(DbgNode).print(OS); - else if (isCompositeType()) - DICompositeType(DbgNode).print(OS); - else { - OS << "Invalid DIType\n"; - return; - } - - OS << "\n"; -} - -/// print - Print basic type. -void DIBasicType::print(raw_ostream &OS) const { - OS << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; + OS << " [fwd]"; } -/// print - Print derived type. -void DIDerivedType::print(raw_ostream &OS) const { - OS << "\n\t Derived From: "; getTypeDerivedFrom().print(OS); +void DIDerivedType::printInternal(raw_ostream &OS) const { + DIType::printInternal(OS); + OS << " [from " << getTypeDerivedFrom().getName() << ']'; } -/// print - Print composite type. -void DICompositeType::print(raw_ostream &OS) const { +void DICompositeType::printInternal(raw_ostream &OS) const { + DIType::printInternal(OS); DIArray A = getTypeArray(); OS << " [" << A.getNumElements() << " elements]"; } -/// print - Print subprogram. -void DISubprogram::print(raw_ostream &OS) const { +void DISubprogram::printInternal(raw_ostream &OS) const { StringRef Res = getName(); if (!Res.empty()) - OS << " [" << Res << "] "; - - unsigned Tag = getTag(); - OS << " [" << dwarf::TagString(Tag) << "] "; + OS << " [" << Res << ']'; // TODO : Print context - OS << " [" << getLineNumber() << "] "; + + OS << " [line " << getLineNumber() << ']'; if (isLocalToUnit()) - OS << " [local] "; + OS << " [local]"; if (isDefinition()) - OS << " [def] "; + OS << " [def]"; - OS << "\n"; + if (getScopeLineNumber() != getLineNumber()) + OS << " [scope " << getScopeLineNumber() << "]"; } -/// print - Print global variable. -void DIGlobalVariable::print(raw_ostream &OS) const { - OS << " ["; +void DIGlobalVariable::printInternal(raw_ostream &OS) const { StringRef Res = getName(); if (!Res.empty()) - OS << " [" << Res << "] "; + OS << " [" << Res << ']'; - unsigned Tag = getTag(); - OS << " [" << dwarf::TagString(Tag) << "] "; + OS << " [line " << getLineNumber() << ']'; // TODO : Print context - OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) - OS << " [local] "; + OS << " [local]"; if (isDefinition()) - OS << " [def] "; + OS << " [def]"; +} - if (isGlobalVariable()) - DIGlobalVariable(DbgNode).print(OS); - OS << "]\n"; +void DIVariable::printInternal(raw_ostream &OS) const { + StringRef Res = getName(); + if (!Res.empty()) + OS << " [" << Res << ']'; + + OS << " [line " << getLineNumber() << ']'; } static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, @@ -766,64 +865,6 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } -/// print - Print variable. -void DIVariable::print(raw_ostream &OS) const { - StringRef Res = getName(); - if (!Res.empty()) - OS << " [" << Res << "] "; - - OS << " [" << getLineNumber() << "] "; - getType().print(OS); - OS << "\n"; - - // FIXME: Dump complex addresses -} - -/// dump - Print descriptor to dbgs() with a newline. -void DIDescriptor::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print compile unit to dbgs() with a newline. -void DICompileUnit::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print type to dbgs() with a newline. -void DIType::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print basic type to dbgs() with a newline. -void DIBasicType::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print derived type to dbgs() with a newline. -void DIDerivedType::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print composite type to dbgs() with a newline. -void DICompositeType::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print subprogram to dbgs() with a newline. -void DISubprogram::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print global variable. -void DIGlobalVariable::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// dump - Print variable. -void DIVariable::dump() const { - print(dbgs()); dbgs() << '\n'; -} - /// fixupObjcLikeName - Replace contains special characters used /// in a typical Objective-C names with '.' in a given string. static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) { @@ -905,6 +946,31 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { /// 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) { + DICompileUnit CU(CU_Nodes->getOperand(i)); + addCompileUnit(CU); + if (CU.getVersion() > LLVMDebugVersion10) { + DIArray GVs = CU.getGlobalVariables(); + for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { + DIGlobalVariable DIG(GVs.getElement(i)); + if (addGlobalVariable(DIG)) + processType(DIG.getType()); + } + DIArray SPs = CU.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) + processSubprogram(DISubprogram(SPs.getElement(i))); + DIArray EnumTypes = CU.getEnumTypes(); + for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) + processType(DIType(EnumTypes.getElement(i))); + DIArray RetainedTypes = CU.getRetainedTypes(); + for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) + processType(DIType(RetainedTypes.getElement(i))); + return; + } + } + } + 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; @@ -923,6 +989,10 @@ void DebugInfoFinder::processModule(Module &M) { addCompileUnit(DICompileUnit(Scope)); else if (Scope.isSubprogram()) processSubprogram(DISubprogram(Scope)); + else if (Scope.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Scope); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } else if (Scope.isLexicalBlock()) processLexicalBlock(DILexicalBlock(Scope)); @@ -934,7 +1004,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()); } } @@ -955,6 +1026,10 @@ void DebugInfoFinder::processLocation(DILocation Loc) { processSubprogram(DISubprogram(S)); else if (S.isLexicalBlock()) processLexicalBlock(DILexicalBlock(S)); + else if (S.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(S); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } processLocation(Loc.getOrigLocation()); } @@ -962,8 +1037,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()); @@ -986,6 +1061,10 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { DIScope Context = LB.getContext(); if (Context.isLexicalBlock()) return processLexicalBlock(DILexicalBlock(Context)); + else if (Context.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Context); + return processLexicalBlock(DILexicalBlock(DBF.getScope())); + } else return processSubprogram(DISubprogram(Context)); } @@ -994,7 +1073,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()); } @@ -1009,8 +1089,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()); } @@ -1068,6 +1148,9 @@ DISubprogram llvm::getDISubprogram(const MDNode *Scope) { if (D.isSubprogram()) return DISubprogram(Scope); + if (D.isLexicalBlockFile()) + return getDISubprogram(DILexicalBlockFile(Scope).getContext()); + if (D.isLexicalBlock()) return getDISubprogram(DILexicalBlock(Scope).getContext());