StringRef Producer, bool isOptimized,
StringRef Flags, unsigned RunTimeVer,
StringRef SplitName,
- DebugEmissionKind Kind) {
+ DebugEmissionKind Kind,
+ bool EmitDebugInfo) {
assert(((Lang <= dwarf::DW_LANG_OCaml && Lang >= dwarf::DW_LANG_C89) ||
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
MDNode *CUNode = MDNode::get(VMContext, Elts);
// Create a named metadata so that it is easier to find cu in a module.
- NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
- NMD->addOperand(CUNode);
+ // Note that we only generate this when the caller wants to actually
+ // emit debug information. When we are only interested in tracking
+ // source line locations throughout the backend, we prevent codegen from
+ // emitting debug info in the final output by not generating llvm.dbg.cu.
+ if (EmitDebugInfo) {
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
+ NMD->addOperand(CUNode);
+ }
return DICompileUnit(CUNode);
}
}
/// createSubroutineType - Create subroutine type.
-DICompositeType DIBuilder::createSubroutineType(DIFile File,
- DIArray ParameterTypes,
- unsigned Flags) {
+DISubroutineType DIBuilder::createSubroutineType(DIFile File,
+ DITypeArray ParameterTypes,
+ unsigned Flags) {
// TAG_subroutine_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type),
nullptr,
nullptr // Type Identifer
};
- return DICompositeType(MDNode::get(VMContext, Elts));
+ return DISubroutineType(MDNode::get(VMContext, Elts));
}
/// createEnumerationType - Create debugging information entry for an
/// createUnspecifiedParameter - Create unspeicified type descriptor
/// for the subroutine type.
-DIDescriptor DIBuilder::createUnspecifiedParameter() {
- Value *Elts[] = {
- GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_parameters)
- };
- return DIDescriptor(MDNode::get(VMContext, Elts));
+DIBasicType DIBuilder::createUnspecifiedParameter() {
+ return DIBasicType();
}
/// createForwardDecl - Create a temporary forward-declared type that
UniqueIdentifier.empty() ? nullptr
: MDString::get(VMContext, UniqueIdentifier)
};
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ DICompositeType RetTy(Node);
+ assert(RetTy.isCompositeType() &&
+ "createForwardDecl result should be a DIType");
+ if (!UniqueIdentifier.empty())
+ retainType(RetTy);
+ return RetTy;
+}
+
+/// createForwardDecl - Create a temporary forward-declared type that
+/// can be RAUW'd if the full type is seen.
+DICompositeType DIBuilder::createReplaceableForwardDecl(
+ unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line,
+ unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
+ StringRef UniqueIdentifier) {
+ // Create a temporary MDNode.
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ F.getFileNode(),
+ DIScope(getNonCompileUnitScope(Scope)).getRef(),
+ MDString::get(VMContext, Name),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Line),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset
+ ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl),
+ nullptr,
+ DIArray(),
+ ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang),
+ nullptr,
+ nullptr, //TemplateParams
+ UniqueIdentifier.empty() ? nullptr
+ : MDString::get(VMContext, UniqueIdentifier)
+ };
MDNode *Node = MDNode::getTemporary(VMContext, Elts);
DICompositeType RetTy(Node);
assert(RetTy.isCompositeType() &&
return DIArray(MDNode::get(VMContext, Elements));
}
+/// getOrCreateTypeArray - Get a DITypeArray, create one if required.
+DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef<Value *> Elements) {
+ SmallVector<llvm::Value *, 16> Elts;
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+ if (Elements[i] && isa<MDNode>(Elements[i]))
+ Elts.push_back(DIType(cast<MDNode>(Elements[i])).getRef());
+ else
+ Elts.push_back(Elements[i]);
+ }
+ return DITypeArray(MDNode::get(VMContext, Elts));
+}
+
/// getOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned.
DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
DITypeRef Ty,
ArrayRef<Value *> Addr,
unsigned ArgNo) {
- SmallVector<Value *, 15> Elts;
- Elts.push_back(GetTagConstant(VMContext, Tag));
- Elts.push_back(getNonCompileUnitScope(Scope)),
- Elts.push_back(MDString::get(VMContext, Name));
- Elts.push_back(F);
- Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext),
- (LineNo | (ArgNo << 24))));
- Elts.push_back(Ty);
- Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
- Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
- Elts.append(Addr.begin(), Addr.end());
+ assert(Addr.size() > 0 && "complex address is empty");
+ Value *Elts[] = {
+ GetTagConstant(VMContext, Tag),
+ getNonCompileUnitScope(Scope),
+ MDString::get(VMContext, Name),
+ F,
+ ConstantInt::get(Type::getInt32Ty(VMContext),
+ (LineNo | (ArgNo << 24))),
+ Ty,
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ MDNode::get(VMContext, Addr)
+ };
+ return DIVariable(MDNode::get(VMContext, Elts));
+}
+
+/// createVariablePiece - Create a descriptor to describe one part
+/// of aggregate variable that is fragmented across multiple Values.
+DIVariable DIBuilder::createVariablePiece(DIVariable Variable,
+ unsigned OffsetInBytes,
+ unsigned SizeInBytes) {
+ assert(SizeInBytes > 0 && "zero-size piece");
+ Value *Addr[] = {
+ ConstantInt::get(Type::getInt32Ty(VMContext), OpPiece),
+ ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBytes),
+ ConstantInt::get(Type::getInt32Ty(VMContext), SizeInBytes)
+ };
+
+ assert((Variable->getNumOperands() == 8 || Variable.isVariablePiece()) &&
+ "variable already has a complex address");
+ SmallVector<Value *, 9> Elts;
+ for (unsigned i = 0; i < 8; ++i)
+ Elts.push_back(Variable->getOperand(i));
+ Elts.push_back(MDNode::get(VMContext, Addr));
return DIVariable(MDNode::get(VMContext, Elts));
}
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
"the compile unit.");
- Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
F.getFileNode(),
Fn,
TParam,
Constant::getNullValue(Type::getInt32Ty(VMContext)),
- MDNode::getTemporary(VMContext, TElts),
+ nullptr,
// FIXME: Do we want to use different scope/lines?
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
};
/// createLexicalBlockFile - This creates a new MDNode that encapsulates
/// an existing scope with a new filename.
DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
- DIFile File) {
+ DIFile File,
+ unsigned Discriminator) {
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
File.getFileNode(),
- Scope
+ Scope,
+ ConstantInt::get(Type::getInt32Ty(VMContext), Discriminator),
};
DILexicalBlockFile R(MDNode::get(VMContext, Elts));
assert(
}
DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
- unsigned Line, unsigned Col,
- unsigned Discriminator) {
+ unsigned Line, unsigned Col) {
+ // FIXME: This isn't thread safe nor the right way to defeat MDNode uniquing.
+ // I believe the right way is to have a self-referential element in the node.
+ // Also: why do we bother with line/column - they're not used and the
+ // documentation (SourceLevelDebugging.rst) claims the line/col are necessary
+ // for uniquing, yet then we have this other solution (because line/col were
+ // inadequate) anyway. Remove all 3 and replace them with a self-reference.
+
// Defeat MDNode uniquing for lexical blocks by using unique id.
static unsigned int unique_id = 0;
Value *Elts[] = {
getNonCompileUnitScope(Scope),
ConstantInt::get(Type::getInt32Ty(VMContext), Line),
ConstantInt::get(Type::getInt32Ty(VMContext), Col),
- ConstantInt::get(Type::getInt32Ty(VMContext), Discriminator),
ConstantInt::get(Type::getInt32Ty(VMContext), unique_id++)
};
DILexicalBlock R(MDNode::get(VMContext, Elts));