Previous Up Next

10  GCC Extensions

The CIL parser handles most of the gcc extensions and compiles them to CIL. The following extensions are not handled (note that we are able to compile a large number of programs, including the Linux kernel, without encountering these):

  1. Nested function definitions.
  2. Constructing function calls.
  3. Naming an expression’s type.
  4. Complex numbers
  5. Hex floats
  6. Subscripts on non-lvalue arrays.
  7. Forward function parameter declarations

The following extensions are handled, typically by compiling them away:

  1. Attributes for functions, variables and types. In fact, we have a clear specification (see Section 6.4) of how attributes are interpreted. The specification extends that of gcc.
  2. Old-style function definitions and prototypes. These are translated to new-style.
  3. Locally-declared labels. As part of the translation to CIL, we generate new labels as needed.
  4. Labels as values and computed goto. This allows a program to take the address of a label and to manipulate it as any value and also to perform a computed goto. We compile this by assigning each label whose address is taken a small integer that acts as its address. Every computed goto in the body of the function is replaced with a switch statement. If you want to invoke the label from another function, you are on your own (the gcc documentation says the same.)
  5. Generalized lvalues. You can write code like (a, b) += 5 and it gets translated to CIL.
  6. Conditionals with omitted operands. Things like x ? : y are translated to CIL.
  7. Double word integers. The type long long and the LL suffix on constants is understood. This is currently interpreted as 64-bit integers.
  8. Local arrays of variable length. These are converted to uses of alloca, the array variable is replaced with a pointer to the allocated array and the instances of sizeof(a) are adjusted to return the size of the array and not the size of the pointer.
  9. Non-constant local initializers. Like all local initializers these are compiled into assignments.
  10. Compound literals. These are also turned into assignments.
  11. Designated initializers. The CIL parser actually supports the full ISO syntax for initializers, which is more than both gcc and MSVC. I (George) think that this is the most complicated part of the C language and whoever designed it should be banned from ever designing languages again.
  12. Case ranges. These are compiled into separate cases. There is no code duplication, just a larger number of case statements.
  13. Transparent unions. This is a strange feature that allows you to define a function whose formal argument has a (tranparent) union type, but the argument is called as if it were the first element of the union. This is compiled away by saying that the type of the formal argument is that of the first field, and the first thing in the function body we copy the formal into a union.
  14. Inline assembly-language. The full syntax is supported and it is carried as such in CIL.
  15. Function names as strings. The identifiers __FUNCTION__ and __PRETTY_FUNCTION__ are replaced with string literals.
  16. Keywords typeof, alignof, inline are supported.

Previous Up Next