1 // RUN: %clang_cc1 -std=c23 %s -E -verify
3 // Test the parsing behavior for __has_embed and all of its parameters to ensure we
4 // recover from failures gracefully.
6 // expected-error@+2 {{missing '(' after '__has_embed'}} \
7 expected
-error@
+2 {{expected value in expression
}}
11 // expected-error@+3 {{expected '>'}} \
12 expected
-note@
+3 {{to match
this '<'}} \
13 expected
-error@
+3 {{expected value in expression
}}
17 // expected-error@+3 {{expected "FILENAME" or <FILENAME>}} \
18 expected
-warning@
+3 {{missing terminating
'"' character
}} \
19 expected
-error@
+3 {{invalid token at start of a preprocessor expression
}}
23 // expected-error@+2 {{missing '(' after '__has_embed'}} \
24 expected-error@+2 {{token is not a valid binary operator in a preprocessor subexpression}}
25 #if __has_embed file.txt
28 // OK, no diagnostic for an unknown embed parameter.
29 #if __has_embed("media/empty" xxx)
32 // expected-error@+2 {{expected identifier}} \
33 expected-error@+2 {{expected value in expression}}
34 #if __has_embed("media/empty" xxx::)
37 // OK, no diagnostic for an unknown embed parameter.
38 #if __has_embed("media/empty" xxx::xxx)
41 // expected-error@+2 {{expected identifier}} \
42 expected-error@+2 {{expected value in expression}}
43 #if __has_embed("media/empty" xxx::42)
46 // expected-error@+2 {{expected '('}} \
47 expected-error@+2 {{expected value in expression}}
48 #if __has_embed("media/empty" limit)
51 // We get the same diagnostic twice intentionally. The first one is because of
52 // the missing value within limit() and the second one is because the #if does
53 // not resolve to a value due to the earlier error.
54 // expected-error@+1 2 {{expected value in expression}}
55 #if __has_embed("media/empty" limit()
58 // expected-error@+3 {{missing ')' after '__has_embed'}} \
59 expected-error@+3 {{expected value in expression}} \
60 expected-note@+3 {{to match this '('}}
61 #if __has_embed("media/empty" limit(xxx)
64 // expected-error@+3 {{missing ')' after '__has_embed'}} \
65 expected-error@+3 {{expected value in expression}} \
66 expected-note@+3 {{to match this '('}}
67 #if __has_embed("media/empty" limit(42)
70 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \
71 expected-error@+2 {{expected value in expression}}
72 #if __has_embed("media/empty" limit([)
75 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \
76 expected-error@+2 {{expected value in expression}}
77 #if __has_embed("media/empty" limit([))
80 // expected-error@+2 {{division by zero in preprocessor expression}} \
81 expected-error@+2 {{expected value in expression}}
82 #if __has_embed("media/empty" limit(1/0))
85 // expected-error@+2 {{expected '('}} \
86 expected-error@+2 {{expected value in expression}}
87 #if __has_embed("media/empty" clang::offset)
90 // We get the same diagnostic twice intentionally. The first one is because of
91 // the missing value within clang::offset() and the second one is because the
92 // #if does not resolve to a value due to the earlier error.
93 // expected-error@+1 2 {{expected value in expression}}
94 #if __has_embed("media/empty" clang::offset()
97 // expected-error@+3 {{missing ')' after '__has_embed'}} \
98 expected-error@+3 {{expected value in expression}} \
99 expected-note@+3 {{to match this '('}}
100 #if __has_embed("media/empty" clang::offset(xxx)
103 // expected-error@+3 {{missing ')' after '__has_embed'}} \
104 expected-error@+3 {{expected value in expression}} \
105 expected-note@+3 {{to match this '('}}
106 #if __has_embed("media/empty" clang::offset(42)
109 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \
110 expected-error@+2 {{expected value in expression}}
111 #if __has_embed("media/empty" clang::offset([)
114 // expected-error@+2 {{invalid token at start of a preprocessor expression}} \
115 expected-error@+2 {{expected value in expression}}
116 #if __has_embed("media/empty" clang::offset([))
119 // expected-error@+2 {{division by zero in preprocessor expression}} \
120 expected-error@+2 {{expected value in expression}}
121 #if __has_embed("media/empty" clang::offset(1/0))
124 // expected-error@+2 {{expected '('}} \
125 expected-error@+2 {{expected value in expression}}
126 #if __has_embed("media/empty" clang::offset 42)
129 // expected-error@+2 {{expected '('}} \
130 expected-error@+2 {{expected value in expression}}
131 #if __has_embed("media/empty" prefix)
134 // expected-error@+3 {{missing ')' after '__has_embed'}} \
135 expected-error@+3 {{expected value in expression}} \
136 expected-note@+3 {{to match this '('}}
137 #if __has_embed("media/empty" prefix()
140 // expected-error@+3 {{missing ')' after '__has_embed'}} \
141 expected-error@+3 {{expected value in expression}} \
142 expected-note@+3 {{to match this '('}}
143 #if __has_embed("media/empty" prefix(xxx)
146 #if __has_embed("media/empty" prefix(1/0)) // OK: emitted as tokens, not evaluated yet.
148 #if __has_embed("media/empty" prefix(([{}]))) // OK: delimiters balanced
150 // expected-error@+3 {{expected '}'}} \
151 expected-note@+3 {{to match this '{'}} \
152 expected-error@+3 {{expected value in expression}}
153 #if __has_embed("media/empty" prefix(([{)]}))
155 // expected-error@+3 {{expected ']'}} \
156 expected-note@+3 {{to match this '['}} \
157 expected-error@+3 {{expected value in expression}}
158 #if __has_embed("media/empty" prefix(([{})}))
160 // expected-error@+3 {{expected ')'}} \
161 expected-note@+3 {{to match this '('}} \
162 expected-error@+3 {{expected value in expression}}
163 #if __has_embed("media/empty" prefix(([{}]}))
165 #if __has_embed("media/empty" prefix()) // OK: tokens within parens are optional
167 // expected-error@+2 {{expected '('}} \
168 expected-error@+2 {{expected value in expression}}
169 #if __has_embed("media/empty" prefix))
172 // expected-error@+2 {{expected '('}} \
173 expected-error@+2 {{expected value in expression}}
174 #if __has_embed("media/empty" suffix)
177 // expected-error@+3 {{missing ')' after '__has_embed'}} \
178 expected-error@+3 {{expected value in expression}} \
179 expected-note@+3 {{to match this '('}}
180 #if __has_embed("media/empty" suffix()
183 // expected-error@+3 {{missing ')' after '__has_embed'}} \
184 expected-error@+3 {{expected value in expression}} \
185 expected-note@+3 {{to match this '('}}
186 #if __has_embed("media/empty" suffix(xxx)
189 #if __has_embed("media/empty" suffix(1/0)) // OK: emitted as tokens, not evaluated yet.
191 #if __has_embed("media/empty" suffix(([{}]))) // OK: delimiters balanced
193 // expected-error@+3 {{expected '}'}} \
194 expected-note@+3 {{to match this '{'}} \
195 expected-error@+3 {{expected value in expression}}
196 #if __has_embed("media/empty" suffix(([{)]}))
198 // expected-error@+3 {{expected ']'}} \
199 expected-note@+3 {{to match this '['}} \
200 expected-error@+3 {{expected value in expression}}
201 #if __has_embed("media/empty" suffix(([{})}))
203 // expected-error@+3 {{expected ')'}} \
204 expected-note@+3 {{to match this '('}} \
205 expected-error@+3 {{expected value in expression}}
206 #if __has_embed("media/empty" suffix(([{}]}))
208 #if __has_embed("media/empty" suffix()) // OK: tokens within parens are optional
210 // expected-error@+2 {{expected '('}} \
211 expected-error@+2 {{expected value in expression}}
212 #if __has_embed("media/empty" suffix))
215 #if __has_embed("media/art.txt" if_empty(1/0)) // OK: emitted as tokens, not evaluated yet.
217 #if __has_embed("media/art.txt" if_empty(([{}]))) // OK: delimiters balanced
219 // expected-error@+3 {{expected '}'}} \
220 expected-note@+3 {{to match this '{'}} \
221 expected-error@+3 {{expected value in expression}}
222 #if __has_embed("media/art.txt" if_empty(([{)]}))
224 // expected-error@+3 {{expected ']'}} \
225 expected-note@+3 {{to match this '['}} \
226 expected-error@+3 {{expected value in expression}}
227 #if __has_embed("media/art.txt" if_empty(([{})}))
229 // expected-error@+3 {{expected ')'}} \
230 expected-note@+3 {{to match this '('}} \
231 expected-error@+3 {{expected value in expression}}
232 #if __has_embed("media/art.txt" if_empty(([{}]}))
234 #if __has_embed("media/art.txt" if_empty()) // OK: tokens within parens are optional
236 // expected-error@+2 {{expected '('}} \
237 expected-error@+2 {{expected value in expression}}
238 #if __has_embed("media/art.txt" if_empty))