Skip to content
Pippijn van Steenhoven edited this page Jul 31, 2013 · 3 revisions

This document describes the coding style in compiler.

Naming conventions

File names

Source files should be named according to their function. The compiler contains many modules, such as abcheck, which is abstract syntax tree verification, and optfoam, the intermediate code optimisation. File names should consist of alphabetic characters and '_'. If a module becomes large, and needs to be split into sub-modules, these should be prefixed with a short name for the main module, followed by an underscore. E.g. of_cprop is the optfoam module for copy propagation.

Identifiers

Different kinds of identifiers have different naming conventions in the compiler code.

  • SUE (struct/union/enum) tags must be camelcase, starting with a lowercase letter. E.g. struct abSyn;.
  • Typedef names must
    • be camelcase, starting with an uppercase letter. E.g. typedef struct abSyn AbSyn;
    • resemble their respective tag name, if they are typedefs of SUE types, so that struct abSyn is AbSyn and union foam is Foam.
  • SUE tags and typedef names may not contain underscores.
  • Enumerators (constants in an enum definition) must start with a short name of their enumeration, followed by an underscore, followed by a camelcase name starting with an uppercase letter. E.g. in enum abSynTag, we have enumerators such as AB_Id and AB_Assign. For grouping and iteration purposes, the enumeration may contain all uppercase, underscore-separated names such as AB_STR_START and AB_STR_END, which mark the first and last literal AST node kind, respectively.
  • Constants may be defined in a nameless enumeration or with #define and follow the naming convention of enumerators.
  • Functions and variables are named in camelcase starting with a lowercase letter. Functions and global variables belonging to a module start with a short name of their module. E.g. all functions and variables in the absyn module start with ab, and all functions in the buffer module start with buf.
  • Function-style macros (introduced with #define) follow the naming convention of functions.
  • Function declarations should equal their definition in argument types and names.
  • Macros introducing new keywords should be named according to the C keyword naming convention, thus all lowercase, underscore-separated. E.g. bitsizeof and local.
  • Local identifiers, types, enumerators, etc. follow the global naming convention, but do not need to be prefixed with their module name. Local names should prefer brevity to descriptiveness, adding a comment to the declaration if necessary, while global names should prefer descriptiveness to brevity.
  • File-scope (static/local) functions and variables do not need to be prefixed with their module name, although this practice is recommended. If a file-scope declaration becomes useful outside the module, no renaming has to be performed if the global naming convention was followed.

Some general rules on identifier meanings:

  • A camelcase name starting with an uppercase letter, not containing underscores, is a type name.
  • A camelcase name starting with a lowercase letter, potentially containing underscores, is an identifier used in function and variable declarations.
  • A camelcase name starting with an uppercase letter, containing at least one underscore, is a link time constant.

The above expressed as regular expressions:

Regular expression Meaning
[A-Z][A-Za-z0-9]* type name
[a-z][A-Za-z0-9]* identifier
[A-Z][A-Za-z0-9]*_[A-Za-z0-9]+ constant

C source file structure

File header (not header file)

A C source file should start with a comment containing the module name and a short description of what the module does. The same description goes into the header file. Here, we assume we are writing a new module for escape analysis, which can be used in various optimisations.

/*****************************************************************************
 *
 * escape.c: Escape analysis for FOAM code.
 *
 * Copyright © 2013 Your name.
 *
 ****************************************************************************/

If you modify an existing file substantially, you should add your own name to the copyright notice, preserving the existing one. If you introduce a new file whose licence is different than the project licence, you must include a short hint at what licence is used. E.g. "This file is licensed under GNU General Public License, version 3 or later".

Includes

After the header, all header files used by the module must be included. No #include directives are allowed after the first declaration. You may comment the directive with a reason for inclusion. Internal header files are included with #include "file", external ones with #include <file>.

#include "list.h"
#include "strops.h"

The inclusions should be lexicographically ordered according to ASCII, which means '_' comes before all alphabetic characters, digits come before both.