Skip to content

Commit

Permalink
fbc: #pragma private
Browse files Browse the repository at this point in the history
Purpose is to allow procedures in sources to be compiled as separate modules with
public linkage or as privately included with minimal overhead for changing desired
linkage.

- set default procedure linkage with
  '#pragma private [=value]' or
  '#pragma push( private [,value] )'

- #pragma private
- #pragma private = true
- #pragma private = false
- #pragma push( private )
- #pragma push( private, true )
- #pragma push( private, false )
- #pragma pop( private )
  • Loading branch information
jayrm committed Oct 1, 2023
1 parent be87cc2 commit 7899fc7
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 16 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -8,6 +8,7 @@ Version 1.20.0

[added]
- x86_64: optimize SHL MOD INTDIV to use 32-bit operation when result will be converted to long/ulong
- set default procedure linkage with '#pragma private [=value]' or '#pragma push( private [,value] )'

[fixed]
- github #410: give consistent floating point comparisons results involving NaNs.
Expand Down
61 changes: 45 additions & 16 deletions src/compiler/pp-pragma.bas
Expand Up @@ -15,24 +15,38 @@ enum LEXPP_PRAGMAFLAG_ENUM
LEXPP_PRAGMAFLAG_CAN_ASSIGN = 2
LEXPP_PRAGMAFLAG_HAS_CALLBACK = 4
LEXPP_PRAGMAFLAG_PRESERVE_UNDER_PP = 8
LEXPP_PRAGMAFLAG_PDCHECK = 16
LEXPP_PRAGMAFLAG_IS_BOOLEAN = 16

LEXPP_PRAGMAFLAG_DEFAULT = LEXPP_PRAGMAFLAG_CAN_PUSHPOP or _
LEXPP_PRAGMAFLAG_CAN_ASSIGN or _
LEXPP_PRAGMAFLAG_PRESERVE_UNDER_PP
LEXPP_PRAGMAFLAG_CAN_ASSIGN or _
LEXPP_PRAGMAFLAG_PRESERVE_UNDER_PP or _
LEXPP_PRAGMAFLAG_IS_BOOLEAN
end enum

enum FBOPTION_ENUM
FBOPTION_PROCPUBLIC = 1 '' env.opt.procpublic (fbint.bi:TYPE FBOPTION)
end enum

enum LEXPP_PRAGMAGRP
LEXPP_PRAGMAGRP_CALLBACK = 0 '' callback
LEXPP_PRAGMAGRP_COMPOPT = 1 '' env.clopt (FB_COMPOPT) fbGet|Set|ChangeOption()
LEXPP_PRAGMAGRP_FBOPTION = 2 '' env.opt (FBOPTION_ENUM)
LEXPP_PRAGMAGRP_PDCHECK = 3 '' env.clopt.pdcheckopt (FB_PDCHECK)
end enum

type LEXPP_PRAGMAOPT
tk as zstring * 16
opt as integer
flags as integer
grp as LEXPP_PRAGMAGRP
opt as integer '' FB_COMPOPT | FB_PDCHECK | FBOPTION_ENUM
flags as LEXPP_PRAGMAFLAG_ENUM
end type

enum LEXPP_PRAGMAOPT_ENUM
LEXPP_PRAGMAOPT_BITFIELD
LEXPP_PRAGMAOPT_ONCE
LEXPP_PRAGMAOPT_WARNCONSTNESS
LEXPP_PRAGMAOPT_RESERVE
LEXPP_PRAGMAOPT_PRIVATE

LEXPP_PRAGMAS
end enum
Expand All @@ -48,10 +62,11 @@ end type
'' same order as LEXPP_PRAGMAOPT_ENUM
dim shared pragmaOpt(0 to LEXPP_PRAGMAS-1) as LEXPP_PRAGMAOPT => _
{ _
("msbitfields", FB_COMPOPT_MSBITFIELDS, LEXPP_PRAGMAFLAG_DEFAULT ), _
("once" , 0 , LEXPP_PRAGMAFLAG_HAS_CALLBACK ), _
("constness" , FB_PDCHECK_CONSTNESS , LEXPP_PRAGMAFLAG_PDCHECK or LEXPP_PRAGMAFLAG_DEFAULT ), _
("reserve" , 0 , LEXPP_PRAGMAFLAG_HAS_CALLBACK ) _
("msbitfields", LEXPP_PRAGMAGRP_COMPOPT , FB_COMPOPT_MSBITFIELDS, LEXPP_PRAGMAFLAG_DEFAULT ), _
("once" , LEXPP_PRAGMAGRP_CALLBACK, 0 , LEXPP_PRAGMAFLAG_HAS_CALLBACK ), _
("constness" , LEXPP_PRAGMAGRP_PDCHECK , FB_PDCHECK_CONSTNESS , LEXPP_PRAGMAFLAG_DEFAULT ), _
("reserve" , LEXPP_PRAGMAGRP_CALLBACK, 0 , LEXPP_PRAGMAFLAG_HAS_CALLBACK ), _
("private" , LEXPP_PRAGMAGRP_FBOPTION, FBOPTION_PROCPUBLIC , LEXPP_PRAGMAFLAG_DEFAULT ) _
}

sub ppPragmaInit( )
Expand Down Expand Up @@ -319,11 +334,18 @@ sub ppPragma( )
value = FALSE

if( ispush ) then
if( (pragmaOpt(p).flags and LEXPP_PRAGMAFLAG_PDCHECK) <> 0 ) then
select case pragmaOpt(p).grp
case LEXPP_PRAGMAGRP_PDCHECK
pragmaPush( p, fbPdCheckIsSet( pragmaOpt(p).opt ) )
else
case LEXPP_PRAGMAGRP_COMPOPT
pragmaPush( p, fbGetOption( pragmaOpt(p).opt ) )
end if
case LEXPP_PRAGMAGRP_FBOPTION
select case pragmaOpt(p).opt
case FBOPTION_PROCPUBLIC
'' #pragma private --> invert value for public
pragmaPush( p, (env.opt.procpublic = 0 ) )
end select
end select

'' ','?
if( lexGetToken() = CHAR_COMMA ) then
Expand Down Expand Up @@ -351,7 +373,7 @@ sub ppPragma( )
if( value = FALSE ) then
'' expr
value = cConstIntExpr( cExpression( ) )
if( (pragmaOpt(p).flags and LEXPP_PRAGMAFLAG_PDCHECK) <> 0 ) then
if( (pragmaOpt(p).flags and LEXPP_PRAGMAFLAG_IS_BOOLEAN) <> 0 ) then
value = (value <> 0)
end if
end if
Expand All @@ -378,12 +400,19 @@ sub ppPragma( )
end select
else
if( (pragmaOpt(p).flags and (LEXPP_PRAGMAFLAG_CAN_PUSHPOP or LEXPP_PRAGMAFLAG_CAN_ASSIGN)) <> 0 ) then
if( (pragmaOpt(p).flags and LEXPP_PRAGMAFLAG_PDCHECK) <> 0 ) then
select case pragmaOpt(p).grp
case LEXPP_PRAGMAGRP_PDCHECK
value = (value and pragmaOpt(p).opt) or (fbGetOption( FB_COMPOPT_PEDANTICCHK ) and not pragmaOpt(p).opt)
fbSetOption( FB_COMPOPT_PEDANTICCHK, value )
else
case LEXPP_PRAGMAGRP_COMPOPT
fbChangeOption( pragmaOpt(p).opt, value )
end if
case LEXPP_PRAGMAGRP_FBOPTION
select case pragmaOpt(p).opt
case FBOPTION_PROCPUBLIC
'' #pragma private --> invert value for public
env.opt.procpublic = ( value = 0 )
end select
end select
end if
end if

Expand Down
108 changes: 108 additions & 0 deletions tests/pp/pragma-private.bas
@@ -0,0 +1,108 @@
' TEST_MODE : COMPILE_ONLY_OK

'' #pragma private
'' #pragma private = false
'' #pragma private = true
'' #pragma push( private )
'' #pragma push( private, false )
'' #pragma push( private, true )
'' #pragma pop( private )
''

'' default value
#assert( __FB_OPTION_PRIVATE__ = false )

'' test implicit true

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma private
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma private = false
#assert( __FB_OPTION_PRIVATE__ = false )

'' test explicit true

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma private = true
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma private = false
#assert( __FB_OPTION_PRIVATE__ = false )


'' test implicit push

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

'' test explicit push false, push false nested

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, false )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, false )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

'' test explicit push false, push true nested

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, false )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, true )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

'' test explicit push true, push false nested

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, true )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma push( private, false )
#assert( __FB_OPTION_PRIVATE__ = false )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

'' test explicit push true, push false nested

#assert( __FB_OPTION_PRIVATE__ = false )

#pragma push( private, true )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma push( private, true )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = true )

#pragma pop( private )
#assert( __FB_OPTION_PRIVATE__ = false )

0 comments on commit 7899fc7

Please sign in to comment.