User's Guide

The module gcc.cdecl provides a function gcc.cdecl.declare, which formats a GCC declaration or type node as a string of C code. In the following examples, we will learn how to use this function to extract functions, variables and types from the operating system’s implementation of the POSIX C API.

1 Functions and variables

To extract function and variable declarations from a C header file, we declare specially-prefixed variables in a C source file that point to the declarations. The source file is parsed using GCC and a Lua plugin script that selects these variables by matching their common name prefix.

Create a file func.c with the following C source code:

Create a file func.lua with the following Lua source code:

Parse the C source file using the GCC Lua plugin:

gcc -S -std=c99 -Wall func.c -fplugin=../gcc-lua/gcc/gcclua.so -fplugin-arg-gcclua-script=func.lua

The output contains the declarations captured in the C source file:

2 Assembler names

Many C libraries use the C preprocessor to substitute documented API names with internal ABI names. For example, the POSIX function basename is implemented as __xpg_basename in the GNU C library.

gcc.cdecl.declare may be passed a function as a second argument. This function is invoked on any declaration or type encountered upon formatting the first argument, and may return a string that overrides the parsed name. In this example, we override the internal ABI name of a declaration with its documented API name.

Create a file asm.c with the following C source code:

Create a file asm.lua with the following Lua source code:

Parse the C source file using the GCC Lua plugin:

gcc -S -std=c99 -Wall asm.c -fplugin=../gcc-lua/gcc/gcclua.so -fplugin-arg-gcclua-script=asm.lua

The output contains the declarations captured in the C source file:

Declarations with a differing assembler name include a GCC asm label.

3 Type declarations

To extract type declarations, we declare variables with a corresponding pointee type. We use pointer variables to avoid warnings about missing initialisation for constant types.

Create a file type.c with the following C source code:

Create a file type.lua with the following Lua source code:

Parse the C source file using the GCC Lua plugin:

gcc -S -std=c99 -Wall type.c -fplugin=../gcc-lua/gcc/gcclua.so -fplugin-arg-gcclua-script=type.lua

The output contains the declarations captured in the C source file:

4 Struct, union and enum types

For a type declaration, gcc.cdecl.declare only expands anonymous struct, union and enum types, for the purpose of allowing forward declarations, and to avoid duplicate definitions. Instead of the type declaration, we format the type itself to define a named struct, union or enum type.

Create a file struct.c with the following C source code:

Create a file struct.lua with the following Lua source code:

Parse the C source file using the GCC Lua plugin:

gcc -S -std=c99 -Wall struct.c -fplugin=../gcc-lua/gcc/gcclua.so -fplugin-arg-gcclua-script=struct.lua

The output contains the definitions of types captured in the C source file:

5 Integer constants

In this example, we extract and declare integer constants, which is the only kind of C constant supported by LuaJIT FFI as of LuaJIT version 2.0.

Create a file const.c with the following C source code:

Create a file const.lua with the following Lua source code:

Parse the C source file using the GCC Lua plugin:

gcc -S -std=c99 -Wall const.c -fplugin=../gcc-lua/gcc/gcclua.so -fplugin-arg-gcclua-script=const.lua

The output contains the definitions of constants captured in the C source file: