mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-12-27 10:32:35 +00:00
b16210a50b
These are needed to correctly distinguish pointer types in _Generic. They should also be used for type compatibility checks in other contexts, but currently are not. This also fixes a couple small problems related to type qualifiers: *restrict was not allowed to appear after * in type-names *volatile status was not properly recorded in sym files Here is an example of using _Generic to distinguish pointer types based on the qualifiers of the pointed-to type: #include <stdio.h> #define f(e) _Generic((e),\ int * restrict *: 1,\ int * volatile const *: 2,\ int **: 3,\ default: 0) #define g(e) _Generic((e),\ int *: 1,\ const int *: 2,\ volatile int *: 3,\ default: 0) int main(void) { int * restrict * p1; int * volatile const * p2; int * const * p3; // should print "1 2 0 1" printf("%i %i %i %i\n", f(p1), f(p2), f(p3), f((int * restrict *)0)); int *q1; const int *q2; volatile int *q3; const volatile int *q4; // should print "1 2 3 0" printf("%i %i %i %i\n", g(q1), g(q2), g(q3), g(q4)); } Here is an example of a problem resulting from volatile not being recorded in sym files (if a sym file was present, the read of x was lifted out of the loop): #pragma optimize -1 static volatile int x; #include <stdio.h> int main(void) { int y; for (unsigned i = 0; i < 100; i++) { y = x*2 + 7; } }
108 lines
3.0 KiB
Plaintext
108 lines
3.0 KiB
Plaintext
procedure PrintOneSymbol {ip: identPtr};
|
|
|
|
{ Print a symbol }
|
|
{ }
|
|
{ Parameters: }
|
|
{ ip - identifier to print }
|
|
|
|
|
|
procedure PrintClass (class: tokenEnum);
|
|
|
|
{ Print the class of a symbol }
|
|
{ }
|
|
{ Parameters: }
|
|
{ class - class of the symbol }
|
|
|
|
begin {PrintClass}
|
|
case class of
|
|
autosy: write('auto');
|
|
externsy: write('extern');
|
|
ident: write('ident');
|
|
otherwise: write(ord(class):1);
|
|
end; {case}
|
|
end; {PrintClass}
|
|
|
|
|
|
procedure PrintType (tp: typePtr);
|
|
|
|
{ Print a type }
|
|
{ }
|
|
{ Parameters: }
|
|
{ tp - type pointer }
|
|
|
|
begin {PrintType}
|
|
with tp^ do begin
|
|
write(' ', size:1, ' byte ');
|
|
if tqConst in qualifiers then
|
|
write('constant ');
|
|
if tqVolatile in qualifiers then
|
|
write('volatile ');
|
|
if tqRestrict in qualifiers then
|
|
write('restricted ');
|
|
case kind of
|
|
scalarType : writeln('scalar');
|
|
arrayType : begin
|
|
writeln(elements: 1, ' element array of');
|
|
PrintType(aType);
|
|
end;
|
|
pointerType : begin
|
|
writeln(' pointer to');
|
|
PrintType(pType);
|
|
end;
|
|
functionType: begin
|
|
writeln(' function returning');
|
|
PrintType(fType);
|
|
end;
|
|
enumConst : writeln('enumeration (', eval: 1, ')');
|
|
enumType : writeln('enum type');
|
|
definedType : begin
|
|
writeln('defined type of');
|
|
PrintType(dType);
|
|
end;
|
|
structType : writeln('struct: ', ord4(tp):1);
|
|
unionType : writeln('union');
|
|
end; {case}
|
|
end; {with}
|
|
end; {PrintType}
|
|
|
|
|
|
begin {PrintOneSymbol}
|
|
with ip^ do begin
|
|
writeln; {start with a blank line}
|
|
write(name^, {write id info}
|
|
': isForwardDeclared = ', isForwardDeclared,
|
|
'; class = ');
|
|
PrintClass(class);
|
|
writeln;
|
|
|
|
PrintType(iType); {print type info}
|
|
end; {with}
|
|
end; {PrintOneSymbol}
|
|
|
|
|
|
procedure PrintTable {sym: symbolTablePtr};
|
|
|
|
{ print a symbol table }
|
|
{ }
|
|
{ parameters: }
|
|
{ sym - symbol table to print }
|
|
|
|
var
|
|
i: integer; {loop variable}
|
|
ip: identPtr; {current symbol}
|
|
|
|
begin {PrintTable}
|
|
if sym <> nil then begin
|
|
writeln; {write header}
|
|
writeln('Symbols:');
|
|
writeln('========');
|
|
for i := 0 to hashSize do begin {loop over all hash buckets}
|
|
ip := sym^.buckets[i]; {trace through all symbols in this bucket}
|
|
while ip <> nil do begin
|
|
PrintOneSymbol(ip); {print a symbol}
|
|
ip := ip^.next; {next symbol}
|
|
end; {while}
|
|
end; {for}
|
|
end; {if}
|
|
end; {PrintTable}
|