| // RUN: %clang_cc1 -std=c23 %s -E -verify |
| |
| // Test the parsing behavior for __has_embed and all of its parameters to ensure we |
| // recover from failures gracefully. |
| |
| // expected-error@+2 {{missing '(' after '__has_embed'}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed |
| #endif |
| |
| // expected-error@+3 {{expected '>'}} \ |
| expected-note@+3 {{to match this '<'}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed(<) |
| #endif |
| |
| // expected-error@+3 {{expected "FILENAME" or <FILENAME>}} \ |
| expected-warning@+3 {{missing terminating '"' character}} \ |
| expected-error@+3 {{invalid token at start of a preprocessor expression}} |
| #if __has_embed(") |
| #endif |
| |
| // expected-error@+2 {{missing '(' after '__has_embed'}} \ |
| expected-error@+2 {{token is not a valid binary operator in a preprocessor subexpression}} |
| #if __has_embed file.txt |
| #endif |
| |
| // OK, no diagnostic for an unknown embed parameter. |
| #if __has_embed("media/empty" xxx) |
| #endif |
| |
| // expected-error@+2 {{expected identifier}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" xxx::) |
| #endif |
| |
| // OK, no diagnostic for an unknown embed parameter. |
| #if __has_embed("media/empty" xxx::xxx) |
| #endif |
| |
| // expected-error@+2 {{expected identifier}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" xxx::42) |
| #endif |
| |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" limit) |
| #endif |
| |
| // We get the same diagnostic twice intentionally. The first one is because of |
| // the missing value within limit() and the second one is because the #if does |
| // not resolve to a value due to the earlier error. |
| // expected-error@+1 2 {{expected value in expression}} |
| #if __has_embed("media/empty" limit() |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" limit(xxx) |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" limit(42) |
| #endif |
| |
| // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" limit([) |
| #endif |
| |
| // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" limit([)) |
| #endif |
| |
| // expected-error@+2 {{division by zero in preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" limit(1/0)) |
| #endif |
| |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset) |
| #endif |
| |
| // We get the same diagnostic twice intentionally. The first one is because of |
| // the missing value within clang::offset() and the second one is because the |
| // #if does not resolve to a value due to the earlier error. |
| // expected-error@+1 2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset() |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" clang::offset(xxx) |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" clang::offset(42) |
| #endif |
| |
| // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset([) |
| #endif |
| |
| // expected-error@+2 {{invalid token at start of a preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset([)) |
| #endif |
| |
| // expected-error@+2 {{division by zero in preprocessor expression}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset(1/0)) |
| #endif |
| |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" clang::offset 42) |
| #endif |
| |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" prefix) |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" prefix() |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" prefix(xxx) |
| #endif |
| |
| #if __has_embed("media/empty" prefix(1/0)) // OK: emitted as tokens, not evaluated yet. |
| #endif |
| #if __has_embed("media/empty" prefix(([{}]))) // OK: delimiters balanced |
| #endif |
| // expected-error@+3 {{expected '}'}} \ |
| expected-note@+3 {{to match this '{'}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" prefix(([{)]})) |
| #endif |
| // expected-error@+3 {{expected ']'}} \ |
| expected-note@+3 {{to match this '['}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" prefix(([{})})) |
| #endif |
| // expected-error@+3 {{expected ')'}} \ |
| expected-note@+3 {{to match this '('}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" prefix(([{}]})) |
| #endif |
| #if __has_embed("media/empty" prefix()) // OK: tokens within parens are optional |
| #endif |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" prefix)) |
| #endif |
| |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" suffix) |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" suffix() |
| #endif |
| |
| // expected-error@+3 {{missing ')' after '__has_embed'}} \ |
| expected-error@+3 {{expected value in expression}} \ |
| expected-note@+3 {{to match this '('}} |
| #if __has_embed("media/empty" suffix(xxx) |
| #endif |
| |
| #if __has_embed("media/empty" suffix(1/0)) // OK: emitted as tokens, not evaluated yet. |
| #endif |
| #if __has_embed("media/empty" suffix(([{}]))) // OK: delimiters balanced |
| #endif |
| // expected-error@+3 {{expected '}'}} \ |
| expected-note@+3 {{to match this '{'}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" suffix(([{)]})) |
| #endif |
| // expected-error@+3 {{expected ']'}} \ |
| expected-note@+3 {{to match this '['}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" suffix(([{})})) |
| #endif |
| // expected-error@+3 {{expected ')'}} \ |
| expected-note@+3 {{to match this '('}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/empty" suffix(([{}]})) |
| #endif |
| #if __has_embed("media/empty" suffix()) // OK: tokens within parens are optional |
| #endif |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/empty" suffix)) |
| #endif |
| |
| #if __has_embed("media/art.txt" if_empty(1/0)) // OK: emitted as tokens, not evaluated yet. |
| #endif |
| #if __has_embed("media/art.txt" if_empty(([{}]))) // OK: delimiters balanced |
| #endif |
| // expected-error@+3 {{expected '}'}} \ |
| expected-note@+3 {{to match this '{'}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/art.txt" if_empty(([{)]})) |
| #endif |
| // expected-error@+3 {{expected ']'}} \ |
| expected-note@+3 {{to match this '['}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/art.txt" if_empty(([{})})) |
| #endif |
| // expected-error@+3 {{expected ')'}} \ |
| expected-note@+3 {{to match this '('}} \ |
| expected-error@+3 {{expected value in expression}} |
| #if __has_embed("media/art.txt" if_empty(([{}]})) |
| #endif |
| #if __has_embed("media/art.txt" if_empty()) // OK: tokens within parens are optional |
| #endif |
| // expected-error@+2 {{expected '('}} \ |
| expected-error@+2 {{expected value in expression}} |
| #if __has_embed("media/art.txt" if_empty)) |
| #endif |
| |