=====================
LLVM Coding Standards
=====================

.. contents::
   :local:

Introduction
============

This document describes coding standards that are used in the LLVM project.
Although no coding standards should be regarded as absolute requirements to be
followed in all instances, coding standards are
particularly important for large-scale code bases that follow a library-based
design (like LLVM).

While this document may provide guidance for some mechanical formatting issues,
whitespace, or other "microscopic details", these are not fixed standards.
Always follow the golden rule:

.. _Golden Rule:

    **If you are extending, enhancing, or bug fixing already implemented code,
    use the style that is already being used so that the source is uniform and
    easy to follow.**

Note that some code bases (e.g. ``libc++``) have special reasons to deviate
from the coding standards.  For example, in the case of ``libc++``, this is
because the naming and other conventions are dictated by the C++ standard.

There are some conventions that are not uniformly followed in the code base
(e.g. the naming convention).  This is because they are relatively new, and a
lot of code was written before they were put in place.  Our long-term goal is
for the entire codebase to follow the convention, but we explicitly *do not*
want patches that do large-scale reformatting of existing code.  On the other
hand, it is reasonable to rename the methods of a class if you're about to
change it in some other way.  Please commit such changes separately to
make code review easier.

The ultimate goal of these guidelines is to increase the readability and
maintainability of our common source base.

Languages, Libraries, and Standards
===================================

Most source code in LLVM and other LLVM projects using these coding standards
is C++ code. There are some places where C code is used either due to
environment restrictions, historical restrictions, or due to third-party source
code imported into the tree. Generally, our preference is for
standards-conforming, modern, and portable C++ code as the implementation language of
choice.

For automation, build systems, and utility scripts, Python is preferred and
is widely used in the LLVM repository already.

C++ Standard Versions
---------------------

Unless otherwise documented, LLVM subprojects are written using standard C++17
code and avoid unnecessary vendor-specific extensions.

Nevertheless, we restrict ourselves to features which are available in the
major toolchains supported as host compilers (see :doc:`GettingStarted` page,
section `Software`).

Each toolchain provides a good reference for what it accepts:

* Clang: https://clang.llvm.org/cxx_status.html

  * libc++: https://libcxx.llvm.org/Status/Cxx17.html

* GCC: https://gcc.gnu.org/projects/cxx-status.html#cxx17

  * libstdc++: https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2017

* MSVC: https://learn.microsoft.com/cpp/overview/visual-cpp-language-conformance

Additionally, there are compiler comparison tables of supported C++ features on
`cppreference.com <https://en.cppreference.com/w/cpp/compiler_support/17>`_.


C++ Standard Library
--------------------

Instead of implementing custom data structures, we encourage the use of C++
standard library facilities or LLVM support libraries whenever they are
available for a particular task. LLVM and related projects emphasize and rely
on the standard library facilities and the LLVM support libraries as much as
possible.

LLVM support libraries (for example, `ADT
<https://github.com/llvm/llvm-project/tree/main/llvm/include/llvm/ADT>`_)
implement specialized data structures or functionality missing in the standard
library. Such libraries are usually implemented in the ``llvm`` namespace and
follow the expected standard interface when there is one.

When both C++ and the LLVM support libraries provide similar functionality, and
there isn't a specific reason to favor the C++ implementation, it is generally
preferable to use the LLVM library. For example, ``llvm::DenseMap`` should
almost always be used instead of ``std::map`` or ``std::unordered_map``, and
``llvm::SmallVector`` should usually be used instead of ``std::vector``.

We explicitly avoid some standard facilities, like the I/O streams, and instead
use LLVM's streams library (raw_ostream_). More detailed information on these
subjects is available in the :doc:`ProgrammersManual`.

For more information about LLVM's data structures and the tradeoffs they make,
please consult `that section of the programmer's manual
<https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task>`_.

Python version and Source Code Formatting
-----------------------------------------

The current minimum version of Python required is documented in the :doc:`GettingStarted`
section. Python code in the LLVM repository should only use language features
available in this version of Python.

The Python code within the LLVM repository should adhere to the formatting guidelines
outlined in `PEP 8 <https://peps.python.org/pep-0008/>`_.

For consistency and to limit churn, code should be automatically formatted with
the `black <https://github.com/psf/black>`_ utility, which is PEP 8 compliant.
Use its default rules. For example, avoid specifying ``--line-length`` even
though it does not default to 80. The default rules can change between major
versions of black. In order to avoid unnecessary churn in the formatting rules,
we currently use black version 23.x in LLVM.

When contributing a patch unrelated to formatting, you should format only the
Python code that the patch modifies. For this purpose, use the `darker
<https://pypi.org/project/darker/>`_ utility, which runs default black rules
over only the modified Python code. Doing so should ensure the patch will pass
the Python format checks in LLVM's pre-commit CI, which also uses darker. When
contributing a patch specifically for reformatting Python files, use black,
which currently only supports formatting entire files.

Here are some quick examples, but see the black and darker documentation for
details:

.. code-block:: bash

    $ pip install black=='23.*' darker # install black 23.x and darker
    $ darker test.py                   # format uncommitted changes
    $ darker -r HEAD^ test.py          # also format changes from last commit
    $ black test.py                    # format entire file

Instead of individual file names, you can specify directories to
darker, and it will find the changed files. However, if a directory is
large, like a clone of the LLVM repository, darker can be painfully
slow. In that case, you might wish to use git to list changed files.
For example:

.. code-block:: bash

   $ darker -r HEAD^ $(git diff --name-only --diff-filter=d HEAD^)

Mechanical Source Issues
========================

Source Code Formatting
----------------------

Commenting
^^^^^^^^^^

Comments are important for readability and maintainability. When writing comments,
write them as English prose, using proper capitalization, punctuation, etc.
Aim to describe what the code is trying to do and why, not *how* it does it at
a micro level. Here are a few important things to document:

.. _header file comment:

File Headers
""""""""""""

Every source file should have a header on it that describes the basic purpose of
the file. The standard header looks like this:

.. code-block:: c++

  //===----------------------------------------------------------------------===//
  //
  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  // See https://llvm.org/LICENSE.txt for license information.
  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  //
  //===----------------------------------------------------------------------===//
  ///
  /// \file
  /// This file contains the declaration of the Instruction class, which is the
  /// base class for all of the VM instructions.
  ///
  //===----------------------------------------------------------------------===//

The first section in the file is a concise note that defines the license that the
file is released under.  This makes it perfectly clear what terms the source
code can be distributed under and should not be modified in any way.

The main body is a `Doxygen <http://www.doxygen.nl/>`_ comment (identified by
the ``///`` comment marker instead of the usual ``//``) describing the purpose
of the file.  The first sentence (or a passage beginning with ``\brief``) is
used as an abstract.  Any additional information should be separated by a blank
line.  If an algorithm is based on a paper or is described in another source,
provide a reference.

Header Guard
""""""""""""

The header file's guard should be the all-caps path that a user of this header
would #include, using '_' instead of path separator and extension marker.
For example, the header file
``llvm/include/llvm/Analysis/Utils/Local.h`` would be ``#include``-ed as
``#include "llvm/Analysis/Utils/Local.h"``, so its guard is
``LLVM_ANALYSIS_UTILS_LOCAL_H``.

Class overviews
"""""""""""""""

Classes are a fundamental part of an object-oriented design.  As such, a
class definition should have a comment block that explains what the class is
used for and how it works.  Every non-trivial class is expected to have a
``doxygen`` comment block.

Method information
""""""""""""""""""

Methods and global functions should also be documented.  A quick note about
what it does and a description of the edge cases is all that is necessary here.
The reader should be able to understand how to use interfaces without reading
the code itself.

Good things to talk about here are what happens when something unexpected
happens, for instance, does the method return null?

Comment Formatting
^^^^^^^^^^^^^^^^^^

In general, prefer C++-style comments (``//`` for normal comments, ``///`` for
``doxygen`` documentation comments).  There are a few cases when it is
useful to use C-style (``/* */``) comments, however:

#. When writing C code to be compatible with C89.

#. When writing a header file that may be ``#include``\d by a C source file.

#. When writing a source file that is used by a tool that only accepts C-style
   comments.

#. When documenting the significance of constants used as actual parameters in
   a call. This is most helpful for ``bool`` parameters, or passing ``0`` or
   ``nullptr``. The comment should contain the parameter name, which ought to be
   meaningful. For example, it's not clear what the parameter means in this call:

   .. code-block:: c++

     Object.emitName(nullptr);

   An in-line C-style comment makes the intent obvious:

   .. code-block:: c++

     Object.emitName(/*Prefix=*/nullptr);

Commenting out large blocks of code is discouraged, but if you really have to do
this (for documentation purposes or as a suggestion for debug printing), use
``#if 0`` and ``#endif``. These nest properly and are better behaved in general
than C-style comments.

Doxygen Use in Documentation Comments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use the ``\file`` command to turn the standard file header into a file-level
comment.

Include descriptive paragraphs for all public interfaces (public classes,
member and non-member functions).  Avoid restating the information that can
be inferred from the API name.  The first sentence (or a paragraph beginning
with ``\brief``) is used as an abstract. Try to use a single sentence as the
``\brief`` adds visual clutter.  Put detailed discussion into separate
paragraphs.

To refer to parameter names inside a paragraph, use the ``\p name`` command.
Don't use the ``\arg name`` command since it starts a new paragraph that
contains documentation for the parameter.

Wrap non-inline code examples in ``\code ... \endcode``.

To document a function parameter, start a new paragraph with the
``\param name`` command.  If the parameter is used as an out or an in/out
parameter, use the ``\param [out] name`` or ``\param [in,out] name`` command,
respectively.

To describe function return value, start a new paragraph with the ``\returns``
command.

A minimal documentation comment:

.. code-block:: c++

  /// Sets the xyzzy property to \p Baz.
  void setXyzzy(bool Baz);

A documentation comment that uses all Doxygen features in a preferred way:

.. code-block:: c++

  /// Does foo and bar.
  ///
  /// Does not do foo the usual way if \p Baz is true.
  ///
  /// Typical usage:
  /// \code
  ///   fooBar(false, "quux", Res);
  /// \endcode
  ///
  /// \param Quux kind of foo to do.
  /// \param [out] Result filled with bar sequence on foo success.
  ///
  /// \returns true on success.
  bool fooBar(bool Baz, StringRef Quux, std::vector<int> &Result);

Don't duplicate the documentation comment in the header file and in the
implementation file.  Put the documentation comments for public APIs into the
header file.  Documentation comments for private APIs can go to the
implementation file.  In any case, implementation files can include additional
comments (not necessarily in Doxygen markup) to explain implementation details
as needed.

Don't duplicate the function or class name at the beginning of the comment.
For humans, it is obvious which function or class is being documented;
automatic documentation processing tools are smart enough to bind the comment
to the correct declaration.

Avoid:

.. code-block:: c++

  // Example.h:

  // example - Does something important.
  void example();

  // Example.cpp:

  // example - Does something important.
  void example() { ... }

Preferred:

.. code-block:: c++

  // Example.h:

  /// Does something important.
  void example();

  // Example.cpp:

  /// Builds a B-tree in order to do foo.  See paper by...
  void example() { ... }

Error and Warning Messages
^^^^^^^^^^^^^^^^^^^^^^^^^^

Clear diagnostic messages are important to help users identify and fix issues in
their inputs. Use succinct but correct English prose that gives the user the
context needed to understand what went wrong. Also, to match error message
styles commonly produced by other tools, start the first sentence with a
lowercase letter, and finish the last sentence without a period, if it would
end in one otherwise. Sentences which end with different punctuation, such as
"did you forget ';'?", should still do so.

For example, this is a good error message:

.. code-block:: none

  error: file.o: section header 3 is corrupt. Size is 10 when it should be 20

This is a bad message, since it does not provide useful information and uses the
wrong style:

.. code-block:: none

  error: file.o: Corrupt section header.

As with other coding standards, individual projects, such as the Clang Static
Analyzer, may have preexisting styles that do not conform to this. If a
different formatting scheme is used consistently throughout the project, use
that style instead. Otherwise, this standard applies to all LLVM tools,
including clang, clang-tidy, and so on.

If the tool or project does not have existing functions to emit warnings or
errors, use the error and warning handlers provided in ``Support/WithColor.h``
to ensure they are printed in the appropriate style, rather than printing to
stderr directly.

When using ``report_fatal_error``, follow the same standards for the message as
regular error messages. Assertion messages and ``llvm_unreachable`` calls do not
necessarily need to follow these same styles as they are automatically
formatted, and thus these guidelines may not be suitable.

``#include`` Style
^^^^^^^^^^^^^^^^^^

Immediately after the `header file comment`_ (and include guards if working on a
header file), the `minimal list of #includes`_ required by the file should be
listed.  We prefer these ``#include``\s to be listed in this order:

.. _Main Module Header:
.. _Local/Private Headers:

#. Main Module Header
#. Local/Private Headers
#. LLVM project/subproject headers (``clang/...``, ``lldb/...``, ``llvm/...``, etc)
#. System ``#include``\s

and each category should be sorted lexicographically by the full path.

The `Main Module Header`_ file applies to ``.cpp`` files which implement an
interface defined by a ``.h`` file.  This ``#include`` should always be included
**first** regardless of where it lives on the file system.  By including a
header file first in the ``.cpp`` files that implement the interfaces, we ensure
that the header does not have any hidden dependencies which are not explicitly
``#include``\d in the header, but should be. It is also a form of documentation
in the ``.cpp`` file to indicate where the interfaces it implements are defined.

LLVM project and subproject headers should be grouped from most specific to least
specific, for the same reasons described above.  For example, LLDB depends on
both clang and LLVM, and clang depends on LLVM.  So an LLDB source file should
include ``lldb`` headers first, followed by ``clang`` headers, followed by
``llvm`` headers, to reduce the possibility (for example) of an LLDB header
accidentally picking up a missing include due to the previous inclusion of that
header in the main source file or some earlier header file.  clang should
similarly include its own headers before including llvm headers.  This rule
applies to all LLVM subprojects.

.. _fit into 80 columns:

Source Code Width
^^^^^^^^^^^^^^^^^

Write your code to fit within 80 columns.

There must be some limit to the width of the code in
order to allow developers to have multiple files side-by-side in
windows on a modest display.  If you are going to pick a width limit, it is
somewhat arbitrary, but you might as well pick something standard.  Going with 90
columns (for example) instead of 80 columns wouldn't add any significant value
and would be detrimental to printing out code.  Also many other projects have
standardized on 80 columns, so some people have already configured their editors
for it (vs something else, like 90 columns).

Whitespace
^^^^^^^^^^

In all cases, prefer spaces to tabs in source files.  People have different
preferred indentation levels, and different styles of indentation that they
like; this is fine.  What isn't fine is that different editors/viewers expand
tabs out to different tab stops.  This can cause your code to look completely
unreadable, and it is not worth dealing with.

As always, follow the `Golden Rule`_ above: follow the style of existing code
if you are modifying and extending it.

Do not add trailing whitespace.  Some common editors will automatically remove
trailing whitespace when saving a file which causes unrelated changes to appear
in diffs and commits.

Format Lambdas Like Blocks Of Code
""""""""""""""""""""""""""""""""""

When formatting a multi-line lambda, format it like a block of code. If there
is only one multi-line lambda in a statement, and there are no expressions
lexically after it in the statement, drop the indent to the standard two space
indent for a block of code, as if it were an if-block opened by the preceding
part of the statement:

.. code-block:: c++

  std::sort(foo.begin(), foo.end(), [&](Foo a, Foo b) -> bool {
    if (a.blah < b.blah)
      return true;
    if (a.baz < b.baz)
      return true;
    return a.bam < b.bam;
  });

To take best advantage of this formatting, if you are designing an API which
accepts a continuation or single callable argument (be it a function object, or
a ``std::function``), it should be the last argument if at all possible.

If there are multiple multi-line lambdas in a statement, or additional
parameters after the lambda, indent the block two spaces from the indent of the
``[]``:

.. code-block:: c++

  dyn_switch(V->stripPointerCasts(),
             [] (PHINode *PN) {
               // process phis...
             },
             [] (SelectInst *SI) {
               // process selects...
             },
             [] (LoadInst *LI) {
               // process loads...
             },
             [] (AllocaInst *AI) {
               // process allocas...
             });

Braced Initializer Lists
""""""""""""""""""""""""

Starting from C++11, there are significantly more uses of braced lists to
perform initialization. For example, they can be used to construct aggregate
temporaries in expressions. They now have a natural way of ending up nested
within each other and within function calls in order to build up aggregates
(such as option structs) from local variables.

The historically common formatting of braced initialization of aggregate
variables does not mix cleanly with deep nesting, general expression contexts,
function arguments, and lambdas. We suggest new code use a simple rule for
formatting braced initialization lists: act as if the braces were parentheses
in a function call. The formatting rules exactly match those already well
understood for formatting nested function calls. Examples:

.. code-block:: c++

  foo({a, b, c}, {1, 2, 3});

  llvm::Constant *Mask[] = {
      llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 0),
      llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 1),
      llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 2)};

This formatting scheme also makes it particularly easy to get predictable,
consistent, and automatic formatting with tools like `Clang Format`_.

.. _Clang Format: https://clang.llvm.org/docs/ClangFormat.html

Language and Compiler Issues
----------------------------

Treat Compiler Warnings Like Errors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Compiler warnings are often useful and help improve the code.  Those that are
not useful, can be often suppressed with a small code change. For example, an
assignment in the ``if`` condition is often a typo:

.. code-block:: c++

  if (V = getValue()) {
    ...
  }

Several compilers will print a warning for the code above. It can be suppressed
by adding parentheses:

.. code-block:: c++

  if ((V = getValue())) {
    ...
  }

Write Portable Code
^^^^^^^^^^^^^^^^^^^

In almost all cases, it is possible to write completely portable code.  When
you need to rely on non-portable code, put it behind a well-defined and
well-documented interface.

Do not use RTTI or Exceptions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In an effort to reduce code and executable size, LLVM does not use exceptions
or RTTI (`runtime type information
<https://en.wikipedia.org/wiki/Run-time_type_information>`_, for example,
``dynamic_cast<>``).

That said, LLVM does make extensive use of a hand-rolled form of RTTI that use
templates like :ref:`isa\<>, cast\<>, and dyn_cast\<> <isa>`.
This form of RTTI is opt-in and can be
:doc:`added to any class <HowToSetUpLLVMStyleRTTI>`.

Prefer C++-style casts
^^^^^^^^^^^^^^^^^^^^^^

When casting, use ``static_cast``, ``reinterpret_cast``, and ``const_cast``,
rather than C-style casts. There are two exceptions to this:

* When casting to ``void`` to suppress warnings about unused variables (as an
  alternative to ``[[maybe_unused]]``). Prefer C-style casts in this instance.
  Note that if the variable is unused because it's used only in ``assert``, use
  ``[[maybe_unused]]`` instead of a C-style void cast.

* When casting between integral types (including enums that are not strongly-
  typed), functional-style casts are permitted as an alternative to
  ``static_cast``.

.. _static constructor:

Do not use Static Constructors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Static constructors and destructors (e.g., global variables whose types have a
constructor or destructor) should not be added to the code base, and should be
removed wherever possible.

Globals in different source files are initialized in an `arbitrary order
<https://yosefk.com/c++fqa/ctors.html#fqa-10.12>`_, making the code more
difficult to reason about.

Static constructors have a negative impact on the launch time of programs that use
LLVM as a library. We would really like for there to be zero cost for linking
in an additional LLVM target or other library into an application, but static
constructors undermine this goal.

Use of ``class`` and ``struct`` Keywords
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In C++, the ``class`` and ``struct`` keywords can be used almost
interchangeably. The only difference is when they are used to declare a class:
``class`` makes all members private by default while ``struct`` makes all
members public by default.

* All declarations and definitions of a given ``class`` or ``struct`` must use
  the same keyword.  For example:

.. code-block:: c++

  // Avoid if `Example` is defined as a struct.
  class Example;

  // OK.
  struct Example;

  struct Example { ... };

* ``struct`` should be used when *all* members are declared public.

.. code-block:: c++

  // Avoid using `struct` here, use `class` instead.
  struct Foo {
  private:
    int Data;
  public:
    Foo() : Data(0) { }
    int getData() const { return Data; }
    void setData(int D) { Data = D; }
  };

  // OK to use `struct`: all members are public.
  struct Bar {
    int Data;
    Bar() : Data(0) { }
  };

Do not use Braced Initializer Lists to Call a Constructor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Starting from C++11 there is a "generalized initialization syntax" which allows
calling constructors using braced initializer lists. Do not use these to call
constructors with non-trivial logic or if you care that you're calling some
*particular* constructor. Those should look like function calls using
parentheses rather than like aggregate initialization. Similarly, if you need
to explicitly name the type and call its constructor to create a temporary,
don't use a braced initializer list. Instead, use a braced initializer list
(without any type for temporaries) when doing aggregate initialization or
something notionally equivalent. Examples:

.. code-block:: c++

  class Foo {
  public:
    // Construct a Foo by reading data from the disk in the whizbang format, ...
    Foo(std::string filename);

    // Construct a Foo by looking up the Nth element of some global data ...
    Foo(int N);

    // ...
  };

  // The Foo constructor call is reading a file, don't use braces to call it.
  llvm::fill(foo, Foo("name"));

  // The pair is being constructed like an aggregate, use braces.
  bar_map.insert({my_key, my_value});

If you use a braced initializer list when initializing a variable, use an equals before the open curly brace:

.. code-block:: c++

  int data[] = {0, 1, 2, 3};

Use ``auto`` Type Deduction to Make Code More Readable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Some are advocating a policy of "almost always ``auto``" in C++11; however, LLVM
uses a more moderate stance. Use ``auto`` if and only if it makes the code more
readable or easier to maintain. Don't "almost always" use ``auto``, but do use
``auto`` with initializers like ``cast<Foo>(...)`` or other places where the
type is already obvious from the context. Another time when ``auto`` works well
for these purposes is when the type would have been abstracted away anyway,
often behind a container's typedef such as ``std::vector<T>::iterator``.

Similarly, C++14 adds generic lambda expressions where parameter types can be
``auto``. Use these where you would have used a template.

Beware unnecessary copies with ``auto``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The convenience of ``auto`` makes it easy to forget that its default behavior
is a copy.  Particularly in range-based ``for`` loops, careless copies are
expensive.

Use ``auto &`` for values and ``auto *`` for pointers unless you need to make a
copy.

.. code-block:: c++

  // Typically there's no reason to copy.
  for (const auto &Val : Container) observe(Val);
  for (auto &Val : Container) Val.change();

  // Remove the reference if you really want a new copy.
  for (auto Val : Container) { Val.change(); saveSomewhere(Val); }

  // Copy pointers, but make it clear that they're pointers.
  for (const auto *Ptr : Container) observe(*Ptr);
  for (auto *Ptr : Container) Ptr->change();

Beware of non-determinism due to ordering of pointers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In general, there is no relative ordering among pointers. As a result,
when unordered containers like sets and maps are used with pointer keys
the iteration order is undefined. Hence, iterating such containers may
result in non-deterministic code generation. While the generated code
might work correctly, non-determinism can make it harder to reproduce bugs and
debug the compiler.

In case an ordered result is expected, remember to
sort an unordered container before iteration. Or use ordered containers
like ``vector``/``MapVector``/``SetVector`` if you want to iterate pointer
keys.

Beware of non-deterministic sorting order of equal elements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``std::sort`` uses a non-stable sorting algorithm in which the order of equal
elements is not guaranteed to be preserved. Thus using ``std::sort`` for a
container having equal elements may result in non-deterministic behavior.
To uncover such instances of non-determinism, LLVM has introduced a new
``llvm::sort`` wrapper function. For an ``EXPENSIVE_CHECKS`` build this will randomly
shuffle the container before sorting. Default to using ``llvm::sort`` instead
of ``std::sort``.

Style Issues
============

The High-Level Issues
---------------------

Self-contained Headers
^^^^^^^^^^^^^^^^^^^^^^

Header files should be self-contained (compile on their own) and end in ``.h``.
Non-header files that are meant for inclusion should end in ``.inc`` and be
used sparingly.

All header files should be self-contained. Users and refactoring tools should
not have to adhere to special conditions to include the header. Specifically, a
header should have header guards and include all other headers it needs.

There are rare cases where a file designed to be included is not
self-contained. These are typically intended to be included at unusual
locations, such as the middle of another file. They might not use header
guards, and might not include their prerequisites. Name such files with the
.inc extension. Use sparingly, and prefer self-contained headers when possible.

In general, a header should be implemented by one or more ``.cpp`` files.  Each
of these ``.cpp`` files should include the header that defines their interface
first.  This ensures that all of the dependencies of the header have been
properly added to the header itself, and are not implicit.  System headers
should be included after user headers for a translation unit.

Library Layering
^^^^^^^^^^^^^^^^

A directory of header files (for example, ``include/llvm/Foo``) defines a
library (``Foo``). One library (both
its headers and implementation) should only use things from the libraries
listed in its dependencies.

Some of this constraint can be enforced by classic Unix linkers (Mac & Windows
linkers, as well as lld, do not enforce this constraint). A Unix linker
searches left to right through the libraries specified on its command line and
never revisits a library. In this way, no circular dependencies between
libraries can exist.

This doesn't fully enforce all inter-library dependencies, and importantly
doesn't enforce header file circular dependencies created by inline functions.
A good way to answer the "is this layered correctly" would be to consider
whether a Unix linker would succeed at linking the program if all inline
functions were defined out-of-line. (& for all valid orderings of dependencies
- since linking resolution is linear, it's possible that some implicit
dependencies can sneak through: A depends on B and C, so valid orderings are
"C B A" or "B C A", in both cases the explicit dependencies come before their
use. But in the first case, B could still link successfully if it implicitly
depended on C, or the opposite in the second case)

.. _minimal list of #includes:

``#include`` as Little as Possible
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``#include`` hurts compile time performance.  Don't do it unless you have to,
especially in header files.

But wait! Sometimes you need to have the definition of a class to use it, or to
inherit from it.  In these cases go ahead and ``#include`` that header file.  Be
aware, however, that there are many cases where you don't need to have the full
definition of a class.  If you are using a pointer or reference to a class, you
don't need the header file.  If you are simply returning a class instance from a
prototyped function or method, you don't need it.  In fact, for most cases, you
simply don't need the definition of a class. And not ``#include``\ing speeds up
compilation.

It is easy to try to go overboard on this recommendation, however.  You
**must** include all of the header files that you are using --- you can include
them either directly or indirectly through another header file.  To make sure
that you don't accidentally forget to include a header file in your module
header, make sure to include your module header **first** in the implementation
file (as mentioned above).  This way there won't be any hidden dependencies that
you'll find out about later.

Keep "Internal" Headers Private
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Many modules have a complex implementation that causes them to use more than one
implementation (``.cpp``) file.  It is often tempting to put the internal
communication interface (helper classes, extra functions, etc) in the public
module header file.  Don't do this!

If you really need to do something like this, put a private header file in the
same directory as the source files, and include it locally.  This ensures that
your private interface remains private and undisturbed by outsiders.

.. note::

    It's okay to put extra implementation methods in a public class itself. Just
    make them private (or protected) and all is well.

Use Namespace Qualifiers to Implement Previously Declared Functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When providing an out-of-line implementation of a function in a source file, do
not open namespace blocks in the source file. Instead, use namespace qualifiers
to help ensure that your definition matches an existing declaration. Do this:

.. code-block:: c++

  // Foo.h
  namespace llvm {
  int foo(const char *s);
  }

  // Foo.cpp
  #include "Foo.h"
  using namespace llvm;
  int llvm::foo(const char *s) {
    // ...
  }

Doing this helps to avoid bugs where the definition does not match the
declaration from the header. For example, the following C++ code defines a new
overload of ``llvm::foo`` instead of providing a definition for the existing
function declared in the header:

.. code-block:: c++

  // Foo.cpp
  #include "Foo.h"
  namespace llvm {
  int foo(char *s) { // Mismatch between "const char *" and "char *"
  }
  } // namespace llvm

This error will not be caught until the build is nearly complete, when the
linker fails to find a definition for any uses of the original function.  If the
function were instead defined with a namespace qualifier, the error would have
been caught immediately when the definition was compiled.

Class method implementations must already name the class and new overloads
cannot be introduced out of line, so this recommendation does not apply to them.

.. _early exits:

Use Early Exits and ``continue`` to Simplify Code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When reading code, keep in mind how much state and how many previous decisions
have to be remembered by the reader to understand a block of code.  Aim to
reduce indentation where possible when it doesn't make it more difficult to
understand the code.  One great way to do this is by making use of early exits
and the ``continue`` keyword in long loops. Consider this code that does not
use an early exit:

.. code-block:: c++

  Value *doSomething(Instruction *I) {
    if (!I->isTerminator() &&
        I->hasOneUse() && doOtherThing(I)) {
      ... some long code ....
    }

    return 0;
  }

This code has several problems if the body of the ``'if'`` is large.  When
you're looking at the top of the function, it isn't immediately clear that this
*only* does interesting things with non-terminator instructions, and only
applies to things with the other predicates.  Second, it is relatively difficult
to describe (in comments) why these predicates are important because the ``if``
statement makes it difficult to lay out the comments.  Third, when you're deep
within the body of the code, it is indented an extra level.  Finally, when
reading the top of the function, it isn't clear what the result is if the
predicate isn't true; you have to read to the end of the function to know that
it returns null.

It is much preferred to format the code like this:

.. code-block:: c++

  Value *doSomething(Instruction *I) {
    // Terminators never need 'something' done to them because ...
    if (I->isTerminator())
      return 0;

    // We conservatively avoid transforming instructions with multiple uses
    // because goats like cheese.
    if (!I->hasOneUse())
      return 0;

    // This is really just here for example.
    if (!doOtherThing(I))
      return 0;

    ... some long code ....
  }

This fixes these problems.  A similar problem frequently happens in ``for``
loops.  A silly example is something like this:

.. code-block:: c++

  for (Instruction &I : BB) {
    if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
      Value *LHS = BO->getOperand(0);
      Value *RHS = BO->getOperand(1);
      if (LHS != RHS) {
        ...
      }
    }
  }

When you have very, very small loops, this sort of structure is fine. But if it
exceeds more than 10-15 lines, it becomes difficult for people to read and
understand at a glance. The problem with this sort of code is that it gets very
nested very quickly. This means that the reader of the code has to keep a lot of
context in their brain to remember what is going immediately on in the loop,
because they don't know if/when the ``if`` conditions will have ``else``\s etc.
It is strongly preferred to structure the loop like this:

.. code-block:: c++

  for (Instruction &I : BB) {
    auto *BO = dyn_cast<BinaryOperator>(&I);
    if (!BO) continue;

    Value *LHS = BO->getOperand(0);
    Value *RHS = BO->getOperand(1);
    if (LHS == RHS) continue;

    ...
  }

This has all the benefits of using early exits for functions: it reduces the nesting
of the loop, it makes it easier to describe why the conditions are true, and it
makes it obvious to the reader that there is no ``else`` coming up that they
have to push context into their brain for.  If a loop is large, this can be a
big understandability win.

Don't use ``else`` after a ``return``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For similar reasons as above (reduction of indentation and easier reading), please
do not use ``'else'`` or ``'else if'`` after something that interrupts control
flow --- like ``return``, ``break``, ``continue``, ``goto``, etc. For example:

.. code-block:: c++

  case 'J': {
    if (Signed) {
      Type = Context.getsigjmp_bufType();
      if (Type.isNull()) {
        Error = ASTContext::GE_Missing_sigjmp_buf;
        return QualType();
      } else {
        break; // Unnecessary.
      }
    } else {
      Type = Context.getjmp_bufType();
      if (Type.isNull()) {
        Error = ASTContext::GE_Missing_jmp_buf;
        return QualType();
      } else {
        break; // Unnecessary.
      }
    }
  }

It is better to write it like this:

.. code-block:: c++

  case 'J':
    if (Signed) {
      Type = Context.getsigjmp_bufType();
      if (Type.isNull()) {
        Error = ASTContext::GE_Missing_sigjmp_buf;
        return QualType();
      }
    } else {
      Type = Context.getjmp_bufType();
      if (Type.isNull()) {
        Error = ASTContext::GE_Missing_jmp_buf;
        return QualType();
      }
    }
    break;

Or better yet (in this case) as:

.. code-block:: c++

  case 'J':
    if (Signed)
      Type = Context.getsigjmp_bufType();
    else
      Type = Context.getjmp_bufType();

    if (Type.isNull()) {
      Error = Signed ? ASTContext::GE_Missing_sigjmp_buf :
                       ASTContext::GE_Missing_jmp_buf;
      return QualType();
    }
    break;

The idea is to reduce indentation and the amount of code you have to keep track
of when reading the code.

Note: this advice does not apply to a ``constexpr if`` statement. The
substatement of the ``else`` clause may be a discarded statement, so removing
the ``else`` can cause unexpected template instantiations. Thus, the following
example is correct:

.. code-block:: c++

  template<typename T>
  static constexpr bool VarTempl = true;

  template<typename T>
  int func() {
    if constexpr (VarTempl<T>)
      return 1;
    else
      static_assert(!VarTempl<T>);
  }

Turn Predicate Loops into Predicate Functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is very common to write small loops that just compute a boolean value.  There
are a number of ways that people commonly write these, but an example of this
sort of thing is:

.. code-block:: c++

  bool FoundFoo = false;
  for (unsigned I = 0, E = BarList.size(); I != E; ++I)
    if (BarList[I]->isFoo()) {
      FoundFoo = true;
      break;
    }

  if (FoundFoo) {
    ...
  }

Instead of this sort of loop, we prefer to use a predicate function (which may
be `static`_) that uses `early exits`_:

.. code-block:: c++

  /// \returns true if the specified list has an element that is a foo.
  static bool containsFoo(const std::vector<Bar*> &List) {
    for (unsigned I = 0, E = List.size(); I != E; ++I)
      if (List[I]->isFoo())
        return true;
    return false;
  }
  ...

  if (containsFoo(BarList)) {
    ...
  }

There are many reasons for doing this: it reduces indentation and factors out
code which can often be shared by other code that checks for the same predicate.
More importantly, it *forces you to pick a name* for the function, and forces
you to write a comment for it.  In this silly example, this doesn't add much
value.  However, if the condition is complex, this can make it a lot easier for
the reader to understand the code that queries for this predicate.  Instead of
being faced with the in-line details of how we check to see if the BarList
contains a foo, we can trust the function name and continue reading with better
locality.

The Low-Level Issues
--------------------

Name Types, Functions, Variables, and Enumerators Properly
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Poorly-chosen names can mislead the reader and cause bugs. We cannot stress
enough how important it is to use *descriptive* names.  Pick names that match
the semantics and role of the underlying entities, within reason.  Avoid
abbreviations unless they are well known.  After picking a good name, make sure
to use consistent capitalization for the name, as inconsistency requires clients
to either memorize the APIs or to look it up to find the exact spelling.

In general, names should be in camel case (e.g. ``TextFileReader`` and
``isLValue()``).  Different kinds of declarations have different rules:

* **Type names** (including classes, structs, enums, typedefs, etc) should be
  nouns and start with an upper-case letter (e.g. ``TextFileReader``).

* **Variable names** should be nouns (as they represent state).  The name should
  be camel case, and start with an upper-case letter (e.g. ``Leader`` or
  ``Boats``).

* **Function names** should be verb phrases (as they represent actions), and
  command-like function should be imperative.  The name should be camel case,
  and start with a lowercase letter (e.g. ``openFile()`` or ``isFoo()``).

* **Enum declarations** (e.g. ``enum Foo {...}``) are types, so they should
  follow the naming conventions for types.  A common use for enums is as a
  discriminator for a union, or an indicator of a subclass.  When an enum is
  used for something like this, it should have a ``Kind`` suffix
  (e.g. ``ValueKind``).

* **Enumerators** (e.g. ``enum { Foo, Bar }``) and **public member variables**
  should start with an upper-case letter, just like types.  Unless the
  enumerators are defined in their own small namespace or inside a class,
  enumerators should have a prefix corresponding to the enum declaration name.
  For example, ``enum ValueKind { ... };`` may contain enumerators like
  ``VK_Argument``, ``VK_BasicBlock``, etc.  Enumerators that are just
  convenience constants are exempt from the requirement for a prefix.  For
  instance:

  .. code-block:: c++

      enum {
        MaxSize = 42,
        Density = 12
      };

As an exception, classes that mimic STL classes can have member names in STL's
style of lowercase words separated by underscores (e.g. ``begin()``,
``push_back()``, and ``empty()``). Classes that provide multiple
iterators should add a singular prefix to ``begin()`` and ``end()``
(e.g. ``global_begin()`` and ``use_begin()``).

Here are some examples:

.. code-block:: c++

  class VehicleMaker {
    ...
    Factory<Tire> F;            // Avoid: a non-descriptive abbreviation.
    Factory<Tire> Factory;      // Better: more descriptive.
    Factory<Tire> TireFactory;  // Even better: if VehicleMaker has more than one
                                // kind of factories.
  };

  Vehicle makeVehicle(VehicleType Type) {
    VehicleMaker M;                         // Might be OK if scope is small.
    Tire Tmp1 = M.makeTire();               // Avoid: 'Tmp1' provides no information.
    Light Headlight = M.makeLight("head");  // Good: descriptive.
    ...
  }

Assert Liberally
^^^^^^^^^^^^^^^^

Use the "``assert``" macro to its fullest.  Check all of your preconditions and
assumptions.  You never know when a bug (not necessarily even yours) might be
caught early by an assertion, which reduces debugging time dramatically.  The
"``<cassert>``" header file is probably already included by the header files you
are using, so it doesn't cost anything to use it.

To further assist with debugging, make sure to put some kind of error message in
the assertion statement, which is printed if the assertion is tripped. This
helps the poor debugger make sense of why an assertion is being made and
enforced, and hopefully what to do about it.  Here is one complete example:

.. code-block:: c++

  inline Value *getOperand(unsigned I) {
    assert(I < Operands.size() && "getOperand() out of range!");
    return Operands[I];
  }

Here are more examples:

.. code-block:: c++

  assert(Ty->isPointerType() && "Can't allocate a non-pointer type!");

  assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");

  assert(idx < getNumSuccessors() && "Successor # out of range!");

  assert(V1.getType() == V2.getType() && "Constant types must be identical!");

  assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");

You get the idea.

In the past, asserts were used to indicate a piece of code that should not be
reached.  These were typically of the form:

.. code-block:: c++

  assert(0 && "Invalid radix for integer literal");

This has a few issues, the main one being that some compilers might not
understand the assertion, or warn about a missing return in builds where
assertions are compiled out.

Today, we have something much better: ``llvm_unreachable``:

.. code-block:: c++

  llvm_unreachable("Invalid radix for integer literal");

When assertions are enabled, this will print the message if it's ever reached
and then exit the program. When assertions are disabled (i.e. in release
builds), ``llvm_unreachable`` becomes a hint to compilers to skip generating
code for this branch. If the compiler does not support this, it will fall back
to the "abort" implementation.

Use ``llvm_unreachable`` to mark a specific point in code that should never be
reached. This is especially desirable for addressing warnings about unreachable
branches, etc., but can be used whenever reaching a particular code path is
unconditionally a bug (not originating from user input; see below) of some kind.
Use of ``assert`` should always include a testable predicate (as opposed to
``assert(false)``).

If the error condition can be triggered by user input then the
recoverable error mechanism described in :doc:`ProgrammersManual` should be
used instead. In cases where this is not practical, ``report_fatal_error`` may
be used.

Another issue is that values used only by assertions will produce an "unused
value" warning when assertions are disabled.  For example, this code will warn:

.. code-block:: c++

  unsigned Size = V.size();
  assert(Size > 42 && "Vector smaller than it should be");

  bool NewToSet = Myset.insert(Value);
  assert(NewToSet && "The value shouldn't be in the set yet");

These are two interesting different cases. In the first case, the call to
``V.size()`` is only useful for the assert, and we don't want it executed when
assertions are disabled.  Code like this should move the call into the assert
itself.  In the second case, the side effects of the call must happen whether
the assert is enabled or not. In this case, the value should be defined using
the ``[[maybe_unused]]`` attribute to suppress the warning. To be specific, it is
preferred to write the code like this:

.. code-block:: c++

  assert(V.size() > 42 && "Vector smaller than it should be");

  [[maybe_unused]] bool NewToSet = Myset.insert(Value);
  assert(NewToSet && "The value shouldn't be in the set yet");

In C code where ``[[maybe_unused]]`` is not supported, use ``void`` cast to
suppress an unused variable warning as follows:

.. code-block:: c

    LLVMValueRef Value = LLVMMetadataAsValue(Context, NodeMD);
    assert(LLVMIsAValueAsMetadata(Value) != NULL);
    (void)Value;

Do Not Use ``using namespace std``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In LLVM, we prefer to explicitly prefix all identifiers from the standard
namespace with an "``std::``" prefix, rather than rely on "``using namespace
std;``".

In header files, adding a ``'using namespace XXX'`` directive pollutes the
namespace of any source file that ``#include``\s the header, creating
maintenance issues.

In implementation files (e.g. ``.cpp`` files), the rule is more of a stylistic
rule, but is still important.  Basically, using explicit namespace prefixes
makes the code **clearer**, because it is immediately obvious what facilities
are being used and where they are coming from. And **more portable**, because
namespace clashes cannot occur between LLVM code and other namespaces.  The
portability rule is important because different standard library implementations
expose different symbols (potentially ones they shouldn't), and future revisions
to the C++ standard will add more symbols to the ``std`` namespace.  As such, we
never use ``'using namespace std;'`` in LLVM.

The exception to the general rule (i.e. it's not an exception for the ``std``
namespace) is for implementation files.  For example, all of the code in the
LLVM project implements code that lives in the 'llvm' namespace.  As such, it is
ok, and actually clearer, for the ``.cpp`` files to have a ``'using namespace
llvm;'`` directive at the top, after the ``#include``\s.  This reduces
indentation in the body of the file for source editors that indent based on
braces, and keeps the conceptual context cleaner.  The general form of this rule
is that any ``.cpp`` file that implements code in any namespace may use that
namespace (and its parents'), but should not use any others.

Provide a Virtual Method Anchor for Classes in Headers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a class is defined in a header file and has a vtable (either it has virtual
methods or it derives from classes with virtual methods), it must always have at
least one out-of-line virtual method in the class.  Without this, the compiler
will copy the vtable and RTTI into every ``.o`` file that ``#include``\s the
header, bloating ``.o`` file sizes and increasing link times.

Don't use default labels in fully covered switches over enumerations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``-Wswitch`` warns if a switch, without a default label, over an enumeration
does not cover every enumeration value. If you write a default label on a fully
covered switch over an enumeration then the ``-Wswitch`` warning won't fire
when new elements are added to that enumeration. To help avoid adding these
kinds of defaults, Clang has the warning ``-Wcovered-switch-default`` which is
off by default but turned on when building LLVM with a version of Clang that
supports the warning.

A knock-on effect of this stylistic requirement is that when building LLVM with
GCC you may get warnings related to "control may reach end of non-void function"
if you return from each case of a covered switch-over-enum because GCC assumes
that the enum expression may take any representable value, not just those of
individual enumerators. To suppress this warning, use ``llvm_unreachable`` after
the switch.

Use range-based ``for`` loops wherever possible
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The introduction of range-based ``for`` loops in C++11 means that explicit
manipulation of iterators is rarely necessary. We use range-based ``for``
loops wherever possible for all newly added code. For example:

.. code-block:: c++

  BasicBlock *BB = ...
  for (Instruction &I : *BB)
    ... use I ...

Usage of ``std::for_each()``/``llvm::for_each()`` functions is discouraged,
unless the callable object already exists.

Don't evaluate ``end()`` every time through a loop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In cases where range-based ``for`` loops can't be used and it is necessary
to write an explicit iterator-based loop, pay close attention to whether
``end()`` is re-evaluated on each loop iteration. One common mistake is to
write a loop in this style:

.. code-block:: c++

  BasicBlock *BB = ...
  for (auto I = BB->begin(); I != BB->end(); ++I)
    ... use I ...

The problem with this construct is that it evaluates "``BB->end()``" every time
through the loop.  Instead of writing the loop like this, we strongly prefer
loops to be written so that they evaluate it once before the loop starts.  A
convenient way to do this is like so:

.. code-block:: c++

  BasicBlock *BB = ...
  for (auto I = BB->begin(), E = BB->end(); I != E; ++I)
    ... use I ...

The observant may quickly point out that these two loops may have different
semantics: if the container (a basic block in this case) is being mutated, then
"``BB->end()``" may change its value every time through the loop and the second
loop may not in fact be correct.  If you actually do depend on this behavior,
please write the loop in the first form and add a comment indicating that you
did it intentionally.

Why do we prefer the second form (when correct)?  Writing the loop in the first
form has two problems. First, it may be less efficient than evaluating it at the
start of the loop.  In this case, the cost is probably minor --- a few extra
loads every time through the loop.  However, if the base expression is more
complex, then the cost can rise quickly.  I've seen loops where the end
expression was actually something like: "``SomeMap[X]->end()``" and map lookups
really aren't cheap.  By writing it in the second form consistently, you
eliminate the issue entirely and don't even have to think about it.

The second (even bigger) issue is that writing the loop in the first form hints
to the reader that the loop is mutating the container (a fact that a comment
would handily confirm!).  If you write the loop in the second form, it is
immediately obvious without even looking at the body of the loop that the
container isn't being modified, which makes it easier to read the code and
understand what it does.

While the second form of the loop is a few extra keystrokes, we do strongly
prefer it.

``#include <iostream>`` is Forbidden
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The use of ``#include <iostream>`` in library files is hereby **forbidden**,
because many common implementations transparently inject a `static constructor`_
into every translation unit that includes it.

Note that using the other stream headers (``<sstream>`` for example) is not
problematic in this regard --- just ``<iostream>``. However, ``raw_ostream``
provides various APIs that are better performing for almost every use than
``std::ostream`` style APIs.

.. note::

  New code should always use `raw_ostream`_ for writing, or the
  ``llvm::MemoryBuffer`` API for reading files.

.. _raw_ostream:

Use ``raw_ostream``
^^^^^^^^^^^^^^^^^^^

LLVM includes a lightweight, simple, and efficient stream implementation in
``llvm/Support/raw_ostream.h``, which provides all of the common features of
``std::ostream``.  All new code should use ``raw_ostream`` instead of
``ostream``.

Unlike ``std::ostream``, ``raw_ostream`` is not a template and can be forward
declared as ``class raw_ostream``.  Public headers should generally not include
the ``raw_ostream`` header, but use forward declarations and constant references
to ``raw_ostream`` instances.

Avoid ``std::endl``
^^^^^^^^^^^^^^^^^^^

The ``std::endl`` modifier, when used with ``iostreams`` outputs a newline to
the output stream specified.  In addition to doing this, however, it also
flushes the output stream.  In other words, these are equivalent:

.. code-block:: c++

  std::cout << std::endl;
  std::cout << '\n' << std::flush;

Most of the time, you probably have no reason to flush the output stream, so
it's better to use a literal ``'\n'``.

Don't use ``inline`` when defining a function in a class definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A member function defined in a class definition is implicitly inline, so don't
put the ``inline`` keyword in this case.

Don't:

.. code-block:: c++

  class Foo {
  public:
    inline void bar() {
      // ...
    }
  };

Do:

.. code-block:: c++

  class Foo {
  public:
    void bar() {
      // ...
    }
  };

Microscopic Details
-------------------

This section describes preferred low-level formatting guidelines along with
reasoning on why we prefer them.

Spaces Before Parentheses
^^^^^^^^^^^^^^^^^^^^^^^^^

Put a space before an open parenthesis only in control flow statements, but not
in normal function call expressions and function-like macros.  For example:

.. code-block:: c++

  if (X) ...
  for (I = 0; I != 100; ++I) ...
  while (LLVMRocks) ...

  somefunc(42);
  assert(3 != 4 && "laws of math are failing me");

  A = foo(42, 92) + bar(X);

The reason for doing this is not completely arbitrary.  This style makes control
flow operators stand out more, and makes expressions flow better.

Prefer Preincrement
^^^^^^^^^^^^^^^^^^^

Hard fast rule: Preincrement (``++X``) may be no slower than postincrement
(``X++``) and could very well be a lot faster than it.  Use preincrementation
whenever possible.

The semantics of postincrement include making a copy of the value being
incremented, returning it, and then preincrementing the "work value".  For
primitive types, this isn't a big deal. But for iterators, it can be a huge
issue (for example, some iterators contain stack and set objects in them...
copying an iterator could invoke the copy ctor's of these as well).  In general,
get in the habit of always using preincrement, and you won't have a problem.


Namespace Indentation
^^^^^^^^^^^^^^^^^^^^^

In general, we strive to reduce indentation wherever possible.  This is useful
because we want code to `fit into 80 columns`_ without excessive wrapping, but
also because it makes it easier to understand the code. To facilitate this and
avoid some insanely deep nesting on occasion, don't indent namespaces. If it
helps readability, feel free to add a comment indicating what namespace is
being closed by a ``}``.  For example:

.. code-block:: c++

  namespace llvm {
  namespace knowledge {

  /// This class represents things that Smith can have an intimate
  /// understanding of and contains the data associated with it.
  class Grokable {
  ...
  public:
    explicit Grokable() { ... }
    virtual ~Grokable() = 0;

    ...

  };

  } // namespace knowledge
  } // namespace llvm


Feel free to skip the closing comment when the namespace being closed is
obvious for any reason. For example, the outer-most namespace in a header file
is rarely a source of confusion. But namespaces both anonymous and named in
source files that are being closed half way through the file probably could use
clarification.

.. _static:

Restrict Visibility
^^^^^^^^^^^^^^^^^^^

Functions and variables should have the most restricted visibility possible.

For class members, that means using appropriate ``private``, ``protected``, or
``public`` keyword to restrict their access.

For non-member functions, variables, and classes, that means restricting
visibility to a single ``.cpp`` file if it is not referenced outside that file.

Visibility of file-scope non-member variables and functions can be restricted to
the current translation unit by using either the ``static`` keyword or an anonymous
namespace.

Anonymous namespaces are a great language feature that tells the C++
compiler that the contents of the namespace are only visible within the current
translation unit, allowing more aggressive optimization and eliminating the
possibility of symbol name collisions.

Anonymous namespaces are to C++ as ``static`` is to C functions and global
variables.  While ``static`` is available in C++, anonymous namespaces are more
general: they can make entire classes private to a file.

The problem with anonymous namespaces is that they naturally want to encourage
indentation of their body, and they reduce locality of reference: if you see a
random function definition in a C++ file, it is easy to see if it is marked
static, but seeing if it is in an anonymous namespace requires scanning a big
chunk of the file.

Because of this, we have a simple guideline: make anonymous namespaces as small
as possible, and only use them for class declarations.  For example:

.. code-block:: c++

  namespace {
  class StringSort {
  ...
  public:
    StringSort(...)
    bool operator<(const char *RHS) const;
  };
  } // namespace

  static void runHelper() {
    ...
  }

  bool StringSort::operator<(const char *RHS) const {
    ...
  }

Avoid putting declarations other than classes into anonymous namespaces:

.. code-block:: c++

  namespace {

  // ... many declarations ...

  void runHelper() {
    ...
  }

  // ... many declarations ...

  } // namespace

When you are looking at ``runHelper`` in the middle of a large C++ file,
you have no immediate way to tell if this function is local to the file.

In contrast, when the function is marked static, you don't need to cross-reference
faraway places in the file to tell that the function is local:

.. code-block:: c++

  static void runHelper() {
    ...
  }

Don't Use Braces on Simple Single-Statement Bodies of if/else/loop Statements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When writing the body of an ``if``, ``else``, or for/while loop statement, we
prefer to omit the braces to avoid unnecessary line noise. However, braces
should be used in cases where the omission of braces harms the readability and
maintainability of the code.

We consider that readability is harmed when omitting the brace in the presence
of a single statement that is accompanied by a comment (assuming the comment
can't be hoisted above the ``if`` or loop statement, see below).

Similarly, braces should be used when a single-statement body is complex enough
that it becomes difficult to see where the block containing the following
statement began. An ``if``/``else`` chain or a loop is considered a single
statement for this rule, and this rule applies recursively.

This list is not exhaustive. For example, readability is also harmed if an
``if``/``else`` chain does not use braced bodies for either all or none of its
members, or has complex conditionals, deep nesting, etc. The examples below
intend to provide some guidelines.

Maintainability is harmed if the body of an ``if`` ends with a (directly or
indirectly) nested ``if`` statement with no ``else``. Braces on the outer ``if``
would help to avoid running into a "dangling else" situation.


.. code-block:: c++

  // Omit the braces since the body is simple and clearly associated with the
  // `if`.
  if (isa<FunctionDecl>(D))
    handleFunctionDecl(D);
  else if (isa<VarDecl>(D))
    handleVarDecl(D);

  // Here we document the condition itself and not the body.
  if (isa<VarDecl>(D)) {
    // It is necessary that we explain the situation with this surprisingly long
    // comment, so it would be unclear without the braces whether the following
    // statement is in the scope of the `if`.
    // Because the condition is documented, we can't really hoist this
    // comment that applies to the body above the `if`.
    handleOtherDecl(D);
  }

  // Use braces on the outer `if` to avoid a potential dangling `else`
  // situation.
  if (isa<VarDecl>(D)) {
    if (shouldProcessAttr(A))
      handleAttr(A);
  }

  // Use braces for the `if` block to keep it uniform with the `else` block.
  if (isa<FunctionDecl>(D)) {
    handleFunctionDecl(D);
  } else {
    // In this `else` case, it is necessary that we explain the situation with
    // this surprisingly long comment, so it would be unclear without the braces
    // whether the following statement is in the scope of the `if`.
    handleOtherDecl(D);
  }

  // Use braces for the `else if` and `else` block to keep it uniform with the
  // `if` block.
  if (isa<FunctionDecl>(D)) {
    verifyFunctionDecl(D);
    handleFunctionDecl(D);
  } else if (isa<GlobalVarDecl>(D)) {
    handleGlobalVarDecl(D);
  } else {
    handleOtherDecl(D);
  }

  // This should also omit braces.  The `for` loop contains only a single
  // statement, so it shouldn't have braces.  The `if` also only contains a
  // single simple statement (the `for` loop), so it also should omit braces.
  if (isa<FunctionDecl>(D))
    for (auto *A : D.attrs())
      handleAttr(A);

  // Use braces for a `do-while` loop and its enclosing statement.
  if (Tok->is(tok::l_brace)) {
    do {
      Tok = Tok->Next;
    } while (Tok);
  }

  // Use braces for the outer `if` since the nested `for` is braced.
  if (isa<FunctionDecl>(D)) {
    for (auto *A : D.attrs()) {
      // In this `for` loop body, it is necessary that we explain the situation
      // with this surprisingly long comment, forcing braces on the `for` block.
      handleAttr(A);
    }
  }

  // Use braces on the outer block because there are more than two levels of
  // nesting.
  if (isa<FunctionDecl>(D)) {
    for (auto *A : D.attrs())
      for (ssize_t i : llvm::seq<ssize_t>(count))
        handleAttrOnDecl(D, A, i);
  }

  // Use braces on the outer block because of a nested `if`; otherwise, the
  // compiler would warn: `add explicit braces to avoid dangling else`
  if (auto *D = dyn_cast<FunctionDecl>(D)) {
    if (shouldProcess(D))
      handleVarDecl(D);
    else
      markAsIgnored(D);
  }


See Also
========

A lot of these comments and recommendations have been culled from other sources.
Two particularly important books for our work are:

#. `Effective C++
   <https://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0321334876>`_
   by Scott Meyers.  Also interesting and useful are "More Effective C++" and
   "Effective STL" by the same author.

#. `Large-Scale C++ Software Design
   <https://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620>`_
   by John Lakos

If you get some free time, and you haven't read them: do so, you might learn
something.
