// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify -Wno-unused %s // RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp -Wno-unused -x c++ -std=c++17 %s // Test various parsing situations for the Clang extension to _Generic which // accepts a type name instead of an expression as the first operand. int foo(); void test() { // We can parse a simple type name. _Generic(int, int : 0); // We can also parse tag types. struct S { int i; }; enum E { A }; union U { int i; }; _Generic(struct S, default : 0); _Generic(enum E, default : 0); _Generic(union U, default : 0); // We can also parse array types. _Generic(int[12], default : 0); // And pointer to array types, too. _Generic(int(*)[12], default : 0); // We do not accept a parenthesized type name. _Generic((int), int : 0); // expected-error {{expected expression}} // We can parse more complex types as well. Note, this is a valid spelling of // a function pointer type in C but is not a valid spelling of a function // pointer type in C++. Surprise! _Generic(__typeof__(foo())(*)(__typeof__(&foo)), int (*)(int (*)()) : 0); // cpp-error {{expected expression}} \ cpp-error {{expected '(' for function-style cast or type construction}} // C being the magical language that it is, lets you define a type anywhere // you can spell a type. _Generic(struct T { int a; }, default : 0); // cpp-error {{'T' cannot be defined in a type specifier}} } #ifdef __cplusplus template struct S { template