Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions clang/lib/CodeGen/CGVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,29 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,

// Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
// they are referencing.
//
// Some types may be still unresolved. As they can't be cloned, keep
// references to the types from the base subprogram.
Comment on lines +138 to +139
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"some" feels concerningly vague - could you be more specific?

// FIXME: As a result, variables of cloned subprogram may refer to local types
// from base subprogram. In such case, type locality information is damaged.
Comment on lines +140 to +141
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIXME is a bit unclear about what should be fixed, and explains more about the problem?

Perhaps the explanation should go above, and the FIXME should be more specific about what should be fixed?

auto PrepareVariableMapping = [&VMap](llvm::DILocalVariable *DILocal) {
if (DILocal->isResolved())
return;

if (llvm::DIType *Ty = DILocal->getType(); Ty && !Ty->isResolved())
VMap.MD()[Ty].reset(Ty);

DILocal->resolve();
};

for (auto &BB : *Fn) {
for (auto &I : BB) {
for (llvm::DbgVariableRecord &DVR :
llvm::filterDbgVars(I.getDbgRecordRange())) {
auto *DILocal = DVR.getVariable();
if (!DILocal->isResolved())
DILocal->resolve();
}
if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
auto *DILocal = DII->getVariable();
if (!DILocal->isResolved())
DILocal->resolve();
}
llvm::filterDbgVars(I.getDbgRecordRange()))
PrepareVariableMapping(DVR.getVariable());

if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I))
PrepareVariableMapping(DII->getVariable());
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions clang/test/CodeGenCXX/tmp-md-nodes3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// REQUIRES: asserts
// Should trigger GenerateVarArgsThunk.
// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \
// RUN: FileCheck %s

// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-obj %s -o - | \
// RUN: llvm-dwarfdump --verify -

// This test checks that the varargs thunk is correctly created if types of
// DILocalVariables of the base function are unresolved at the cloning time.
Comment on lines +9 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on the test criteria -- as I understand it this test is to avoid a crash in a tricky situation where types have no full definition? If so, please say that explicitly, and what kind of DILocalVariable information should be produced (currently none / incorrect information).

(I'm thinking ahead to if/when this test fails and someone has to determine the intention behind it).


typedef signed char __int8_t;
typedef int BOOL;
class CMsgAgent;

class CFs {
public:
typedef enum {} CACHE_HINT;
virtual BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) ;
};

typedef struct {} _Lldiv_t;

class CBdVfs {
public:
virtual ~CBdVfs( ) {}
};

class CBdVfsImpl : public CBdVfs, public CFs {
BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... );
};

BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) {
// Complete enum with no defintion. Clang allows to declare variables of
// such type.
enum class E : int;
E enum_var;
// Structure has forward declaration. DIDerivedType which is a pointer
// to it is unresolved during debug info generation for the function.
struct LocalStruct;
LocalStruct *struct_var;

struct GlobalStruct {};

return true;
}

// Check that thunk is emitted.
// CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
2 changes: 1 addition & 1 deletion clang/test/DebugInfo/CXX/access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class B : public A {
static int public_static;

protected:
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_using",{{.*}} line: [[@LINE+3]],{{.*}} flags: DIFlagProtected)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in why this is failing / necessary -- the '-DAG' suffix should mean the check lines are re-orderable anyway, and as far as I read the diff you're only changing the CHECK-line position and updating the relative-line-num calculation accordingly?

// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_typedef",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected)
typedef int prot_typedef;
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_using",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected)
using prot_using = prot_typedef;
prot_using prot_member;

Expand Down
12 changes: 6 additions & 6 deletions clang/test/DebugInfo/CXX/anon-union-vars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ void instantiate(int x) {
// CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
// CHECK: !DIGlobalVariable(name: "result", {{.*}} isLocal: false, isDefinition: true
// CHECK: !DIGlobalVariable(name: "value", {{.*}} isLocal: false, isDefinition: true
// CHECK: !DILocalVariable(name: "i", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION:[0-9]+]]
// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK: ![[UNION:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
// CHECK: elements
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]],
// CHECK: !DILocalVariable(name: "i", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be CHECK-SAME, to ensure that we're on the same line as the nameless DILocalVariable? Otherwise this (while unlikely) could match an unrelated later type.

110 changes: 62 additions & 48 deletions clang/test/DebugInfo/CXX/codeview-unnamed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,72 @@

int main(int argc, char* argv[], char* arge[]) {
//
// LINUX: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )
//
// MSVC: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-one>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-one>@?1??main@@9@"
// MSVC-SAME: )


//
// LINUX: [[TYPE_OF_TWO:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )
//
// MSVC: [[TYPE_OF_TWO:![0-9]+]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-two>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-two>@?2??main@@9@"
// MSVC-SAME: )


//
// LINUX: [[TYPE_OF_THREE:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-SAME: name: "named"
// LINUX-NOT: identifier:
// LINUX-SAME: )
//
// MSVC: [[TYPE_OF_THREE:![0-9]+]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "named"
// MSVC-SAME: identifier: ".?AUnamed@?1??main@@9@"
// MSVC-SAME: )

//
// LINUX: [[TYPE_OF_FOUR:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_class_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )
//
// MSVC: [[TYPE_OF_FOUR:![0-9]+]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_class_type
// MSVC-SAME: name: "<lambda_0>"
// MSVC-SAME: identifier: ".?AV<lambda_0>@?0??main@@9@"
// MSVC-SAME: )


// In CodeView, the LF_MFUNCTION entry for "bar()" refers to the forward
// reference of the unnamed struct. Visual Studio requires a unique
// identifier to match the LF_STRUCTURE forward reference to the definition.
//
struct { void bar() {} } one;
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
// LINUX-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_ONE]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_ONE]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
// MSVC-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// MSVC-SAME: )
// MSVC: [[TYPE_OF_ONE]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-one>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-one>@?1??main@@9@"
// MSVC-SAME: type: [[TYPE_OF_ONE]]
// MSVC-SAME: )


Expand All @@ -37,21 +81,11 @@ int main(int argc, char* argv[], char* arge[]) {
int decltype(two)::*ptr2unnamed = &decltype(two)::bar;
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "two"
// LINUX-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_TWO]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_TWO]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "two"
// MSVC-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
// MSVC-SAME: )
// MSVC: [[TYPE_OF_TWO]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-two>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-two>@?2??main@@9@"
// MSVC-SAME: type: [[TYPE_OF_TWO]]
// MSVC-SAME: )


Expand All @@ -62,21 +96,11 @@ int main(int argc, char* argv[], char* arge[]) {
struct named { int bar; int named::* p2mem; } three = { 42, &named::bar };
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "three"
// LINUX-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_THREE]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-SAME: name: "named"
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_THREE]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "three"
// MSVC-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
// MSVC-SAME: )
// MSVC: [[TYPE_OF_THREE]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "named"
// MSVC-SAME: identifier: ".?AUnamed@?1??main@@9@"
// MSVC-SAME: type: [[TYPE_OF_THREE]]
// MSVC-SAME: )


Expand All @@ -88,21 +112,11 @@ int main(int argc, char* argv[], char* arge[]) {
auto four = [argc](int i) -> int { return argc == i ? 1 : 0; };
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "four"
// LINUX-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_FOUR]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_class_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_FOUR]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "four"
// MSVC-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
// MSVC-SAME: )
// MSVC: [[TYPE_OF_FOUR]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_class_type
// MSVC-SAME: name: "<lambda_0>"
// MSVC-SAME: identifier: ".?AV<lambda_0>@?0??main@@9@"
// MSVC-SAME: type: [[TYPE_OF_FOUR]]
// MSVC-SAME: )

return 0;
Expand Down
4 changes: 2 additions & 2 deletions clang/test/DebugInfo/CXX/gline-tables-only-codeview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ void test() {
// CHECK-SAME: name: "<lambda_2_1>",
c.lambda_params();

// CHECK: !DISubprogram(name: "operator()", scope: ![[LAMBDA1:[0-9]+]],
// CHECK: ![[LAMBDA1]] = !DICompositeType(tag: DW_TAG_class_type,
// CHECK: ![[LAMBDA1:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "<lambda_1>",
// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK: !DISubprogram(name: "operator()", scope: ![[LAMBDA1]],
c.lambda2();
}
15 changes: 7 additions & 8 deletions clang/test/DebugInfo/CXX/lambda-capture-packs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,22 @@
// RUN: -debug-info-kind=standalone -std=c++26 %s -o - | FileCheck %s


// CHECK: ![[PACK1:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int>"
// CHECK: ![[PACK2:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int, int>"
// CHECK: ![[PACK3:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int>"
// CHECK: ![[PACK4:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int, int>"
// CHECK: ![[PACK5:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int>"
// CHECK: ![[PACK6:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int, int>"
// CHECK: ![[PACK7:[0-9]+]] = distinct !DISubprogram(name: "capture_binding_and_param_pack<int, int>"

template<typename... Args>
auto capture_pack(Args... args) {
return [args..., ...params = args] {
return 0;
}();
}

// CHECK: ![[PACK1:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK1]]
// CHECK-SAME: elements: ![[PACK1_ELEMS:[0-9]+]]
// CHECK-DAG: ![[PACK1_ELEMS]] = !{![[PACK1_ARGS:[0-9]+]], ![[PACK1_PARAMS:[0-9]+]]}
// CHECK-DAG: ![[PACK1_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
// CHECK-DAG: ![[PACK1_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
// CHECK-NOT: DW_TAG_member

// CHECK: ![[PACK2:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int, int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK2]]
// CHECK-SAME: elements: ![[PACK2_ELEMS:[0-9]+]]
// CHECK: ![[PACK2_ELEMS]] = !{![[PACK2_ARGS:[0-9]+]]
Expand All @@ -42,6 +36,7 @@ auto capture_pack_and_locals(int x, Args... args) {
}();
}

// CHECK: ![[PACK3:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK3]]
// CHECK-SAME: elements: ![[PACK3_ELEMS:[0-9]+]]
// CHECK: ![[PACK3_ELEMS]] = !{![[PACK3_ARGS:[0-9]+]]
Expand All @@ -55,6 +50,7 @@ auto capture_pack_and_locals(int x, Args... args) {
// CHECK-DAG: ![[PACK3_W]] = !DIDerivedType(tag: DW_TAG_member, name: "w"
// CHECK-NOT: DW_TAG_member

// CHECK: ![[PACK4:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int, int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK4]]
// CHECK-SAME: elements: ![[PACK4_ELEMS:[0-9]+]]
// CHECK: ![[PACK4_ELEMS]] = !{![[PACK4_ARGS:[0-9]+]]
Expand Down Expand Up @@ -90,6 +86,7 @@ struct Foo {
int w = 10;
} f;

// CHECK: ![[PACK5:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK5]]
// CHECK-SAME: elements: ![[PACK5a_ELEMS:[0-9]+]]
// CHECK: ![[PACK5a_ELEMS]] = !{![[PACK5a_THIS:[0-9]+]]
Expand Down Expand Up @@ -120,6 +117,7 @@ struct Foo {
// CHECK-DAG: ![[PACK5c_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
// CHECK-NOT: DW_TAG_member

// CHECK: ![[PACK6:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int, int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK6]]
// CHECK-SAME: elements: ![[PACK6a_ELEMS:[0-9]+]]
// CHECK: ![[PACK6a_ELEMS]] = !{![[PACK6a_THIS:[0-9]+]]
Expand Down Expand Up @@ -168,6 +166,7 @@ auto capture_binding_and_param_pack(Args... args) {
}();
}

// CHECK: ![[PACK7:[0-9]+]] = distinct !DISubprogram(name: "capture_binding_and_param_pack<int, int>"
// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C"
// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK7]]
// CHECK-SAME: elements: ![[PACK7_ELEMS:[0-9]+]]
Expand Down
4 changes: 2 additions & 2 deletions clang/test/DebugInfo/CXX/lambda-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ void D::d(int x) {
}

// CHECK: ![[D:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D",
// CHECK: ![[POINTER:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[D]], size: 64)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "this",
// CHECK-SAME: line: 11
// CHECK-SAME: baseType: ![[POINTER]]
// CHECK-SAME: baseType: ![[POINTER:[0-9]+]]
// CHECK-SAME: size: 64
// CHECK-NOT: offset: 0
// CHECK-SAME: ){{$}}
// CHECK: ![[POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[D]], size: 64)
Loading
Loading