summaryrefslogtreecommitdiff
path: root/lib/IR
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-09-13 01:12:59 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-09-13 01:12:59 +0000
commit5420de3f15e01ad9dfb05b08e2600ccff10c5817 (patch)
tree1f35fb90b9c4d1b953d7f3ec837625a2a0bdce23 /lib/IR
parent8d684cae12593b494408a95774f03c812b5b37ed (diff)
DebugInfo: New metadata representation for global variables.
This patch reverses the edge from DIGlobalVariable to GlobalVariable. This will allow us to more easily preserve debug info metadata when manipulating global variables. Fixes PR30362. A program for upgrading test cases is attached to that bug. Differential Revision: http://reviews.llvm.org/D20147 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281284 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/AsmWriter.cpp2
-rw-r--r--lib/IR/DIBuilder.cpp8
-rw-r--r--lib/IR/DebugInfoMetadata.cpp6
-rw-r--r--lib/IR/LLVMContextImpl.h12
-rw-r--r--lib/IR/Metadata.cpp27
-rw-r--r--lib/IR/Verifier.cpp8
6 files changed, 45 insertions, 18 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index bcb5f198853..0734a3772e3 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -1816,7 +1816,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
Printer.printMetadata("type", N->getRawType());
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
- Printer.printMetadata("variable", N->getRawVariable());
+ Printer.printMetadata("expr", N->getExpr());
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Out << ")";
}
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index 21cedeee78d..1adf9288e25 100644
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
@@ -535,13 +535,13 @@ static void checkGlobalVariableScope(DIScope *Context) {
DIGlobalVariable *DIBuilder::createGlobalVariable(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
- unsigned LineNumber, DIType *Ty, bool isLocalToUnit, Constant *Val,
+ unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
MDNode *Decl) {
checkGlobalVariableScope(Context);
auto *N = DIGlobalVariable::getDistinct(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, true, Val,
+ LineNumber, Ty, isLocalToUnit, true, Expr,
cast_or_null<DIDerivedType>(Decl));
AllGVs.push_back(N);
return N;
@@ -549,13 +549,13 @@ DIGlobalVariable *DIBuilder::createGlobalVariable(
DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
- unsigned LineNumber, DIType *Ty, bool isLocalToUnit, Constant *Val,
+ unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
MDNode *Decl) {
checkGlobalVariableScope(Context);
return DIGlobalVariable::getTemporary(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, false, Val,
+ LineNumber, Ty, isLocalToUnit, false, Expr,
cast_or_null<DIDerivedType>(Decl))
.release();
}
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp
index 208fa9bf9df..74f8ce84db0 100644
--- a/lib/IR/DebugInfoMetadata.cpp
+++ b/lib/IR/DebugInfoMetadata.cpp
@@ -551,6 +551,7 @@ unsigned DIExpression::ExprOperand::getSize() const {
switch (getOp()) {
case dwarf::DW_OP_bit_piece:
return 3;
+ case dwarf::DW_OP_constu:
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
return 2;
@@ -570,8 +571,11 @@ bool DIExpression::isValid() const {
default:
return false;
case dwarf::DW_OP_bit_piece:
- // Piece expressions must be at the end.
+ case dwarf::DW_OP_stack_value:
+ // We only support bit piece and stack value expressions which appear at
+ // the end.
return I->get() + I->getSize() == E->get();
+ case dwarf::DW_OP_constu:
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
case dwarf::DW_OP_deref:
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index 1d0b1b1524a..40935d9331e 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -758,23 +758,23 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
Metadata *Type;
bool IsLocalToUnit;
bool IsDefinition;
- Metadata *Variable;
+ Metadata *Expr;
Metadata *StaticDataMemberDeclaration;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Expr,
Metadata *StaticDataMemberDeclaration)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
- IsDefinition(IsDefinition), Variable(Variable),
+ IsDefinition(IsDefinition), Expr(Expr),
StaticDataMemberDeclaration(StaticDataMemberDeclaration) {}
MDNodeKeyImpl(const DIGlobalVariable *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
- Variable(N->getRawVariable()),
+ Expr(N->getRawExpr()),
StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()) {}
bool isKeyOf(const DIGlobalVariable *RHS) const {
@@ -783,13 +783,13 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
File == RHS->getRawFile() && Line == RHS->getLine() &&
Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
IsDefinition == RHS->isDefinition() &&
- Variable == RHS->getRawVariable() &&
+ Expr == RHS->getRawExpr() &&
StaticDataMemberDeclaration ==
RHS->getRawStaticDataMemberDeclaration();
}
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
- IsLocalToUnit, IsDefinition, Variable,
+ IsLocalToUnit, IsDefinition, Expr,
StaticDataMemberDeclaration);
}
};
diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp
index ad95bff9e83..223326b715f 100644
--- a/lib/IR/Metadata.cpp
+++ b/lib/IR/Metadata.cpp
@@ -1424,6 +1424,21 @@ void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) {
*MDNode::get(getContext(), {NewOffsetMD, TypeId}));
continue;
}
+ // If an offset adjustment was specified we need to modify the DIExpression
+ // to prepend the adjustment:
+ // !DIExpression(DW_OP_plus, Offset, [original expr])
+ if (Offset != 0 && MD.first == LLVMContext::MD_dbg) {
+ DIGlobalVariable *GV = cast<DIGlobalVariable>(MD.second);
+ DIExpression *E = GV->getExpr();
+ ArrayRef<uint64_t> OrigElements;
+ if (E)
+ OrigElements = E->getElements();
+ std::vector<uint64_t> Elements(OrigElements.size() + 2);
+ Elements[0] = dwarf::DW_OP_plus;
+ Elements[1] = Offset;
+ std::copy(OrigElements.begin(), OrigElements.end(), Elements.begin() + 2);
+ GV->replaceExpr(DIExpression::get(getContext(), Elements));
+ }
addMetadata(MD.first, *MD.second);
}
}
@@ -1444,3 +1459,15 @@ void Function::setSubprogram(DISubprogram *SP) {
DISubprogram *Function::getSubprogram() const {
return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg));
}
+
+void GlobalVariable::addDebugInfo(DIGlobalVariable *GV) {
+ addMetadata(LLVMContext::MD_dbg, *GV);
+}
+
+void GlobalVariable::getDebugInfo(
+ SmallVectorImpl<DIGlobalVariable *> &GVs) const {
+ SmallVector<MDNode *, 1> MDs;
+ getMetadata(LLVMContext::MD_dbg, MDs);
+ for (MDNode *MD : MDs)
+ GVs.push_back(cast<DIGlobalVariable>(MD));
+}
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index ba7db85094e..32ead4f54ad 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -1112,12 +1112,8 @@ void Verifier::visitDIGlobalVariable(const DIGlobalVariable &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
AssertDI(!N.getName().empty(), "missing global variable name", &N);
- if (auto *V = N.getRawVariable()) {
- AssertDI(isa<ConstantAsMetadata>(V) &&
- !isa<Function>(cast<ConstantAsMetadata>(V)->getValue()),
- "invalid global variable ref", &N, V);
- visitConstantExprsRecursively(cast<ConstantAsMetadata>(V)->getValue());
- }
+ if (auto *V = N.getRawExpr())
+ AssertDI(isa<DIExpression>(V), "invalid expression location", &N, V);
if (auto *Member = N.getRawStaticDataMemberDeclaration()) {
AssertDI(isa<DIDerivedType>(Member),
"invalid static data member declaration", &N, Member);