X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FDebugInfo.cpp;h=42b0dc0fc271b0cf1544b5b8ac66a47d269c395d;hb=f9e44c8bf8deb202e668a045c4e47f4ee312c66f;hp=c28dc693e7709bf9a6f773834ade5c4249e930a4;hpb=f652ec594e62eb5bce6bd297700be4aa495debde;p=oota-llvm.git diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index c28dc693e77..42b0dc0fc27 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" @@ -46,10 +47,9 @@ bool DIDescriptor::Verify() const { DILexicalBlockFile(DbgNode).Verify() || DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() || DIObjCProperty(DbgNode).Verify() || - DIUnspecifiedParameter(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() || DITemplateValueParameter(DbgNode).Verify() || - DIImportedEntity(DbgNode).Verify()); + DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify()); } static Value *getField(const MDNode *DbgNode, unsigned Elt) { @@ -138,23 +138,54 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { } } -uint64_t DIVariable::getAddrElement(unsigned Idx) const { - DIDescriptor ComplexExpr = getDescriptorField(8); - if (Idx < ComplexExpr->getNumOperands()) - if (auto *CI = dyn_cast_or_null(ComplexExpr->getOperand(Idx))) +/// getInlinedAt - If this variable is inlined then return inline location. +MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } + +/// Return the size reported by the variable's type. +unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) { + DIType Ty = getType().resolve(Map); + // Follow derived types until we reach a type that + // reports back a size. + while (Ty.isDerivedType() && !Ty.getSizeInBits()) { + DIDerivedType DT(&*Ty); + Ty = DT.getTypeDerivedFrom().resolve(Map); + } + assert(Ty.getSizeInBits() && "type with size 0"); + return Ty.getSizeInBits(); +} + +uint64_t DIExpression::getElement(unsigned Idx) const { + unsigned I = Idx + 1; + if (I < DbgNode->getNumOperands()) + if (auto *CI = dyn_cast_or_null(DbgNode->getOperand(I))) return CI->getZExtValue(); assert(false && "non-existing complex address element requested"); return 0; } -/// getInlinedAt - If this variable is inlined then return inline location. -MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } +bool DIExpression::isVariablePiece() const { + return getNumElements() && getElement(0) == dwarf::DW_OP_piece; +} + +uint64_t DIExpression::getPieceOffset() const { + assert(isVariablePiece()); + return getElement(1); +} + +uint64_t DIExpression::getPieceSize() const { + assert(isVariablePiece()); + return getElement(2); +} //===----------------------------------------------------------------------===// // Predicates //===----------------------------------------------------------------------===// +bool DIDescriptor::isSubroutineType() const { + return isCompositeType() && getTag() == dwarf::DW_TAG_subroutine_type; +} + /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { @@ -241,12 +272,6 @@ bool DIDescriptor::isGlobalVariable() const { getTag() == dwarf::DW_TAG_constant); } -/// isUnspecifiedParmeter - Return true if the specified tag is -/// DW_TAG_unspecified_parameters. -bool DIDescriptor::isUnspecifiedParameter() const { - return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters; -} - /// isScope - Return true if the specified tag is one of the scope /// related tag. bool DIDescriptor::isScope() const { @@ -298,7 +323,7 @@ bool DIDescriptor::isNameSpace() const { /// lexical block with an extra file. bool DIDescriptor::isLexicalBlockFile() const { return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() == 3); + (DbgNode->getNumOperands() == 4); } /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. @@ -329,19 +354,19 @@ bool DIDescriptor::isImportedEntity() const { getTag() == dwarf::DW_TAG_imported_declaration); } +/// \brief Return true if the specified tag is DW_TAG_imported_module or +/// DW_TAG_imported_declaration. +bool DIDescriptor::isExpression() const { + return DbgNode && (getTag() == dwarf::DW_TAG_expression); +} + //===----------------------------------------------------------------------===// // Simple Descriptor Constructors and other Methods //===----------------------------------------------------------------------===// -unsigned DIArray::getNumElements() const { - if (!DbgNode) - return 0; - return DbgNode->getNumOperands(); -} - /// replaceAllUsesWith - Replace all uses of the MDNode used by this /// type with the one in the passed descriptor. -void DIType::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { +void DIDescriptor::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { assert(DbgNode && "Trying to replace an unverified type!"); @@ -362,12 +387,12 @@ void DIType::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { const Value *V = cast_or_null(DN); Node->replaceAllUsesWith(const_cast(V)); MDNode::deleteTemporary(Node); - DbgNode = D; + DbgNode = DN; } /// replaceAllUsesWith - Replace all uses of the MDNode used by this /// type with the one in D. -void DIType::replaceAllUsesWith(MDNode *D) { +void DIDescriptor::replaceAllUsesWith(MDNode *D) { assert(DbgNode && "Trying to replace an unverified type!"); assert(DbgNode != D && "This replacement should always happen"); @@ -467,6 +492,7 @@ bool DIType::Verify() const { Tag != dwarf::DW_TAG_inheritance && Tag != dwarf::DW_TAG_friend && getFilename().empty()) return false; + // DIType is abstract, it should be a BasicType, a DerivedType or // a CompositeType. if (isBasicType()) @@ -573,12 +599,20 @@ bool DIVariable::Verify() const { if (!fieldIsTypeRef(DbgNode, 5)) return false; - // Variable without a complex expression. - if (DbgNode->getNumOperands() == 8) + // Variable without an inline location. + if (DbgNode->getNumOperands() == 7) return true; - // Make sure the complex expression is an MDNode. - return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8)); + return DbgNode->getNumOperands() == 8; +} + +/// Verify - Verify that a variable descriptor is well formed. +bool DIExpression::Verify() const { + // Empty DIExpressions may be represented as a nullptr. + if (!DbgNode) + return true; + + return isExpression(); } /// Verify - Verify that a location descriptor is well formed. @@ -616,17 +650,12 @@ bool DISubrange::Verify() const { /// \brief Verify that the lexical block descriptor is well formed. bool DILexicalBlock::Verify() const { - return isLexicalBlock() && DbgNode->getNumOperands() == 7; + return isLexicalBlock() && DbgNode->getNumOperands() == 6; } /// \brief Verify that the file-scoped lexical block descriptor is well formed. bool DILexicalBlockFile::Verify() const { - return isLexicalBlockFile() && DbgNode->getNumOperands() == 3; -} - -/// \brief Verify that an unspecified parameter descriptor is well formed. -bool DIUnspecifiedParameter::Verify() const { - return isUnspecifiedParameter() && DbgNode->getNumOperands() == 1; + return isLexicalBlockFile() && DbgNode->getNumOperands() == 4; } /// \brief Verify that the template type parameter descriptor is well formed. @@ -670,10 +699,7 @@ static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { #endif /// \brief Set the array of member DITypes. -void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) { - assert((!TParams || DbgNode->getNumOperands() == 15) && - "If you're setting the template parameters this should include a slot " - "for that!"); +void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) { TrackingVH N(*this); if (Elements) { #ifndef NDEBUG @@ -837,7 +863,7 @@ DIArray DICompileUnit::getImportedEntities() const { /// copyWithNewScope - Return a copy of this location, replacing the /// current scope with the given one. DILocation DILocation::copyWithNewScope(LLVMContext &Ctx, - DILexicalBlock NewScope) { + DILexicalBlockFile NewScope) { SmallVector Elts; assert(Verify()); for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) { @@ -1058,7 +1084,13 @@ void DebugInfoFinder::processType(DIType DT) { if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); - DIArray DA = DCT.getTypeArray(); + if (DT.isSubroutineType()) { + DITypeArray DTA = DISubroutineType(DT).getTypeArray(); + for (unsigned i = 0, e = DTA.getNumElements(); i != e; ++i) + processType(DTA.getElement(i).resolve(TypeIdentifierMap)); + return; + } + DIArray DA = DCT.getElements(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); if (D.isType()) @@ -1259,6 +1291,8 @@ void DIDescriptor::print(raw_ostream &OS) const { DINameSpace(DbgNode).printInternal(OS); } else if (this->isScope()) { DIScope(DbgNode).printInternal(OS); + } else if (this->isExpression()) { + DIExpression(DbgNode).printInternal(OS); } } @@ -1311,6 +1345,8 @@ void DIType::printInternal(raw_ostream &OS) const { OS << " [private]"; else if (isProtected()) OS << " [protected]"; + else if (isPublic()) + OS << " [public]"; if (isArtificial()) OS << " [artificial]"; @@ -1341,7 +1377,7 @@ void DIDerivedType::printInternal(raw_ostream &OS) const { void DICompositeType::printInternal(raw_ostream &OS) const { DIType::printInternal(OS); - DIArray A = getTypeArray(); + DIArray A = getElements(); OS << " [" << A.getNumElements() << " elements]"; } @@ -1370,6 +1406,8 @@ void DISubprogram::printInternal(raw_ostream &OS) const { OS << " [private]"; else if (isProtected()) OS << " [protected]"; + else if (isPublic()) + OS << " [public]"; if (isLValueReference()) OS << " [reference]"; @@ -1406,6 +1444,30 @@ void DIVariable::printInternal(raw_ostream &OS) const { OS << " [line " << getLineNumber() << ']'; } +void DIExpression::printInternal(raw_ostream &OS) const { + for (unsigned I = 0; I < getNumElements(); ++I) { + uint64_t OpCode = getElement(I); + OS << " [" << OperationEncodingString(OpCode); + switch (OpCode) { + case DW_OP_plus: { + OS << " " << getElement(++I); + break; + } + case DW_OP_piece: { + unsigned Offset = getElement(++I); + unsigned Size = getElement(++I); + OS << " offset=" << Offset << ", size=" << Size; + break; + } + default: + // Else bail out early. This may be a line table entry. + OS << "Unknown]"; + return; + } + OS << "]"; + } +} + void DIObjCProperty::printInternal(raw_ostream &OS) const { StringRef Name = getObjCPropertyName(); if (!Name.empty()) @@ -1527,8 +1589,9 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { return cast(Val)->getZExtValue(); } -llvm::DenseMap llvm::makeSubprogramMap(Module &M) { - DenseMap R; +llvm::DenseMap +llvm::makeSubprogramMap(const Module &M) { + DenseMap R; NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes)