| author | |
| committer | |
| log | c757f197903940115c1d42883240ec1fe7ef660c |
| tree | 31915696778776c3a906df85cbf08e428f052b90 |
| parent | f36bf8506c9c1fa48dadd699b3122acd15890cf6 |
LLVM backend: generate DIGlobalVariable's for non-function globals and
rename linkage names when exporting functions and globals.
zig_llvm.cpp: add some wrappers to convert a handful of DI classes
into DINode's since DIGlobalVariable is not a DIScope like the others.
zig_llvm.cpp: add some wrappers to allow replacing the LinkageName of
DISubprogram and DIGlobalVariable.
zig_llvm.cpp: fix DI class mixup causing nonsense reinterpret_cast.
The end result is that GDB is now usable since you now no longer need
to manually cast every global nor fully qualify every export.5 files changed, 150 insertions(+), 8 deletions(-)
src/Module.zig+1-1| ... | ... | @@ -663,7 +663,7 @@ pub const Decl = struct { |
| 663 | 663 | return (try decl.typedValue()).val; |
| 664 | 664 | } |
| 665 | 665 | |
| 666 | pub fn isFunction(decl: *Decl) !bool { | |
| 666 | pub fn isFunction(decl: Decl) !bool { | |
| 667 | 667 | const tv = try decl.typedValue(); |
| 668 | 668 | return tv.ty.zigTypeTag() == .Fn; |
| 669 | 669 | } |
src/codegen/llvm.zig+47-4| ... | ... | @@ -164,8 +164,9 @@ pub const Object = struct { |
| 164 | 164 | di_builder: ?*llvm.DIBuilder, |
| 165 | 165 | /// One of these mappings: |
| 166 | 166 | /// - *Module.File => *DIFile |
| 167 | /// - *Module.Decl => *DISubprogram | |
| 168 | di_map: std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DIScope), | |
| 167 | /// - *Module.Decl (Fn) => *DISubprogram | |
| 168 | /// - *Module.Decl (Non-Fn) => *DIGlobalVariable | |
| 169 | di_map: std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode), | |
| 169 | 170 | di_compile_unit: ?*llvm.DICompileUnit, |
| 170 | 171 | context: *const llvm.Context, |
| 171 | 172 | target_machine: *const llvm.TargetMachine, |
| ... | ... | @@ -591,6 +592,7 @@ pub const Object = struct { |
| 591 | 592 | dg.module.comp.bin_file.options.optimize_mode != .Debug, |
| 592 | 593 | null, // decl_subprogram |
| 593 | 594 | ); |
| 595 | try dg.object.di_map.put(gpa, decl, subprogram.toNode()); | |
| 594 | 596 | |
| 595 | 597 | llvm_func.fnSetSubprogram(subprogram); |
| 596 | 598 | |
| ... | ... | @@ -667,6 +669,17 @@ pub const Object = struct { |
| 667 | 669 | llvm_global.setValueName(decl.name); |
| 668 | 670 | llvm_global.setUnnamedAddr(.False); |
| 669 | 671 | llvm_global.setLinkage(.External); |
| 672 | if (self.di_map.get(decl)) |di_node| { | |
| 673 | if (try decl.isFunction()) { | |
| 674 | const di_func = @ptrCast(*llvm.DISubprogram, di_node); | |
| 675 | const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name)); | |
| 676 | di_func.replaceLinkageName(linkage_name); | |
| 677 | } else { | |
| 678 | const di_global = @ptrCast(*llvm.DIGlobalVariable, di_node); | |
| 679 | const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name)); | |
| 680 | di_global.replaceLinkageName(linkage_name); | |
| 681 | } | |
| 682 | } | |
| 670 | 683 | if (decl.val.castTag(.variable)) |variable| { |
| 671 | 684 | if (variable.data.is_threadlocal) { |
| 672 | 685 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); |
| ... | ... | @@ -681,6 +694,17 @@ pub const Object = struct { |
| 681 | 694 | const exp_name = exports[0].options.name; |
| 682 | 695 | llvm_global.setValueName2(exp_name.ptr, exp_name.len); |
| 683 | 696 | llvm_global.setUnnamedAddr(.False); |
| 697 | if (self.di_map.get(decl)) |di_node| { | |
| 698 | if (try decl.isFunction()) { | |
| 699 | const di_func = @ptrCast(*llvm.DISubprogram, di_node); | |
| 700 | const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len); | |
| 701 | di_func.replaceLinkageName(linkage_name); | |
| 702 | } else { | |
| 703 | const di_global = @ptrCast(*llvm.DIGlobalVariable, di_node); | |
| 704 | const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len); | |
| 705 | di_global.replaceLinkageName(linkage_name); | |
| 706 | } | |
| 707 | } | |
| 684 | 708 | switch (exports[0].options.linkage) { |
| 685 | 709 | .Internal => unreachable, |
| 686 | 710 | .Strong => llvm_global.setLinkage(.External), |
| ... | ... | @@ -746,7 +770,7 @@ pub const Object = struct { |
| 746 | 770 | const dir_path_z = try gpa.dupeZ(u8, dir_path); |
| 747 | 771 | defer gpa.free(dir_path_z); |
| 748 | 772 | const di_file = o.di_builder.?.createFile(sub_file_path_z, dir_path_z); |
| 749 | gop.value_ptr.* = di_file.toScope(); | |
| 773 | gop.value_ptr.* = di_file.toNode(); | |
| 750 | 774 | return di_file; |
| 751 | 775 | } |
| 752 | 776 | }; |
| ... | ... | @@ -784,7 +808,7 @@ pub const DeclGen = struct { |
| 784 | 808 | _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl); |
| 785 | 809 | } else { |
| 786 | 810 | const target = dg.module.getTarget(); |
| 787 | const global = try dg.resolveGlobalDecl(decl); | |
| 811 | var global = try dg.resolveGlobalDecl(decl); | |
| 788 | 812 | global.setAlignment(decl.getAlignment(target)); |
| 789 | 813 | assert(decl.has_tv); |
| 790 | 814 | const init_val = if (decl.val.castTag(.variable)) |payload| init_val: { |
| ... | ... | @@ -828,8 +852,27 @@ pub const DeclGen = struct { |
| 828 | 852 | dg.object.decl_map.putAssumeCapacity(decl, new_global); |
| 829 | 853 | new_global.takeName(global); |
| 830 | 854 | global.deleteGlobal(); |
| 855 | global = new_global; | |
| 831 | 856 | } |
| 832 | 857 | } |
| 858 | ||
| 859 | if (dg.object.di_builder) |dib| { | |
| 860 | const di_file = try dg.object.getDIFile(dg.gpa, decl.src_namespace.file_scope); | |
| 861 | ||
| 862 | const line_number = decl.src_line + 1; | |
| 863 | const is_internal_linkage = !dg.module.decl_exports.contains(decl); | |
| 864 | const di_global = dib.createGlobalVariable( | |
| 865 | di_file.toScope(), | |
| 866 | decl.name, | |
| 867 | global.getValueName(), | |
| 868 | di_file, | |
| 869 | line_number, | |
| 870 | try dg.lowerDebugType(decl.ty), | |
| 871 | is_internal_linkage, | |
| 872 | ); | |
| 873 | ||
| 874 | try dg.object.di_map.put(dg.gpa, dg.decl, di_global.toNode()); | |
| 875 | } | |
| 833 | 876 | } |
| 834 | 877 | } |
| 835 | 878 |
src/codegen/llvm/bindings.zig+36-2| ... | ... | @@ -855,7 +855,17 @@ pub const Builder = opaque { |
| 855 | 855 | extern fn LLVMBuildShuffleVector(*const Builder, V1: *const Value, V2: *const Value, Mask: *const Value, Name: [*:0]const u8) *const Value; |
| 856 | 856 | }; |
| 857 | 857 | |
| 858 | pub const DIScope = opaque {}; | |
| 858 | pub const MDString = opaque { | |
| 859 | pub const get = LLVMMDStringInContext2; | |
| 860 | extern fn LLVMMDStringInContext2(C: *const Context, Str: [*]const u8, SLen: usize) *MDString; | |
| 861 | }; | |
| 862 | ||
| 863 | pub const DIScope = opaque { | |
| 864 | pub const toNode = ZigLLVMScopeToNode; | |
| 865 | extern fn ZigLLVMScopeToNode(scope: *DIScope) *DINode; | |
| 866 | }; | |
| 867 | ||
| 868 | pub const DINode = opaque {}; | |
| 859 | 869 | pub const Metadata = opaque {}; |
| 860 | 870 | |
| 861 | 871 | pub const IntPredicate = enum(c_uint) { |
| ... | ... | @@ -1421,28 +1431,52 @@ pub const address_space = struct { |
| 1421 | 1431 | |
| 1422 | 1432 | pub const DIEnumerator = opaque {}; |
| 1423 | 1433 | pub const DILocalVariable = opaque {}; |
| 1424 | pub const DIGlobalVariable = opaque {}; | |
| 1425 | 1434 | pub const DILocation = opaque {}; |
| 1426 | 1435 | |
| 1436 | pub const DIGlobalVariable = opaque { | |
| 1437 | pub const toNode = ZigLLVMGlobalVariableToNode; | |
| 1438 | extern fn ZigLLVMGlobalVariableToNode(global_variable: *DIGlobalVariable) *DINode; | |
| 1439 | ||
| 1440 | pub const replaceLinkageName = ZigLLVMGlobalVariableReplaceLinkageName; | |
| 1441 | extern fn ZigLLVMGlobalVariableReplaceLinkageName(global_variable: *DIGlobalVariable, linkage_name: *MDString) void; | |
| 1442 | }; | |
| 1427 | 1443 | pub const DIType = opaque { |
| 1428 | 1444 | pub const toScope = ZigLLVMTypeToScope; |
| 1429 | 1445 | extern fn ZigLLVMTypeToScope(ty: *DIType) *DIScope; |
| 1446 | ||
| 1447 | pub const toNode = ZigLLVMTypeToNode; | |
| 1448 | extern fn ZigLLVMTypeToNode(ty: *DIType) *DINode; | |
| 1430 | 1449 | }; |
| 1431 | 1450 | pub const DIFile = opaque { |
| 1432 | 1451 | pub const toScope = ZigLLVMFileToScope; |
| 1433 | 1452 | extern fn ZigLLVMFileToScope(difile: *DIFile) *DIScope; |
| 1453 | ||
| 1454 | pub const toNode = ZigLLVMFileToNode; | |
| 1455 | extern fn ZigLLVMFileToNode(difile: *DIFile) *DINode; | |
| 1434 | 1456 | }; |
| 1435 | 1457 | pub const DILexicalBlock = opaque { |
| 1436 | 1458 | pub const toScope = ZigLLVMLexicalBlockToScope; |
| 1437 | 1459 | extern fn ZigLLVMLexicalBlockToScope(lexical_block: *DILexicalBlock) *DIScope; |
| 1460 | ||
| 1461 | pub const toNode = ZigLLVMLexicalBlockToNode; | |
| 1462 | extern fn ZigLLVMLexicalBlockToNode(lexical_block: *DILexicalBlock) *DINode; | |
| 1438 | 1463 | }; |
| 1439 | 1464 | pub const DICompileUnit = opaque { |
| 1440 | 1465 | pub const toScope = ZigLLVMCompileUnitToScope; |
| 1441 | 1466 | extern fn ZigLLVMCompileUnitToScope(compile_unit: *DICompileUnit) *DIScope; |
| 1467 | ||
| 1468 | pub const toNode = ZigLLVMCompileUnitToNode; | |
| 1469 | extern fn ZigLLVMCompileUnitToNode(compile_unit: *DICompileUnit) *DINode; | |
| 1442 | 1470 | }; |
| 1443 | 1471 | pub const DISubprogram = opaque { |
| 1444 | 1472 | pub const toScope = ZigLLVMSubprogramToScope; |
| 1445 | 1473 | extern fn ZigLLVMSubprogramToScope(subprogram: *DISubprogram) *DIScope; |
| 1474 | ||
| 1475 | pub const toNode = ZigLLVMSubprogramToNode; | |
| 1476 | extern fn ZigLLVMSubprogramToNode(subprogram: *DISubprogram) *DINode; | |
| 1477 | ||
| 1478 | pub const replaceLinkageName = ZigLLVMSubprogramReplaceLinkageName; | |
| 1479 | extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void; | |
| 1446 | 1480 | }; |
| 1447 | 1481 | |
| 1448 | 1482 | pub const getDebugLoc = ZigLLVMGetDebugLoc; |
src/zig_llvm.cpp+51-1| ... | ... | @@ -842,7 +842,7 @@ ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder, |
| 842 | 842 | line_no, |
| 843 | 843 | reinterpret_cast<DIType*>(di_type), |
| 844 | 844 | is_local_to_unit); |
| 845 | return reinterpret_cast<ZigLLVMDIGlobalVariable*>(result); | |
| 845 | return reinterpret_cast<ZigLLVMDIGlobalVariable*>(result->getVariable()); | |
| 846 | 846 | } |
| 847 | 847 | |
| 848 | 848 | ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder, |
| ... | ... | @@ -887,6 +887,56 @@ ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type) { |
| 887 | 887 | return reinterpret_cast<ZigLLVMDIScope*>(scope); |
| 888 | 888 | } |
| 889 | 889 | |
| 890 | ZigLLVMDINode *ZigLLVMLexicalBlockToNode(ZigLLVMDILexicalBlock *lexical_block) { | |
| 891 | DINode *node = reinterpret_cast<DILexicalBlock*>(lexical_block); | |
| 892 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 893 | } | |
| 894 | ||
| 895 | ZigLLVMDINode *ZigLLVMCompileUnitToNode(ZigLLVMDICompileUnit *compile_unit) { | |
| 896 | DINode *node = reinterpret_cast<DICompileUnit*>(compile_unit); | |
| 897 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 898 | } | |
| 899 | ||
| 900 | ZigLLVMDINode *ZigLLVMFileToNode(ZigLLVMDIFile *difile) { | |
| 901 | DINode *node = reinterpret_cast<DIFile*>(difile); | |
| 902 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 903 | } | |
| 904 | ||
| 905 | ZigLLVMDINode *ZigLLVMSubprogramToNode(ZigLLVMDISubprogram *subprogram) { | |
| 906 | DINode *node = reinterpret_cast<DISubprogram*>(subprogram); | |
| 907 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 908 | } | |
| 909 | ||
| 910 | ZigLLVMDINode *ZigLLVMTypeToNode(ZigLLVMDIType *type) { | |
| 911 | DINode *node = reinterpret_cast<DIType*>(type); | |
| 912 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 913 | } | |
| 914 | ||
| 915 | ZigLLVMDINode *ZigLLVMScopeToNode(ZigLLVMDIScope *scope) { | |
| 916 | DINode *node = reinterpret_cast<DIScope*>(scope); | |
| 917 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 918 | } | |
| 919 | ||
| 920 | ZigLLVMDINode *ZigLLVMGlobalVariableToNode(ZigLLVMDIGlobalVariable *global_variable) { | |
| 921 | DINode *node = reinterpret_cast<DIGlobalVariable*>(global_variable); | |
| 922 | return reinterpret_cast<ZigLLVMDINode*>(node); | |
| 923 | } | |
| 924 | ||
| 925 | void ZigLLVMSubprogramReplaceLinkageName(ZigLLVMDISubprogram *subprogram, | |
| 926 | ZigLLVMMDString *linkage_name) | |
| 927 | { | |
| 928 | MDString *linkage_name_md = reinterpret_cast<MDString*>(linkage_name); | |
| 929 | reinterpret_cast<DISubprogram*>(subprogram)->replaceLinkageName(linkage_name_md); | |
| 930 | } | |
| 931 | ||
| 932 | void ZigLLVMGlobalVariableReplaceLinkageName(ZigLLVMDIGlobalVariable *global_variable, | |
| 933 | ZigLLVMMDString *linkage_name) | |
| 934 | { | |
| 935 | Metadata *linkage_name_md = reinterpret_cast<MDString*>(linkage_name); | |
| 936 | // NOTE: Operand index must match llvm::DIGlobalVariable | |
| 937 | reinterpret_cast<DIGlobalVariable*>(global_variable)->replaceOperandWith(5, linkage_name_md); | |
| 938 | } | |
| 939 | ||
| 890 | 940 | ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder, |
| 891 | 941 | unsigned lang, ZigLLVMDIFile *difile, const char *producer, |
| 892 | 942 | bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name, |
src/zig_llvm.h+15| ... | ... | @@ -38,6 +38,8 @@ struct ZigLLVMDIGlobalVariable; |
| 38 | 38 | struct ZigLLVMDILocation; |
| 39 | 39 | struct ZigLLVMDIEnumerator; |
| 40 | 40 | struct ZigLLVMInsertionPoint; |
| 41 | struct ZigLLVMDINode; | |
| 42 | struct ZigLLVMMDString; | |
| 41 | 43 | |
| 42 | 44 | ZIG_EXTERN_C void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R); |
| 43 | 45 | ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R); |
| ... | ... | @@ -238,6 +240,19 @@ ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMFileToScope(struct ZigLLVMDIFile *dif |
| 238 | 240 | ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMSubprogramToScope(struct ZigLLVMDISubprogram *subprogram); |
| 239 | 241 | ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMTypeToScope(struct ZigLLVMDIType *type); |
| 240 | 242 | |
| 243 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMLexicalBlockToNode(struct ZigLLVMDILexicalBlock *lexical_block); | |
| 244 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMCompileUnitToNode(struct ZigLLVMDICompileUnit *compile_unit); | |
| 245 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMFileToNode(struct ZigLLVMDIFile *difile); | |
| 246 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMSubprogramToNode(struct ZigLLVMDISubprogram *subprogram); | |
| 247 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMTypeToNode(struct ZigLLVMDIType *type); | |
| 248 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMScopeToNode(struct ZigLLVMDIScope *scope); | |
| 249 | ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMGlobalVariableToNode(struct ZigLLVMDIGlobalVariable *global_variable); | |
| 250 | ||
| 251 | ZIG_EXTERN_C void ZigLLVMSubprogramReplaceLinkageName(struct ZigLLVMDISubprogram *subprogram, | |
| 252 | struct ZigLLVMMDString *linkage_name); | |
| 253 | ZIG_EXTERN_C void ZigLLVMGlobalVariableReplaceLinkageName(struct ZigLLVMDIGlobalVariable *global_variable, | |
| 254 | struct ZigLLVMMDString *linkage_name); | |
| 255 | ||
| 241 | 256 | ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(struct ZigLLVMDIBuilder *dbuilder, |
| 242 | 257 | struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no, |
| 243 | 258 | struct ZigLLVMDIType *type, bool always_preserve, unsigned flags); |