Skip to content

Commit f1c0088

Browse files
address ^^ in binary expression
1 parent bf7e78a commit f1c0088

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

clang/lib/Basic/OperatorPrecedence.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
5454
case tok::pipepipe: return prec::LogicalOr;
5555
case tok::ampamp: return prec::LogicalAnd;
5656
case tok::pipe: return prec::InclusiveOr;
57+
case tok::caretcaret:
5758
case tok::caret: return prec::ExclusiveOr;
5859
case tok::amp: return prec::And;
5960
case tok::exclaimequal:

clang/lib/Parse/ParseExpr.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,27 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
333333
Token OpToken = Tok;
334334
ConsumeToken();
335335

336+
// the reflection operator can't be in a binary expression
337+
// so if reflection and blocks are enabled, we need to
338+
// split caretcaret into two caret's
339+
if (OpToken.is(tok::caretcaret)) {
340+
assert(getLangOpts().Reflection &&
341+
"reflection support disabled - compile with -freflection");
342+
if (getLangOpts().Blocks) {
343+
OpToken.setKind(tok::caret);
344+
Token Caret;
345+
{
346+
Caret.startToken();
347+
Caret.setKind(tok::caret);
348+
Caret.setLocation(Tok.getLocation());
349+
Caret.setLength(1);
350+
}
351+
UnconsumeToken(OpToken);
352+
PP.EnterToken(Caret, /*IsReinject=*/true);
353+
return ParseRHSOfBinaryExpression(LHS, MinPrec);
354+
}
355+
}
356+
336357
// If we're potentially in a template-id, we may now be able to determine
337358
// whether we're actually in one or not.
338359
if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
@@ -1209,10 +1230,15 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand,
12091230
Res = ParseUnaryExprOrTypeTraitExpression();
12101231
break;
12111232
case tok::caretcaret: {
1212-
if (getLangOpts().Reflection) {
1213-
SourceLocation DoubleCaret = ConsumeToken();
1214-
Res = ParseCXXReflectExpression(/*OpLoc=*/DoubleCaret);
1233+
if (!getLangOpts().Reflection) {
1234+
NotCastExpr = true;
1235+
return ExprError();
12151236
}
1237+
1238+
if (NotPrimaryExpression)
1239+
*NotPrimaryExpression = true;
1240+
AllowSuffix = false;
1241+
Res = ParseUnaryExprOrTypeTraitExpression();
12161242
break;
12171243
}
12181244
case tok::ampamp: { // unary-expression: '&&' identifier
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 %s -std=c++26 -freflection -fblocks -fsyntax-only
2+
3+
struct A {
4+
int operator^(int (^block)(int x)) const {
5+
return block(0);
6+
}
7+
};
8+
9+
10+
int main()
11+
{
12+
(void)(A{}^^(int y){ return y + 1; });
13+
}

0 commit comments

Comments
 (0)