diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 8118a9d7aaf0..fd45f620dcd4 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2835,6 +2835,31 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::Tag Tag, return; } else if (isa(VD->getType())) Expr.push_back(llvm::dwarf::DW_OP_deref); + } else if (const RecordType *RT = dyn_cast(VD->getType())) { + // If VD is an anonymous union then Storage represents value for + // all union fields. + const RecordDecl *RD = cast(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(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. diff --git a/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp index 318c9c9e23f5..d75ce69d4c6c 100644 --- a/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp +++ b/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp @@ -21,26 +21,8 @@ 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]],