SupportLibrary.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ===============
  2. Support Library
  3. ===============
  4. Abstract
  5. ========
  6. This document provides some details on LLVM's Support Library, located in the
  7. source at ``lib/Support`` and ``include/llvm/Support``. The library's purpose
  8. is to shield LLVM from the differences between operating systems for the few
  9. services LLVM needs from the operating system. Much of LLVM is written using
  10. portability features of standard C++. However, in a few areas, system dependent
  11. facilities are needed and the Support Library is the wrapper around those
  12. system calls.
  13. By centralizing LLVM's use of operating system interfaces, we make it possible
  14. for the LLVM tool chain and runtime libraries to be more easily ported to new
  15. platforms since (theoretically) only ``lib/Support`` needs to be ported. This
  16. library also unclutters the rest of LLVM from #ifdef use and special cases for
  17. specific operating systems. Such uses are replaced with simple calls to the
  18. interfaces provided in ``include/llvm/Support``.
  19. Note that the Support Library is not intended to be a complete operating system
  20. wrapper (such as the Adaptive Communications Environment (ACE) or Apache
  21. Portable Runtime (APR)), but only provides the functionality necessary to
  22. support LLVM.
  23. The Support Library was originally referred to as the System Library, written
  24. by Reid Spencer who formulated the design based on similar work originating
  25. from the eXtensible Programming System (XPS). Several people helped with the
  26. effort; especially, Jeff Cohen and Henrik Bach on the Win32 port.
  27. Keeping LLVM Portable
  28. =====================
  29. In order to keep LLVM portable, LLVM developers should adhere to a set of
  30. portability rules associated with the Support Library. Adherence to these rules
  31. should help the Support Library achieve its goal of shielding LLVM from the
  32. variations in operating system interfaces and doing so efficiently. The
  33. following sections define the rules needed to fulfill this objective.
  34. Don't Include System Headers
  35. ----------------------------
  36. Except in ``lib/Support``, no LLVM source code should directly ``#include`` a
  37. system header. Care has been taken to remove all such ``#includes`` from LLVM
  38. while ``lib/Support`` was being developed. Specifically this means that header
  39. files like "``unistd.h``", "``windows.h``", "``stdio.h``", and "``string.h``"
  40. are forbidden to be included by LLVM source code outside the implementation of
  41. ``lib/Support``.
  42. To obtain system-dependent functionality, existing interfaces to the system
  43. found in ``include/llvm/Support`` should be used. If an appropriate interface is
  44. not available, it should be added to ``include/llvm/Support`` and implemented in
  45. ``lib/Support`` for all supported platforms.
  46. Don't Expose System Headers
  47. ---------------------------
  48. The Support Library must shield LLVM from **all** system headers. To obtain
  49. system level functionality, LLVM source must
  50. ``#include "llvm/Support/Thing.h"`` and nothing else. This means that
  51. ``Thing.h`` cannot expose any system header files. This protects LLVM from
  52. accidentally using system specific functionality and only allows it via
  53. the ``lib/Support`` interface.
  54. Use Standard C Headers
  55. ----------------------
  56. The **standard** C headers (the ones beginning with "c") are allowed to be
  57. exposed through the ``lib/Support`` interface. These headers and the things they
  58. declare are considered to be platform agnostic. LLVM source files may include
  59. them directly or obtain their inclusion through ``lib/Support`` interfaces.
  60. Use Standard C++ Headers
  61. ------------------------
  62. The **standard** C++ headers from the standard C++ library and standard
  63. template library may be exposed through the ``lib/Support`` interface. These
  64. headers and the things they declare are considered to be platform agnostic.
  65. LLVM source files may include them or obtain their inclusion through
  66. ``lib/Support`` interfaces.
  67. High Level Interface
  68. --------------------
  69. The entry points specified in the interface of ``lib/Support`` must be aimed at
  70. completing some reasonably high level task needed by LLVM. We do not want to
  71. simply wrap each operating system call. It would be preferable to wrap several
  72. operating system calls that are always used in conjunction with one another by
  73. LLVM.
  74. For example, consider what is needed to execute a program, wait for it to
  75. complete, and return its result code. On Unix, this involves the following
  76. operating system calls: ``getenv``, ``fork``, ``execve``, and ``wait``. The
  77. correct thing for ``lib/Support`` to provide is a function, say
  78. ``ExecuteProgramAndWait``, that implements the functionality completely. what
  79. we don't want is wrappers for the operating system calls involved.
  80. There must **not** be a one-to-one relationship between operating system
  81. calls and the Support library's interface. Any such interface function will be
  82. suspicious.
  83. No Unused Functionality
  84. -----------------------
  85. There must be no functionality specified in the interface of ``lib/Support``
  86. that isn't actually used by LLVM. We're not writing a general purpose operating
  87. system wrapper here, just enough to satisfy LLVM's needs. And, LLVM doesn't
  88. need much. This design goal aims to keep the ``lib/Support`` interface small and
  89. understandable which should foster its actual use and adoption.
  90. No Duplicate Implementations
  91. ----------------------------
  92. The implementation of a function for a given platform must be written exactly
  93. once. This implies that it must be possible to apply a function's
  94. implementation to multiple operating systems if those operating systems can
  95. share the same implementation. This rule applies to the set of operating
  96. systems supported for a given class of operating system (e.g. Unix, Win32).
  97. No Virtual Methods
  98. ------------------
  99. The Support Library interfaces can be called quite frequently by LLVM. In order
  100. to make those calls as efficient as possible, we discourage the use of virtual
  101. methods. There is no need to use inheritance for implementation differences, it
  102. just adds complexity. The ``#include`` mechanism works just fine.
  103. No Exposed Functions
  104. --------------------
  105. Any functions defined by system libraries (i.e. not defined by ``lib/Support``)
  106. must not be exposed through the ``lib/Support`` interface, even if the header
  107. file for that function is not exposed. This prevents inadvertent use of system
  108. specific functionality.
  109. For example, the ``stat`` system call is notorious for having variations in the
  110. data it provides. ``lib/Support`` must not declare ``stat`` nor allow it to be
  111. declared. Instead it should provide its own interface to discovering
  112. information about files and directories. Those interfaces may be implemented in
  113. terms of ``stat`` but that is strictly an implementation detail. The interface
  114. provided by the Support Library must be implemented on all platforms (even
  115. those without ``stat``).
  116. No Exposed Data
  117. ---------------
  118. Any data defined by system libraries (i.e. not defined by ``lib/Support``) must
  119. not be exposed through the ``lib/Support`` interface, even if the header file
  120. for that function is not exposed. As with functions, this prevents inadvertent
  121. use of data that might not exist on all platforms.
  122. Minimize Soft Errors
  123. --------------------
  124. Operating system interfaces will generally provide error results for every
  125. little thing that could go wrong. In almost all cases, you can divide these
  126. error results into two groups: normal/good/soft and abnormal/bad/hard. That is,
  127. some of the errors are simply information like "file not found", "insufficient
  128. privileges", etc. while other errors are much harder like "out of space", "bad
  129. disk sector", or "system call interrupted". We'll call the first group "*soft*"
  130. errors and the second group "*hard*" errors.
  131. ``lib/Support`` must always attempt to minimize soft errors. This is a design
  132. requirement because the minimization of soft errors can affect the granularity
  133. and the nature of the interface. In general, if you find that you're wanting to
  134. throw soft errors, you must review the granularity of the interface because it
  135. is likely you're trying to implement something that is too low level. The rule
  136. of thumb is to provide interface functions that **can't** fail, except when
  137. faced with hard errors.
  138. For a trivial example, suppose we wanted to add an "``OpenFileForWriting``"
  139. function. For many operating systems, if the file doesn't exist, attempting to
  140. open the file will produce an error. However, ``lib/Support`` should not simply
  141. throw that error if it occurs because its a soft error. The problem is that the
  142. interface function, ``OpenFileForWriting`` is too low level. It should be
  143. ``OpenOrCreateFileForWriting``. In the case of the soft "doesn't exist" error,
  144. this function would just create it and then open it for writing.
  145. This design principle needs to be maintained in ``lib/Support`` because it
  146. avoids the propagation of soft error handling throughout the rest of LLVM.
  147. Hard errors will generally just cause a termination for an LLVM tool so don't
  148. be bashful about throwing them.
  149. Rules of thumb:
  150. #. Don't throw soft errors, only hard errors.
  151. #. If you're tempted to throw a soft error, re-think the interface.
  152. #. Handle internally the most common normal/good/soft error conditions
  153. so the rest of LLVM doesn't have to.
  154. No throw Specifications
  155. -----------------------
  156. None of the ``lib/Support`` interface functions may be declared with C++
  157. ``throw()`` specifications on them. This requirement makes sure that the
  158. compiler does not insert additional exception handling code into the interface
  159. functions. This is a performance consideration: ``lib/Support`` functions are
  160. at the bottom of many call chains and as such can be frequently called. We
  161. need them to be as efficient as possible. However, no routines in the system
  162. library should actually throw exceptions.
  163. Code Organization
  164. -----------------
  165. Implementations of the Support Library interface are separated by their general
  166. class of operating system. Currently only Unix and Win32 classes are defined
  167. but more could be added for other operating system classifications. To
  168. distinguish which implementation to compile, the code in ``lib/Support`` uses
  169. the ``LLVM_ON_UNIX`` and ``_WIN32`` ``#defines``. Each source file in
  170. ``lib/Support``, after implementing the generic (operating system independent)
  171. functionality needs to include the correct implementation using a set of
  172. ``#if defined(LLVM_ON_XYZ)`` directives. For example, if we had
  173. ``lib/Support/Path.cpp``, we'd expect to see in that file:
  174. .. code-block:: c++
  175. #if defined(LLVM_ON_UNIX)
  176. #include "Unix/Path.inc"
  177. #endif
  178. #if defined(_WIN32)
  179. #include "Windows/Path.inc"
  180. #endif
  181. The implementation in ``lib/Support/Unix/Path.inc`` should handle all Unix
  182. variants. The implementation in ``lib/Support/Windows/Path.inc`` should handle
  183. all Windows variants. What this does is quickly inc the basic class
  184. of operating system that will provide the implementation. The specific details
  185. for a given platform must still be determined through the use of ``#ifdef``.
  186. Consistent Semantics
  187. --------------------
  188. The implementation of a ``lib/Support`` interface can vary drastically between
  189. platforms. That's okay as long as the end result of the interface function is
  190. the same. For example, a function to create a directory is pretty straight
  191. forward on all operating system. System V IPC on the other hand isn't even
  192. supported on all platforms. Instead of "supporting" System V IPC,
  193. ``lib/Support`` should provide an interface to the basic concept of
  194. inter-process communications. The implementations might use System V IPC if
  195. that was available or named pipes, or whatever gets the job done effectively
  196. for a given operating system. In all cases, the interface and the
  197. implementation must be semantically consistent.