eddyz87 created this revision. Herald added a project: All. eddyz87 published this revision for review. eddyz87 added a reviewer: yonghong-song. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Generate DILocalVariable entries for parameters of extern functions, the "annotations" field of DILocalVariable is used to link "btf_decl_tag" annotation with the parameter. Do this only for BPF backend as there are no other users for this information. Final DWARF is valid as "Appendix A" is very much lax in what is allowed as attributes for "DW_TAG_formal_parameter": > DWARF does not in general require that a given debugging information > entry contain a particular attribute or set of attributes. Instead, > a DWARF producer is free to generate any, all, or none of the > attributes ... other attributes ... may also appear in a given > debugging information entry. DWARF Debugging Information Format Version 5, Appendix A: Attributes by Tag Value (Informative) Page 251, Line 3. Depends on D140969 <https://reviews.llvm.org/D140969> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D140970 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGen/bpf-decl-tag-extern-func-args.c Index: clang/test/CodeGen/bpf-decl-tag-extern-func-args.c =================================================================== --- /dev/null +++ clang/test/CodeGen/bpf-decl-tag-extern-func-args.c @@ -0,0 +1,37 @@ +// RUN: %clang -target bpf -S -emit-llvm -g -O2 -o - %s | FileCheck %s + +#define __decl_tag(x) __attribute__((btf_decl_tag(x))) + +extern void foo(int aa __decl_tag("aa_tag"), long bb __decl_tag("bb_tag")); +extern void bar(char cc __decl_tag("cc_tag")); +extern void buz(int __decl_tag("buz_arg_tag")); + +void root(void) { + foo(0, 1); + bar(0); + buz(0); +} +// CHECK: [[foo:![0-9]+]] = !DISubprogram(name: "foo", {{.*}}, retainedNodes: [[foo_nodes:![0-9]+]]) +// CHECK: [[foo_nodes]] = !{[[aa:![0-9]+]], [[bb:![0-9]+]]} + +// CHECK: [[aa]] = !DILocalVariable(name: "aa", arg: 1, scope: [[foo]], {{.*}}, annotations: [[aa_annot:![0-9]+]]) +// CHECK: [[aa_annot]] = !{[[aa_tag:![0-9]+]]} +// CHECK: [[aa_tag]] = !{!"btf_decl_tag", !"aa_tag"} + +// CHECK: [[bb]] = !DILocalVariable(name: "bb", arg: 2, scope: [[foo]], {{.*}}, annotations: [[bb_annot:![0-9]+]]) +// CHECK: [[bb_annot]] = !{[[bb_tag:![0-9]+]]} +// CHECK: [[bb_tag]] = !{!"btf_decl_tag", !"bb_tag"} + +// CHECK: [[bar:![0-9]+]] = !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[bar_nodes:![0-9]+]]) +// CHECK: [[bar_nodes]] = !{[[cc:![0-9]+]]} + +// CHECK: [[cc]] = !DILocalVariable(name: "cc", arg: 1, scope: [[bar]], {{.*}}, annotations: [[cc_annot:![0-9]+]]) +// CHECK: [[cc_annot]] = !{[[cc_tag:![0-9]+]]} +// CHECK: [[cc_tag]] = !{!"btf_decl_tag", !"cc_tag"} + +// CHECK: [[buz:![0-9]+]] = !DISubprogram(name: "buz", {{.*}}, retainedNodes: [[buz_nodes:![0-9]+]]) +// CHECK: [[buz_nodes]] = !{[[buz_arg:![0-9]+]]} + +// CHECK: [[buz_arg]] = !DILocalVariable(arg: 1, scope: [[buz]], {{.*}}, annotations: [[buz_arg_annot:![0-9]+]]) +// CHECK: [[buz_arg_annot]] = !{[[buz_arg_tag:![0-9]+]]} +// CHECK: [[buz_arg_tag]] = !{!"btf_decl_tag", !"buz_arg_tag"} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -4206,11 +4206,29 @@ SPFlags |= llvm::DISubprogram::SPFlagOptimized; llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D); + llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit); llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, + STy, ScopeLine, Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(D), nullptr, Annotations); + // Preserve btf_decl_tag attributes for parameters of extern functions + // for BPF target. The parameters created in this loop are attached as + // DISubprogram's retainedNodes in the subsequent finalizeSubprogram call. + if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) { + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + llvm::DITypeRefArray ParamTypes = STy->getTypeArray(); + unsigned ArgNo = 1; + for (ParmVarDecl *PD : FD->parameters()) { + llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD); + DBuilder.createParameterVariable + (SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo], true, + llvm::DINode::FlagZero, ParamAnnotations); + ++ArgNo; + } + } + } + if (IsDeclForCallSite) Fn->setSubprogram(SP);
Index: clang/test/CodeGen/bpf-decl-tag-extern-func-args.c =================================================================== --- /dev/null +++ clang/test/CodeGen/bpf-decl-tag-extern-func-args.c @@ -0,0 +1,37 @@ +// RUN: %clang -target bpf -S -emit-llvm -g -O2 -o - %s | FileCheck %s + +#define __decl_tag(x) __attribute__((btf_decl_tag(x))) + +extern void foo(int aa __decl_tag("aa_tag"), long bb __decl_tag("bb_tag")); +extern void bar(char cc __decl_tag("cc_tag")); +extern void buz(int __decl_tag("buz_arg_tag")); + +void root(void) { + foo(0, 1); + bar(0); + buz(0); +} +// CHECK: [[foo:![0-9]+]] = !DISubprogram(name: "foo", {{.*}}, retainedNodes: [[foo_nodes:![0-9]+]]) +// CHECK: [[foo_nodes]] = !{[[aa:![0-9]+]], [[bb:![0-9]+]]} + +// CHECK: [[aa]] = !DILocalVariable(name: "aa", arg: 1, scope: [[foo]], {{.*}}, annotations: [[aa_annot:![0-9]+]]) +// CHECK: [[aa_annot]] = !{[[aa_tag:![0-9]+]]} +// CHECK: [[aa_tag]] = !{!"btf_decl_tag", !"aa_tag"} + +// CHECK: [[bb]] = !DILocalVariable(name: "bb", arg: 2, scope: [[foo]], {{.*}}, annotations: [[bb_annot:![0-9]+]]) +// CHECK: [[bb_annot]] = !{[[bb_tag:![0-9]+]]} +// CHECK: [[bb_tag]] = !{!"btf_decl_tag", !"bb_tag"} + +// CHECK: [[bar:![0-9]+]] = !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[bar_nodes:![0-9]+]]) +// CHECK: [[bar_nodes]] = !{[[cc:![0-9]+]]} + +// CHECK: [[cc]] = !DILocalVariable(name: "cc", arg: 1, scope: [[bar]], {{.*}}, annotations: [[cc_annot:![0-9]+]]) +// CHECK: [[cc_annot]] = !{[[cc_tag:![0-9]+]]} +// CHECK: [[cc_tag]] = !{!"btf_decl_tag", !"cc_tag"} + +// CHECK: [[buz:![0-9]+]] = !DISubprogram(name: "buz", {{.*}}, retainedNodes: [[buz_nodes:![0-9]+]]) +// CHECK: [[buz_nodes]] = !{[[buz_arg:![0-9]+]]} + +// CHECK: [[buz_arg]] = !DILocalVariable(arg: 1, scope: [[buz]], {{.*}}, annotations: [[buz_arg_annot:![0-9]+]]) +// CHECK: [[buz_arg_annot]] = !{[[buz_arg_tag:![0-9]+]]} +// CHECK: [[buz_arg_tag]] = !{!"btf_decl_tag", !"buz_arg_tag"} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -4206,11 +4206,29 @@ SPFlags |= llvm::DISubprogram::SPFlagOptimized; llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D); + llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit); llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, + STy, ScopeLine, Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(D), nullptr, Annotations); + // Preserve btf_decl_tag attributes for parameters of extern functions + // for BPF target. The parameters created in this loop are attached as + // DISubprogram's retainedNodes in the subsequent finalizeSubprogram call. + if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) { + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + llvm::DITypeRefArray ParamTypes = STy->getTypeArray(); + unsigned ArgNo = 1; + for (ParmVarDecl *PD : FD->parameters()) { + llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD); + DBuilder.createParameterVariable + (SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo], true, + llvm::DINode::FlagZero, ParamAnnotations); + ++ArgNo; + } + } + } + if (IsDeclForCallSite) Fn->setSubprogram(SP);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits