Support the predefined identifier __func__ (from C99).
This gives the name of the current function, as if the following definition appeared at the beginning of the function body: static const char __func__[] = "function-name";
This commit is contained in:
parent
f19d21365a
commit
77d66ab699
|
@ -256,6 +256,18 @@ procedure TypeName; extern;
|
||||||
{ outputs: }
|
{ outputs: }
|
||||||
{ typeSpec - pointer to the type }
|
{ typeSpec - pointer to the type }
|
||||||
|
|
||||||
|
|
||||||
|
function MakeFuncIdentifier: identPtr; extern;
|
||||||
|
|
||||||
|
{ Make the predefined identifier __func__. }
|
||||||
|
{ }
|
||||||
|
{ It is inserted in the symbol table as if the following }
|
||||||
|
{ declaration appeared at the beginning of the function body: }
|
||||||
|
{ }
|
||||||
|
{ static const char __func__[] = "function-name"; }
|
||||||
|
{ }
|
||||||
|
{ This must only be called within a function body. }
|
||||||
|
|
||||||
{-- External unsigned math routines ----------------------------}
|
{-- External unsigned math routines ----------------------------}
|
||||||
|
|
||||||
function lshr (x,y: longint): longint; extern;
|
function lshr (x,y: longint): longint; extern;
|
||||||
|
@ -905,7 +917,9 @@ var
|
||||||
|
|
||||||
{if the id is not declared, create a function returning integer}
|
{if the id is not declared, create a function returning integer}
|
||||||
else if id = nil then begin
|
else if id = nil then begin
|
||||||
if token.kind = lparench then begin
|
if (fToken.name^ = '__func__') and (functionTable <> nil) then
|
||||||
|
id := MakeFuncIdentifier
|
||||||
|
else if token.kind = lparench then begin
|
||||||
fnPtr := pointer(GCalloc(sizeof(typeRecord)));
|
fnPtr := pointer(GCalloc(sizeof(typeRecord)));
|
||||||
{fnPtr^.size := 0;}
|
{fnPtr^.size := 0;}
|
||||||
{fnPtr^.saveDisp := 0;}
|
{fnPtr^.saveDisp := 0;}
|
||||||
|
|
72
Parser.pas
72
Parser.pas
|
@ -57,6 +57,18 @@ procedure AutoInit (variable: identPtr; line: integer);
|
||||||
{ line - line number (used for debugging) }
|
{ line - line number (used for debugging) }
|
||||||
|
|
||||||
|
|
||||||
|
function MakeFuncIdentifier: identPtr;
|
||||||
|
|
||||||
|
{ Make the predefined identifier __func__. }
|
||||||
|
{ }
|
||||||
|
{ It is inserted in the symbol table as if the following }
|
||||||
|
{ declaration appeared at the beginning of the function body: }
|
||||||
|
{ }
|
||||||
|
{ static const char __func__[] = "function-name"; }
|
||||||
|
{ }
|
||||||
|
{ This must only be called within a function body. }
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
|
@ -152,6 +164,7 @@ type
|
||||||
var
|
var
|
||||||
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
|
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
|
||||||
fType: typePtr; {return type of the current function}
|
fType: typePtr; {return type of the current function}
|
||||||
|
functionName: stringPtr; {name of the current function}
|
||||||
isForwardDeclared: boolean; {is the field list component }
|
isForwardDeclared: boolean; {is the field list component }
|
||||||
{ referencing a forward struct/union? }
|
{ referencing a forward struct/union? }
|
||||||
isFunction: boolean; {is the declaration a function?}
|
isFunction: boolean; {is the declaration a function?}
|
||||||
|
@ -356,6 +369,8 @@ if not doingFunction then begin {if so, finish it off}
|
||||||
nameFound := false; {no pc_nam for the next function (yet)}
|
nameFound := false; {no pc_nam for the next function (yet)}
|
||||||
volatile := savedVolatile; {local volatile vars are out of scope}
|
volatile := savedVolatile; {local volatile vars are out of scope}
|
||||||
fIsNoreturn := false; {not doing a noreturn function}
|
fIsNoreturn := false; {not doing a noreturn function}
|
||||||
|
functionTable := nil;
|
||||||
|
functionName := nil;
|
||||||
end; {if}
|
end; {if}
|
||||||
PopTable; {remove this symbol table}
|
PopTable; {remove this symbol table}
|
||||||
dispose(stPtr); {dump the record}
|
dispose(stPtr); {dump the record}
|
||||||
|
@ -3732,6 +3747,7 @@ if isFunction then begin
|
||||||
Gen0 (dc_pin);
|
Gen0 (dc_pin);
|
||||||
if not isAsm then
|
if not isAsm then
|
||||||
Gen1Name(pc_ent, 0, variable^.name);
|
Gen1Name(pc_ent, 0, variable^.name);
|
||||||
|
functionName := variable^.name;
|
||||||
nextLocalLabel := 1; {initialize GetLocalLabel}
|
nextLocalLabel := 1; {initialize GetLocalLabel}
|
||||||
returnLabel := GenLabel; {set up an exit point}
|
returnLabel := GenLabel; {set up an exit point}
|
||||||
tempList := nil; {initialize the work label list}
|
tempList := nil; {initialize the work label list}
|
||||||
|
@ -3792,6 +3808,7 @@ if isFunction then begin
|
||||||
else
|
else
|
||||||
GenParameters(fnType^.parameterList);
|
GenParameters(fnType^.parameterList);
|
||||||
savedVolatile := volatile;
|
savedVolatile := volatile;
|
||||||
|
functionTable := table;
|
||||||
CompoundStatement(false); {process the statements}
|
CompoundStatement(false); {process the statements}
|
||||||
end; {else}
|
end; {else}
|
||||||
end; {else}
|
end; {else}
|
||||||
|
@ -4436,6 +4453,61 @@ if variable^.class <> staticsy then begin
|
||||||
end; {AutoInit}
|
end; {AutoInit}
|
||||||
|
|
||||||
|
|
||||||
|
function MakeFuncIdentifier{: identPtr};
|
||||||
|
|
||||||
|
{ Make the predefined identifier __func__. }
|
||||||
|
{ }
|
||||||
|
{ It is inserted in the symbol table as if the following }
|
||||||
|
{ declaration appeared at the beginning of the function body: }
|
||||||
|
{ }
|
||||||
|
{ static const char __func__[] = "function-name"; }
|
||||||
|
{ }
|
||||||
|
{ This must only be called within a function body. }
|
||||||
|
|
||||||
|
var
|
||||||
|
lTable: symbolTablePtr; {saved copy of current symbol table}
|
||||||
|
tp: typePtr; {the type of __func__}
|
||||||
|
id: identPtr; {the identifier for __func__}
|
||||||
|
sval: longstringPtr; {the initializer string}
|
||||||
|
iPtr: initializerPtr; {the initializer}
|
||||||
|
i: integer; {loop variable}
|
||||||
|
len: integer; {string length}
|
||||||
|
|
||||||
|
begin {MakeFuncIdentifier}
|
||||||
|
lTable := table;
|
||||||
|
table := functionTable;
|
||||||
|
|
||||||
|
len := ord(functionName^[0]) + 1;
|
||||||
|
tp := pointer(GCalloc(sizeof(typeRecord)));
|
||||||
|
tp^.size := len;
|
||||||
|
tp^.saveDisp := 0;
|
||||||
|
tp^.isConstant := false;
|
||||||
|
tp^.kind := arrayType;
|
||||||
|
tp^.aType := constCharPtr;
|
||||||
|
tp^.elements := len;
|
||||||
|
id := NewSymbol(@'__func__', tp, staticsy, variableSpace, initialized);
|
||||||
|
|
||||||
|
sval := pointer(GCalloc(len + sizeof(integer)));
|
||||||
|
sval^.length := len;
|
||||||
|
for i := 1 to len-1 do
|
||||||
|
sval^.str[i] := functionName^[i];
|
||||||
|
sval^.str[len] := chr(0);
|
||||||
|
iPtr := pointer(GCalloc(sizeof(initializerRecord)));
|
||||||
|
iPtr^.next := nil;
|
||||||
|
iPtr^.count := 1;
|
||||||
|
iPtr^.bitdisp := 0;
|
||||||
|
iPtr^.bitsize := 0;
|
||||||
|
iPtr^.isStructOrUnion := false;
|
||||||
|
iPtr^.isConstant := true;
|
||||||
|
iPtr^.itype := cgString;
|
||||||
|
iPtr^.sval := sval;
|
||||||
|
id^.iPtr := iPtr;
|
||||||
|
|
||||||
|
table := lTable;
|
||||||
|
MakeFuncIdentifier := id;
|
||||||
|
end; {MakeFuncIdentifier}
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
|
|
10
Symbol.pas
10
Symbol.pas
|
@ -47,6 +47,7 @@
|
||||||
{ voidPtrPtr - typeless pointer, for some type casting }
|
{ voidPtrPtr - typeless pointer, for some type casting }
|
||||||
{ stringTypePtr - pointer to the base type for string }
|
{ stringTypePtr - pointer to the base type for string }
|
||||||
{ constants }
|
{ constants }
|
||||||
|
{ constCharPtr - pointer to the type const char }
|
||||||
{ defaultStruct - default for structures with errors }
|
{ defaultStruct - default for structures with errors }
|
||||||
{ }
|
{ }
|
||||||
{---------------------------------------------------------------}
|
{---------------------------------------------------------------}
|
||||||
|
@ -76,12 +77,13 @@ var
|
||||||
noDeclarations: boolean; {have we declared anything at this level?}
|
noDeclarations: boolean; {have we declared anything at this level?}
|
||||||
table: symbolTablePtr; {current symbol table}
|
table: symbolTablePtr; {current symbol table}
|
||||||
globalTable: symbolTablePtr; {global symbol table}
|
globalTable: symbolTablePtr; {global symbol table}
|
||||||
|
functionTable: symbolTablePtr; {table for top level of current function}
|
||||||
|
|
||||||
{base types}
|
{base types}
|
||||||
charPtr,sCharPtr,uCharPtr,shortPtr,uShortPtr,intPtr,uIntPtr,int32Ptr,
|
charPtr,sCharPtr,uCharPtr,shortPtr,uShortPtr,intPtr,uIntPtr,int32Ptr,
|
||||||
uInt32Ptr,longPtr,uLongPtr,longLongPtr,uLongLongPtr,boolPtr,
|
uInt32Ptr,longPtr,uLongPtr,longLongPtr,uLongLongPtr,boolPtr,
|
||||||
floatPtr,doublePtr,compPtr,extendedPtr,stringTypePtr,voidPtr,
|
floatPtr,doublePtr,compPtr,extendedPtr,stringTypePtr,voidPtr,
|
||||||
voidPtrPtr,defaultStruct: typePtr;
|
voidPtrPtr,constCharPtr,defaultStruct: typePtr;
|
||||||
|
|
||||||
{---------------------------------------------------------------}
|
{---------------------------------------------------------------}
|
||||||
|
|
||||||
|
@ -1215,6 +1217,7 @@ table := nil; {initialize the global symbol table}
|
||||||
PushTable;
|
PushTable;
|
||||||
globalTable := table;
|
globalTable := table;
|
||||||
noDeclarations := false;
|
noDeclarations := false;
|
||||||
|
functionTable := nil;
|
||||||
{declare base types}
|
{declare base types}
|
||||||
new(sCharPtr); {signed char}
|
new(sCharPtr); {signed char}
|
||||||
with sCharPtr^ do begin
|
with sCharPtr^ do begin
|
||||||
|
@ -1369,7 +1372,7 @@ with extendedPtr^ do begin
|
||||||
baseType := cgExtended;
|
baseType := cgExtended;
|
||||||
cType := ctLongDouble;
|
cType := ctLongDouble;
|
||||||
end; {with}
|
end; {with}
|
||||||
new(boolPtr); {_Bool}
|
new(boolPtr); {_Bool}
|
||||||
with boolPtr^ do begin
|
with boolPtr^ do begin
|
||||||
size := cgWordSize;
|
size := cgWordSize;
|
||||||
saveDisp := 0;
|
saveDisp := 0;
|
||||||
|
@ -1422,6 +1425,9 @@ with defaultStruct^ do begin {(for structures with errors)}
|
||||||
bitdisp := 0;
|
bitdisp := 0;
|
||||||
end; {with}
|
end; {with}
|
||||||
end; {with}
|
end; {with}
|
||||||
|
new(constCharPtr); {const char}
|
||||||
|
constCharPtr^ := charPtr^;
|
||||||
|
constCharPtr^.isConstant := true;
|
||||||
end; {InitSymbol}
|
end; {InitSymbol}
|
||||||
|
|
||||||
|
|
||||||
|
|
4
cc.notes
4
cc.notes
|
@ -391,6 +391,10 @@ Several new library functions in <stdlib.h> support operations on these types, a
|
||||||
|
|
||||||
The predefined macro __ORCAC_HAS_LONG_LONG__ is now defined, and expands to the integer constant 1. This indicates that these long long types are supported.
|
The predefined macro __ORCAC_HAS_LONG_LONG__ is now defined, and expands to the integer constant 1. This indicates that these long long types are supported.
|
||||||
|
|
||||||
|
20. (C99) The predefined identifier __func__ is now supported, providing a way for code within a function to get the function's name. Specifically, it behaves as if the following declaration appeared at the beginning of each function body (where function-name is the name of the function):
|
||||||
|
|
||||||
|
static const char __func__[] = "function-name";
|
||||||
|
|
||||||
|
|
||||||
Multi-Character Character Constants
|
Multi-Character Character Constants
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
Loading…
Reference in New Issue