diff options
Diffstat (limited to 'lib/Analysis/DebugInfo.cpp')
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 1199 |
1 files changed, 720 insertions, 479 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 9eecc33..7bb7e9b 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -18,12 +18,13 @@ #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/Dwarf.h" #include "llvm/Support/DebugLoc.h" -#include "llvm/Support/Streams.h" - +#include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace llvm::dwarf; @@ -32,18 +33,12 @@ using namespace llvm::dwarf; //===----------------------------------------------------------------------===// /// ValidDebugInfo - Return true if V represents valid debug info value. -bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) { - if (!V) - return false; - - GlobalVariable *GV = dyn_cast<GlobalVariable>(V->stripPointerCasts()); - if (!GV) - return false; - - if (!GV->hasInternalLinkage () && !GV->hasLinkOnceLinkage()) +/// FIXME : Add DIDescriptor.isValid() +bool DIDescriptor::ValidDebugInfo(MDNode *N, CodeGenOpt::Level OptLevel) { + if (!N) return false; - DIDescriptor DI(GV); + DIDescriptor DI(N); // Check current version. Allow Version6 for now. unsigned Version = DI.getVersion(); @@ -53,13 +48,13 @@ bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) { unsigned Tag = DI.getTag(); switch (Tag) { case DW_TAG_variable: - assert(DIVariable(GV).Verify() && "Invalid DebugInfo value"); + assert(DIVariable(N).Verify() && "Invalid DebugInfo value"); break; case DW_TAG_compile_unit: - assert(DICompileUnit(GV).Verify() && "Invalid DebugInfo value"); + assert(DICompileUnit(N).Verify() && "Invalid DebugInfo value"); break; case DW_TAG_subprogram: - assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); + assert(DISubprogram(N).Verify() && "Invalid DebugInfo value"); break; case DW_TAG_lexical_block: // FIXME: This interfers with the quality of generated code during @@ -74,84 +69,75 @@ bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) { return true; } -DIDescriptor::DIDescriptor(GlobalVariable *GV, unsigned RequiredTag) { - DbgGV = GV; - - // If this is non-null, check to see if the Tag matches. If not, set to null. - if (GV && getTag() != RequiredTag) - DbgGV = 0; -} +DIDescriptor::DIDescriptor(MDNode *N, unsigned RequiredTag) { + DbgNode = N; -const std::string & -DIDescriptor::getStringField(unsigned Elt, std::string &Result) const { - if (DbgGV == 0) { - Result.clear(); - return Result; + // If this is non-null, check to see if the Tag matches. If not, set to null. + if (N && getTag() != RequiredTag) { + DbgNode = 0; } +} - Constant *C = DbgGV->getInitializer(); - if (C == 0 || Elt >= C->getNumOperands()) { - Result.clear(); - return Result; - } +const char * +DIDescriptor::getStringField(unsigned Elt) const { + if (DbgNode == 0) + return NULL; - // Fills in the string if it succeeds - if (!GetConstantStringInfo(C->getOperand(Elt), Result)) - Result.clear(); + if (Elt < DbgNode->getNumElements()) + if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getElement(Elt))) + return MDS->getString().data(); - return Result; + return NULL; } uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { - if (DbgGV == 0) return 0; - - Constant *C = DbgGV->getInitializer(); - if (C == 0 || Elt >= C->getNumOperands()) + if (DbgNode == 0) return 0; - if (ConstantInt *CI = dyn_cast<ConstantInt>(C->getOperand(Elt))) - return CI->getZExtValue(); + if (Elt < DbgNode->getNumElements()) + if (ConstantInt *CI = dyn_cast<ConstantInt>(DbgNode->getElement(Elt))) + return CI->getZExtValue(); + return 0; } DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { - if (DbgGV == 0) return DIDescriptor(); - - Constant *C = DbgGV->getInitializer(); - if (C == 0 || Elt >= C->getNumOperands()) + if (DbgNode == 0) return DIDescriptor(); - C = C->getOperand(Elt); - return DIDescriptor(dyn_cast<GlobalVariable>(C->stripPointerCasts())); + if (Elt < DbgNode->getNumElements() && DbgNode->getElement(Elt)) + return DIDescriptor(dyn_cast<MDNode>(DbgNode->getElement(Elt))); + + return DIDescriptor(); } GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { - if (DbgGV == 0) return 0; - - Constant *C = DbgGV->getInitializer(); - if (C == 0 || Elt >= C->getNumOperands()) + if (DbgNode == 0) return 0; - C = C->getOperand(Elt); - return dyn_cast<GlobalVariable>(C->stripPointerCasts()); + if (Elt < DbgNode->getNumElements()) + return dyn_cast_or_null<GlobalVariable>(DbgNode->getElement(Elt)); + return 0; } //===----------------------------------------------------------------------===// -// Simple Descriptor Constructors and other Methods +// Predicates //===----------------------------------------------------------------------===// -// 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)) - DbgGV = 0; +/// 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; } -/// isDerivedType - Return true if the specified tag is legal for -/// DIDerivedType. -bool DIType::isDerivedType(unsigned Tag) { +/// isDerivedType - Return true if the specified tag is legal for DIDerivedType. +bool DIDescriptor::isDerivedType() const { + assert (!isNull() && "Invalid descriptor!"); + unsigned Tag = getTag(); + switch (Tag) { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: @@ -163,16 +149,18 @@ bool DIType::isDerivedType(unsigned Tag) { case dwarf::DW_TAG_inheritance: return true; default: - // FIXME: Even though it doesn't make sense, CompositeTypes are current - // modelled as DerivedTypes, this should return true for them as well. - return false; + // CompositeTypes are currently modelled as DerivedTypes. + return isCompositeType(); } } /// isCompositeType - Return true if the specified tag is legal for /// DICompositeType. -bool DIType::isCompositeType(unsigned TAG) { - switch (TAG) { +bool DIDescriptor::isCompositeType() const { + assert (!isNull() && "Invalid descriptor!"); + unsigned Tag = getTag(); + + switch (Tag) { case dwarf::DW_TAG_array_type: case dwarf::DW_TAG_structure_type: case dwarf::DW_TAG_union_type: @@ -187,7 +175,10 @@ bool DIType::isCompositeType(unsigned TAG) { } /// isVariable - Return true if the specified tag is legal for DIVariable. -bool DIVariable::isVariable(unsigned Tag) { +bool DIDescriptor::isVariable() const { + assert (!isNull() && "Invalid descriptor!"); + unsigned Tag = getTag(); + switch (Tag) { case dwarf::DW_TAG_auto_variable: case dwarf::DW_TAG_arg_variable: @@ -198,19 +189,126 @@ bool DIVariable::isVariable(unsigned Tag) { } } +/// isType - Return true if the specified tag is legal for DIType. +bool DIDescriptor::isType() const { + return isBasicType() || isCompositeType() || isDerivedType(); +} + +/// 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; +} + +/// 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; +} + +/// isGlobal - Return true if the specified tag is legal for DIGlobal. +bool DIDescriptor::isGlobal() const { + return isGlobalVariable(); +} + +/// 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; + } + 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(); + + return Tag == dwarf::DW_TAG_compile_unit; +} + +/// 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; +} + +/// 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; +} + +/// 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; +} + +//===----------------------------------------------------------------------===// +// Simple Descriptor Constructors and other Methods +//===----------------------------------------------------------------------===// + +DIType::DIType(MDNode *N) : DIDescriptor(N) { + if (!N) return; + if (!isBasicType() && !isDerivedType() && !isCompositeType()) { + DbgNode = 0; + } +} + unsigned DIArray::getNumElements() const { - assert (DbgGV && "Invalid DIArray"); - Constant *C = DbgGV->getInitializer(); - assert (C && "Invalid DIArray initializer"); - return C->getNumOperands(); + assert (DbgNode && "Invalid DIArray"); + return DbgNode->getNumElements(); +} + +/// replaceAllUsesWith - Replace all uses of debug info referenced by +/// this descriptor. After this completes, the current debug info value +/// is erased. +void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) { + if (isNull()) + return; + + 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 + // which, due to uniquing, has merged with the source. We shield clients from + // this detail by allowing a value to be replaced with replaceAllUsesWith() + // itself. + if (getNode() != D.getNode()) { + MDNode *Node = DbgNode; + Node->replaceAllUsesWith(D.getNode()); + delete Node; + } } /// Verify - Verify that a compile unit is well formed. bool DICompileUnit::Verify() const { - if (isNull()) + if (isNull()) return false; - std::string Res; - if (getFilename(Res).empty()) + const char *N = getFilename(); + if (!N) return false; // It is possible that directory and produce string is empty. return true; @@ -218,26 +316,26 @@ bool DICompileUnit::Verify() const { /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { - if (isNull()) + if (isNull()) return false; - if (getContext().isNull()) + if (getContext().isNull()) return false; DICompileUnit CU = getCompileUnit(); - if (!CU.isNull() && !CU.Verify()) + if (!CU.isNull() && !CU.Verify()) return false; return true; } /// Verify - Verify that a composite type descriptor is well formed. bool DICompositeType::Verify() const { - if (isNull()) + if (isNull()) return false; - if (getContext().isNull()) + if (getContext().isNull()) return false; DICompileUnit CU = getCompileUnit(); - if (!CU.isNull() && !CU.Verify()) + if (!CU.isNull() && !CU.Verify()) return false; return true; } @@ -246,12 +344,12 @@ bool DICompositeType::Verify() const { bool DISubprogram::Verify() const { if (isNull()) return false; - + if (getContext().isNull()) return false; DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (!CU.Verify()) return false; DICompositeType Ty = getType(); @@ -264,12 +362,12 @@ bool DISubprogram::Verify() const { bool DIGlobalVariable::Verify() const { if (isNull()) return false; - + if (getContext().isNull()) return false; DICompileUnit CU = getCompileUnit(); - if (!CU.isNull() && !CU.Verify()) + if (!CU.isNull() && !CU.Verify()) return false; DIType Ty = getType(); @@ -286,7 +384,7 @@ bool DIGlobalVariable::Verify() const { bool DIVariable::Verify() const { if (isNull()) return false; - + if (getContext().isNull()) return false; @@ -312,15 +410,38 @@ uint64_t DIDerivedType::getOriginalTypeSize() const { /// information for the function F. bool DISubprogram::describes(const Function *F) { assert (F && "Invalid function"); - std::string Name; - getLinkageName(Name); - if (Name.empty()) - getName(Name); - if (!Name.empty() && (strcmp(Name.c_str(), F->getNameStart()) == false)) + const char *Name = getLinkageName(); + if (!Name) + Name = getName(); + if (strcmp(F->getName().data(), Name) == 0) return true; return false; } +const char *DIScope::getFilename() const { + if (isLexicalBlock()) + return DILexicalBlock(DbgNode).getFilename(); + else if (isSubprogram()) + return DISubprogram(DbgNode).getFilename(); + else if (isCompileUnit()) + return DICompileUnit(DbgNode).getFilename(); + else + assert (0 && "Invalid DIScope!"); + return NULL; +} + +const char *DIScope::getDirectory() const { + if (isLexicalBlock()) + return DILexicalBlock(DbgNode).getDirectory(); + else if (isSubprogram()) + return DISubprogram(DbgNode).getDirectory(); + else if (isCompileUnit()) + return DICompileUnit(DbgNode).getDirectory(); + else + assert (0 && "Invalid DIScope!"); + return NULL; +} + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// @@ -328,69 +449,67 @@ bool DISubprogram::describes(const Function *F) { /// dump - Print descriptor. void DIDescriptor::dump() const { - cerr << "[" << dwarf::TagString(getTag()) << "] "; - cerr << std::hex << "[GV:" << DbgGV << "]" << std::dec; + errs() << "[" << dwarf::TagString(getTag()) << "] "; + errs().write_hex((intptr_t) &*DbgNode) << ']'; } /// dump - Print compile unit. void DICompileUnit::dump() const { if (getLanguage()) - cerr << " [" << dwarf::LanguageString(getLanguage()) << "] "; + errs() << " [" << dwarf::LanguageString(getLanguage()) << "] "; - std::string Res1, Res2; - cerr << " [" << getDirectory(Res1) << "/" << getFilename(Res2) << " ]"; + errs() << " [" << getDirectory() << "/" << getFilename() << " ]"; } /// dump - Print type. void DIType::dump() const { if (isNull()) return; - std::string Res; - if (!getName(Res).empty()) - cerr << " [" << Res << "] "; + if (const char *Res = getName()) + errs() << " [" << Res << "] "; unsigned Tag = getTag(); - cerr << " [" << dwarf::TagString(Tag) << "] "; + errs() << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context getCompileUnit().dump(); - cerr << " [" - << getLineNumber() << ", " - << getSizeInBits() << ", " - << getAlignInBits() << ", " - << getOffsetInBits() - << "] "; - - if (isPrivate()) - cerr << " [private] "; + errs() << " [" + << getLineNumber() << ", " + << getSizeInBits() << ", " + << getAlignInBits() << ", " + << getOffsetInBits() + << "] "; + + if (isPrivate()) + errs() << " [private] "; else if (isProtected()) - cerr << " [protected] "; + errs() << " [protected] "; if (isForwardDecl()) - cerr << " [fwd] "; - - if (isBasicType(Tag)) - DIBasicType(DbgGV).dump(); - else if (isDerivedType(Tag)) - DIDerivedType(DbgGV).dump(); - else if (isCompositeType(Tag)) - DICompositeType(DbgGV).dump(); + errs() << " [fwd] "; + + if (isBasicType()) + DIBasicType(DbgNode).dump(); + else if (isDerivedType()) + DIDerivedType(DbgNode).dump(); + else if (isCompositeType()) + DICompositeType(DbgNode).dump(); else { - cerr << "Invalid DIType\n"; + errs() << "Invalid DIType\n"; return; } - cerr << "\n"; + errs() << "\n"; } /// dump - Print basic type. void DIBasicType::dump() const { - cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; + errs() << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; } /// dump - Print derived type. void DIDerivedType::dump() const { - cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump(); + errs() << "\n\t Derived From: "; getTypeDerivedFrom().dump(); } /// dump - Print composite type. @@ -398,54 +517,72 @@ void DICompositeType::dump() const { DIArray A = getTypeArray(); if (A.isNull()) return; - cerr << " [" << A.getNumElements() << " elements]"; + errs() << " [" << A.getNumElements() << " elements]"; } /// dump - Print global. void DIGlobal::dump() const { - std::string Res; - if (!getName(Res).empty()) - cerr << " [" << Res << "] "; + if (const char *Res = getName()) + errs() << " [" << Res << "] "; unsigned Tag = getTag(); - cerr << " [" << dwarf::TagString(Tag) << "] "; + errs() << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context getCompileUnit().dump(); - cerr << " [" << getLineNumber() << "] "; + errs() << " [" << getLineNumber() << "] "; if (isLocalToUnit()) - cerr << " [local] "; + errs() << " [local] "; if (isDefinition()) - cerr << " [def] "; + errs() << " [def] "; - if (isGlobalVariable(Tag)) - DIGlobalVariable(DbgGV).dump(); + if (isGlobalVariable()) + DIGlobalVariable(DbgNode).dump(); - cerr << "\n"; + errs() << "\n"; } /// dump - Print subprogram. void DISubprogram::dump() const { - DIGlobal::dump(); + if (const char *Res = getName()) + errs() << " [" << Res << "] "; + + unsigned Tag = getTag(); + errs() << " [" << dwarf::TagString(Tag) << "] "; + + // TODO : Print context + getCompileUnit().dump(); + errs() << " [" << getLineNumber() << "] "; + + if (isLocalToUnit()) + errs() << " [local] "; + + if (isDefinition()) + errs() << " [def] "; + + errs() << "\n"; } /// dump - Print global variable. void DIGlobalVariable::dump() const { - cerr << " ["; getGlobal()->dump(); cerr << "] "; + errs() << " ["; + getGlobal()->dump(); + errs() << "] "; } /// dump - Print variable. void DIVariable::dump() const { - std::string Res; - if (!getName(Res).empty()) - cerr << " [" << Res << "] "; + if (const char *Res = getName()) + errs() << " [" << Res << "] "; getCompileUnit().dump(); - cerr << " [" << getLineNumber() << "] "; + errs() << " [" << getLineNumber() << "] "; getType().dump(); - cerr << "\n"; + errs() << "\n"; + + // FIXME: Dump complex addresses } //===----------------------------------------------------------------------===// @@ -453,98 +590,46 @@ void DIVariable::dump() const { //===----------------------------------------------------------------------===// DIFactory::DIFactory(Module &m) - : M(m), StopPointFn(0), FuncStartFn(0), RegionStartFn(0), RegionEndFn(0), + : M(m), VMContext(M.getContext()), StopPointFn(0), FuncStartFn(0), + RegionStartFn(0), RegionEndFn(0), DeclareFn(0) { - EmptyStructPtr = PointerType::getUnqual(StructType::get()); -} - -/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'. -/// This is only valid when the descriptor is non-null. -Constant *DIFactory::getCastToEmpty(DIDescriptor D) { - if (D.isNull()) return Constant::getNullValue(EmptyStructPtr); - return ConstantExpr::getBitCast(D.getGV(), EmptyStructPtr); + EmptyStructPtr = PointerType::getUnqual(StructType::get(VMContext)); } Constant *DIFactory::GetTagConstant(unsigned TAG) { assert((TAG & LLVMDebugVersionMask) == 0 && "Tag too large for debug encoding!"); - return ConstantInt::get(Type::Int32Ty, TAG | LLVMDebugVersion); -} - -Constant *DIFactory::GetStringConstant(const std::string &String) { - // Check string cache for previous edition. - Constant *&Slot = StringCache[String]; - - // Return Constant if previously defined. - if (Slot) return Slot; - - const PointerType *DestTy = PointerType::getUnqual(Type::Int8Ty); - - // If empty string then use a i8* null instead. - if (String.empty()) - return Slot = ConstantPointerNull::get(DestTy); - - // Construct string as an llvm constant. - Constant *ConstStr = ConstantArray::get(String); - - // Otherwise create and return a new string global. - GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true, - GlobalVariable::InternalLinkage, - ConstStr, ".str", &M); - StrGV->setSection("llvm.metadata"); - return Slot = ConstantExpr::getBitCast(StrGV, DestTy); + return ConstantInt::get(Type::getInt32Ty(VMContext), TAG | LLVMDebugVersion); } //===----------------------------------------------------------------------===// // DIFactory: Primary Constructors //===----------------------------------------------------------------------===// -/// GetOrCreateArray - Create an descriptor for an array of descriptors. +/// GetOrCreateArray - Create an descriptor for an array of descriptors. /// This implicitly uniques the arrays created. DIArray DIFactory::GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys) { - SmallVector<Constant*, 16> Elts; - - for (unsigned i = 0; i != NumTys; ++i) - Elts.push_back(getCastToEmpty(Tys[i])); - - Constant *Init = ConstantArray::get(ArrayType::get(EmptyStructPtr, - Elts.size()), - Elts.data(), Elts.size()); - // If we already have this array, just return the uniqued version. - DIDescriptor &Entry = SimpleConstantCache[Init]; - if (!Entry.isNull()) return DIArray(Entry.getGV()); - - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.array", &M); - GV->setSection("llvm.metadata"); - Entry = DIDescriptor(GV); - return DIArray(GV); + SmallVector<Value*, 16> Elts; + + if (NumTys == 0) + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); + else + for (unsigned i = 0; i != NumTys; ++i) + Elts.push_back(Tys[i].getNode()); + + return DIArray(MDNode::get(VMContext,Elts.data(), Elts.size())); } /// GetOrCreateSubrange - Create a descriptor for a value range. This /// implicitly uniques the values returned. DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_subrange_type), - ConstantInt::get(Type::Int64Ty, Lo), - ConstantInt::get(Type::Int64Ty, Hi) + ConstantInt::get(Type::getInt64Ty(VMContext), Lo), + ConstantInt::get(Type::getInt64Ty(VMContext), Hi) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - // If we already have this range, just return the uniqued version. - DIDescriptor &Entry = SimpleConstantCache[Init]; - if (!Entry.isNull()) return DISubrange(Entry.getGV()); - - M.addTypeName("llvm.dbg.subrange.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.subrange", &M); - GV->setSection("llvm.metadata"); - Entry = DIDescriptor(GV); - return DISubrange(GV); + return DISubrange(MDNode::get(VMContext, &Elts[0], 3)); } @@ -552,92 +637,69 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) { /// CreateCompileUnit - Create a new descriptor for the specified compile /// unit. Note that this does not unique compile units within the module. DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, - const std::string &Filename, - const std::string &Directory, - const std::string &Producer, + StringRef Filename, + StringRef Directory, + StringRef Producer, bool isMain, bool isOptimized, const char *Flags, unsigned RunTimeVer) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_compile_unit), - Constant::getNullValue(EmptyStructPtr), - ConstantInt::get(Type::Int32Ty, LangID), - GetStringConstant(Filename), - GetStringConstant(Directory), - GetStringConstant(Producer), - ConstantInt::get(Type::Int1Ty, isMain), - ConstantInt::get(Type::Int1Ty, isOptimized), - GetStringConstant(Flags), - ConstantInt::get(Type::Int32Ty, RunTimeVer) + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), + ConstantInt::get(Type::getInt32Ty(VMContext), LangID), + MDString::get(VMContext, Filename), + MDString::get(VMContext, Directory), + MDString::get(VMContext, Producer), + ConstantInt::get(Type::getInt1Ty(VMContext), isMain), + ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), + MDString::get(VMContext, Flags), + ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.compile_unit.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::LinkOnceAnyLinkage, - Init, "llvm.dbg.compile_unit", &M); - GV->setSection("llvm.metadata"); - return DICompileUnit(GV); + + return DICompileUnit(MDNode::get(VMContext, &Elts[0], 10)); } /// CreateEnumerator - Create a single enumerator value. -DIEnumerator DIFactory::CreateEnumerator(const std::string &Name, uint64_t Val){ - Constant *Elts[] = { +DIEnumerator DIFactory::CreateEnumerator(StringRef Name, uint64_t Val){ + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_enumerator), - GetStringConstant(Name), - ConstantInt::get(Type::Int64Ty, Val) + MDString::get(VMContext, Name), + ConstantInt::get(Type::getInt64Ty(VMContext), Val) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.enumerator.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.enumerator", &M); - GV->setSection("llvm.metadata"); - return DIEnumerator(GV); + return DIEnumerator(MDNode::get(VMContext, &Elts[0], 3)); } /// CreateBasicType - Create a basic type like int, float, etc. DIBasicType DIFactory::CreateBasicType(DIDescriptor Context, - const std::string &Name, + StringRef Name, DICompileUnit CompileUnit, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, unsigned Encoding) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_base_type), - getCastToEmpty(Context), - GetStringConstant(Name), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNumber), - ConstantInt::get(Type::Int64Ty, SizeInBits), - ConstantInt::get(Type::Int64Ty, AlignInBits), - ConstantInt::get(Type::Int64Ty, OffsetInBits), - ConstantInt::get(Type::Int32Ty, Flags), - ConstantInt::get(Type::Int32Ty, Encoding) + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + ConstantInt::get(Type::getInt32Ty(VMContext), Encoding) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.basictype.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.basictype", &M); - GV->setSection("llvm.metadata"); - return DIBasicType(GV); + return DIBasicType(MDNode::get(VMContext, &Elts[0], 10)); } /// CreateDerivedType - Create a derived type like const qualified type, /// pointer, typedef, etc. DIDerivedType DIFactory::CreateDerivedType(unsigned Tag, DIDescriptor Context, - const std::string &Name, + StringRef Name, DICompileUnit CompileUnit, unsigned LineNumber, uint64_t SizeInBits, @@ -645,33 +707,25 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(Tag), - getCastToEmpty(Context), - GetStringConstant(Name), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNumber), - ConstantInt::get(Type::Int64Ty, SizeInBits), - ConstantInt::get(Type::Int64Ty, AlignInBits), - ConstantInt::get(Type::Int64Ty, OffsetInBits), - ConstantInt::get(Type::Int32Ty, Flags), - getCastToEmpty(DerivedFrom) + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + DerivedFrom.getNode(), }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.derivedtype.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.derivedtype", &M); - GV->setSection("llvm.metadata"); - return DIDerivedType(GV); + return DIDerivedType(MDNode::get(VMContext, &Elts[0], 10)); } /// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType DIFactory::CreateCompositeType(unsigned Tag, DIDescriptor Context, - const std::string &Name, + StringRef Name, DICompileUnit CompileUnit, unsigned LineNumber, uint64_t SizeInBits, @@ -682,143 +736,143 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag, DIArray Elements, unsigned RuntimeLang) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(Tag), - getCastToEmpty(Context), - GetStringConstant(Name), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNumber), - ConstantInt::get(Type::Int64Ty, SizeInBits), - ConstantInt::get(Type::Int64Ty, AlignInBits), - ConstantInt::get(Type::Int64Ty, OffsetInBits), - ConstantInt::get(Type::Int32Ty, Flags), - getCastToEmpty(DerivedFrom), - getCastToEmpty(Elements), - ConstantInt::get(Type::Int32Ty, RuntimeLang) + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + DerivedFrom.getNode(), + Elements.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.composite.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.composite", &M); - GV->setSection("llvm.metadata"); - return DICompositeType(GV); + return DICompositeType(MDNode::get(VMContext, &Elts[0], 12)); } /// CreateSubprogram - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. This /// method does not unique the generated descriptors. -DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, - const std::string &Name, - const std::string &DisplayName, - const std::string &LinkageName, +DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, + StringRef Name, + StringRef DisplayName, + StringRef LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, bool isDefinition) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_subprogram), - Constant::getNullValue(EmptyStructPtr), - getCastToEmpty(Context), - GetStringConstant(Name), - GetStringConstant(DisplayName), - GetStringConstant(LinkageName), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNo), - getCastToEmpty(Type), - ConstantInt::get(Type::Int1Ty, isLocalToUnit), - ConstantInt::get(Type::Int1Ty, isDefinition) + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), + Context.getNode(), + MDString::get(VMContext, Name), + MDString::get(VMContext, DisplayName), + MDString::get(VMContext, LinkageName), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + Type.getNode(), + ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), + ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition) }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.subprogram.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::LinkOnceAnyLinkage, - Init, "llvm.dbg.subprogram", &M); - GV->setSection("llvm.metadata"); - return DISubprogram(GV); + return DISubprogram(MDNode::get(VMContext, &Elts[0], 11)); } /// CreateGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable -DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name, - const std::string &DisplayName, - const std::string &LinkageName, +DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name, + StringRef DisplayName, + StringRef LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type,bool isLocalToUnit, bool isDefinition, llvm::GlobalVariable *Val) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_variable), - Constant::getNullValue(EmptyStructPtr), - getCastToEmpty(Context), - GetStringConstant(Name), - GetStringConstant(DisplayName), - GetStringConstant(LinkageName), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNo), - getCastToEmpty(Type), - ConstantInt::get(Type::Int1Ty, isLocalToUnit), - ConstantInt::get(Type::Int1Ty, isDefinition), - ConstantExpr::getBitCast(Val, EmptyStructPtr) + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), + Context.getNode(), + MDString::get(VMContext, Name), + MDString::get(VMContext, DisplayName), + MDString::get(VMContext, LinkageName), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + Type.getNode(), + ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), + ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), + Val }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.global_variable.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::LinkOnceAnyLinkage, - Init, "llvm.dbg.global_variable", &M); - GV->setSection("llvm.metadata"); - return DIGlobalVariable(GV); + + Value *const *Vs = &Elts[0]; + MDNode *Node = MDNode::get(VMContext,Vs, 12); + + // Create a named metadata so that we do not lose this mdnode. + NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); + NMD->addElement(Node); + + return DIGlobalVariable(Node); } /// CreateVariable - Create a new descriptor for the specified variable. DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context, - const std::string &Name, + StringRef Name, DICompileUnit CompileUnit, unsigned LineNo, DIType Type) { - Constant *Elts[] = { + Value *Elts[] = { GetTagConstant(Tag), - getCastToEmpty(Context), - GetStringConstant(Name), - getCastToEmpty(CompileUnit), - ConstantInt::get(Type::Int32Ty, LineNo), - getCastToEmpty(Type) + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + Type.getNode(), }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.variable.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.variable", &M); - GV->setSection("llvm.metadata"); - return DIVariable(GV); + return DIVariable(MDNode::get(VMContext, &Elts[0], 6)); +} + + +/// CreateComplexVariable - Create a new descriptor for the specified variable +/// which has a complex address expression for its address. +DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context, + const std::string &Name, + DICompileUnit CompileUnit, + unsigned LineNo, + DIType Type, SmallVector<Value *, 9> &addr) { + SmallVector<Value *, 9> Elts; + Elts.push_back(GetTagConstant(Tag)); + Elts.push_back(Context.getNode()); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(CompileUnit.getNode()); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)); + Elts.push_back(Type.getNode()); + Elts.insert(Elts.end(), addr.begin(), addr.end()); + + return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size())); } /// CreateBlock - This creates a descriptor for a lexical block with the -/// specified parent context. -DIBlock DIFactory::CreateBlock(DIDescriptor Context) { - Constant *Elts[] = { +/// specified parent VMContext. +DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) { + Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_lexical_block), - getCastToEmpty(Context) + Context.getNode() + }; + return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); +} + +/// CreateLocation - Creates a debug info location. +DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, + DIScope S, DILocation OrigLoc) { + Value *Elts[] = { + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo), + S.getNode(), + OrigLoc.getNode(), }; - - Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); - - M.addTypeName("llvm.dbg.block.type", Init->getType()); - GlobalVariable *GV = new GlobalVariable(Init->getType(), true, - GlobalValue::InternalLinkage, - Init, "llvm.dbg.block", &M); - GV->setSection("llvm.metadata"); - return DIBlock(GV); + return DILocation(MDNode::get(VMContext, &Elts[0], 4)); } @@ -830,17 +884,17 @@ DIBlock DIFactory::CreateBlock(DIDescriptor Context) { /// inserting it at the end of the specified basic block. void DIFactory::InsertStopPoint(DICompileUnit CU, unsigned LineNo, unsigned ColNo, BasicBlock *BB) { - + // Lazily construct llvm.dbg.stoppoint function. if (!StopPointFn) - StopPointFn = llvm::Intrinsic::getDeclaration(&M, + StopPointFn = llvm::Intrinsic::getDeclaration(&M, llvm::Intrinsic::dbg_stoppoint); - + // Invoke llvm.dbg.stoppoint Value *Args[] = { - llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo), - llvm::ConstantInt::get(llvm::Type::Int32Ty, ColNo), - getCastToEmpty(CU) + ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo), + ConstantInt::get(llvm::Type::getInt32Ty(VMContext), ColNo), + CU.getNode() }; CallInst::Create(StopPointFn, Args, Args+3, "", BB); } @@ -851,9 +905,9 @@ void DIFactory::InsertSubprogramStart(DISubprogram SP, BasicBlock *BB) { // Lazily construct llvm.dbg.func.start. if (!FuncStartFn) FuncStartFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_func_start); - + // Call llvm.dbg.func.start which also implicitly sets a stoppoint. - CallInst::Create(FuncStartFn, getCastToEmpty(SP), "", BB); + CallInst::Create(FuncStartFn, SP.getNode(), "", BB); } /// InsertRegionStart - Insert a new llvm.dbg.region.start intrinsic call to @@ -864,7 +918,7 @@ void DIFactory::InsertRegionStart(DIDescriptor D, BasicBlock *BB) { RegionStartFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_region_start); // Call llvm.dbg.func.start. - CallInst::Create(RegionStartFn, getCastToEmpty(D), "", BB); + CallInst::Create(RegionStartFn, D.getNode(), "", BB); } /// InsertRegionEnd - Insert a new llvm.dbg.region.end intrinsic call to @@ -875,19 +929,220 @@ void DIFactory::InsertRegionEnd(DIDescriptor D, BasicBlock *BB) { RegionEndFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_region_end); // Call llvm.dbg.region.end. - CallInst::Create(RegionEndFn, getCastToEmpty(D), "", BB); + CallInst::Create(RegionEndFn, D.getNode(), "", BB); } /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. -void DIFactory::InsertDeclare(Value *Storage, DIVariable D, BasicBlock *BB) { +void DIFactory::InsertDeclare(Value *Storage, DIVariable D, + Instruction *InsertBefore) { // Cast the storage to a {}* for the call to llvm.dbg.declare. - Storage = new BitCastInst(Storage, EmptyStructPtr, "", BB); - + Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertBefore); + if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = { Storage, getCastToEmpty(D) }; - CallInst::Create(DeclareFn, Args, Args+2, "", BB); + Value *Args[] = { Storage, D.getNode() }; + CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore); +} + +/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. +void DIFactory::InsertDeclare(Value *Storage, DIVariable D, + BasicBlock *InsertAtEnd) { + // Cast the storage to a {}* for the call to llvm.dbg.declare. + Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertAtEnd); + + if (!DeclareFn) + DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); + + Value *Args[] = { Storage, D.getNode() }; + CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); +} + + +//===----------------------------------------------------------------------===// +// DebugInfoFinder implementations. +//===----------------------------------------------------------------------===// + +/// processModule - Process entire module and collect debug info. +void DebugInfoFinder::processModule(Module &M) { + +#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN + MetadataContext &TheMetadata = M.getContext().getMetadata(); + unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); +#endif + 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; + ++BI) { + if (DbgStopPointInst *SPI = dyn_cast<DbgStopPointInst>(BI)) + processStopPoint(SPI); + else if (DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI)) + processFuncStart(FSI); + else if (DbgRegionStartInst *DRS = dyn_cast<DbgRegionStartInst>(BI)) + processRegionStart(DRS); + else if (DbgRegionEndInst *DRE = dyn_cast<DbgRegionEndInst>(BI)) + processRegionEnd(DRE); + else if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) + processDeclare(DDI); +#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN + else if (MDDbgKind) { + if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI)) { + DILocation Loc(L); + DIScope S(Loc.getScope().getNode()); + if (S.isCompileUnit()) + addCompileUnit(DICompileUnit(S.getNode())); + else if (S.isSubprogram()) + processSubprogram(DISubprogram(S.getNode())); + else if (S.isLexicalBlock()) + processLexicalBlock(DILexicalBlock(S.getNode())); + } + } +#endif + } + + 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))); + if (addGlobalVariable(DIG)) { + addCompileUnit(DIG.getCompileUnit()); + processType(DIG.getType()); + } + } +} + +/// processType - Process DIType. +void DebugInfoFinder::processType(DIType DT) { + if (!addType(DT)) + return; + + addCompileUnit(DT.getCompileUnit()); + if (DT.isCompositeType()) { + DICompositeType DCT(DT.getNode()); + processType(DCT.getTypeDerivedFrom()); + DIArray DA = DCT.getTypeArray(); + if (!DA.isNull()) + for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { + DIDescriptor D = DA.getElement(i); + DIType TypeE = DIType(D.getNode()); + if (!TypeE.isNull()) + processType(TypeE); + else + processSubprogram(DISubprogram(D.getNode())); + } + } else if (DT.isDerivedType()) { + DIDerivedType DDT(DT.getNode()); + if (!DDT.isNull()) + processType(DDT.getTypeDerivedFrom()); + } +} + +/// processLexicalBlock +void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { + if (LB.isNull()) + return; + DIScope Context = LB.getContext(); + if (Context.isLexicalBlock()) + return processLexicalBlock(DILexicalBlock(Context.getNode())); + else + return processSubprogram(DISubprogram(Context.getNode())); +} + +/// processSubprogram - Process DISubprogram. +void DebugInfoFinder::processSubprogram(DISubprogram SP) { + if (SP.isNull()) + return; + if (!addSubprogram(SP)) + return; + addCompileUnit(SP.getCompileUnit()); + processType(SP.getType()); +} + +/// processStopPoint - Process DbgStopPointInst. +void DebugInfoFinder::processStopPoint(DbgStopPointInst *SPI) { + MDNode *Context = dyn_cast<MDNode>(SPI->getContext()); + addCompileUnit(DICompileUnit(Context)); +} + +/// processFuncStart - Process DbgFuncStartInst. +void DebugInfoFinder::processFuncStart(DbgFuncStartInst *FSI) { + MDNode *SP = dyn_cast<MDNode>(FSI->getSubprogram()); + processSubprogram(DISubprogram(SP)); +} + +/// processRegionStart - Process DbgRegionStart. +void DebugInfoFinder::processRegionStart(DbgRegionStartInst *DRS) { + MDNode *SP = dyn_cast<MDNode>(DRS->getContext()); + processSubprogram(DISubprogram(SP)); +} + +/// processRegionEnd - Process DbgRegionEnd. +void DebugInfoFinder::processRegionEnd(DbgRegionEndInst *DRE) { + MDNode *SP = dyn_cast<MDNode>(DRE->getContext()); + processSubprogram(DISubprogram(SP)); +} + +/// processDeclare - Process DbgDeclareInst. +void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) { + DIVariable DV(cast<MDNode>(DDI->getVariable())); + if (DV.isNull()) + return; + + if (!NodesSeen.insert(DV.getNode())) + return; + + addCompileUnit(DV.getCompileUnit()); + processType(DV.getType()); +} + +/// addType - Add type into Tys. +bool DebugInfoFinder::addType(DIType DT) { + if (DT.isNull()) + return false; + + if (!NodesSeen.insert(DT.getNode())) + return false; + + TYs.push_back(DT.getNode()); + return true; +} + +/// addCompileUnit - Add compile unit into CUs. +bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { + if (CU.isNull()) + return false; + + if (!NodesSeen.insert(CU.getNode())) + return false; + + CUs.push_back(CU.getNode()); + return true; +} + +/// addGlobalVariable - Add global variable into GVs. +bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { + if (DIG.isNull()) + return false; + + if (!NodesSeen.insert(DIG.getNode())) + return false; + + GVs.push_back(DIG.getNode()); + return true; +} + +// addSubprogram - Add subprgoram into SPs. +bool DebugInfoFinder::addSubprogram(DISubprogram SP) { + if (SP.isNull()) + return false; + + if (!NodesSeen.insert(SP.getNode())) + return false; + + SPs.push_back(SP.getNode()); + return true; } namespace llvm { @@ -939,30 +1194,17 @@ namespace llvm { Value *findDbgGlobalDeclare(GlobalVariable *V) { const Module *M = V->getParent(); - const Type *Ty = M->getTypeByName("llvm.dbg.global_variable.type"); - if (!Ty) return 0; - - Ty = PointerType::get(Ty, 0); - - Value *Val = V->stripPointerCasts(); - for (Value::use_iterator I = Val->use_begin(), E = Val->use_end(); - I != E; ++I) { - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I)) { - if (CE->getOpcode() == Instruction::BitCast) { - Value *VV = CE; - - while (VV->hasOneUse()) - VV = *VV->use_begin(); + NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); + if (!NMD) + return 0; - if (VV->getType() == Ty) - return VV; - } - } + 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(); } - - if (Val->getType() == Ty) - return Val; - return 0; } @@ -990,8 +1232,8 @@ namespace llvm { return 0; } - bool getLocationInfo(const Value *V, std::string &DisplayName, - std::string &Type, unsigned &LineNo, std::string &File, +bool getLocationInfo(const Value *V, std::string &DisplayName, + std::string &Type, unsigned &LineNo, std::string &File, std::string &Dir) { DICompileUnit Unit; DIType TypeD; @@ -999,81 +1241,56 @@ namespace llvm { if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) { Value *DIGV = findDbgGlobalDeclare(GV); if (!DIGV) return false; - DIGlobalVariable Var(cast<GlobalVariable>(DIGV)); + DIGlobalVariable Var(cast<MDNode>(DIGV)); - Var.getDisplayName(DisplayName); + if (const char *D = Var.getDisplayName()) + DisplayName = D; LineNo = Var.getLineNumber(); Unit = Var.getCompileUnit(); TypeD = Var.getType(); } else { const DbgDeclareInst *DDI = findDbgDeclare(V); if (!DDI) return false; - DIVariable Var(cast<GlobalVariable>(DDI->getVariable())); + DIVariable Var(cast<MDNode>(DDI->getVariable())); - Var.getName(DisplayName); + if (const char *D = Var.getName()) + DisplayName = D; LineNo = Var.getLineNumber(); Unit = Var.getCompileUnit(); TypeD = Var.getType(); } - TypeD.getName(Type); - Unit.getFilename(File); - Unit.getDirectory(Dir); + if (const char *T = TypeD.getName()) + Type = T; + if (const char *F = Unit.getFilename()) + File = F; + if (const char *D = Unit.getDirectory()) + Dir = D; return true; } - /// CollectDebugInfoAnchors - Collect debugging information anchors. - void CollectDebugInfoAnchors(Module &M, - SmallVector<GlobalVariable *, 2> &CUs, - SmallVector<GlobalVariable *, 4> &GVs, - SmallVector<GlobalVariable *, 4> &SPs) { - - for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); - GVI != E; GVI++) { - GlobalVariable *GV = GVI; - if (GV->hasName() && strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0 - && GV->isConstant() && GV->hasInitializer()) { - DICompileUnit C(GV); - if (C.isNull() == false) { - CUs.push_back(GV); - continue; - } - DIGlobalVariable G(GV); - if (G.isNull() == false) { - GVs.push_back(GV); - continue; - } - DISubprogram S(GV); - if (S.isNull() == false) { - SPs.push_back(GV); - continue; - } - } - } - } - - /// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug + /// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug /// info intrinsic. - bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI, + bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI, CodeGenOpt::Level OptLev) { return DIDescriptor::ValidDebugInfo(SPI.getContext(), OptLev); } - /// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug + /// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug /// info intrinsic. bool isValidDebugInfoIntrinsic(DbgFuncStartInst &FSI, CodeGenOpt::Level OptLev) { return DIDescriptor::ValidDebugInfo(FSI.getSubprogram(), OptLev); } - /// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug + /// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug /// info intrinsic. bool isValidDebugInfoIntrinsic(DbgRegionStartInst &RSI, CodeGenOpt::Level OptLev) { return DIDescriptor::ValidDebugInfo(RSI.getContext(), OptLev); } - /// isValidDebugInfoIntrinsic - Return true if REI is a valid debug + /// isValidDebugInfoIntrinsic - Return true if REI is a valid debug /// info intrinsic. bool isValidDebugInfoIntrinsic(DbgRegionEndInst &REI, CodeGenOpt::Level OptLev) { @@ -1081,14 +1298,14 @@ namespace llvm { } - /// isValidDebugInfoIntrinsic - Return true if DI is a valid debug + /// isValidDebugInfoIntrinsic - Return true if DI is a valid debug /// info intrinsic. bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI, CodeGenOpt::Level OptLev) { return DIDescriptor::ValidDebugInfo(DI.getVariable(), OptLev); } - /// ExtractDebugLocation - Extract debug location information + /// ExtractDebugLocation - Extract debug location information /// from llvm.dbg.stoppoint intrinsic. DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI, DebugLocTracker &DebugLocInfo) { @@ -1096,7 +1313,7 @@ namespace llvm { Value *Context = SPI.getContext(); // If this location is already tracked then use it. - DebugLocTuple Tuple(cast<GlobalVariable>(Context), SPI.getLine(), + DebugLocTuple Tuple(cast<MDNode>(Context), NULL, SPI.getLine(), SPI.getColumn()); DenseMap<DebugLocTuple, unsigned>::iterator II = DebugLocInfo.DebugIdMap.find(Tuple); @@ -1107,23 +1324,48 @@ namespace llvm { 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 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 + /// 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<GlobalVariable>(SP)); + 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.getGV(), Line, /* Column */ 0); + DebugLocTuple Tuple(CU.getNode(), NULL, Line, /* Column */ 0); DenseMap<DebugLocTuple, unsigned>::iterator II = DebugLocInfo.DebugIdMap.find(Tuple); if (II != DebugLocInfo.DebugIdMap.end()) @@ -1133,13 +1375,13 @@ namespace llvm { unsigned Id = DebugLocInfo.DebugLocations.size(); DebugLocInfo.DebugLocations.push_back(Tuple); DebugLocInfo.DebugIdMap[Tuple] = Id; - + return DebugLoc::get(Id); } /// isInlinedFnStart - Return true if FSI is starting an inlined function. bool isInlinedFnStart(DbgFuncStartInst &FSI, const Function *CurrentFn) { - DISubprogram Subprogram(cast<GlobalVariable>(FSI.getSubprogram())); + DISubprogram Subprogram(cast<MDNode>(FSI.getSubprogram())); if (Subprogram.describes(CurrentFn)) return false; @@ -1148,11 +1390,10 @@ namespace llvm { /// isInlinedFnEnd - Return true if REI is ending an inlined function. bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn) { - DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext())); + DISubprogram Subprogram(cast<MDNode>(REI.getContext())); if (Subprogram.isNull() || Subprogram.describes(CurrentFn)) return false; return true; } - } |