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

Reply via email to