Explorar o código

* support taking the address of labels defined in assembler blocks in the
LLVM code genrator (for the rtti unit's thunk hacking)

git-svn-id: trunk@42969 -

Jonas Maebe %!s(int64=5) %!d(string=hai) anos
pai
achega
dcf4e4cb2c
Modificáronse 4 ficheiros con 33 adicións e 12 borrados
  1. 1 0
      compiler/aasmbase.pas
  2. 12 5
      compiler/llvm/agllvm.pas
  3. 18 6
      compiler/llvm/nllvmtcon.pas
  4. 2 1
      compiler/rautils.pas

+ 1 - 0
compiler/aasmbase.pas

@@ -224,6 +224,7 @@ interface
          labeltype : TAsmLabelType;
          is_set    : boolean;
          is_public : boolean;
+         defined_in_asmstatement : boolean;
          constructor Createlocal(AList: TFPHashObjectList; nr: longint; ltyp: TAsmLabelType);
          constructor Createstatic(AList: TFPHashObjectList; nr: longint; ltyp: TAsmLabelType);
          constructor Createglobal(AList: TFPHashObjectList; const modulename: TSymStr; nr: longint; ltyp: TAsmLabelType);

+ 12 - 5
compiler/llvm/agllvm.pas

@@ -973,8 +973,15 @@ implementation
 
     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; is_definition: boolean);
         begin
+          { re-declaration of a symbol defined in the current module (in an
+            assembler block) }
+          if not is_definition then
+            begin
+              writer.AsmWrite(' external');
+              exit;
+            end;
           case bind of
              AB_EXTERNAL,
              AB_EXTERNAL_INDIRECT:
@@ -1297,7 +1304,7 @@ implementation
                       writer.AsmWrite('define');
                       if ldf_weak in taillvmdecl(hp).flags then
                         writer.AsmWrite(' weak');
-                      WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind);
+                      WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind, true);
                       writer.AsmWrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_def));
                       WriteFunctionFlags(tprocdef(taillvmdecl(hp).def));
                       if assigned(tprocdef(taillvmdecl(hp).def).personality) then
@@ -1319,7 +1326,7 @@ implementation
                     writer.AsmWrite(' weak');
                   if ldf_appending in taillvmdecl(hp).flags then
                     writer.AsmWrite(' appending');
-                  WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind);
+                  WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind, ldf_definition in taillvmdecl(hp).flags);
                   writer.AsmWrite(' ');
                   if (ldf_tls in taillvmdecl(hp).flags) then
                     writer.AsmWrite('thread_local ');
@@ -1332,7 +1339,7 @@ implementation
                   if not assigned(taillvmdecl(hp).initdata) then
                     begin
                       writer.AsmWrite(llvmencodetypename(taillvmdecl(hp).def));
-                      if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL,AB_EXTERNAL_INDIRECT]) then
+                      if ldf_definition in taillvmdecl(hp).flags then
                         writer.AsmWrite(' zeroinitializer');
                     end
                   else
@@ -1384,7 +1391,7 @@ implementation
             begin
               writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym));
               writer.AsmWrite(' = alias ');
-              WriteLinkageVibilityFlags(taillvmalias(hp).bind);
+              WriteLinkageVibilityFlags(taillvmalias(hp).bind, true);
               if taillvmalias(hp).def.typ=procdef then
                 sstr:=llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias)
               else

+ 18 - 6
compiler/llvm/nllvmtcon.pas

@@ -794,12 +794,24 @@ implementation
       firstop,
       secondop: tllvmop;
     begin
-      ai:=taillvm.blockaddress(voidcodepointertype,
-          current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION),
-          current_asmdata.RefAsmSymbol(l.mangledname,AT_LABEL)
-        );
-      emit_tai(ai,voidcodepointertype);
-      fqueue_offset:=low(fqueue_offset);
+      if not assigned(l.asmblocklabel) or
+         not l.asmblocklabel.defined_in_asmstatement then
+        begin
+          ai:=taillvm.blockaddress(voidcodepointertype,
+              current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION),
+              current_asmdata.RefAsmSymbol(l.mangledname,AT_LABEL)
+            );
+          emit_tai(ai,voidcodepointertype);
+          fqueue_offset:=low(fqueue_offset);
+        end
+      else
+        begin
+          { we've already incorporated the offset via the inserted operations above,
+            make sure it doesn't get emitted again as part of the tai_const for
+            the tasmsymbol }
+          fqueue_offset:=0;
+          inherited;
+        end;
     end;
 
 

+ 2 - 1
compiler/rautils.pas

@@ -1754,7 +1754,8 @@ Begin
           begin
             if tlabelsym(sym).defined then
               Message(sym_e_label_already_defined);
-            tlabelsym(sym).defined:=true
+            tlabelsym(sym).defined:=true;
+            hl.defined_in_asmstatement:=true
           end
         else
           tlabelsym(sym).used:=true;