[clang] 488185c - [Clang][DebugInfo][AMDGPU] Emit zero size bitfields in the debug info to delimit bitfields in different allocation units.
Juan Manuel MARTINEZ CAAMAÑO via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 28 01:19:46 PDT 2023
Author: Juan Manuel MARTINEZ CAAMAÑO
Date: 2023-03-28T10:07:32+02:00
New Revision: 488185cca3871a0ef2ec3b9b4c642dc6db6eeea5
URL: https://github.com/llvm/llvm-project/commit/488185cca3871a0ef2ec3b9b4c642dc6db6eeea5
DIFF: https://github.com/llvm/llvm-project/commit/488185cca3871a0ef2ec3b9b4c642dc6db6eeea5.diff
LOG: [Clang][DebugInfo][AMDGPU] Emit zero size bitfields in the debug info to delimit bitfields in different allocation units.
Consider the following sturctures when targetting:
struct foo {
int space[4];
char a : 8;
char b : 8;
char x : 8;
char y : 8;
};
struct bar {
int space[4];
char a : 8;
char b : 8;
char : 0;
char x : 8;
char y : 8;
};
Even if both structs have the same layout in memory, they are handled
differenlty by the AMDGPU ABI.
With the following code:
// clang --target=amdgcn-amd-amdhsa -g -O1 example.c -S
char use_foo(struct foo f) { return f.y; }
char use_bar(struct bar b) { return b.y; }
For use_foo, the 'y' field is passed in v4
; v_ashrrev_i32_e32 v0, 24, v4
; s_setpc_b64 s[30:31]
For use_bar, the 'y' field is passed in v5
; v_bfe_i32 v0, v5, 8, 8
; s_setpc_b64 s[30:31]
To make this distinction, we record a single 0-size bitfield for every member that is preceded
by it.
Reviewed By: probinson
Differential Revision: https://reviews.llvm.org/D144870
Added:
clang/test/CodeGen/debug-info-bitfield-0-struct.c
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/CodeGen/TargetInfo.h
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0b4c24ac2555d..a5d2cf9650276 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -18,6 +18,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
+#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclFriend.h"
@@ -1483,9 +1484,9 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
return F;
}
-llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
- llvm::DIScope *RecordTy,
- const RecordDecl *RD) {
+llvm::DIDerivedType *
+CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
+ llvm::DIScope *RecordTy, const RecordDecl *RD) {
StringRef Name = BitFieldDecl->getName();
QualType Ty = BitFieldDecl->getType();
SourceLocation Loc = BitFieldDecl->getLocation();
@@ -1516,6 +1517,78 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
Flags, DebugType, Annotations);
}
+llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
+ const FieldDecl *BitFieldDecl, const llvm::DIDerivedType *BitFieldDI,
+ llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI, const RecordDecl *RD) {
+
+ if (!CGM.getTargetCodeGenInfo().shouldEmitDWARFBitFieldSeparators())
+ return nullptr;
+
+ /*
+ Add a *single* zero-bitfield separator between two non-zero bitfields
+ separated by one or more zero-bitfields. This is used to distinguish between
+ structures such the ones below, where the memory layout is the same, but how
+ the ABI assigns fields to registers
diff ers.
+
+ struct foo {
+ int space[4];
+ char a : 8; // on amdgpu, passed on v4
+ char b : 8;
+ char x : 8;
+ char y : 8;
+ };
+ struct bar {
+ int space[4];
+ char a : 8; // on amdgpu, passed on v4
+ char b : 8;
+ char : 0;
+ char x : 8; // passed on v5
+ char y : 8;
+ };
+ */
+ if (PreviousFieldsDI.empty())
+ return nullptr;
+
+ // If we already emitted metadata for a 0-length bitfield, nothing to do here.
+ auto *PreviousMDEntry =
+ PreviousFieldsDI.empty() ? nullptr : PreviousFieldsDI.back();
+ auto *PreviousMDField =
+ dyn_cast_or_null<llvm::DIDerivedType>(PreviousMDEntry);
+ if (!PreviousMDField || !PreviousMDField->isBitField() ||
+ PreviousMDField->getSizeInBits() == 0)
+ return nullptr;
+
+ auto PreviousBitfield = RD->field_begin();
+ std::advance(PreviousBitfield, BitFieldDecl->getFieldIndex() - 1);
+
+ assert(PreviousBitfield->isBitField());
+
+ ASTContext &Context = CGM.getContext();
+ if (!PreviousBitfield->isZeroLengthBitField(Context))
+ return nullptr;
+
+ QualType Ty = PreviousBitfield->getType();
+ SourceLocation Loc = PreviousBitfield->getLocation();
+ llvm::DIFile *VUnit = getOrCreateFile(Loc);
+ llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
+ llvm::DIScope *RecordTy = BitFieldDI->getScope();
+
+ llvm::DIFile *File = getOrCreateFile(Loc);
+ unsigned Line = getLineNumber(Loc);
+
+ uint64_t StorageOffsetInBits =
+ cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
+ ->getZExtValue();
+
+ llvm::DINode::DIFlags Flags =
+ getAccessFlag(PreviousBitfield->getAccess(), RD);
+ llvm::DINodeArray Annotations =
+ CollectBTFDeclTagAnnotations(*PreviousBitfield);
+ return DBuilder.createBitFieldMemberType(
+ RecordTy, "", File, Line, 0, StorageOffsetInBits, StorageOffsetInBits,
+ Flags, DebugType, Annotations);
+}
+
llvm::DIType *CGDebugInfo::createFieldType(
StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS,
uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
@@ -1624,7 +1697,11 @@ void CGDebugInfo::CollectRecordNormalField(
llvm::DIType *FieldType;
if (field->isBitField()) {
- FieldType = createBitFieldType(field, RecordTy, RD);
+ llvm::DIDerivedType *BitFieldType;
+ FieldType = BitFieldType = createBitFieldType(field, RecordTy, RD);
+ if (llvm::DIType *Separator =
+ createBitFieldSeparatorIfNeeded(field, BitFieldType, elements, RD))
+ elements.push_back(Separator);
} else {
auto Align = getDeclAlignIfRequired(field, CGM.getContext());
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index a70b72e2d1420..089a26be4bc2a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -322,9 +322,15 @@ class CGDebugInfo {
}
/// Create new bit field member.
- llvm::DIType *createBitFieldType(const FieldDecl *BitFieldDecl,
- llvm::DIScope *RecordTy,
- const RecordDecl *RD);
+ llvm::DIDerivedType *createBitFieldType(const FieldDecl *BitFieldDecl,
+ llvm::DIScope *RecordTy,
+ const RecordDecl *RD);
+
+ /// Create an anonnymous zero-size separator for bit-field-decl if needed on
+ /// the target.
+ llvm::DIDerivedType *createBitFieldSeparatorIfNeeded(
+ const FieldDecl *BitFieldDecl, const llvm::DIDerivedType *BitFieldDI,
+ llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI, const RecordDecl *RD);
/// Helpers for collecting fields of a record.
/// @{
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index a7766ea8aa57f..dd838c3746000 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -9474,6 +9474,7 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo {
llvm::Function *BlockInvokeFunc,
llvm::Type *BlockTy) const override;
bool shouldEmitStaticExternCAliases() const override;
+ bool shouldEmitDWARFBitFieldSeparators() const override;
void setCUDAKernelCallingConvention(const FunctionType *&FT) const override;
};
}
@@ -9691,6 +9692,10 @@ bool AMDGPUTargetCodeGenInfo::shouldEmitStaticExternCAliases() const {
return false;
}
+bool AMDGPUTargetCodeGenInfo::shouldEmitDWARFBitFieldSeparators() const {
+ return true;
+}
+
void AMDGPUTargetCodeGenInfo::setCUDAKernelCallingConvention(
const FunctionType *&FT) const {
FT = getABIInfo().getContext().adjustFunctionType(
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 3971dba70762e..b225a5c35adc5 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -349,6 +349,11 @@ class TargetCodeGenInfo {
/// as 'used', and having internal linkage.
virtual bool shouldEmitStaticExternCAliases() const { return true; }
+ /// \return true if annonymous zero-sized bitfields should be emitted to
+ /// correctly distinguish between struct types whose memory layout is the
+ /// same, but whose layout may
diff er when used as argument passed by value
+ virtual bool shouldEmitDWARFBitFieldSeparators() const { return false; }
+
virtual void setCUDAKernelCallingConvention(const FunctionType *&FT) const {}
/// Return the device-side type for the CUDA device builtin surface type.
diff --git a/clang/test/CodeGen/debug-info-bitfield-0-struct.c b/clang/test/CodeGen/debug-info-bitfield-0-struct.c
new file mode 100644
index 0000000000000..0535b62677142
--- /dev/null
+++ b/clang/test/CodeGen/debug-info-bitfield-0-struct.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=limited %s | FileCheck --check-prefixes NOSEPARATOR,BOTH %s
+// RUN: %clang_cc1 -triple amdgcn-unk-unk -o - -emit-llvm -debug-info-kind=limited %s | FileCheck --check-prefixes SEPARATOR,BOTH %s
+
+struct First {
+ // BOTH-DAG: ![[FIRST:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "First", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, elements: ![[FIRST_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[FIRST_ELEMENTS]] = !{![[FIRST_X:[0-9]+]], ![[FIRST_Y:[0-9]+]]}
+ // BOTH-DAG: ![[FIRST_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[FIRST]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[FIRST_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[FIRST]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 4, flags: DIFlagBitField, extraData: i64 0)
+ int : 0;
+ int x : 4;
+ int y : 4;
+};
+
+struct FirstDuplicate {
+ // BOTH-DAG: ![[FIRSTDUP:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "FirstDuplicate", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, elements: ![[FIRSTDUP_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[FIRSTDUP_ELEMENTS]] = !{![[FIRSTDUP_X:[0-9]+]], ![[FIRSTDUP_Y:[0-9]+]]}
+ // BOTH-DAG: ![[FIRSTDUP_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[FIRSTDUP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[FIRSTDUP_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[FIRSTDUP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 4, flags: DIFlagBitField, extraData: i64 0)
+ int : 0;
+ int : 0;
+ int x : 4;
+ int y : 4;
+};
+
+struct Second {
+ // BOTH-DAG: ![[SECOND:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Second", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 64, elements: ![[SECOND_ELEMENTS:[0-9]+]])
+
+ // NOSEPARATOR-DAG: ![[SECOND_ELEMENTS]] = !{![[SECOND_X:[0-9]+]], ![[SECOND_Y:[0-9]+]]}
+ // SEPARATOR-DAG: ![[SECOND_ELEMENTS]] = !{![[SECOND_X:[0-9]+]], ![[SECOND_ZERO:[0-9]+]], ![[SECOND_Y:[0-9]+]]}
+
+ // BOTH-DAG: ![[SECOND_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[SECOND]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // SEPARATOR-DAG: ![[SECOND_ZERO]] = !DIDerivedType(tag: DW_TAG_member, scope: ![[SECOND]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ // BOTH-DAG: ![[SECOND_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[SECOND]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ int x : 4;
+ int : 0;
+ int y : 4;
+};
+
+struct SecondDuplicate {
+ // BOTH-DAG: ![[SECONDDUP:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SecondDuplicate", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 64, elements: ![[SECONDDUP_ELEMENTS:[0-9]+]])
+
+ // NOSEPARATOR-DAG: ![[SECONDDUP_ELEMENTS]] = !{![[SECONDDUP_X:[0-9]+]], ![[SECONDDUP_Y:[0-9]+]]}
+ // SEPARATOR-DAG: ![[SECONDDUP_ELEMENTS]] = !{![[SECONDDUP_X:[0-9]+]], ![[SECONDDUP_ZERO:[0-9]+]], ![[SECONDDUP_Y:[0-9]+]]}
+
+ // BOTH-DAG: ![[SECONDDUP_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[SECONDDUP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // SEPARATOR-DAG: ![[SECONDDUP_ZERO]] = !DIDerivedType(tag: DW_TAG_member, scope: ![[SECONDDUP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ // BOTH-DAG: ![[SECONDDUP_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[SECONDDUP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ int x : 4;
+ int : 0;
+ int : 0;
+ int y : 4;
+};
+
+struct Last {
+ // BOTH-DAG: ![[LAST:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Last", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, elements: ![[LAST_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[LAST_ELEMENTS]] = !{![[LAST_X:[0-9]+]], ![[LAST_Y:[0-9]+]]}
+ // BOTH-DAG: ![[LAST_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[LAST]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[LAST_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[LAST]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 4, flags: DIFlagBitField, extraData: i64 0)
+ int x : 4;
+ int y : 4;
+ int : 0;
+};
+
+struct Several {
+ // BOTH-DAG: ![[SEVERAL:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Several", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 96, elements: ![[SEVERAL_ELEMENTS:[0-9]+]])
+
+ // SEPARATOR-DAG: ![[SEVERAL_ELEMENTS]] = !{![[SEVERAL_X:[0-9]+]], ![[SEVERAL_FIRST_ZERO:[0-9]+]], ![[SEVERAL_Y:[0-9]+]], ![[SEVERAL_SECOND_ZERO:[0-9]+]], ![[SEVERAL_Z:[0-9]+]]}
+ // NOSEPARATOR-DAG: ![[SEVERAL_ELEMENTS]] = !{![[SEVERAL_X:[0-9]+]], ![[SEVERAL_Y:[0-9]+]], ![[SEVERAL_Z:[0-9]+]]}
+
+ // BOTH-DAG: ![[SEVERAL_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[SEVERAL]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, flags: DIFlagBitField, extraData: i64 0)
+ // SEPARATOR-DAG: ![[SEVERAL_FIRST_ZERO]] = !DIDerivedType(tag: DW_TAG_member, scope: ![[SEVERAL]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ // BOTH-DAG: ![[SEVERAL_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[SEVERAL]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ // SEPARATOR-DAG: ![[SEVERAL_SECOND_ZERO]] = !DIDerivedType(tag: DW_TAG_member, scope: ![[SEVERAL]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, offset: 64, flags: DIFlagBitField, extraData: i64 64)
+ // BOTH-DAG: ![[SEVERAL_Z]] = !DIDerivedType(tag: DW_TAG_member, name: "z", scope: ![[SEVERAL]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 64, flags: DIFlagBitField, extraData: i64 64)
+ int x : 4;
+ int : 0;
+ int y : 4;
+ int : 0;
+ int z : 4;
+};
+
+struct None_A {
+ // BOTH-DAG: ![[NONE_A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "None_A", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 64, elements: ![[NONE_A_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[NONE_A_ELEMENTS]] = !{![[NONE_A_FIELD:[0-9]+]], ![[NONE_A_X:[0-9]+]]}
+ // BOTH-DAG: ![[NONE_A_FIELD]] = !DIDerivedType(tag: DW_TAG_member, name: "field", scope: ![[NONE_A]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 32)
+ // BOTH-DAG: ![[NONE_A_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[NONE_A]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ int : 0;
+ int field;
+ int x : 4;
+};
+
+struct None_B {
+ // BOTH-DAG: ![[NONE_B:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "None_B", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 64, elements: ![[NONE_B_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[NONE_B_ELEMENTS]] = !{![[NONE_B_FIELD:[0-9]+]], ![[NONE_B_X:[0-9]+]], ![[NONE_B_Y:[0-9]+]]}
+ // BOTH-DAG: ![[NONE_B_FIELD]] = !DIDerivedType(tag: DW_TAG_member, name: "field", scope: ![[NONE_B]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 32)
+ // BOTH-DAG: ![[NONE_B_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[NONE_B]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 32, flags: DIFlagBitField, extraData: i64 32)
+ // BOTH-DAG: ![[NONE_B_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[NONE_B]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 4, offset: 36, flags: DIFlagBitField, extraData: i64 32)
+ int field;
+ int : 0;
+ int x : 4;
+ int y : 4;
+};
+
+struct None_C {
+ // BOTH-DAG: ![[NONE_C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "None_C", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, elements: ![[NONE_C_ELEMENTS:[0-9]+]])
+ // BOTH-DAG: ![[NONE_C_ELEMENTS]] = !{![[NONE_C_X:[0-9]+]], ![[NONE_C_Y:[0-9]+]], ![[NONE_C_A:[0-9]+]], ![[NONE_C_B:[0-9]+]]}
+ // BOTH-DAG: ![[NONE_C_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[NONE_C_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, offset: 8, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[NONE_C_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, offset: 16, flags: DIFlagBitField, extraData: i64 0)
+ // BOTH-DAG: ![[NONE_C_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, offset: 24, flags: DIFlagBitField, extraData: i64 0)
+ char x : 8;
+ char y : 8;
+ char a : 8;
+ char b : 8;
+};
+
+void foo(struct First f, struct FirstDuplicate fs, struct Second s, struct SecondDuplicate sd, struct Last l, struct Several ss, struct None_A na, struct None_B nb, struct None_C nc) {
+ return;
+}
More information about the cfe-commits
mailing list