Browse Source

llvmdbg: emit debug information for global variables

Jonas Maebe 3 years ago
parent
commit
9a7a97175e
1 changed files with 95 additions and 23 deletions
  1. 95 23
      compiler/llvm/dbgllvm.pas

+ 95 - 23
compiler/llvm/dbgllvm.pas

@@ -81,6 +81,9 @@ interface
         fcunode: tai_llvmspecialisedmetadatanode;
         fenums: tai_llvmunnamedmetadatanode;
         fretainedtypes: tai_llvmunnamedmetadatanode;
+        fglobals: tai_llvmunnamedmetadatanode;
+        { reusable empty expression node }
+        femptyexpression: tai_llvmspecialisedmetadatanode;
 
         function absolute_llvm_path(const s:tcmdstr):tcmdstr;
       protected
@@ -124,6 +127,8 @@ interface
 
         procedure appendprocdef(list:TAsmList;def:tprocdef);override;
 
+        procedure adddefinitionlocal(dinode: tai_llvmspecialisedmetadatanode; definition, local, usedispflags: boolean; out dispFlags: tsymstr);
+
         function  get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
         procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
         procedure appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: TSymStr; def: tdef; offset: pint(*; const flags: tdwarfvarsymflags*));
@@ -410,6 +415,8 @@ implementation
 
         fenums:=nil;
         fretainedtypes:=nil;
+        fglobals:=nil;
+        femptyexpression:=nil;
         fcunode:=nil;
 
         ffilemeta:=thashset.Create(10000,true,false);
@@ -427,7 +434,7 @@ implementation
 
     destructor TDebugInfoLLVM.Destroy;
       begin
-        // don't free fenums/fretainedtypes, they get emitted in the assembler list
+        // don't free fenums/fretainedtypes/fglobals, they get emitted in the assembler list
         ffilemeta.free;
         ffilemeta:=nil;
         flocationmeta.free;
@@ -470,6 +477,8 @@ implementation
           begin
             fenums:=tai_llvmunnamedmetadatanode.create;
             fretainedtypes:=tai_llvmunnamedmetadatanode.create;
+            fglobals:=tai_llvmunnamedmetadatanode.create;
+            femptyexpression:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
             fcunode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompileUnit);
           end;
       end;
@@ -504,6 +513,8 @@ implementation
         fcunode:=nil;
         fenums:=nil;
         fretainedtypes:=nil;
+        fglobals:=nil;
+        femptyexpression:=nil;
       end;
 
     procedure TDebugInfoLLVM.collectglobalsyms;
@@ -1211,17 +1222,14 @@ implementation
       procedure adddispflags(dinode: tai_llvmspecialisedmetadatanode; is_definition, is_virtual: boolean);
         var
           dispflags: TSymStr;
+          islocal: boolean;
         begin
+          islocal:=
+            not((po_global in def.procoptions) and
+                (def.parast.symtablelevel<=normal_function_level));
+          adddefinitionlocal(dinode,is_definition,islocal,not(llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion]),dispflags);
           if llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion] then
             begin
-              dinode.addboolean('isDefinition',is_definition);
-              if is_definition then
-                begin
-                  dinode.addboolean('isLocal',
-                    not((po_global in def.procoptions) and
-                     (def.parast.symtablelevel<=normal_function_level))
-                  );
-                end;
               if is_virtual then
                 begin
                   if not(po_abstractmethod in def.procoptions) then
@@ -1232,15 +1240,6 @@ implementation
               exit;
             end;
 
-          dispflags:='';
-          if is_definition then
-            begin
-              dispflags:='DISPFlagDefinition';
-              if not((po_global in def.procoptions) and
-                     (def.parast.symtablelevel<=normal_function_level)) then
-                dispflags:=dispflags+'|DISPFlagLocalToUnit';
-            end;
-
           if is_virtual then
             begin
               if dispflags<>'' then
@@ -1411,6 +1410,27 @@ implementation
         def.dbg_state:=dbg_state_written;
       end;
 
+    procedure TDebugInfoLLVM.adddefinitionlocal(dinode: tai_llvmspecialisedmetadatanode; definition, local, usedispflags: boolean; out dispFlags: tsymstr);
+      begin
+        dispflags:='';
+        if not usedispflags then
+          begin
+            dinode.addboolean('isDefinition',definition);
+            if definition then
+              begin
+                dinode.addboolean('isLocal',local);
+              end;
+            exit;
+          end;
+
+        if definition then
+          begin
+            dispflags:='DISPFlagDefinition';
+            if local then
+              dispflags:=dispflags+'|DISPFlagLocalToUnit';
+          end;
+    end;
+
 
     function TDebugInfoLLVM.get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
 (*
@@ -1794,20 +1814,58 @@ implementation
 
 
     procedure TDebugInfoLLVM.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
+      var
+        decl: taillvmdecl;
+        globalvarexpression, globalvar: tai_llvmspecialisedmetadatanode;
+        dispflags: tsymstr;
+        islocal: boolean;
       begin
-        appendsym_var(list,sym);
+        decl:=sym_get_decl(sym);
+        if not assigned(decl) then
+          begin
+            list.concat(tai_comment.create(strpnew('no declaration found for '+sym.mangledname)));
+            exit;
+          end;
+        globalvar:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIGlobalVariable);
+        list.concat(globalvar);
+
+        globalvarexpression:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIGlobalVariableExpression);
+        globalvarexpression.addmetadatarefto('var',globalvar);
+        globalvarexpression.addmetadatarefto('expr',femptyexpression);
+        list.concat(globalvarexpression);
+        fglobals.addvalue(llvm_getmetadatareftypedconst(globalvarexpression));
+
+        decl.addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',globalvarexpression));
+
+        globalvar.addstring('name',symname(sym,false));
+        if not assigned(sym.owner.defowner) then
+          globalvar.addmetadatarefto('scope',fcunode)
+        else
+          globalvar.addmetadatarefto('scope',def_meta_node(tdef(sym.owner.defowner)));
+        try_add_file_metaref(globalvar,sym.fileinfo,false);
+        globalvar.addmetadatarefto('type',def_meta_node(sym.vardef));
+
+        islocal:=not(
+          ((sym.owner.symtabletype = globalsymtable) or
+          (sp_static in sym.symoptions) or
+          (vo_is_public in sym.varoptions))
+        );
+
+        adddefinitionlocal(globalvar,not(vo_is_external in sym.varoptions),islocal,false,dispflags);
+        if dispflags<>'' then
+          globalvar.addenum('spFlags',dispflags);
       end;
 
 
     procedure TDebugInfoLLVM.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
       begin
-        appendsym_var(list,sym);
+//        appendsym_var(list,sym);
       end;
 
 
     procedure TDebugInfoLLVM.appendsym_paravar(list:TAsmList;sym:tparavarsym);
       begin
-        appendsym_var(list,sym);
+//        appendsym_var(list,sym);
       end;
 
 
@@ -2239,8 +2297,8 @@ implementation
           begin
             fcunode.addmetadatarefto('enums',nil);
             fenums.free;
-            fenums:=nil;
           end;
+        fenums:=nil;
         if fretainedtypes.valuecount<>0 then
           begin
             fcunode.addmetadatarefto('retainedTypes',fretainedtypes);
@@ -2250,8 +2308,22 @@ implementation
           begin
             fcunode.addmetadatarefto('retainedTypes',nil);
             fretainedtypes.free;
-            fretainedtypes:=nil;
           end;
+        fretainedtypes:=nil;
+        if fglobals.valuecount<>0 then
+          begin
+            fcunode.addmetadatarefto('globals',fglobals);
+            current_asmdata.AsmLists[al_dwarf_info].Concat(fglobals);
+          end
+        else
+          begin
+            fcunode.addmetadatarefto('globals',nil);
+            fglobals.free;
+          end;
+        fglobals:=nil;
+        current_asmdata.AsmLists[al_dwarf_info].Concat(femptyexpression);
+        femptyexpression:=nil;
+
         if target_info.system in systems_darwin then
           fcunode.addenum('nameTableKind','GNU');
         current_asmdata.AsmLists[al_dwarf_info].Concat(fcunode);