View Issue Details

IDProjectCategoryView StatusLast Update
0026173FPCCompilerpublic2016-01-24 21:41
ReporterRobert Gilland Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Summary0026173: Using "exports" in a unit does not compile
DescriptionThe below unit compiles in Delphi XE but fails in FPC with the following error:

Fatal: Syntax error, "IMPLEMENTATION" expected but "EXPORTS" found


Why?

Kind Regards,

Robert.



unit testexports;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses Classes, SysUtils;

function GetTestExport( id_ws : Integer; strwsList : string; procfilescreated : TGetStrProc ): Boolean; stdcall;


exports GetTestExport;

implementation

function GetTestExport( id_ws : Integer; strwsList : string; procfilescreated : TGetStrProc ): Boolean;
begin
  // do something
end;

end.
Steps To Reproduce1. use the unit in the description compile in Delphi XE. Good
2. Same unit in FPC. Fatal: Syntax error, "IMPLEMENTATION" expected but "EXPORTS" found
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Anton Kavalenka

2014-05-16 10:54

reporter   ~0075018

Last edited: 2014-05-16 10:54

View 3 revisions

imo exports works only in implementation section and only on windows.
see also 0018030

Thaddy de Koning

2014-05-16 18:43

reporter   ~0075027

Last edited: 2014-05-16 18:48

View 2 revisions

Huh? If that is the case the bug is major.

It is rather obvious that exports belong in the interface section, because that is what it ultimately is by definition: a form of interface.

Anton Kavalenka

2014-05-16 22:26

reporter   ~0075036

This example would export nothing from liba.so

library a;
uses b;
end.
==============================
unit b;
interface
procedure c;
//exports c;
implementation
procedure c;
begin
  writeln('c');
end;
exports c;
end.
===========================================
/usr/local/lib/fpc/2.7.1/ppc386 -Cg a.pas
Free Pascal Compiler version 2.7.1 [2014/03/09] for i386
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for i386
Compiling a.pas
Compiling b.pas
Linking liba.so
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
24 lines compiled, 0.2 sec

nm liba.so
nm: liba.so: no symbols

Jonas Maebe

2014-05-16 23:16

manager   ~0075037

You have to use "nm -D" to show the dynamic symbols.

Anton Kavalenka

2014-05-17 10:43

reporter   ~0075040

Last edited: 2014-05-17 10:50

View 2 revisions

nm -D liba.so
nm: liba.so: no symbols

now with debug info
/usr/local/lib/fpc/2.7.1/ppc386 -Cg -glv a.pas

nm -D liba.so
         U calloc
         w __cxa_finalize
         U free
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         w _Jv_RegisterClasses
         U malloc
         U realloc

Do-wan Kim

2014-05-21 00:53

reporter   ~0075152

how about with 0016070 patch?

Anton Kavalenka

2014-05-22 18:01

reporter   ~0075201

r27811 with unit_exports_support_03.patch from 0016070 does not work on
x86_64 linux.

still no export symbols. I think they are just eliminated by optimizer at some stage.

Using exports in interface is not allowed.

Anton Kavalenka

2016-01-24 15:36

reporter   ~0089308

Very rude but working approach to collect all exports in list, and write them at single pass.
exports now working both in interface and implementation and in all units of library.

Patch in two files proposed.

Anton Kavalenka

2016-01-24 15:36

reporter  

psub.diff (753 bytes)   
Index: psub.pas
===================================================================
--- psub.pas	(revision 32993)
+++ psub.pas	(working copy)
@@ -2429,6 +2429,17 @@
                  handle_unexpected_had_generic;
                  threadvar_dec(hadgeneric);
                end;
+             _EXPORTS:
+                begin
+									if islibrary or
+                     (target_info.system in systems_unit_program_exports) then
+                     read_exports
+                   else
+                     begin
+                        Message(parser_w_unsupported_feature);
+                        consume(_BEGIN);
+                     end;
+                end;
              _FUNCTION,
              _PROCEDURE,
              _OPERATOR :
psub.diff (753 bytes)   

Anton Kavalenka

2016-01-24 15:37

reporter  

expunix.diff (1,645 bytes)   
Index: expunix.pas
===================================================================
--- expunix.pas	(revision 32993)
+++ expunix.pas	(working copy)
@@ -37,6 +37,7 @@
   texportlibunix=class(texportlib)
    private
      fexportedsymnames: TCmdStrList;
+     fexpsyms: tfplist;
    public
     constructor Create; override;
     destructor destroy; override;
@@ -67,11 +68,13 @@
 constructor texportlibunix.create;
 begin
   inherited create;
-  fexportedsymnames:=tcmdstrlist.create_no_double;
+  fexportedsymnames := tcmdstrlist.create_no_double;
+  fexpsyms := tfplist.create;
 end;
 
 destructor texportlibunix.destroy;
 begin
+  fexpsyms.free;
   fexportedsymnames.free;
   inherited destroy;
 end;
@@ -117,6 +120,7 @@
     end
   else
     current_module._exports.concat(hp);
+  self.fexpsyms.add(hp);
 end;
 
 
@@ -131,6 +135,8 @@
 var
   hp2 : texported_item;
   pd  : tprocdef;
+  exp_mod: tmodule;
+  cnt:integer;
 {$ifdef x86}
   sym : tasmsymbol;
   r : treference;
@@ -138,9 +144,10 @@
 begin
   create_hlcodegen;
   new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
-  hp2:=texported_item(current_module._exports.first);
-  while assigned(hp2) do
+  exp_mod := main_module;
+  for cnt:=0 to fexpsyms.count-1 do
    begin
+     hp2:=texported_item(fexpsyms[cnt]);//texported_item(exp_mod._exports.first);
      if (not hp2.is_var) and
         assigned(hp2.sym) and
         (hp2.sym.typ=procsym) then
@@ -181,7 +188,7 @@
          else
            exportedsymnames.insert(hp2.name^);
        end;
-     hp2:=texported_item(hp2.next);
+//     hp2:=texported_item(hp2.next);
    end;
    destroy_hlcodegen;
 end;
expunix.diff (1,645 bytes)   

Anton Kavalenka

2016-01-24 15:40

reporter  

a.pas (71 bytes)   
library a;

uses b;

procedure d;
begin
writeln;
end;

exports d;

end.
a.pas (71 bytes)   

Anton Kavalenka

2016-01-24 15:41

reporter  

b.pas (124 bytes)   
unit b;

interface


procedure c;

//exports c;

implementation

procedure c;
begin
  writeln('c');
end;

exports c;

end.

b.pas (124 bytes)   

Anton Kavalenka

2016-01-24 15:41

reporter   ~0089310

Test project files a.pas and b.pas uploaded

Cyrax

2016-01-24 21:41

reporter   ~0089323

Related to http://bugs.freepascal.org/view.php?id=16070

Issue History

Date Modified Username Field Change
2014-05-16 00:42 Robert Gilland New Issue
2014-05-16 01:45 Maxim Ganetsky Project Lazarus => FPC
2014-05-16 10:54 Anton Kavalenka Note Added: 0075018
2014-05-16 10:54 Anton Kavalenka Note Edited: 0075018 View Revisions
2014-05-16 10:54 Anton Kavalenka Note Edited: 0075018 View Revisions
2014-05-16 18:43 Thaddy de Koning Note Added: 0075027
2014-05-16 18:48 Thaddy de Koning Note Edited: 0075027 View Revisions
2014-05-16 22:26 Anton Kavalenka Note Added: 0075036
2014-05-16 23:16 Jonas Maebe Note Added: 0075037
2014-05-17 10:43 Anton Kavalenka Note Added: 0075040
2014-05-17 10:50 Anton Kavalenka Note Edited: 0075040 View Revisions
2014-05-21 00:53 Do-wan Kim Note Added: 0075152
2014-05-22 18:01 Anton Kavalenka Note Added: 0075201
2016-01-24 15:36 Anton Kavalenka Note Added: 0089308
2016-01-24 15:36 Anton Kavalenka File Added: psub.diff
2016-01-24 15:37 Anton Kavalenka File Added: expunix.diff
2016-01-24 15:40 Anton Kavalenka File Added: a.pas
2016-01-24 15:41 Anton Kavalenka File Added: b.pas
2016-01-24 15:41 Anton Kavalenka Note Added: 0089310
2016-01-24 21:41 Cyrax Note Added: 0089323