Author: Will Hawkins Date: 2026-03-27T04:53:01-04:00 New Revision: 5c0c4214812b2fa6b8e843eecb6bedb47b9b7621
URL: https://github.com/llvm/llvm-project/commit/5c0c4214812b2fa6b8e843eecb6bedb47b9b7621 DIFF: https://github.com/llvm/llvm-project/commit/5c0c4214812b2fa6b8e843eecb6bedb47b9b7621.diff LOG: Support Serializing/Deserializing Extended Generic Selection Expressions Clang supports using a type as the predicate for generic selection expressions but lacked support for serializing/deserializing these extended generic selection expressions. Signed-off-by: Will Hawkins <[email protected]> Added: clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c clang/test/ASTMerge/generic-selection-expr/test-type.c Modified: clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp Removed: ################################################################################ diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 27f6af3ea6a66..801eed43c2440 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1462,15 +1462,16 @@ void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) { E->DefaultLoc = readSourceLocation(); E->RParenLoc = readSourceLocation(); + // During serialization, either one more Stmt or one more + // TypeSourceInfo was encoded to account for the predicate + // (whether it was an expression or a type). Stmt **Stmts = E->getTrailingObjects<Stmt *>(); - // Add 1 to account for the controlling expression which is the first - // expression in the trailing array of Stmt *. This is not needed for - // the trailing array of TypeSourceInfo *. - for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I) + for (unsigned I = 0, N = NumAssocs + (E->IsExprPredicate ? 1 : 0); I < N; ++I) Stmts[I] = Record.readSubExpr(); TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); - for (unsigned I = 0, N = NumAssocs; I < N; ++I) + for (unsigned I = 0, N = NumAssocs + (!E->IsExprPredicate ? 1 : 0); I < N; + ++I) TSIs[I] = readTypeSourceInfo(); } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index fcd289d5918db..934a95df1be7e 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprOpenMP.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TypeBase.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTRecordWriter.h" #include "llvm/Bitstream/BitstreamWriter.h" @@ -1418,15 +1419,22 @@ void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) { Record.AddSourceLocation(E->getDefaultLoc()); Record.AddSourceLocation(E->getRParenLoc()); + // Either the trailing Stmt-s or the trailing TypeSourceInfo-s + // will hold one more item than the number of associations + // to account for the predicate (whether it is an expression + // or a type). Stmt **Stmts = E->getTrailingObjects<Stmt *>(); - // Add 1 to account for the controlling expression which is the first - // expression in the trailing array of Stmt *. This is not needed for - // the trailing array of TypeSourceInfo *. - for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I) + for (unsigned I = 0, N = E->numTrailingObjects( + ASTConstraintSatisfaction::OverloadToken<Stmt *>()); + I < N; ++I) Record.AddStmt(Stmts[I]); TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); - for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I) + for (unsigned + I = 0, + N = E->numTrailingObjects( + ASTConstraintSatisfaction::OverloadToken<TypeSourceInfo *>()); + I < N; ++I) Record.AddTypeSourceInfo(TSIs[I]); Code = serialization::EXPR_GENERIC_SELECTION; diff --git a/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c b/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c new file mode 100644 index 0000000000000..d802b4398c760 --- /dev/null +++ b/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c @@ -0,0 +1,4 @@ +void f(void) { + _Static_assert(_Generic(int, float : 0, int : 1), "Incorrect semantics of _Generic"); + _Static_assert(_Generic(float, float : 1, int : 0), "Incorrect semantics of _Generic"); +} diff --git a/clang/test/ASTMerge/generic-selection-expr/test-type.c b/clang/test/ASTMerge/generic-selection-expr/test-type.c new file mode 100644 index 0000000000000..e51ec198afa6a --- /dev/null +++ b/clang/test/ASTMerge/generic-selection-expr/test-type.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -std=c11 -emit-pch -o %t.ast %S/Inputs/generic-type.c +// RUN: %clang_cc1 -std=c11 -ast-merge %t.ast -fsyntax-only -verify %s +// expected-no-diagnostics _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
