summaryrefslogtreecommitdiff
path: root/lib/IR/DebugInfoMetadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/DebugInfoMetadata.cpp')
-rw-r--r--lib/IR/DebugInfoMetadata.cpp87
1 files changed, 69 insertions, 18 deletions
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp
index d14c6018d409..cdbe237766a3 100644
--- a/lib/IR/DebugInfoMetadata.cpp
+++ b/lib/IR/DebugInfoMetadata.cpp
@@ -15,6 +15,7 @@
#include "LLVMContextImpl.h"
#include "MetadataImpl.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
using namespace llvm;
@@ -214,6 +215,10 @@ void GenericDINode::recalculateHash() {
#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
return storeImpl(new (array_lengthof(OPS)) CLASS(Context, Storage, OPS), \
Storage, Context.pImpl->CLASS##s)
+#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
+ return storeImpl(new (NUM_OPS) \
+ CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
+ Storage, Context.pImpl->CLASS##s)
DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
StorageType Storage, bool ShouldCreate) {
@@ -441,21 +446,30 @@ DISubprogram *DISubprogram::getImpl(
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
- StorageType Storage, bool ShouldCreate) {
+ Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(
- DISubprogram,
- (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
- ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
- Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables));
- Metadata *Ops[] = {File, Scope, Name, Name,
- LinkageName, Type, ContainingType, Unit,
- TemplateParams, Declaration, Variables};
- DEFINE_GETIMPL_STORE(DISubprogram, (Line, ScopeLine, Virtuality, VirtualIndex,
- ThisAdjustment, Flags, IsLocalToUnit,
- IsDefinition, IsOptimized),
- Ops);
+ DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
+ TemplateParams, Declaration, Variables, ThrownTypes));
+ SmallVector<Metadata *, 11> Ops = {
+ File, Scope, Name, LinkageName, Type, Unit,
+ Declaration, Variables, ContainingType, TemplateParams, ThrownTypes};
+ if (!ThrownTypes) {
+ Ops.pop_back();
+ if (!TemplateParams) {
+ Ops.pop_back();
+ if (!ContainingType)
+ Ops.pop_back();
+ }
+ }
+ DEFINE_GETIMPL_STORE_N(DISubprogram,
+ (Line, ScopeLine, Virtuality, VirtualIndex,
+ ThisAdjustment, Flags, IsLocalToUnit, IsDefinition,
+ IsOptimized),
+ Ops, Ops.size());
}
bool DISubprogram::describes(const Function *F) const {
@@ -493,13 +507,13 @@ DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
}
DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
- Metadata *File, MDString *Name, unsigned Line,
- bool ExportSymbols, StorageType Storage,
- bool ShouldCreate) {
+ MDString *Name, bool ExportSymbols,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, File, Name, Line, ExportSymbols));
- Metadata *Ops[] = {File, Scope, Name};
- DEFINE_GETIMPL_STORE(DINamespace, (Line, ExportSymbols), Ops);
+ DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols));
+ // The nullptr is for DIScope's File operand. This should be refactored.
+ Metadata *Ops[] = {nullptr, Scope, Name};
+ DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
}
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope,
@@ -647,6 +661,43 @@ DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
return None;
}
+void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
+ int64_t Offset) {
+ if (Offset > 0) {
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Offset);
+ } else if (Offset < 0) {
+ Ops.push_back(dwarf::DW_OP_minus);
+ Ops.push_back(-Offset);
+ }
+}
+
+DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref,
+ int64_t Offset, bool StackValue) {
+ SmallVector<uint64_t, 8> Ops;
+ appendOffset(Ops, Offset);
+ if (Deref)
+ Ops.push_back(dwarf::DW_OP_deref);
+ if (Expr)
+ for (auto Op : Expr->expr_ops()) {
+ // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
+ if (StackValue) {
+ if (Op.getOp() == dwarf::DW_OP_stack_value)
+ StackValue = false;
+ else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
+ Ops.push_back(dwarf::DW_OP_stack_value);
+ StackValue = false;
+ }
+ }
+ Ops.push_back(Op.getOp());
+ for (unsigned I = 0; I < Op.getNumArgs(); ++I)
+ Ops.push_back(Op.getArg(I));
+ }
+ if (StackValue)
+ Ops.push_back(dwarf::DW_OP_stack_value);
+ return DIExpression::get(Expr->getContext(), Ops);
+}
+
bool DIExpression::isConstant() const {
// Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?.
if (getNumElements() != 3 && getNumElements() != 6)