Ver Fonte

* basic llvm metadata support

git-svn-id: branches/debug_eh@41978 -
Jonas Maebe há 6 anos atrás
pai
commit
3fa6838815

+ 1 - 0
.gitattributes

@@ -338,6 +338,7 @@ compiler/jvm/tgcpu.pas svneol=native#text/plain
 compiler/ldscript.pas svneol=native#text/plain
 compiler/ldscript.pas svneol=native#text/plain
 compiler/link.pas svneol=native#text/plain
 compiler/link.pas svneol=native#text/plain
 compiler/llvm/aasmllvm.pas svneol=native#text/plain
 compiler/llvm/aasmllvm.pas svneol=native#text/plain
+compiler/llvm/aasmllvmmetadata.pas svneol=native#text/plain
 compiler/llvm/agllvm.pas svneol=native#text/plain
 compiler/llvm/agllvm.pas svneol=native#text/plain
 compiler/llvm/cgllvm.pas svneol=native#text/plain
 compiler/llvm/cgllvm.pas svneol=native#text/plain
 compiler/llvm/hlcgllvm.pas svneol=native#text/plain
 compiler/llvm/hlcgllvm.pas svneol=native#text/plain

+ 2 - 2
compiler/aasmcnst.pas

@@ -52,7 +52,7 @@ type
 
 
    { a simple data element; the value is stored as a tai }
    { a simple data element; the value is stored as a tai }
    tai_simpletypedconst = class(tai_abstracttypedconst)
    tai_simpletypedconst = class(tai_abstracttypedconst)
-   private
+    private
      procedure setval(AValue: tai);
      procedure setval(AValue: tai);
     protected
     protected
      fval: tai;
      fval: tai;
@@ -90,7 +90,7 @@ type
     public
     public
      constructor create(_adetyp: ttypedconstkind; _fdef: tdef);
      constructor create(_adetyp: ttypedconstkind; _fdef: tdef);
      function getenumerator: tadeenumerator;
      function getenumerator: tadeenumerator;
-     procedure addvalue(val: tai_abstracttypedconst);
+     procedure addvalue(val: tai_abstracttypedconst); virtual;
      function valuecount: longint;
      function valuecount: longint;
      procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
      procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
      procedure replacevalueatpos(val: tai_abstracttypedconst; pos: longint);
      procedure replacevalueatpos(val: tai_abstracttypedconst; pos: longint);

+ 9 - 0
compiler/aasmtai.pas

@@ -87,6 +87,9 @@ interface
           ait_llvmins, { llvm instruction }
           ait_llvmins, { llvm instruction }
           ait_llvmalias, { alias for a symbol }
           ait_llvmalias, { alias for a symbol }
           ait_llvmdecl, { llvm symbol declaration (global/external variable, external procdef) }
           ait_llvmdecl, { llvm symbol declaration (global/external variable, external procdef) }
+          ait_llvmmetadatanode, (* llvm metadata node: !id = !{type value, ...} *)
+          ait_llvmmetadatareftypedconst, { reference to metadata inside a metadata constant }
+          ait_llvmmetadatarefoperand, { llvm metadata referece: !metadataname !id }
 {$endif}
 {$endif}
           { SEH directives used in ARM,MIPS and x86_64 COFF targets }
           { SEH directives used in ARM,MIPS and x86_64 COFF targets }
           ait_seh_directive,
           ait_seh_directive,
@@ -222,6 +225,9 @@ interface
           'llvmins',
           'llvmins',
           'llvmalias',
           'llvmalias',
           'llvmdecl',
           'llvmdecl',
+          'llvmmetadata',
+          'llvmmetadatareftc',
+          'llvmmetadatarefop',
 {$endif}
 {$endif}
           'cfi',
           'cfi',
           'seh_directive'
           'seh_directive'
@@ -323,6 +329,9 @@ interface
 {$endif JVM}
 {$endif JVM}
 {$ifdef llvm}
 {$ifdef llvm}
                      ait_llvmdecl,
                      ait_llvmdecl,
+                     ait_llvmmetadatanode,
+                     ait_llvmmetadatareftypedconst,
+                     ait_llvmmetadatarefoperand,
 {$endif llvm}
 {$endif llvm}
                      ait_seh_directive,
                      ait_seh_directive,
                      ait_cfi
                      ait_cfi

+ 187 - 0
compiler/llvm/aasmllvmmetadata.pas

@@ -0,0 +1,187 @@
+{
+    Copyright (c) 2019 by Jonas Maebe,
+    member of the Free Pascal Compiler development team
+
+    Support for LLVM metadata
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit aasmllvmmetadata;
+
+{$i fpcdefs.inc}
+
+interface
+
+  uses
+    aasmtai, aasmcnst,
+    symtype;
+
+  type
+    tspecialisedmetadatanodekind = (
+      smeta_DIFile,
+      smeta_DIBasicType,
+      smeta_DISubroutineType,
+      smeta_DIDerivedType,
+      smeta_DICompositeType,
+      smeta_DISubrange,
+      smeta_DIEnumerator,
+      smeta_DITemplateTypeParameter,
+      smeta_DITemplateValueParameter,
+      smeta_DINamespace,
+      smeta_DIGlobalVariable,
+      smeta_DISubprogram,
+      smeta_DILexicalBlock,
+      smeta_DILexicalBlockFile,
+      smeta_DILocation,
+      smeta_DILocalVariable,
+      smeta_DIExpression,
+      smeta_DIObjCProperty,
+      smeta_DIImportedEntity,
+      smeta_DIMacro,
+      smeta_DIMacroFile
+    );
+
+    tai_llvmbasemetadatanode = class abstract(tai_aggregatetypedconst)
+     strict protected
+      function getname: ansistring; virtual; abstract;
+     public
+      procedure addvalue(val: tai_abstracttypedconst); override;
+      property name: ansistring read getname;
+      constructor create; reintroduce;
+    end;
+
+    (* !0 = !{ type1 value1, ... } *)
+    tai_llvmunnamedmetadatanode = class(tai_llvmbasemetadatanode)
+     strict private class var
+      snextid: cardinal;
+      class function getnextid: cardinal;
+     strict protected
+      fnameval: cardinal;
+     public
+      constructor create; reintroduce;
+      function getname: ansistring; override;
+    end;
+
+    (* !name = !{ type1 value1, ... } *)
+    tai_llvmnamedmetadatanode = class(tai_llvmbasemetadatanode)
+     strict protected
+      fname: ansistring;
+      function getname: ansistring; override;
+     public
+      constructor create(const aName: ansistring);
+    end;
+
+    tai_llvmmetadatareftypedconst = class(tai_simple)
+     strict private
+      fval: tai_llvmbasemetadatanode;
+     public
+      constructor create(_val: tai_llvmbasemetadatanode);
+      property val: tai_llvmbasemetadatanode read fval;
+    end;
+
+    { @g1 = global i32 0, *!id !value.name* }
+    tai_llvmmetadatareferenceoperand = class(tai_simple)
+     strict private
+      fid: ansistring;
+      fvalue: tai_llvmbasemetadatanode;
+     public
+      constructor create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
+      property id: ansistring read fid;
+      property value: tai_llvmbasemetadatanode read fvalue;
+    end;
+
+      { !name = !kindname(field1: value1, ...) }
+    tai_llvmspecialisedmetadatanode = class(tai_llvmunnamedmetadatanode)
+      { identifies name and fieldnames }
+      kind: tspecialisedmetadatanodekind;
+    end;
+
+    function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
+
+implementation
+
+  uses
+    symdef;
+
+  function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
+    begin
+      result:=tai_simpletypedconst.create(llvm_metadatatype, tai_llvmmetadatareftypedconst.create(metadata));
+    end;
+
+  procedure tai_llvmbasemetadatanode.addvalue(val: tai_abstracttypedconst);
+    begin
+      { bypass string merging attempts, as we add tai_strings directly here }
+      fvalues.add(val);
+    end;
+
+  constructor tai_llvmbasemetadatanode.create;
+    begin
+      inherited create(tck_array, llvm_metadatatype);
+      typ:=ait_llvmmetadatanode;
+    end;
+
+
+  class function tai_llvmunnamedmetadatanode.getnextid: cardinal;
+    begin
+      result:=snextid;
+      inc(snextid);
+    end;
+
+
+  function tai_llvmunnamedmetadatanode.getname: ansistring;
+    begin
+      str(fnameval,result);
+    end;
+
+
+  constructor tai_llvmunnamedmetadatanode.create;
+    begin
+      inherited;
+      fnameval:=getnextid;
+    end;
+
+
+  function tai_llvmnamedmetadatanode.getname: ansistring;
+    begin
+      result:=fname;
+    end;
+
+
+  constructor tai_llvmnamedmetadatanode.create(const aName: ansistring);
+    begin
+      inherited create;
+      fname:=aName;
+    end;
+
+
+  constructor tai_llvmmetadatareftypedconst.create(_val: tai_llvmbasemetadatanode);
+    begin
+      inherited create(ait_llvmmetadatareftypedconst);
+      fval:=_val;
+    end;
+
+
+  constructor tai_llvmmetadatareferenceoperand.create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
+    begin
+      inherited create(ait_llvmmetadatarefoperand);
+      fid:=anID;
+      fvalue:=aValue;
+    end;
+
+
+end.
+

+ 103 - 24
compiler/llvm/agllvm.pas

@@ -30,7 +30,7 @@ interface
       globtype,globals,systems,
       globtype,globals,systems,
       aasmbase,aasmtai,aasmdata,
       aasmbase,aasmtai,aasmdata,
       assemble,
       assemble,
-      aasmllvm;
+      aasmllvm, aasmllvmmetadata;
 
 
     type
     type
       TLLVMInstrWriter = class;
       TLLVMInstrWriter = class;
@@ -61,7 +61,7 @@ interface
         procedure WriteDirectiveName(dir: TAsmDirective); virtual;
         procedure WriteDirectiveName(dir: TAsmDirective); virtual;
         procedure WriteRealConst(hp: tai_realconst; do_line: boolean);
         procedure WriteRealConst(hp: tai_realconst; do_line: boolean);
         procedure WriteOrdConst(hp: tai_const);
         procedure WriteOrdConst(hp: tai_const);
-        procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
+        procedure WriteTai(const replaceforbidden: boolean; const do_line, inmetadata: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
        public
        public
         constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
         constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteTree(p:TAsmList);override;
@@ -376,7 +376,7 @@ implementation
                  hp:=para^.ai;
                  hp:=para^.ai;
                  owner.writer.AsmWrite(fstr);
                  owner.writer.AsmWrite(fstr);
                  fstr:='';
                  fstr:='';
-                 owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
+                 owner.WriteTai(false,false,para^.def=llvm_metadatatype,tmpinline,tmpasmblock,hp);
                end;
                end;
              { empty records }
              { empty records }
              top_undef:
              top_undef:
@@ -436,7 +436,6 @@ implementation
 
 
    function TLLVMInstrWriter.getopstr(const o:toper; refwithalign: boolean) : TSymStr;
    function TLLVMInstrWriter.getopstr(const o:toper; refwithalign: boolean) : TSymStr;
      var
      var
-       hs : ansistring;
        hp: tai;
        hp: tai;
        tmpinline: cardinal;
        tmpinline: cardinal;
        tmpasmblock: boolean;
        tmpasmblock: boolean;
@@ -499,7 +498,7 @@ implementation
                  hp:=o.ai;
                  hp:=o.ai;
                  owner.writer.AsmWrite(fstr);
                  owner.writer.AsmWrite(fstr);
                  fstr:='';
                  fstr:='';
-                 owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
+                 owner.WriteTai(false,false,false,tmpinline,tmpasmblock,hp);
                end;
                end;
              result:='';
              result:='';
            end;
            end;
@@ -838,7 +837,7 @@ implementation
               WriteSourceLine(hp as tailineinfo);
               WriteSourceLine(hp as tailineinfo);
           end;
           end;
 
 
-         WriteTai(replaceforbidden, do_line, InlineLevel, asmblock, hp);
+         WriteTai(replaceforbidden, do_line, false, InlineLevel, asmblock, hp);
          hp:=tai(hp.next);
          hp:=tai(hp.next);
        end;
        end;
     end;
     end;
@@ -971,7 +970,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
+    procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line, inmetadata: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
 
 
       procedure WriteLinkageVibilityFlags(bind: TAsmSymBind);
       procedure WriteLinkageVibilityFlags(bind: TAsmSymBind);
         begin
         begin
@@ -1021,20 +1020,34 @@ implementation
         end;
         end;
 
 
 
 
-      procedure WriteTypedConstData(hp: tai_abstracttypedconst);
+      procedure WriteTypedConstData(hp: tai_abstracttypedconst; metadata: boolean);
         var
         var
           p: tai_abstracttypedconst;
           p: tai_abstracttypedconst;
           pval: tai;
           pval: tai;
           defstr: TSymStr;
           defstr: TSymStr;
           first, gotstring: boolean;
           first, gotstring: boolean;
         begin
         begin
-          defstr:=llvmencodetypename(hp.def);
+          if hp.def<>llvm_metadatatype then
+            begin
+              defstr:=llvmencodetypename(hp.def)
+            end
+          else
+            begin
+              defstr:=''
+            end;
           { write the struct, array or simple type }
           { write the struct, array or simple type }
           case hp.adetyp of
           case hp.adetyp of
             tck_record:
             tck_record:
               begin
               begin
-                writer.AsmWrite(defstr);
-                writer.AsmWrite(' <{');
+                if not(metadata) then
+                  begin
+                    writer.AsmWrite(defstr);
+                    writer.AsmWrite(' <{');
+                  end
+                else
+                  begin
+                    writer.AsmWrite(' !{');
+                  end;
                 first:=true;
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                   begin
@@ -1042,19 +1055,29 @@ implementation
                       writer.AsmWrite(', ')
                       writer.AsmWrite(', ')
                     else
                     else
                       first:=false;
                       first:=false;
-                    WriteTypedConstData(p);
+                    WriteTypedConstData(p,metadata);
+                  end;
+                if not(metadata) then
+                  begin
+                    writer.AsmWrite('}>');
+                  end
+                else
+                  begin
+                    writer.AsmWrite('}');
                   end;
                   end;
-                writer.AsmWrite('}>');
               end;
               end;
             tck_array:
             tck_array:
               begin
               begin
-                writer.AsmWrite(defstr);
+                if not(metadata) then
+                  begin
+                    writer.AsmWrite(defstr);
+                  end;
                 first:=true;
                 first:=true;
                 gotstring:=false;
                 gotstring:=false;
                 for p in tai_aggregatetypedconst(hp) do
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                   begin
                     if not first then
                     if not first then
-                      writer.AsmWrite(',')
+                      writer.AsmWrite(', ')
                     else
                     else
                       begin
                       begin
                         writer.AsmWrite(' ');
                         writer.AsmWrite(' ');
@@ -1065,33 +1088,65 @@ implementation
                           end
                           end
                         else
                         else
                           begin
                           begin
-                            writer.AsmWrite('[');
+                            if not metadata then
+                              begin
+                                writer.AsmWrite('[');
+                              end
+                            else
+                              begin
+                                writer.AsmWrite('!{');
+                              end;
                           end;
                           end;
                         first:=false;
                         first:=false;
                       end;
                       end;
                     { cannot concat strings and other things }
                     { cannot concat strings and other things }
                     if gotstring and
                     if gotstring and
+                       not metadata and
                        ((tai_abstracttypedconst(p).adetyp<>tck_simple) or
                        ((tai_abstracttypedconst(p).adetyp<>tck_simple) or
                         (tai_simpletypedconst(p).val.typ<>ait_string)) then
                         (tai_simpletypedconst(p).val.typ<>ait_string)) then
                       internalerror(2014062701);
                       internalerror(2014062701);
-                    WriteTypedConstData(p);
+                    WriteTypedConstData(p,metadata);
                   end;
                   end;
                 if not gotstring then
                 if not gotstring then
-                  writer.AsmWrite(']');
+                  begin
+                    if not metadata then
+                      begin
+                        writer.AsmWrite(']');
+                      end
+                    else
+                      begin
+                        writer.AsmWrite('}');
+                      end;
+                  end;
               end;
               end;
             tck_simple:
             tck_simple:
               begin
               begin
                 pval:=tai_simpletypedconst(hp).val;
                 pval:=tai_simpletypedconst(hp).val;
-                if pval.typ<>ait_string then
+                if (pval.typ<>ait_string) and
+                   (defstr<>'') then
                   begin
                   begin
                     writer.AsmWrite(defstr);
                     writer.AsmWrite(defstr);
                     writer.AsmWrite(' ');
                     writer.AsmWrite(' ');
                   end;
                   end;
-                WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
+                WriteTai(replaceforbidden,do_line,metadata,InlineLevel,asmblock,pval);
               end;
               end;
           end;
           end;
         end;
         end;
 
 
+      procedure WriteLlvmMetadataNode(hp: tai_llvmbasemetadatanode);
+        begin
+          { must only appear at the top level }
+          if fdecllevel<>0 then
+            internalerror(2019050111);
+          writer.AsmWrite('!');
+          writer.AsmWrite(tai_llvmbasemetadatanode(hp).name);
+          writer.AsmWrite(' =');
+          inc(fdecllevel);
+          WriteTypedConstData(hp,true);
+          writer.AsmLn;
+          dec(fdecllevel);
+        end;
+
       var
       var
         hp2: tai;
         hp2: tai;
         s: string;
         s: string;
@@ -1162,7 +1217,10 @@ implementation
             begin
             begin
               if fdecllevel=0 then
               if fdecllevel=0 then
                 internalerror(2016120201);
                 internalerror(2016120201);
-              writer.AsmWrite('c"');
+              if not inmetadata then
+                writer.AsmWrite('c"')
+              else
+                writer.AsmWrite('!"');
               for i:=1 to tai_string(hp).len do
               for i:=1 to tai_string(hp).len do
                begin
                begin
                  ch:=tai_string(hp).str[i-1];
                  ch:=tai_string(hp).str[i-1];
@@ -1278,7 +1336,7 @@ implementation
                       hp2:=tai(taillvmdecl(hp).initdata.first);
                       hp2:=tai(taillvmdecl(hp).initdata.first);
                       while assigned(hp2) do
                       while assigned(hp2) do
                         begin
                         begin
-                          WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,hp2);
+                          WriteTai(replaceforbidden,do_line,inmetadata,InlineLevel,asmblock,hp2);
                           hp2:=tai(hp2.next);
                           hp2:=tai(hp2.next);
                         end;
                         end;
                       dec(fdecllevel);
                       dec(fdecllevel);
@@ -1328,6 +1386,28 @@ implementation
               writer.AsmWrite('* ');
               writer.AsmWrite('* ');
               writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
               writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
             end;
             end;
+          ait_llvmmetadatanode:
+            begin
+              WriteLlvmMetadataNode(tai_llvmbasemetadatanode(hp));
+            end;
+          ait_llvmmetadatareftypedconst:
+            begin
+              { must only appear as an element in a typed const }
+              if fdecllevel=0 then
+                internalerror(2019050110);
+              writer.AsmWrite('!');
+              writer.AsmWrite(tai_llvmbasemetadatanode(tai_llvmmetadatareftypedconst(hp).val).name);
+            end;
+          ait_llvmmetadatarefoperand:
+            begin
+              { must only appear as an operand }
+              if fdecllevel=0 then
+                internalerror(2019050110);
+              writer.AsmWrite('!');
+              writer.AsmWrite(tai_llvmmetadatareferenceoperand(hp).id);
+              writer.AsmWrite(' !');
+              writer.AsmWrite(tai_llvmmetadatareferenceoperand(hp).value.name);
+            end;
           ait_symbolpair:
           ait_symbolpair:
             begin
             begin
               { should be emitted as part of the symbol def }
               { should be emitted as part of the symbol def }
@@ -1411,7 +1491,7 @@ implementation
             end;
             end;
            ait_typedconst:
            ait_typedconst:
              begin
              begin
-               WriteTypedConstData(tai_abstracttypedconst(hp));
+               WriteTypedConstData(tai_abstracttypedconst(hp),false);
              end
              end
           else
           else
             internalerror(2019012010);
             internalerror(2019012010);
@@ -1435,7 +1515,6 @@ implementation
     procedure TLLVMAssember.WriteAsmList;
     procedure TLLVMAssember.WriteAsmList;
       var
       var
         hal : tasmlisttype;
         hal : tasmlisttype;
-        i: longint;
         a: TExternalAssembler;
         a: TExternalAssembler;
         decorator: TLLVMModuleInlineAssemblyDecorator;
         decorator: TLLVMModuleInlineAssemblyDecorator;
       begin
       begin

+ 3 - 0
compiler/llvm/llvmtype.pas

@@ -191,6 +191,9 @@ implementation
         if def.stab_number<>0 then
         if def.stab_number<>0 then
           exit;
           exit;
         def.stab_number:=1;
         def.stab_number:=1;
+        { this is an internal llvm type }
+        if def=llvm_metadatatype then
+          exit;
         if def.dbg_state=dbg_state_unused then
         if def.dbg_state=dbg_state_unused then
           begin
           begin
             def.dbg_state:=dbg_state_used;
             def.dbg_state:=dbg_state_used;

+ 8 - 0
compiler/psystem.pas

@@ -619,6 +619,11 @@ implementation
         addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[],true));
         addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[],true));
         nestedprocpointertype:=crecorddef.create('',hrecst);
         nestedprocpointertype:=crecorddef.create('',hrecst);
         addtype('$nestedprocpointer',nestedprocpointertype);
         addtype('$nestedprocpointer',nestedprocpointertype);
+{$ifdef llvm}
+        llvm_metadatatype:=cpointerdef.create(voidtype);
+        { if this gets renamed, also adjust agllvm so it still writes the identifier of this type as "metadata" }
+        addtype('$metadata',llvm_metadatatype);
+{$endif}
         symtablestack.pop(systemunit);
         symtablestack.pop(systemunit);
       end;
       end;
 
 
@@ -734,6 +739,9 @@ implementation
           end;
           end;
         loadtype('methodpointer',methodpointertype);
         loadtype('methodpointer',methodpointertype);
         loadtype('nestedprocpointer',nestedprocpointertype);
         loadtype('nestedprocpointer',nestedprocpointertype);
+{$ifdef llvm}
+        loadtype('metadata',llvm_metadatatype);
+{$endif}
         loadtype('HRESULT',hresultdef);
         loadtype('HRESULT',hresultdef);
         loadtype('TTYPEKIND',typekindtype);
         loadtype('TTYPEKIND',typekindtype);
         set_default_int_types;
         set_default_int_types;

+ 6 - 0
compiler/symdef.pas

@@ -1150,6 +1150,12 @@ interface
        objc_fastenumeration      : tobjectdef;
        objc_fastenumeration      : tobjectdef;
        objc_fastenumerationstate : trecorddef;
        objc_fastenumerationstate : trecorddef;
 
 
+{$ifdef llvm}
+       { llvm types }
+       { a unique def to identify any kind of metadata }
+       llvm_metadatatype         : tdef;
+{$endif llvm}
+
        { Java base types }
        { Java base types }
        { java.lang.Object }
        { java.lang.Object }
        java_jlobject             : tobjectdef;
        java_jlobject             : tobjectdef;