## 7 Function Declarations

fundecl | ::= | [fn_ctype] funinfo * funid ([PARAMSEQ(param, ε)]) { [stmt_seq] }
funproto | ::= | fn_ctype funinfo * funid ([PARAMSEQ(param, ε)]);
funinfo | ::= | inline
| | | storage
| | | attribute
storage | ::= | static
| | | auto
| | | register
| | | extern
funid | ::= | id
| | | metaidId
| | | OR(funid)
param | ::= | type id
| | | metaidParam
| | | metaidParamList
| | | ......
decl | ::= | ctype id
| | | fn_ctype (* id) (PARAMSEQ(name_opt_decl, ε))
| | | void
| | | metaidParam

PARAMSEQ(gram_p, when_p) | ::= | COMMA_LIST(gram_p | …[when_p])

To match a function it is not necessary to provide all of the annotations that appear before the function name. For example, the following semantic patch:

1@@ 2@@ 3 4foo() { ... }

matches a function declared as follows:

1 static int foo() { return 12; }

This behavior can be turned off by disabling the optional_storage isomorphism. If one adds code before a function declaration, then the effect depends on the kind of code that is added. If the added code is a function definition or CPP code, then the new code is placed before all information associated with the function definition, including any comments preceding the function definition. On the other hand, if the new code is associated with the function, such as the addition of the keyword static, the new code is placed exactly where it appears with respect to the rest of the function definition in the semantic patch. For example,

1@@ 2@@ 3 4+ static 5foo() { ... }

causes static to be placed just before the function name. The following causes it to be placed just before the type

1@@ 2 type T; 3@@ 4 5+ static 6T foo() { ... }

It may be necessary to consider several cases to ensure that the added code is placed in the right position. For example, one may need one pattern that considers that the function is declared inline and another that considers that it is not.

Varargs are written in C using …. Unfortunately, this notation is already used in the semantic patch language. A pattern for a varargs parameter is written as a sequence of 6 dots.

The C parser allows functions that have no return type, and assumes that the return type is int. The support for parsing such functions is limited. In particular, the parameter list must contain a type for each parameter, and may not contain varargs.

For a function prototype, unlike a function definition, a specification of the return type is obligatory.