]> git.ipfire.org Git - thirdparty/gcc.git/blob - libcody/internal.hh
Use OEP_DECL_NAME when comparing VLA bounds [PR101585].
[thirdparty/gcc.git] / libcody / internal.hh
1 // CODYlib -*- mode:c++ -*-
2 // Copyright (C) 2020 Nathan Sidwell, nathan@acm.org
3 // License: Apache v2.0
4
5 #include "cody.hh"
6
7 #ifndef __has_builtin
8 #define __has_builtin(X) 0
9 #endif
10 #ifndef __has_include
11 #define __has_include(X) 0
12 #endif
13
14 // C++
15 #if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
16 #define CODY_LOC_BUILTIN 1
17 #elif __has_include (<source_location>)
18 #include <source_location>
19 #ifdef __cpp_lib_source_location
20 #define CODY_LOC_SOURCE 1
21 #endif
22 #endif
23
24 // C
25 #include <cstdio>
26
27 namespace Cody {
28
29 // Location is needed regardless of checking, to make the fatal
30 // handler simpler
31 class Location
32 {
33 protected:
34 char const *file;
35 unsigned line;
36
37 public:
38 constexpr Location (char const *file_
39 #if CODY_LOC_BUILTIN
40 = __builtin_FILE ()
41 #elif !CODY_LOC_SOURCE
42 = nullptr
43 #endif
44 , unsigned line_
45 #if CODY_LOC_BUILTIN
46 = __builtin_LINE ()
47 #elif !CODY_LOC_SOURCE
48 = 0
49 #endif
50 )
51 :file (file_), line (line_)
52 {
53 }
54
55 #if !CODY_LOC_BUILTIN && CODY_LOC_SOURCE
56 using source_location = std::source_location;
57
58 constexpr Location (source_location loc = source_location::current ())
59 : Location (loc.file (), loc.line ())
60 {
61 }
62 #endif
63
64 public:
65 constexpr char const *File () const
66 {
67 return file;
68 }
69 constexpr unsigned Line () const
70 {
71 return line;
72 }
73 };
74
75 void HCF [[noreturn]]
76 (
77 char const *msg
78 #if NMS_CHECKING
79 , Location const = Location ()
80 #if !CODY_LOC_BUILTIN && !CODY_LOC_SOURCE
81 #define HCF(M) HCF ((M), Cody::Location (__FILE__, __LINE__))
82 #endif
83 #endif
84 ) noexcept;
85
86 #if NMS_CHECKING
87 void AssertFailed [[noreturn]] (Location loc = Location ()) noexcept;
88 void Unreachable [[noreturn]] (Location loc = Location ()) noexcept;
89 #if !CODY_LOC_BUILTIN && !CODY_LOC_SOURCE
90 #define AssertFailed() AssertFailed (Cody::Location (__FILE__, __LINE__))
91 #define Unreachable() Unreachable (Cody::Location (__FILE__, __LINE__))
92 #endif
93
94 // Do we have __VA_OPT__, alas no specific feature macro for it :(
95 // From stack overflow
96 // https://stackoverflow.com/questions/48045470/portably-detect-va-opt-support
97 // Relies on having variadic macros, but they're a C++11 thing, so
98 // we're good
99 #define HAVE_ARG_3(a,b,c,...) c
100 #define HAVE_VA_OPT_(...) HAVE_ARG_3(__VA_OPT__(,),true,false,)
101 #define HAVE_VA_OPT HAVE_VA_OPT_(?)
102
103 // Oh, for lazily evaluated function parameters
104 #if HAVE_VA_OPT
105 // Assert is variadic, so you can write Assert (TPL<A,B>(C)) without
106 // extraneous parens. I don't think we need that though.
107 #define Assert(EXPR, ...) \
108 (__builtin_expect (bool (EXPR __VA_OPT__ (, __VA_ARGS__)), true) \
109 ? (void)0 : AssertFailed ())
110 #else
111 // If you don't have the GNU ,##__VA_ARGS__ pasting extension, we'll
112 // need another fallback
113 #define Assert(EXPR, ...) \
114 (__builtin_expect (bool (EXPR, ##__VA_ARGS__), true) \
115 ? (void)0 : AssertFailed ())
116 #endif
117 #else
118 // Not asserting, use EXPR in an unevaluated context
119 #if HAVE_VA_OPT
120 #define Assert(EXPR, ...) \
121 ((void)sizeof (bool (EXPR __VA_OPT__ (, __VA_ARGS__))), (void)0)
122 #else
123 #define Assert(EXPR, ...) \
124 ((void)sizeof (bool (EXPR, ##__VA_ARGS__)), (void)0)
125 #endif
126
127 inline void Unreachable () noexcept
128 {
129 __builtin_unreachable ();
130 }
131 #endif
132
133 }