1 /* vim: set expandtab ts=4 sw=4: */
2 /*
3  * You may redistribute this program and/or modify it under the terms of
4  * the GNU General Public License as published by the Free Software Foundation,
5  * either version 3 of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
14  */
15 #ifndef Gcc_H
16 #define Gcc_H
17 
18 #include "util/Js.h"
19 
20 // GCC > 6
21 #if defined(__GNUC__) && (__GNUC__ > 6)
22 
23 #define Gcc_FALLTHRU \
24     __attribute__((fallthrough));
25 #endif
26 
27 
28 // clang OR GCC >= 4.4
29 #if defined(__clang__) || (defined(__GNUC__) && \
30     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)))
31 
32 #define Gcc_PRINTF( format_idx, arg_idx ) \
33     __attribute__((__format__ (__printf__, format_idx, arg_idx)))
34 
35 #define Gcc_ALLOC_SIZE(...) \
36     __attribute__ ((alloc_size(__VA_ARGS__)))
37 
38 #define Gcc_USE_RET \
39     __attribute__ ((warn_unused_result))
40 
41 #define Gcc_PACKED \
42     __attribute__ ((packed))
43 
44 #define Gcc_NORETURN \
45     __attribute__((__noreturn__))
46 #endif
47 
48 
49 // GCC >= 4.4
50 #if !defined(__clang__) && \
51     defined(__GNUC__) && \
52     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
53 
54 #define Gcc_NONNULL(...) \
55     __attribute__((__nonnull__(__VA_ARGS__)))
56 
57 #define Gcc_PURE \
58     __attribute__ ((__pure__))
59 #endif
60 
61 
62 // clang only
63 #if defined(__clang__)
64 // C11 only
65 //#define Gcc_NORETURN _Noreturn
66 #endif
67 
68 
69 
70 
71 #ifndef Gcc_PRINTF
72     #define Gcc_PRINTF( format_idx, arg_idx )
73 #endif
74 #ifndef Gcc_NORETURN
75     #define Gcc_NORETURN
76 #endif
77 #ifndef Gcc_NONNULL
78     #define Gcc_NONNULL(...)
79 #endif
80 #ifndef Gcc_PURE
81     #define Gcc_PURE
82 #endif
83 // Missing this will lead to very wrong code
84 // #ifndef Gcc_PACKED
85 //     #define Gcc_PACKED
86 // #endif
87 #ifndef Gcc_FALLTHRU
88     #define Gcc_FALLTHRU
89 #endif
90 #ifndef Gcc_ALLOC_SIZE
91     #define Gcc_ALLOC_SIZE(...)
92 #endif
93 #ifndef Gcc_USE_RET
94     #define Gcc_USE_RET
95 #endif
96 
97 Js({ this.Gcc_shortFile = (x) => '"' + x.substring(x.lastIndexOf('/')+1) + '"'; })
98 
99 #define Gcc_SHORT_FILE \
100     Js_or({ return this.Gcc_shortFile(__FILE__); }, __FILE__)
101 
102 #define Gcc_FILE Gcc_SHORT_FILE
103 #define Gcc_LINE __LINE__
104 
105 Gcc_PRINTF(1,2)
Gcc_checkPrintf(const char * format,...)106 static inline void Gcc_checkPrintf(const char* format, ...)
107 {
108     // This does nothing except to trigger warnings if the format is wrong.
109 }
110 
111 #endif
112