mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-02-11 07:30:24 +00:00
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: }
|
||||
{ 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 ----------------------------}
|
||||
|
||||
function lshr (x,y: longint): longint; extern;
|
||||
@ -905,7 +917,9 @@ var
|
||||
|
||||
{if the id is not declared, create a function returning integer}
|
||||
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^.size := 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) }
|
||||
|
||||
|
||||
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;
|
||||
|
||||
{ Initialize the parser }
|
||||
@ -152,6 +164,7 @@ type
|
||||
var
|
||||
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
|
||||
fType: typePtr; {return type of the current function}
|
||||
functionName: stringPtr; {name of the current function}
|
||||
isForwardDeclared: boolean; {is the field list component }
|
||||
{ referencing a forward struct/union? }
|
||||
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)}
|
||||
volatile := savedVolatile; {local volatile vars are out of scope}
|
||||
fIsNoreturn := false; {not doing a noreturn function}
|
||||
functionTable := nil;
|
||||
functionName := nil;
|
||||
end; {if}
|
||||
PopTable; {remove this symbol table}
|
||||
dispose(stPtr); {dump the record}
|
||||
@ -3732,6 +3747,7 @@ if isFunction then begin
|
||||
Gen0 (dc_pin);
|
||||
if not isAsm then
|
||||
Gen1Name(pc_ent, 0, variable^.name);
|
||||
functionName := variable^.name;
|
||||
nextLocalLabel := 1; {initialize GetLocalLabel}
|
||||
returnLabel := GenLabel; {set up an exit point}
|
||||
tempList := nil; {initialize the work label list}
|
||||
@ -3792,6 +3808,7 @@ if isFunction then begin
|
||||
else
|
||||
GenParameters(fnType^.parameterList);
|
||||
savedVolatile := volatile;
|
||||
functionTable := table;
|
||||
CompoundStatement(false); {process the statements}
|
||||
end; {else}
|
||||
end; {else}
|
||||
@ -4436,6 +4453,61 @@ if variable^.class <> staticsy then begin
|
||||
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;
|
||||
|
||||
{ Initialize the parser }
|
||||
|
10
Symbol.pas
10
Symbol.pas
@ -47,6 +47,7 @@
|
||||
{ voidPtrPtr - typeless pointer, for some type casting }
|
||||
{ stringTypePtr - pointer to the base type for string }
|
||||
{ constants }
|
||||
{ constCharPtr - pointer to the type const char }
|
||||
{ defaultStruct - default for structures with errors }
|
||||
{ }
|
||||
{---------------------------------------------------------------}
|
||||
@ -76,12 +77,13 @@ var
|
||||
noDeclarations: boolean; {have we declared anything at this level?}
|
||||
table: symbolTablePtr; {current symbol table}
|
||||
globalTable: symbolTablePtr; {global symbol table}
|
||||
functionTable: symbolTablePtr; {table for top level of current function}
|
||||
|
||||
{base types}
|
||||
charPtr,sCharPtr,uCharPtr,shortPtr,uShortPtr,intPtr,uIntPtr,int32Ptr,
|
||||
uInt32Ptr,longPtr,uLongPtr,longLongPtr,uLongLongPtr,boolPtr,
|
||||
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;
|
||||
globalTable := table;
|
||||
noDeclarations := false;
|
||||
functionTable := nil;
|
||||
{declare base types}
|
||||
new(sCharPtr); {signed char}
|
||||
with sCharPtr^ do begin
|
||||
@ -1369,7 +1372,7 @@ with extendedPtr^ do begin
|
||||
baseType := cgExtended;
|
||||
cType := ctLongDouble;
|
||||
end; {with}
|
||||
new(boolPtr); {_Bool}
|
||||
new(boolPtr); {_Bool}
|
||||
with boolPtr^ do begin
|
||||
size := cgWordSize;
|
||||
saveDisp := 0;
|
||||
@ -1422,6 +1425,9 @@ with defaultStruct^ do begin {(for structures with errors)}
|
||||
bitdisp := 0;
|
||||
end; {with}
|
||||
end; {with}
|
||||
new(constCharPtr); {const char}
|
||||
constCharPtr^ := charPtr^;
|
||||
constCharPtr^.isConstant := true;
|
||||
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.
|
||||
|
||||
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
|
||||
-----------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user