]> granicus.if.org Git - clang/commitdiff
Debug Info: Represent local anonymous unions as anonymous unions
authorAdrian Prantl <aprantl@apple.com>
Tue, 28 Apr 2015 23:01:24 +0000 (23:01 +0000)
committerAdrian Prantl <aprantl@apple.com>
Tue, 28 Apr 2015 23:01:24 +0000 (23:01 +0000)
in the debug info. This patch deletes a hack that emits the members
of local anonymous unions as local variables.

Besides being morally wrong, the existing representation using local
variables breaks internal assumptions about the local variables' storage
size.

Compiling

```
   void fn1() {
     union {
       int i;
       char c;
     };
     i = c;
   }

```

with -g -O3 -verify will cause the verifier to fail after SROA splits
the 32-bit storage for the "local variable" c into two pieces because the
second piece is clearly outside the 8-bit range that is expected for a
variable of type char. Given the choice I'd rather fix the debug
representation than weaken the verifier.

Debuggers generally already know how to deal with anonymous unions when
they are members of C++ record types, but they may have problems finding
the local anonymous struct members in the expression evaluator.

rdar://problem/20730771

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236059 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
test/CodeGenCXX/debug-info-anon-union-vars.cpp

index fd45f620dcd44951a81b143851138dbe3b968500..8118a9d7aaf03a903b577ff346f598e7836880dc 100644 (file)
@@ -2835,31 +2835,6 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::Tag Tag,
       return;
     } else if (isa<VariableArrayType>(VD->getType()))
       Expr.push_back(llvm::dwarf::DW_OP_deref);
-  } else if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {
-    // If VD is an anonymous union then Storage represents value for
-    // all union fields.
-    const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
-    if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
-      for (const auto *Field : RD->fields()) {
-        llvm::MDType *FieldTy = getOrCreateType(Field->getType(), Unit);
-        StringRef FieldName = Field->getName();
-
-        // Ignore unnamed fields. Do not ignore unnamed records.
-        if (FieldName.empty() && !isa<RecordType>(Field->getType()))
-          continue;
-
-        // Use VarDecl's Tag, Scope and Line number.
-        auto *D = DBuilder.createLocalVariable(
-            Tag, Scope, FieldName, Unit, Line, FieldTy,
-            CGM.getLangOpts().Optimize, Flags, ArgNo);
-
-        // Insert an llvm.dbg.declare into the current block.
-        DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                               llvm::DebugLoc::get(Line, Column, Scope),
-                               Builder.GetInsertBlock());
-      }
-      return;
-    }
   }
 
   // Create the descriptor for the variable.
index d75ce69d4c6c026a263b287c1f8cb3e68dbef5f3..318c9c9e23f5b76f56220c3f482ec54df63b7cd9 100644 (file)
@@ -21,8 +21,26 @@ int test_it() {
   return (c == 1);
 }
 
+// This is not necessary (and actually harmful because it breaks IR assumptions)
+// for local variables.
+void foo() {
+  union {
+    int i;
+    char c;
+  };
+  i = 8;
+}
+
 // CHECK: [[FILE:.*]] = !MDFile(filename: "{{.*}}debug-info-anon-union-vars.cpp",
 // CHECK: !MDGlobalVariable(name: "c",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
 // CHECK: !MDGlobalVariable(name: "d",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
 // CHECK: !MDGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
 // CHECK: !MDGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: !MDLocalVariable(
+// CHECK-NOT: name:
+// CHECK: type: ![[UNION:[0-9]+]]
+// CHECK: ![[UNION]] = !MDCompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK: elements
+// CHECK: !MDDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
+// CHECK: !MDDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]],