mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Coding Standards: Document library layering requirements & header isolation.
(I suppose these two pieces could be separated - but seemed related enough) As discussed on llvm-dev, this documents the general expectation of how library layering should be handled. There are a few existing cases where these constraints are not met, but as with most style guide things - this is forward looking and provides guidance when cleaning up existing code, it doesn't immediately require that all previous code be cleaned up to match. (see: naming conventions, etc) Differential Revision: https://reviews.llvm.org/D42771 llvm-svn: 324004
This commit is contained in:
parent
2a3ca1333b
commit
1f3c1d599a
@ -808,8 +808,8 @@ As a rule of thumb, use ``auto &`` unless you need to copy the result, and use
|
||||
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(); }
|
||||
for (const auto \*Ptr : Container) { observe(\*Ptr); }
|
||||
for (auto \*Ptr : Container) { Ptr->change(); }
|
||||
|
||||
Beware of non-determinism due to ordering of pointers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -832,27 +832,54 @@ Style Issues
|
||||
The High-Level Issues
|
||||
---------------------
|
||||
|
||||
A Public Header File **is** a Module
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Self-contained Headers
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
C++ doesn't do too well in the modularity department. There is no real
|
||||
encapsulation or data hiding (unless you use expensive protocol classes), but it
|
||||
is what we have to work with. When you write a public header file (in the LLVM
|
||||
source tree, they live in the top level "``include``" directory), you are
|
||||
defining a module of functionality.
|
||||
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.
|
||||
|
||||
Ideally, modules should be completely independent of each other, and their
|
||||
header files should only ``#include`` the absolute minimum number of headers
|
||||
possible. A module is not just a class, a function, or a namespace: it's a
|
||||
collection of these that defines an interface. This interface may be several
|
||||
functions, classes, or data structures, but the important issue is how they work
|
||||
together.
|
||||
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.
|
||||
|
||||
In general, a module should be implemented by one or more ``.cpp`` files. Each
|
||||
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 dependences of the module header have been
|
||||
properly added to the module header itself, and are not implicit. System
|
||||
headers should be included after user headers for a translation unit.
|
||||
first. This ensures that all of the dependences 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``). Dependencies between libraries are defined by the
|
||||
``LLVMBuild.txt`` file in their implementation (``lib/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:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user