diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2016-09-13 01:12:59 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-09-13 01:12:59 +0000 |
commit | 5420de3f15e01ad9dfb05b08e2600ccff10c5817 (patch) | |
tree | 1f35fb90b9c4d1b953d7f3ec837625a2a0bdce23 /lib/IR | |
parent | 8d684cae12593b494408a95774f03c812b5b37ed (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.cpp | 2 | ||||
-rw-r--r-- | lib/IR/DIBuilder.cpp | 8 | ||||
-rw-r--r-- | lib/IR/DebugInfoMetadata.cpp | 6 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 12 | ||||
-rw-r--r-- | lib/IR/Metadata.cpp | 27 | ||||
-rw-r--r-- | lib/IR/Verifier.cpp | 8 |
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); |