Add missing copyrights
[oota-llvm.git] / runtime / GCCLibraries / crtend / crtend.c
1 /*===- crtend.c - Initialization code for programs ------------------------===*\
2  * 
3  *                     The LLVM Compiler Infrastructure
4  *
5  * This file was developed by the LLVM research group and is distributed under
6  * the University of Illinois Open Source License. See LICENSE.TXT for details.
7  *
8  *===----------------------------------------------------------------------===*
9  *
10  * This file defines the __main function, which is used to run static
11  * constructors and destructors in C++ programs, or with C programs that use GCC
12  * extensions to accomplish the same effect.
13  *
14  * The main data structures used to implement this functionality is the
15  * llvm.global_ctors and llvm.global_dtors lists, which are null terminated
16  * lists of TorRec (defined below) structures.
17  *
18 \*===----------------------------------------------------------------------===*/
19
20 #include <stdlib.h>
21
22 /* TorRec - The record type for each element of the ctor/dtor list */
23 typedef struct TorRec {
24   int Priority;
25   void (*FP)(void);
26 } TorRec;
27
28 /* __llvm_getGlobalCtors, __llvm_getGlobalDtors - Interface to the LLVM
29  * listend.ll file to get access to the start of the ctor and dtor lists...
30  */
31 TorRec *__llvm_getGlobalCtors(void);
32 TorRec *__llvm_getGlobalDtors(void);
33
34 static void run_destructors(void);
35
36 /* __main - A call to this function is automatically inserted into the top of
37  * the "main" function in the program compiled.  This function is responsible
38  * for calling static constructors before the program starts executing.
39  */
40 void __main(void) {
41   /* Loop over all of the constructor records, calling each function pointer. */
42   TorRec *R = __llvm_getGlobalCtors();
43
44   /* Recursively calling main is not legal C, but lots of people do it for
45    * testing stuff.  We might as well work for them.
46    */
47   static _Bool Initialized = 0;
48   if (Initialized) return;
49   Initialized = 1;
50
51   /* Only register the global dtor handler if there is at least one global
52    * dtor!
53    */
54   if (__llvm_getGlobalDtors()[0].FP)
55     if (atexit(run_destructors))
56       abort();  /* Should be able to install ONE atexit handler! */
57
58   /* FIXME: This should sort the list by priority! */
59   if (R->FP)
60     for (; R->FP; ++R)
61       R->FP();
62 }
63
64 static void run_destructors(void) {
65   /* Loop over all of the destructor records, calling each function pointer. */
66   TorRec *R = __llvm_getGlobalDtors();
67
68   /* FIXME: This should sort the list by priority! */
69   for (; R->FP; ++R)
70     R->FP();
71 }