[IR] Remove the DIExpression field from DIGlobalVariable.
This patch implements PR31013 by introducing a
DIGlobalVariableExpression that holds a pair of DIGlobalVariable and
DIExpression.
Currently, DIGlobalVariables holds a DIExpression. This is not the
best way to model this:
(1) The DIGlobalVariable should describe the source level variable,
not how to get to its location.
(2) It makes it unsafe/hard to update the expressions when we call
replaceExpression on the DIGLobalVariable.
(3) It makes it impossible to represent a global variable that is in
more than one location (e.g., a variable with multiple
DW_OP_LLVM_fragment-s). We also moved away from attaching the
DIExpression to DILocalVariable for the same reasons.
This reapplies r289902 with additional testcase upgrades and a change
to the Bitcode record for DIGlobalVariable, that makes upgrading the
old format unambiguous also for variables without DIExpressions.
<rdar://problem/29250149>
https://llvm.org/bugs/show_bug.cgi?id=31013
Differential Revision: https://reviews.llvm.org/D26769
llvm-svn: 290153
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index b0ba1c7..d6ea433 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -580,7 +580,6 @@
"Global variable initializer type does not match global "
"variable type!",
&GV);
-
// If the global has common linkage, it must have a zero initializer and
// cannot be constant.
if (GV.hasCommonLinkage()) {
@@ -646,6 +645,15 @@
GV.hasAvailableExternallyLinkage(),
"Global is marked as dllimport, but not external", &GV);
+ // Visit any debug info attachments.
+ SmallVector<MDNode *, 1> MDs;
+ GV.getMetadata(LLVMContext::MD_dbg, MDs);
+ for (auto *MD : MDs)
+ if (auto *GVE = dyn_cast<DIGlobalVariableExpression>(MD))
+ visitDIGlobalVariableExpression(*GVE);
+ else
+ AssertDI(false, "!dbg attachment of global variable must be a DIGlobalVariableExpression");
+
if (!GV.hasInitializer()) {
visitGlobalValue(GV);
return;
@@ -988,8 +996,8 @@
if (auto *Array = N.getRawGlobalVariables()) {
AssertDI(isa<MDTuple>(Array), "invalid global variable list", &N, Array);
for (Metadata *Op : N.getGlobalVariables()->operands()) {
- AssertDI(Op && isa<DIGlobalVariable>(Op), "invalid global variable ref",
- &N, Op);
+ AssertDI(Op && (isa<DIGlobalVariableExpression>(Op)),
+ "invalid global variable ref", &N, Op);
}
}
if (auto *Array = N.getRawImportedEntities()) {
@@ -1132,8 +1140,6 @@
AssertDI(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
AssertDI(!N.getName().empty(), "missing global variable name", &N);
- 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);
@@ -1153,6 +1159,15 @@
AssertDI(N.isValid(), "invalid expression", &N);
}
+void Verifier::visitDIGlobalVariableExpression(
+ const DIGlobalVariableExpression &GVE) {
+ AssertDI(GVE.getVariable(), "missing variable");
+ if (auto *Var = GVE.getVariable())
+ visitDIGlobalVariable(*Var);
+ if (auto *Expr = GVE.getExpression())
+ visitDIExpression(*Expr);
+}
+
void Verifier::visitDIObjCProperty(const DIObjCProperty &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_APPLE_property, "invalid tag", &N);
if (auto *T = N.getRawType())