aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DebugInfoMetadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/DebugInfoMetadata.cpp')
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp188
1 files changed, 168 insertions, 20 deletions
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index b9fc5261fefe..50799327c78a 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -15,6 +15,7 @@
#include "MetadataImpl.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -26,7 +27,7 @@ using namespace llvm;
namespace llvm {
// Use FS-AFDO discriminator.
cl::opt<bool> EnableFSDiscriminator(
- "enable-fs-discriminator", cl::Hidden, cl::init(false),
+ "enable-fs-discriminator", cl::Hidden,
cl::desc("Enable adding flow sensitive discriminators"));
} // namespace llvm
@@ -77,8 +78,8 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
Ops.push_back(Scope);
if (InlinedAt)
Ops.push_back(InlinedAt);
- return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column,
- Ops, ImplicitCode),
+ return storeImpl(new (Ops.size(), Storage) DILocation(
+ Context, Storage, Line, Column, Ops, ImplicitCode),
Storage, Context.pImpl->DILocations);
}
@@ -180,6 +181,7 @@ void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
CI = getUnsignedFromPrefixEncoding(
getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
}
+dwarf::Tag DINode::getTag() const { return (dwarf::Tag)SubclassData16; }
DINode::DIFlags DINode::getFlag(StringRef Flag) {
return StringSwitch<DIFlags>(Flag)
@@ -282,6 +284,7 @@ static bool isCanonical(const MDString *S) {
}
#endif
+dwarf::Tag GenericDINode::getTag() const { return (dwarf::Tag)SubclassData16; }
GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
MDString *Header,
ArrayRef<Metadata *> DwarfOps,
@@ -301,7 +304,7 @@ GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
// Use a nullptr for empty headers.
assert(isCanonical(Header) && "Expected canonical MDString");
Metadata *PreOps[] = {Header};
- return storeImpl(new (DwarfOps.size() + 1) GenericDINode(
+ return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
Context, Storage, Hash, Tag, PreOps, DwarfOps),
Storage, Context.pImpl->GenericDINodes);
}
@@ -326,20 +329,25 @@ void GenericDINode::recalculateHash() {
} \
} while (false)
#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
- return storeImpl(new (array_lengthof(OPS)) \
+ return storeImpl(new (array_lengthof(OPS), Storage) \
CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
- return storeImpl(new (0u) CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
+ return storeImpl(new (0u, Storage) \
+ CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
- return storeImpl(new (array_lengthof(OPS)) CLASS(Context, Storage, OPS), \
+ return storeImpl(new (array_lengthof(OPS), Storage) \
+ CLASS(Context, Storage, OPS), \
Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
- return storeImpl(new (NUM_OPS) \
+ return storeImpl(new (NUM_OPS, Storage) \
CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
Storage, Context.pImpl->CLASS##s)
+DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
StorageType Storage, bool ShouldCreate) {
auto *CountNode = ConstantAsMetadata::get(
@@ -450,6 +458,10 @@ DISubrange::BoundType DISubrange::getStride() const {
return BoundType();
}
+DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
+ Ops) {}
DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
Metadata *CountNode, Metadata *LB,
@@ -529,6 +541,13 @@ DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
return BoundType();
}
+DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
+ const APInt &Value, bool IsUnsigned,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
+ Value(Value) {
+ SubclassData32 = IsUnsigned;
+}
DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, MDString *Name,
StorageType Storage, bool ShouldCreate) {
@@ -580,6 +599,36 @@ DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
Ops);
}
+DIType *DIDerivedType::getClassType() const {
+ assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+ return cast_or_null<DIType>(getExtraData());
+}
+uint32_t DIDerivedType::getVBPtrOffset() const {
+ assert(getTag() == dwarf::DW_TAG_inheritance);
+ if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
+ return static_cast<uint32_t>(CI->getZExtValue());
+ return 0;
+}
+Constant *DIDerivedType::getStorageOffsetInBits() const {
+ assert(getTag() == dwarf::DW_TAG_member && isBitField());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+}
+
+Constant *DIDerivedType::getConstant() const {
+ assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+}
+Constant *DIDerivedType::getDiscriminantValue() const {
+ assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+}
DIDerivedType *DIDerivedType::getImpl(
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -701,6 +750,12 @@ DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,
return nullptr;
return Context.pImpl->DITypeMap->lookup(&Identifier);
}
+DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
+ DIFlags Flags, uint8_t CC,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
+ 0, 0, 0, Flags, Ops),
+ CC(CC) {}
DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
uint8_t CC, Metadata *TypeArray,
@@ -711,6 +766,12 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
}
+DIFile::DIFile(LLVMContext &C, StorageType Storage,
+ Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
+ ArrayRef<Metadata *> Ops)
+ : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
+ Checksum(CS), Source(Src) {}
+
// FIXME: Implement this string-enum correspondence with a .def file and macros,
// so that the association is explicit rather than implied.
static const char *ChecksumKindName[DIFile::CSK_Last] = {
@@ -746,9 +807,23 @@ DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
assert((!Source || isCanonical(*Source)) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));
Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr,
- Source.getValueOr(nullptr)};
+ Source.value_or(nullptr)};
DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
}
+DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
+ unsigned SourceLanguage, bool IsOptimized,
+ unsigned RuntimeVersion, unsigned EmissionKind,
+ uint64_t DWOId, bool SplitDebugInlining,
+ bool DebugInfoForProfiling, unsigned NameTableKind,
+ bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
+ : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
+ SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
+ RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId),
+ SplitDebugInlining(SplitDebugInlining),
+ DebugInfoForProfiling(DebugInfoForProfiling),
+ NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
+ assert(Storage != Uniqued);
+}
DICompileUnit *DICompileUnit::getImpl(
LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
@@ -775,7 +850,7 @@ DICompileUnit *DICompileUnit::getImpl(
Macros,
SysRoot,
SDK};
- return storeImpl(new (array_lengthof(Ops)) DICompileUnit(
+ return storeImpl(new (array_lengthof(Ops), Storage) DICompileUnit(
Context, Storage, SourceLanguage, IsOptimized,
RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
@@ -827,6 +902,30 @@ const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
}
return nullptr;
}
+DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned ScopeLine, unsigned VirtualIndex,
+ int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
+ ArrayRef<Metadata *> Ops)
+ : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
+ Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
+ ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
+ static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
+}
+DISubprogram::DISPFlags
+DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
+ unsigned Virtuality, bool IsMainSubprogram) {
+ // We're assuming virtuality is the low-order field.
+ static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
+ int(SPFlagPureVirtual) ==
+ int(dwarf::DW_VIRTUALITY_pure_virtual),
+ "Virtuality constant mismatch");
+ return static_cast<DISPFlags>(
+ (Virtuality & SPFlagVirtuality) |
+ (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
+ (IsDefinition ? SPFlagDefinition : SPFlagZero) |
+ (IsOptimized ? SPFlagOptimized : SPFlagZero) |
+ (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
+}
DISubprogram *DILocalScope::getSubprogram() const {
if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
@@ -881,27 +980,33 @@ DISubprogram *DISubprogram::getImpl(
unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
- Metadata *ThrownTypes, Metadata *Annotations, StorageType Storage,
- bool ShouldCreate) {
+ Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
+ assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DISubprogram,
(Scope, Name, LinkageName, File, Line, Type, ScopeLine,
ContainingType, VirtualIndex, ThisAdjustment, Flags,
SPFlags, Unit, TemplateParams, Declaration,
- RetainedNodes, ThrownTypes, Annotations));
- SmallVector<Metadata *, 12> Ops = {
+ RetainedNodes, ThrownTypes, Annotations,
+ TargetFuncName));
+ SmallVector<Metadata *, 13> Ops = {
File, Scope, Name, LinkageName,
Type, Unit, Declaration, RetainedNodes,
- ContainingType, TemplateParams, ThrownTypes, Annotations};
- if (!Annotations) {
+ ContainingType, TemplateParams, ThrownTypes, Annotations,
+ TargetFuncName};
+ if (!TargetFuncName) {
Ops.pop_back();
- if (!ThrownTypes) {
+ if (!Annotations) {
Ops.pop_back();
- if (!TemplateParams) {
+ if (!ThrownTypes) {
Ops.pop_back();
- if (!ContainingType)
+ if (!TemplateParams) {
Ops.pop_back();
+ if (!ContainingType)
+ Ops.pop_back();
+ }
}
}
}
@@ -915,6 +1020,10 @@ bool DISubprogram::describes(const Function *F) const {
assert(F && "Invalid function");
return F->getSubprogram() == this;
}
+DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID,
+ StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line,
@@ -940,6 +1049,10 @@ DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
}
+DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
+ bool ExportSymbols, ArrayRef<Metadata *> Ops)
+ : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops),
+ ExportSymbols(ExportSymbols) {}
DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, bool ExportSymbols,
StorageType Storage, bool ShouldCreate) {
@@ -950,6 +1063,11 @@ DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
}
+DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
+ unsigned LineNo, ArrayRef<Metadata *> Ops)
+ : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
+ Ops),
+ LineNo(LineNo) {}
DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *Decl, MDString *Name,
Metadata *File, unsigned LineNo,
@@ -961,6 +1079,10 @@ DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);
}
+DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
+ bool IsDecl, ArrayRef<Metadata *> Ops)
+ : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
+ LineNo(LineNo), IsDecl(IsDecl) {}
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros,
@@ -974,6 +1096,13 @@ DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
IncludePath, APINotesFile};
DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
}
+DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
+ StorageType Storage,
+ bool IsDefault,
+ ArrayRef<Metadata *> Ops)
+ : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
+ dwarf::DW_TAG_template_type_parameter, IsDefault,
+ Ops) {}
DITemplateTypeParameter *
DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
@@ -1039,6 +1168,11 @@ DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
}
+DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage,
+ signed Line, ArrayRef<Metadata *> Ops,
+ uint32_t AlignInBits)
+ : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
+ AlignInBits(AlignInBits) {}
Optional<uint64_t> DIVariable::getSizeInBits() const {
// This is used by the Verifier so be mindful of broken types.
const Metadata *RawType = getRawType();
@@ -1062,6 +1196,9 @@ Optional<uint64_t> DIVariable::getSizeInBits() const {
return None;
}
+DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Metadata *File, unsigned Line, StorageType Storage,
bool ShouldCreate) {
@@ -1078,6 +1215,12 @@ DIExpression *DIExpression::getImpl(LLVMContext &Context,
DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
}
+bool DIExpression::isEntryValue() const {
+ return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_LLVM_entry_value;
+}
+bool DIExpression::startsWithDeref() const {
+ return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
+}
unsigned DIExpression::ExprOperand::getSize() const {
uint64_t Op = getOp();
@@ -1439,7 +1582,7 @@ DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
//
// Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?.
Optional<FragmentInfo> FI = Expr->getFragmentInfo();
- unsigned DropUntilStackValue = FI.hasValue() ? 3 : 0;
+ unsigned DropUntilStackValue = FI ? 3 : 0;
ArrayRef<uint64_t> ExprOpsBeforeFragment =
Expr->getElements().drop_back(DropUntilStackValue);
bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&
@@ -1597,6 +1740,11 @@ DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
Metadata *Ops[] = {Variable, Expression};
DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops);
}
+DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
+ unsigned Line, unsigned Attributes,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
+ Line(Line), Attributes(Attributes) {}
DIObjCProperty *DIObjCProperty::getImpl(
LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,