[PATCH] D149904: Generic selection expressions that accept a type operand

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu May 4 14:08:19 PDT 2023


aaron.ballman created this revision.
aaron.ballman added reviewers: clang-language-wg, efriedma, jyknight, hubert.reinterpretcast, rsmith.
Herald added a subscriber: martong.
Herald added a reviewer: shafik.
Herald added a reviewer: NoQ.
Herald added a project: All.
aaron.ballman requested review of this revision.
Herald added a project: clang.

Extends `_Generic` selection expressions to accept a type operand in addition to an expression operand. The type operand form does not perform lvalue conversions on the operand, which allows the expression to select *qualified* types, making it more useful for generic programming in C.

C has a few operators that take either a type or an expression, such as `sizeof`. It is natural to extend that idea to `_Generic` so that it can also accept a type for the first operand. This type does not undergo any conversions, which allows it to match qualified types, incomplete types, and function types. C2x has the `typeof` operator as a way to get the type of an expression before lvalue conversion takes place, and so it keeps the qualification. This makes `typeof` a straightforward approach to determining a type operand for `_Generic` that considers qualifiers. This allows writing a helper macro like:

  #define EXPR_HAS_TYPE(Expr, Type) _Generic(typeof(Expr), Type : 1, default : 0)

which can be called with an expression of any value category (no need to be an lvalue) and will test against (almost) any type. This is a conforming extension to C (it's defining the behavior of invalid syntax), and I believe this is a natural way to extend this functionality.

`_Generic` with a type operand will relax the requirements of what can be a valid association. Specifically, it allows incomplete types and non-object types (but still prevents use of variably-modified types). This relaxation only happens for the type operand form; the expression operand form continues to behave as it always has.

This extension allows incomplete and non-object types because the goal is to better enable type-generic programming in C, and so we want to allow any typed construct we can statically determine the type of. There is no reason to prevent matching against `void` or function types, but this does explain why we continue to prohibit variably-modified types.

Please see the RFC at https://discourse.llvm.org/t/rfc-generic-selection-expression-with-a-type-operand/70388 for more details.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149904

Files:
  clang/include/clang/AST/ASTNodeTraverser.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/ExprMutationAnalyzer.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaPseudoObject.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/Parser/generic-selection-type-extension-pedantic.c
  clang/test/Parser/generic-selection-type-extension.c
  clang/test/Sema/generic-selection-type-extension.c
  clang/test/SemaCXX/generic-selection.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149904.519648.patch
Type: text/x-patch
Size: 62272 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230504/459defcf/attachment-0001.bin>


More information about the cfe-commits mailing list