mibintc updated this revision to Diff 253341.
mibintc marked 12 inline comments as done.
mibintc added a comment.
@rjmccall Many thanks for your code review. Please take a look at this when
you get a chance.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76384/new/
https://reviews.llvm.org/D76384
Files:
clang/include/clang/AST/Expr.h
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/StmtVisitor.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Basic/StmtNodes.td
clang/include/clang/Serialization/ASTBitCodes.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/AST/ExprClassification.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Analysis/CFG.cpp
clang/lib/Analysis/ReachableCode.cpp
clang/lib/Analysis/ThreadSafetyCommon.cpp
clang/lib/CodeGen/CGExpr.cpp
clang/lib/CodeGen/CGExprComplex.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
clang/lib/Frontend/Rewrite/RewriteObjC.cpp
clang/lib/Index/IndexBody.cpp
clang/lib/Sema/AnalysisBasedWarnings.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaExceptionSpec.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaPseudoObject.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
clang/test/AST/ast-dump-expr-json.c
clang/test/AST/ast-dump-expr.c
clang/test/AST/dump.cpp
clang/test/Import/compound-assign-op/test.cpp
clang/tools/libclang/CXCursor.cpp
Index: clang/tools/libclang/CXCursor.cpp
===================================================================
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -427,10 +427,6 @@
K = CXCursor_BinaryOperator;
break;
- case Stmt::CompoundAssignOperatorClass:
- K = CXCursor_CompoundAssignOperator;
- break;
-
case Stmt::ConditionalOperatorClass:
K = CXCursor_ConditionalOperator;
break;
Index: clang/test/Import/compound-assign-op/test.cpp
===================================================================
--- clang/test/Import/compound-assign-op/test.cpp
+++ clang/test/Import/compound-assign-op/test.cpp
@@ -2,42 +2,42 @@
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '+='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '-='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '*='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '/='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '&='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '^='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '<<='
// CHECK: VarDecl
// CHECK-NEXT: Integer
-// CHECK-NEXT: CompoundAssignOperator
+// CHECK-NEXT: BinaryOperator
// CHECK-SAME: '>>='
void expr() {
Index: clang/test/AST/dump.cpp
===================================================================
--- clang/test/AST/dump.cpp
+++ clang/test/AST/dump.cpp
@@ -14,14 +14,14 @@
#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:[[@LINE-4]]:35> col:35 operator+ 'int' combiner 0x{{.+}}
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
+// CHECK-NEXT: | |-BinaryOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int'
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue>
// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int'
// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int'
// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int'
// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner 0x{{.+}}
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
+// CHECK-NEXT: | |-BinaryOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char'
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast>
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue>
@@ -29,7 +29,7 @@
// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char'
// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char'
// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:[[@LINE-17]]:37> col:37 fun 'float' combiner 0x{{.+}} initializer 0x{{.+}}
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float'
+// CHECK-NEXT: | |-BinaryOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float'
// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float'
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue>
// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float'
Index: clang/test/AST/ast-dump-expr.c
===================================================================
--- clang/test/AST/ast-dump-expr.c
+++ clang/test/AST/ast-dump-expr.c
@@ -16,7 +16,7 @@
// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:7> 'int' 12
a += a;
- // CHECK: CompoundAssignOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '+=' ComputeLHSTy='int' ComputeResultTy='int'
+ // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '+=' ComputeLHSTy='int' ComputeResultTy='int'
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int'
Index: clang/test/AST/ast-dump-expr-json.c
===================================================================
--- clang/test/AST/ast-dump-expr-json.c
+++ clang/test/AST/ast-dump-expr-json.c
@@ -270,7 +270,6 @@
// CHECK-NEXT: ]
// CHECK-NEXT: }
-
// CHECK: "kind": "FunctionDecl",
// CHECK-NEXT: "loc": {
// CHECK-NEXT: "offset": 157,
@@ -417,7 +416,7 @@
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CompoundAssignOperator",
+// CHECK-NEXT: "kind": "BinaryOperator",
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
// CHECK-NEXT: "offset": 191,
@@ -529,7 +528,6 @@
// CHECK-NEXT: ]
// CHECK-NEXT: }
-
// CHECK: "kind": "FunctionDecl",
// CHECK-NEXT: "loc": {
// CHECK-NEXT: "offset": 210,
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -141,12 +141,10 @@
SVal V = state->getSVal(LHS, LCtx);
// Get the computation type.
- QualType CTy =
- cast<CompoundAssignOperator>(B)->getComputationResultType();
+ QualType CTy = B->getComputationResultType();
CTy = getContext().getCanonicalType(CTy);
- QualType CLHSTy =
- cast<CompoundAssignOperator>(B)->getComputationLHSType();
+ QualType CLHSTy = B->getComputationLHSType();
CLHSTy = getContext().getCanonicalType(CLHSTy);
QualType LTy = getContext().getCanonicalType(LHS->getType());
Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1665,12 +1665,6 @@
break;
}
- case Stmt::CompoundAssignOperatorClass:
- Bldr.takeNodes(Pred);
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
- Bldr.addNodes(Dst);
- break;
-
case Stmt::CompoundLiteralExprClass:
Bldr.takeNodes(Pred);
VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
Index: clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -445,7 +445,6 @@
return true;
}
- case Stmt::CompoundAssignOperatorClass:
case Stmt::BinaryOperatorClass: {
const BinaryOperator *BinOp1 = cast<BinaryOperator>(Stmt1);
const BinaryOperator *BinOp2 = cast<BinaryOperator>(Stmt2);
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -878,21 +878,23 @@
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
VisitExpr(E);
+ bool HasFPFeatures = E->HasFPFeatures();
+ // Write this first for easy access when deserializing, as they affect the
+ // size of the UnaryOperator.
+ Record.push_back(HasFPFeatures);
+ Record.push_back(E->getOpcode()); // FIXME: stable encoding
Record.AddStmt(E->getLHS());
Record.AddStmt(E->getRHS());
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->getFPFeatures().getInt());
+ if (HasFPFeatures)
+ Record.push_back(E->getFPFeatures().getInt());
+ if (E->isCompoundAssignmentOp()) {
+ Record.AddTypeRef(E->getComputationLHSType());
+ Record.AddTypeRef(E->getComputationResultType());
+ }
Code = serialization::EXPR_BINARY_OPERATOR;
}
-void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- VisitBinaryOperator(E);
- Record.AddTypeRef(E->getComputationLHSType());
- Record.AddTypeRef(E->getComputationResultType());
- Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
-}
-
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
VisitExpr(E);
Record.AddStmt(E->getCond());
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -583,7 +583,6 @@
RECORD(EXPR_CALL);
RECORD(EXPR_MEMBER);
RECORD(EXPR_BINARY_OPERATOR);
- RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
RECORD(EXPR_CONDITIONAL_OPERATOR);
RECORD(EXPR_IMPLICIT_CAST);
RECORD(EXPR_CSTYLE_CAST);
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1006,18 +1006,22 @@
}
void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
+ bool hasFP_Features;
+ BinaryOperator::Opcode opc;
VisitExpr(E);
+ E->setHasFPFeatures(hasFP_Features = Record.readInt());
+ E->setOpcode(opc = (BinaryOperator::Opcode)Record.readInt());
E->setLHS(Record.readSubExpr());
E->setRHS(Record.readSubExpr());
- E->setOpcode((BinaryOperator::Opcode)Record.readInt());
E->setOperatorLoc(readSourceLocation());
- E->setFPFeatures(FPOptions(Record.readInt()));
-}
-
-void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- VisitBinaryOperator(E);
- E->setComputationLHSType(Record.readType());
- E->setComputationResultType(Record.readType());
+ if (hasFP_Features) {
+ int x = Record.readInt();
+ E->setFPFeatures(FPOptions(x));
+ }
+ if (BinaryOperator::isCompoundAssignmentOp(opc)) {
+ E->setComputationLHSType(Record.readType());
+ E->setComputationResultType(Record.readType());
+ }
}
void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
@@ -2674,6 +2678,8 @@
return nullptr;
}
switch ((StmtCode)MaybeStmtCode.get()) {
+ default:
+ llvm_unreachable("Unexpected StmtCode");
case STMT_STOP:
Finished = true;
break;
@@ -2883,11 +2889,9 @@
break;
case EXPR_BINARY_OPERATOR:
- S = new (Context) BinaryOperator(Empty);
- break;
-
- case EXPR_COMPOUND_ASSIGN_OPERATOR:
- S = new (Context) CompoundAssignOperator(Empty);
+ S = BinaryOperator::CreateEmpty(Context,
+ Record[ASTStmtReader::NumExprFields],
+ Record[ASTStmtReader::NumExprFields + 1]);
break;
case EXPR_CONDITIONAL_OPERATOR:
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -10147,7 +10147,7 @@
return E;
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
- getSema().FPFeatures = E->getFPFeatures();
+ getSema().FPFeatures = E->getFPFeatures(getSema().getLangOpts());
return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
LHS.get(), RHS.get());
@@ -10197,13 +10197,6 @@
E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformCompoundAssignOperator(
- CompoundAssignOperator *E) {
- return getDerived().TransformBinaryOperator(E);
-}
-
template<typename Derived>
ExprResult TreeTransform<Derived>::
TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
Index: clang/lib/Sema/SemaPseudoObject.cpp
===================================================================
--- clang/lib/Sema/SemaPseudoObject.cpp
+++ clang/lib/Sema/SemaPseudoObject.cpp
@@ -448,11 +448,9 @@
ExprResult result;
if (opcode == BO_Assign) {
result = semanticRHS;
- syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
- opcode, capturedRHS->getType(),
- capturedRHS->getValueKind(),
- OK_Ordinary, opcLoc,
- FPOptions());
+ syntactic = BinaryOperator::Create(
+ S.Context, syntacticLHS, capturedRHS, opcode, capturedRHS->getType(),
+ capturedRHS->getValueKind(), OK_Ordinary, opcLoc, FPOptions());
} else {
ExprResult opLHS = buildGet();
if (opLHS.isInvalid()) return ExprError();
@@ -463,14 +461,12 @@
result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS);
if (result.isInvalid()) return ExprError();
- syntactic =
- new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
- result.get()->getType(),
- result.get()->getValueKind(),
- OK_Ordinary,
- opLHS.get()->getType(),
- result.get()->getType(),
- opcLoc, FPOptions());
+ QualType CompLHS = opLHS.get()->getType();
+ QualType CompRes = result.get()->getType();
+ syntactic = BinaryOperator::Create(
+ S.Context, syntacticLHS, capturedRHS, opcode, result.get()->getType(),
+ result.get()->getValueKind(), OK_Ordinary, opcLoc, FPOptions(),
+ &CompLHS, &CompRes);
}
// The result of the assignment, if not void, is the value set into
@@ -1586,9 +1582,9 @@
Expr *LHS, Expr *RHS) {
// Do nothing if either argument is dependent.
if (LHS->isTypeDependent() || RHS->isTypeDependent())
- return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
- VK_RValue, OK_Ordinary, opcLoc,
- FPOptions());
+ return BinaryOperator::Create(Context, LHS, RHS, opcode,
+ Context.DependentTy, VK_RValue, OK_Ordinary,
+ opcLoc, FPOptions());
// Filter out non-overload placeholder types in the RHS.
if (RHS->getType()->isNonOverloadPlaceholderType()) {
@@ -1639,24 +1635,26 @@
/// operations.
Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
Expr *syntax = E->getSyntacticForm();
+ BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax);
if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
return new (Context) UnaryOperator(
op, uop->getOpcode(), uop->getType(), uop->getValueKind(),
uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow());
- } else if (CompoundAssignOperator *cop
- = dyn_cast<CompoundAssignOperator>(syntax)) {
- Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
- Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
- return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
- cop->getType(),
- cop->getValueKind(),
- cop->getObjectKind(),
- cop->getComputationLHSType(),
- cop->getComputationResultType(),
- cop->getOperatorLoc(),
- FPOptions());
- } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
+ } else if (bop && bop->isCompoundAssignmentOp()) {
+ Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
+ Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
+ QualType CompLHS = bop->getComputationLHSType();
+ QualType CompRes = bop->getComputationResultType();
+ return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
+ bop->getType(),
+ bop->getValueKind(),
+ bop->getObjectKind(),
+ bop->getOperatorLoc(),
+ FPOptions(),
+ &CompLHS,
+ &CompRes);
+ } else if (bop) {
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -13048,8 +13048,8 @@
Args[0] = Input;
CallExpr *TheCall = CXXOperatorCallExpr::Create(
- Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc,
- FPOptions(), Best->IsADLCandidate);
+ Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, FPFeatures,
+ Best->IsADLCandidate);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
return ExprError();
@@ -13218,14 +13218,15 @@
// If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
if (Opc <= BO_Assign || Opc > BO_OrAssign)
- return new (Context) BinaryOperator(
- Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
- OpLoc, FPFeatures);
+ return BinaryOperator::Create(Context, Args[0], Args[1], Opc,
+ Context.DependentTy, VK_RValue,
+ OK_Ordinary, OpLoc, FPFeatures);
- return new (Context) CompoundAssignOperator(
- Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
- Context.DependentTy, Context.DependentTy, OpLoc,
- FPFeatures);
+ QualType DependentTy = Context.DependentTy;
+ return BinaryOperator::Create(Context, Args[0], Args[1], Opc,
+ Context.DependentTy, VK_LValue, OK_Ordinary,
+ OpLoc, FPFeatures,
+ &DependentTy, &DependentTy);
}
// FIXME: save results of ADL from here?
@@ -14522,7 +14523,7 @@
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
- Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPOptions());
+ Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPFeatures);
if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
return ExprError();
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -9187,20 +9187,18 @@
AtomicBody = AtomicBody->IgnoreParenImpCasts();
if (AtomicBody->getType()->isScalarType() ||
AtomicBody->isInstantiationDependent()) {
- if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
- AtomicBody->IgnoreParenImpCasts())) {
- // Check for Compound Assignment Operation
- Op = BinaryOperator::getOpForCompoundAssignment(
- AtomicCompAssignOp->getOpcode());
- OpLoc = AtomicCompAssignOp->getOperatorLoc();
- E = AtomicCompAssignOp->getRHS();
- X = AtomicCompAssignOp->getLHS()->IgnoreParens();
- IsXLHSInRHSPart = true;
- } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
- AtomicBody->IgnoreParenImpCasts())) {
- // Check for Binary Operation
- if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
+ if (auto *AtomicBinOp =
+ dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
+ if (AtomicBinOp->isCompoundAssignmentOp()) {
+ Op = BinaryOperator::getOpForCompoundAssignment(
+ AtomicBinOp->getOpcode());
+ OpLoc = AtomicBinOp->getOperatorLoc();
+ E = AtomicBinOp->getRHS();
+ X = AtomicBinOp->getLHS()->IgnoreParens();
+ IsXLHSInRHSPart = true;
+ } else if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
return true;
+ // Check for Binary Operation
} else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
AtomicBody->IgnoreParenImpCasts())) {
// Check for Unary Operation
@@ -14801,8 +14799,8 @@
ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Expr *Args[] = {LHS.get(), RHS.get()};
- ReductionOp =
- CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
+ ReductionOp = CallExpr::Create(Context, OVE, Args, Context.VoidTy,
+ VK_RValue, ELoc);
} else {
ReductionOp = S.BuildBinOp(
Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7001,9 +7001,10 @@
return ExprError();
if (RHS.get() == BO->getRHS())
return E;
- return new (Context) BinaryOperator(
- BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
- BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures());
+ return BinaryOperator::Create(
+ Context, BO->getLHS(), RHS.get(), BO_Comma, BO->getType(),
+ BO->getValueKind(), BO->getObjectKind(), BO->getOperatorLoc(),
+ BO->getFPFeatures(getLangOpts()));
}
}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -12992,13 +12992,13 @@
BinOpResTy = S.GetSignedVectorType(BinOpResTy);
if (IsCompAssign)
- return new (Context) CompoundAssignOperator(
- LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, BinOpResTy, BinOpResTy,
- OpLoc, FPFeatures);
+ return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy,
+ VK, OK, OpLoc, FPFeatures,
+ &BinOpResTy, &BinOpResTy);
LHS = convertVector(LHS.get(), Context.FloatTy, S);
- auto *BO = new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, BinOpResTy,
- VK, OK, OpLoc, FPFeatures);
+ auto *BO = BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc,
+ BinOpResTy, VK, OK, OpLoc, FPFeatures);
return convertVector(BO, ResultTy->castAs<VectorType>()->getElementType(), S);
}
@@ -13312,8 +13312,8 @@
if (ConvertHalfVec)
return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, false,
OpLoc, FPFeatures);
- return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
- OK, OpLoc, FPFeatures);
+ return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy,
+ VK, OK, OpLoc, FPFeatures);
}
// Handle compound assignments.
@@ -13327,9 +13327,12 @@
return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
OpLoc, FPFeatures);
- return new (Context) CompoundAssignOperator(
- LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
- OpLoc, FPFeatures);
+ if (!BinaryOperator::isCompoundAssignmentOp(Opc))
+ return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy,
+ VK, OK, OpLoc, FPFeatures);
+ return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy,
+ VK, OK, OpLoc, FPFeatures,
+ &CompLHSTy, &CompResultTy);
}
/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
Index: clang/lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- clang/lib/Sema/SemaExceptionSpec.cpp
+++ clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1301,7 +1301,6 @@
case Expr::OMPArraySectionExprClass:
case Expr::BinaryOperatorClass:
case Expr::DependentCoawaitExprClass:
- case Expr::CompoundAssignOperatorClass:
case Expr::CStyleCastExprClass:
case Expr::CXXStaticCastExprClass:
case Expr::CXXFunctionalCastExprClass:
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -10858,7 +10858,8 @@
/// Analyze the given compound assignment for the possible losing of
/// floating-point precision.
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
- assert(isa<CompoundAssignOperator>(E) &&
+
+ assert(E->isCompoundAssignmentOp() &&
"Must be compound assignment operation");
// Recurse on the LHS and RHS in here
AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
@@ -10869,9 +10870,7 @@
// Now check the outermost expression
const auto *ResultBT = E->getLHS()->getType()->getAs<BuiltinType>();
- const auto *RBT = cast<CompoundAssignOperator>(E)
- ->getComputationResultType()
- ->getAs<BuiltinType>();
+ const auto *RBT = E->getComputationResultType()->getAs<BuiltinType>();
// The below checks assume source is floating point.
if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return;
@@ -11727,7 +11726,7 @@
if (BO->getOpcode() == BO_Assign)
return AnalyzeAssignment(S, BO);
// And with compound assignments.
- if (BO->isAssignmentOp())
+ if (BO->isAssignmentOp() || BO->isCompoundAssignmentOp())
return AnalyzeCompoundAssignment(S, BO);
}
@@ -12534,7 +12533,7 @@
Region = LHSRegion;
Visit(BO->getLHS());
- if (O && isa<CompoundAssignOperator>(BO))
+ if (O && BO->isCompoundAssignmentOp())
notePostUse(O, BO);
} else {
@@ -12542,7 +12541,7 @@
Region = LHSRegion;
Visit(BO->getLHS());
- if (O && isa<CompoundAssignOperator>(BO))
+ if (O && BO->isCompoundAssignmentOp())
notePostUse(O, BO);
Region = RHSRegion;
@@ -12564,10 +12563,6 @@
}
}
- void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO) {
- VisitBinAssign(CAO);
- }
-
void VisitUnaryPreInc(const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
void VisitUnaryPreDec(const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
void VisitUnaryPreIncDec(const UnaryOperator *UO) {
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2075,7 +2075,6 @@
else {
AC.getCFGBuildOptions()
.setAlwaysAdd(Stmt::BinaryOperatorClass)
- .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
.setAlwaysAdd(Stmt::BlockExprClass)
.setAlwaysAdd(Stmt::CStyleCastExprClass)
.setAlwaysAdd(Stmt::DeclRefExprClass)
Index: clang/lib/Index/IndexBody.cpp
===================================================================
--- clang/lib/Index/IndexBody.cpp
+++ clang/lib/Index/IndexBody.cpp
@@ -75,6 +75,11 @@
if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
Roles |= (unsigned)SymbolRole::Write;
+ if (BO->isCompoundAssignmentOp() &&
+ BO->getLHS()->IgnoreParenCasts() == E) {
+ Roles |= (unsigned)SymbolRole::Read;
+ Roles |= (unsigned)SymbolRole::Write;
+ }
} else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
if (UO->isIncrementDecrementOp()) {
@@ -84,12 +89,6 @@
Roles |= (unsigned)SymbolRole::AddressOf;
}
- } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
- if (CA->getLHS()->IgnoreParenCasts() == E) {
- Roles |= (unsigned)SymbolRole::Read;
- Roles |= (unsigned)SymbolRole::Write;
- }
-
} else if (auto CE = dyn_cast<CallExpr>(Parent)) {
if (CE->getCallee()->IgnoreParenCasts() == E) {
addCallRole(Roles, Relations);
Index: clang/lib/Frontend/Rewrite/RewriteObjC.cpp
===================================================================
--- clang/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ clang/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2026,8 +2026,9 @@
const auto *FT = msgSendType->castAs<FunctionType>();
- CallExpr *Exp = CallExpr::Create(
- *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
+ CallExpr *Exp =
+ CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
+ VK_RValue, EndLoc);
return Exp;
}
Index: clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
===================================================================
--- clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -2108,8 +2108,9 @@
DRE, nullptr, VK_RValue);
const auto *FT = msgSendType->castAs<FunctionType>();
- CallExpr *Exp = CallExpr::Create(
- *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
+ CallExpr *Exp =
+ CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
+ VK_RValue, EndLoc);
return Exp;
}
@@ -2877,8 +2878,9 @@
CK_BitCast,
DictLiteralValueME);
// (const id <NSCopying> [])keys
- Expr *NSKeyCallExpr = CallExpr::Create(
- *Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue, SourceLocation());
+ Expr *NSKeyCallExpr =
+ CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue,
+ SourceLocation());
MemberExpr *DictLiteralKeyME =
MemberExpr::CreateImplicit(*Context, NSKeyCallExpr, false, ARRFD,
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -3613,13 +3613,13 @@
/// Emit an l-value for an assignment (simple or compound) of complex type.
LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
- LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
- LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
+ LValue EmitComplexCompoundAssignmentLValue(const BinaryOperator *E);
+ LValue EmitScalarCompoundAssignWithComplex(const BinaryOperator *E,
llvm::Value *&Result);
// Note: only available for agg return types
LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
- LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E);
+ LValue EmitCompoundAssignmentLValue(const BinaryOperator *E);
// Note: only available for agg return types
LValue EmitCallExprLValue(const CallExpr *E);
// Note: only available for agg return types
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -777,20 +777,21 @@
Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
BinOpInfo EmitBinOps(const BinaryOperator *E);
- LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
- Value *&Result);
+ LValue
+ EmitCompoundAssignLValue(const BinaryOperator *E,
+ Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
+ Value *&Result);
- Value *EmitCompoundAssign(const CompoundAssignOperator *E,
+ Value *EmitCompoundAssign(const BinaryOperator *E,
Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
// Binary operators and binary compound assignment operators.
-#define HANDLEBINOP(OP) \
- Value *VisitBin ## OP(const BinaryOperator *E) { \
- return Emit ## OP(EmitBinOps(E)); \
- } \
- Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
- return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
+#define HANDLEBINOP(OP) \
+ Value *VisitBin##OP(const BinaryOperator *E) { \
+ return Emit##OP(EmitBinOps(E)); \
+ } \
+ Value *VisitBin##OP##Assign(const BinaryOperator *E) { \
+ return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
}
HANDLEBINOP(Mul)
HANDLEBINOP(Div)
@@ -2897,15 +2898,14 @@
Result.RHS = Visit(E->getRHS());
Result.Ty = E->getType();
Result.Opcode = E->getOpcode();
- Result.FPFeatures = E->getFPFeatures();
+ Result.FPFeatures = E->getFPFeatures(CGF.getLangOpts());
Result.E = E;
return Result;
}
LValue ScalarExprEmitter::EmitCompoundAssignLValue(
- const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
- Value *&Result) {
+ const BinaryOperator *E,
+ Value *(ScalarExprEmitter::*Func)(const BinOpInfo &), Value *&Result) {
QualType LHSTy = E->getLHS()->getType();
BinOpInfo OpInfo;
@@ -2917,7 +2917,7 @@
OpInfo.RHS = Visit(E->getRHS());
OpInfo.Ty = E->getComputationResultType();
OpInfo.Opcode = E->getOpcode();
- OpInfo.FPFeatures = E->getFPFeatures();
+ OpInfo.FPFeatures = E->getFPFeatures(CGF.getLangOpts());
OpInfo.E = E;
// Load/convert the LHS.
LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
@@ -3032,8 +3032,9 @@
return LHSLV;
}
-Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
+Value *ScalarExprEmitter::EmitCompoundAssign(
+ const BinaryOperator *E,
+ Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
bool Ignore = TestAndClearIgnoreResultAssign();
Value *RHS = nullptr;
LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
@@ -4623,9 +4624,7 @@
return MakeAddrLValue(Addr, E->getType());
}
-
-LValue CodeGenFunction::EmitCompoundAssignmentLValue(
- const CompoundAssignOperator *E) {
+LValue CodeGenFunction::EmitCompoundAssignmentLValue(const BinaryOperator *E) {
ScalarExprEmitter Scalar(*this);
Value *Result = nullptr;
switch (E->getOpcode()) {
Index: clang/lib/CodeGen/CGExprComplex.cpp
===================================================================
--- clang/lib/CodeGen/CGExprComplex.cpp
+++ clang/lib/CodeGen/CGExprComplex.cpp
@@ -251,13 +251,13 @@
};
BinOpInfo EmitBinOps(const BinaryOperator *E);
- LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)
- (const BinOpInfo &),
- RValue &Val);
- ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)
- (const BinOpInfo &));
+ LValue EmitCompoundAssignLValue(
+ const BinaryOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &),
+ RValue &Val);
+ ComplexPairTy EmitCompoundAssign(
+ const BinaryOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &));
ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
ComplexPairTy EmitBinSub(const BinOpInfo &Op);
@@ -285,16 +285,16 @@
}
// Compound assignments.
- ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
+ ComplexPairTy VisitBinAddAssign(const BinaryOperator *E) {
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
}
- ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
+ ComplexPairTy VisitBinSubAssign(const BinaryOperator *E) {
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
}
- ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
+ ComplexPairTy VisitBinMulAssign(const BinaryOperator *E) {
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
}
- ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
+ ComplexPairTy VisitBinDivAssign(const BinaryOperator *E) {
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
}
@@ -884,11 +884,9 @@
return Ops;
}
-
-LValue ComplexExprEmitter::
-EmitCompoundAssignLValue(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
- RValue &Val) {
+LValue ComplexExprEmitter::EmitCompoundAssignLValue(
+ const BinaryOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &), RValue &Val) {
TestAndClearIgnoreReal();
TestAndClearIgnoreImag();
QualType LHSTy = E->getLHS()->getType();
@@ -955,9 +953,9 @@
}
// Compound assignments.
-ComplexPairTy ComplexExprEmitter::
-EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
+ComplexPairTy ComplexExprEmitter::EmitCompoundAssign(
+ const BinaryOperator *E,
+ ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &)) {
RValue Val;
LValue LV = EmitCompoundAssignLValue(E, Func, Val);
@@ -1160,16 +1158,16 @@
}
}
-LValue CodeGenFunction::
-EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
+LValue
+CodeGenFunction::EmitComplexCompoundAssignmentLValue(const BinaryOperator *E) {
CompoundFunc Op = getComplexOp(E->getOpcode());
RValue Val;
return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
}
-LValue CodeGenFunction::
-EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
- llvm::Value *&Result) {
+LValue
+CodeGenFunction::EmitScalarCompoundAssignWithComplex(const BinaryOperator *E,
+ llvm::Value *&Result) {
CompoundFunc Op = getComplexOp(E->getOpcode());
RValue Val;
LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -1271,15 +1271,17 @@
return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
case Expr::ObjCIsaExprClass:
return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
- case Expr::BinaryOperatorClass:
- return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
- case Expr::CompoundAssignOperatorClass: {
- QualType Ty = E->getType();
- if (const AtomicType *AT = Ty->getAs<AtomicType>())
- Ty = AT->getValueType();
- if (!Ty->isAnyComplexType())
- return EmitCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
- return EmitComplexCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
+ case Expr::BinaryOperatorClass: {
+ const auto *const BO = cast<BinaryOperator>(E);
+ if (BO->isCompoundAssignmentOp()) {
+ QualType Ty = BO->getType();
+ if (const AtomicType *AT = Ty->getAs<AtomicType>())
+ Ty = AT->getValueType();
+ if (!Ty->isAnyComplexType())
+ return EmitCompoundAssignmentLValue(BO);
+ return EmitComplexCompoundAssignmentLValue(BO);
+ }
+ return EmitBinaryOperatorLValue(BO);
}
case Expr::CallExprClass:
case Expr::CXXMemberCallExprClass:
Index: clang/lib/Analysis/ThreadSafetyCommon.cpp
===================================================================
--- clang/lib/Analysis/ThreadSafetyCommon.cpp
+++ clang/lib/Analysis/ThreadSafetyCommon.cpp
@@ -222,7 +222,6 @@
case Stmt::UnaryOperatorClass:
return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
case Stmt::BinaryOperatorClass:
- case Stmt::CompoundAssignOperatorClass:
return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
case Stmt::ArraySubscriptExprClass:
Index: clang/lib/Analysis/ReachableCode.cpp
===================================================================
--- clang/lib/Analysis/ReachableCode.cpp
+++ clang/lib/Analysis/ReachableCode.cpp
@@ -561,12 +561,6 @@
R1 = UO->getSubExpr()->getSourceRange();
return UO->getOperatorLoc();
}
- case Expr::CompoundAssignOperatorClass: {
- const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(S);
- R1 = CAO->getLHS()->getSourceRange();
- R2 = CAO->getRHS()->getSourceRange();
- return CAO->getOperatorLoc();
- }
case Expr::BinaryConditionalOperatorClass:
case Expr::ConditionalOperatorClass: {
const AbstractConditionalOperator *CO =
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -2150,8 +2150,12 @@
case Stmt::BinaryConditionalOperatorClass:
return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc);
- case Stmt::BinaryOperatorClass:
+ case Stmt::BinaryOperatorClass: {
+ auto BO = dyn_cast<BinaryOperator>(S);
+ if (BO->isCompoundAssignmentOp())
+ return VisitStmt(S, asc);
return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
+ }
case Stmt::BlockExprClass:
return VisitBlockExpr(cast<BlockExpr>(S), asc);
Index: clang/lib/Analysis/BodyFarm.cpp
===================================================================
--- clang/lib/Analysis/BodyFarm.cpp
+++ clang/lib/Analysis/BodyFarm.cpp
@@ -114,20 +114,18 @@
BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
QualType Ty) {
- return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
- BO_Assign, Ty, VK_RValue,
- OK_Ordinary, SourceLocation(), FPOptions());
+ return BinaryOperator::Create(
+ C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty,
+ VK_RValue, OK_Ordinary, SourceLocation(), FPOptions());
}
BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
BinaryOperator::Opcode Op) {
assert(BinaryOperator::isLogicalOp(Op) ||
BinaryOperator::isComparisonOp(Op));
- return new (C) BinaryOperator(const_cast<Expr*>(LHS),
- const_cast<Expr*>(RHS),
- Op,
- C.getLogicalOperationType(),
- VK_RValue,
+ return BinaryOperator::Create(C, const_cast<Expr *>(LHS),
+ const_cast<Expr *>(RHS), Op,
+ C.getLogicalOperationType(), VK_RValue,
OK_Ordinary, SourceLocation(), FPOptions());
}
@@ -578,8 +576,8 @@
ASTMaker M(C);
DeclRefExpr *DR = M.makeDeclRefExpr(PV);
ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
- CallExpr *CE =
- CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation());
+ CallExpr *CE = CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue,
+ SourceLocation());
return CE;
}
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -869,15 +869,12 @@
void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
-}
-
-void TextNodeDumper::VisitCompoundAssignOperator(
- const CompoundAssignOperator *Node) {
- OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
- << "' ComputeLHSTy=";
- dumpBareType(Node->getComputationLHSType());
- OS << " ComputeResultTy=";
- dumpBareType(Node->getComputationResultType());
+ if (Node->isCompoundAssignmentOp()) {
+ OS << " ComputeLHSTy=";
+ dumpBareType(Node->getComputationLHSType());
+ OS << " ComputeResultTy=";
+ dumpBareType(Node->getComputationResultType());
+ }
}
void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
Index: clang/lib/AST/StmtProfile.cpp
===================================================================
--- clang/lib/AST/StmtProfile.cpp
+++ clang/lib/AST/StmtProfile.cpp
@@ -1234,11 +1234,6 @@
ID.AddInteger(S->getOpcode());
}
-void
-StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
- VisitBinaryOperator(S);
-}
-
void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
VisitExpr(S);
}
@@ -1507,35 +1502,35 @@
case OO_PlusEqual:
BinaryOp = BO_AddAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_MinusEqual:
BinaryOp = BO_SubAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_StarEqual:
BinaryOp = BO_MulAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_SlashEqual:
BinaryOp = BO_DivAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_PercentEqual:
BinaryOp = BO_RemAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_CaretEqual:
BinaryOp = BO_XorAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_AmpEqual:
BinaryOp = BO_AndAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_PipeEqual:
BinaryOp = BO_OrAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_LessLess:
BinaryOp = BO_Shl;
@@ -1547,11 +1542,11 @@
case OO_LessLessEqual:
BinaryOp = BO_ShlAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_GreaterGreaterEqual:
BinaryOp = BO_ShrAssign;
- return Stmt::CompoundAssignOperatorClass;
+ return Stmt::BinaryOperatorClass;
case OO_EqualEqual:
BinaryOp = BO_EQ;
@@ -1638,8 +1633,7 @@
Visit(S->getArg(I));
if (SC == Stmt::UnaryOperatorClass)
ID.AddInteger(UnaryOp);
- else if (SC == Stmt::BinaryOperatorClass ||
- SC == Stmt::CompoundAssignOperatorClass)
+ else if (SC == Stmt::BinaryOperatorClass)
ID.AddInteger(BinaryOp);
else
assert(SC == Stmt::ArraySubscriptExprClass);
Index: clang/lib/AST/StmtPrinter.cpp
===================================================================
--- clang/lib/AST/StmtPrinter.cpp
+++ clang/lib/AST/StmtPrinter.cpp
@@ -1437,12 +1437,6 @@
PrintExpr(Node->getRHS());
}
-void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
- PrintExpr(Node->getLHS());
- OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
- PrintExpr(Node->getRHS());
-}
-
void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
PrintExpr(Node->getCond());
OS << " ? ";
Index: clang/lib/AST/JSONNodeDumper.cpp
===================================================================
--- clang/lib/AST/JSONNodeDumper.cpp
+++ clang/lib/AST/JSONNodeDumper.cpp
@@ -1162,14 +1162,12 @@
void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
-}
-
-void JSONNodeDumper::VisitCompoundAssignOperator(
- const CompoundAssignOperator *CAO) {
- VisitBinaryOperator(CAO);
- JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
- JOS.attribute("computeResultType",
- createQualType(CAO->getComputationResultType()));
+ if (BO->isCompoundAssignmentOp()) {
+ JOS.attribute("computeLHSType",
+ createQualType(BO->getComputationLHSType()));
+ JOS.attribute("computeResultType",
+ createQualType(BO->getComputationResultType()));
+ }
}
void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -4167,7 +4167,6 @@
break;
}
- case Expr::CompoundAssignOperatorClass: // fallthrough
case Expr::BinaryOperatorClass: {
const BinaryOperator *BO = cast<BinaryOperator>(E);
if (BO->getOpcode() == BO_PtrMemD)
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -7485,7 +7485,6 @@
return VisitUnaryPreIncDec(UO);
}
bool VisitBinAssign(const BinaryOperator *BO);
- bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
bool VisitCastExpr(const CastExpr *E) {
switch (E->getCastKind()) {
@@ -7786,32 +7785,28 @@
UO->isIncrementOp(), nullptr);
}
-bool LValueExprEvaluator::VisitCompoundAssignOperator(
- const CompoundAssignOperator *CAO) {
+bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) {
if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
- return Error(CAO);
-
- APValue RHS;
+ return Error(E);
- // The overall lvalue result is the result of evaluating the LHS.
- if (!this->Visit(CAO->getLHS())) {
- if (Info.noteFailure())
- Evaluate(RHS, this->Info, CAO->getRHS());
- return false;
- }
+ if (E->isCompoundAssignmentOp()) {
+ APValue RHS;
- if (!Evaluate(RHS, this->Info, CAO->getRHS()))
- return false;
+ // The overall lvalue result is the result of evaluating the LHS.
+ if (!this->Visit(E->getLHS())) {
+ if (Info.noteFailure())
+ Evaluate(RHS, this->Info, E->getRHS());
+ return false;
+ }
- return handleCompoundAssignment(
- this->Info, CAO,
- Result, CAO->getLHS()->getType(), CAO->getComputationLHSType(),
- CAO->getOpForCompoundAssignment(CAO->getOpcode()), RHS);
-}
+ if (!Evaluate(RHS, this->Info, E->getRHS()))
+ return false;
-bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) {
- if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
- return Error(E);
+ return handleCompoundAssignment(
+ this->Info, E, Result, E->getLHS()->getType(),
+ E->getComputationLHSType(),
+ E->getOpForCompoundAssignment(E->getOpcode()), RHS);
+ }
APValue NewVal;
@@ -14160,7 +14155,6 @@
case Expr::ArraySubscriptExprClass:
case Expr::OMPArraySectionExprClass:
case Expr::MemberExprClass:
- case Expr::CompoundAssignOperatorClass:
case Expr::CompoundLiteralExprClass:
case Expr::ExtVectorElementExprClass:
case Expr::DesignatedInitExprClass:
Index: clang/lib/AST/ExprClassification.cpp
===================================================================
--- clang/lib/AST/ExprClassification.cpp
+++ clang/lib/AST/ExprClassification.cpp
@@ -296,7 +296,6 @@
return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
case Expr::BinaryOperatorClass:
- case Expr::CompoundAssignOperatorClass:
// C doesn't have any binary expressions that are lvalues.
if (Lang.CPlusPlus)
return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E));
Index: clang/lib/AST/ExprCXX.cpp
===================================================================
--- clang/lib/AST/ExprCXX.cpp
+++ clang/lib/AST/ExprCXX.cpp
@@ -531,11 +531,11 @@
OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
CXXOperatorCallExprBits.OperatorKind = OpKind;
CXXOperatorCallExprBits.FPFeatures = FPFeatures.getInt();
+ assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
+ "FPFeatures overflow!");
assert(
(CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
"OperatorKind overflow!");
- assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
- "FPFeatures overflow!");
Range = getSourceRangeImpl();
}
@@ -1639,4 +1639,4 @@
void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
alignof(CUDAKernelCallExpr));
return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
-}
\ No newline at end of file
+}
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1352,8 +1352,9 @@
ADLCallKind UsesADL) {
assert(!(reinterpret_cast<uintptr_t>(Mem) % alignof(CallExpr)) &&
"Misaligned memory in CallExpr::CreateTemporary!");
- return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty,
- VK, RParenLoc, /*MinNumArgs=*/0, UsesADL);
+ return new (Mem)
+ CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty, VK,
+ RParenLoc, /*MinNumArgs=*/0, UsesADL);
}
CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
@@ -2358,7 +2359,6 @@
R2 = BO->getRHS()->getSourceRange();
return true;
}
- case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
return false;
@@ -3370,7 +3370,6 @@
case MSPropertyRefExprClass:
case MSPropertySubscriptExprClass:
- case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
case CXXThrowExprClass:
@@ -4340,6 +4339,31 @@
return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
}
+BinaryOperator *BinaryOperator::CreateEmpty(const ASTContext &C,
+ unsigned hasFPFeatures,
+ unsigned isCompound) {
+ unsigned SizeOfTrailingObjects =
+ BinaryOperator::sizeOfTrailingObjects(hasFPFeatures, isCompound);
+ void *Mem = C.Allocate(sizeof(BinaryOperator) + SizeOfTrailingObjects,
+ alignof(BinaryOperator));
+ return new (Mem) BinaryOperator(EmptyShell(), hasFPFeatures, isCompound);
+}
+
+BinaryOperator *
+BinaryOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation opLoc, FPOptions FPFeatures,
+ QualType *CompLHSType, QualType *CompResultType) {
+ bool hasFPFeatures = true;
+ unsigned SizeOfTrailingObjects =
+ BinaryOperator::sizeOfTrailingObjects(hasFPFeatures,
+ isCompoundAssignmentOp(opc));
+ void *Mem = C.Allocate(sizeof(BinaryOperator) + SizeOfTrailingObjects,
+ alignof(BinaryOperator));
+ return new (Mem) BinaryOperator(lhs, rhs, opc, ResTy, VK, OK, opLoc,
+ FPFeatures, CompLHSType, CompResultType);
+}
+
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
e = ewc->getSubExpr();
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -606,7 +606,6 @@
ExpectedStmt VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
ExpectedStmt VisitExpressionTraitExpr(ExpressionTraitExpr *E);
ExpectedStmt VisitArraySubscriptExpr(ArraySubscriptExpr *E);
- ExpectedStmt VisitCompoundAssignOperator(CompoundAssignOperator *E);
ExpectedStmt VisitImplicitCastExpr(ImplicitCastExpr *E);
ExpectedStmt VisitExplicitCastExpr(ExplicitCastExpr *E);
ExpectedStmt VisitOffsetOfExpr(OffsetOfExpr *OE);
@@ -6688,9 +6687,22 @@
if (Err)
return std::move(Err);
- return new (Importer.getToContext()) BinaryOperator(
- ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
- E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
+ if (E->IsCompoundAssign()) {
+ auto ToComputationLHSType = importChecked(Err, E->getComputationLHSType());
+ auto ToComputationResultType =
+ importChecked(Err, E->getComputationResultType());
+ if (Err)
+ return std::move(Err);
+ return BinaryOperator::Create(
+ Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
+ E->getValueKind(), E->getObjectKind(),
+ ToOperatorLoc, E->getFPFeatures(Importer.getToContext().getLangOpts()),
+ &ToComputationLHSType, &ToComputationResultType);
+ }
+ return BinaryOperator::Create(
+ Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
+ E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
+ E->getFPFeatures(Importer.getToContext().getLangOpts()));
}
ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
@@ -6785,25 +6797,6 @@
ToRBracketLoc);
}
-ExpectedStmt
-ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- Error Err = Error::success();
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToType = importChecked(Err, E->getType());
- auto ToComputationLHSType = importChecked(Err, E->getComputationLHSType());
- auto ToComputationResultType =
- importChecked(Err, E->getComputationResultType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- if (Err)
- return std::move(Err);
-
- return new (Importer.getToContext()) CompoundAssignOperator(
- ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
- E->getObjectKind(), ToComputationLHSType, ToComputationResultType,
- ToOperatorLoc, E->getFPFeatures());
-}
-
Expected<CXXCastPath>
ASTNodeImporter::ImportCastPath(CastExpr *CE) {
CXXCastPath Path;
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -1559,7 +1559,7 @@
/// A BinaryOperator record.
EXPR_BINARY_OPERATOR,
- /// A CompoundAssignOperator record.
+ /// Defunct: CompoundAssignOperator is part of BinaryOperator
EXPR_COMPOUND_ASSIGN_OPERATOR,
/// A ConditionOperator record.
Index: clang/include/clang/Basic/StmtNodes.td
===================================================================
--- clang/include/clang/Basic/StmtNodes.td
+++ clang/include/clang/Basic/StmtNodes.td
@@ -74,7 +74,6 @@
def MemberExpr : StmtNode<Expr>;
def CastExpr : StmtNode<Expr, 1>;
def BinaryOperator : StmtNode<Expr>;
-def CompoundAssignOperator : StmtNode<BinaryOperator>;
def AbstractConditionalOperator : StmtNode<Expr, 1>;
def ConditionalOperator : StmtNode<AbstractConditionalOperator>;
def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -356,11 +356,10 @@
/// Floating point control options
class FPOptions {
public:
- FPOptions() : fp_contract(LangOptions::FPC_Off),
- fenv_access(LangOptions::FEA_Off),
- rounding(LangOptions::FPR_ToNearest),
- exceptions(LangOptions::FPE_Ignore)
- {}
+ FPOptions()
+ : fp_contract(LangOptions::FPC_Off), fenv_access(LangOptions::FEA_Off),
+ rounding(LangOptions::FPR_ToNearest),
+ exceptions(LangOptions::FPE_Ignore) {}
// Used for serializing.
explicit FPOptions(unsigned I)
@@ -372,12 +371,30 @@
explicit FPOptions(const LangOptions &LangOpts)
: fp_contract(LangOpts.getDefaultFPContractMode()),
- fenv_access(LangOptions::FEA_Off),
- rounding(LangOptions::FPR_ToNearest),
- exceptions(LangOptions::FPE_Ignore)
- {}
+ fenv_access(LangOptions::FEA_Off), rounding(LangOptions::FPR_ToNearest),
+ exceptions(LangOptions::FPE_Ignore) {}
// FIXME: Use getDefaultFEnvAccessMode() when available.
+
+ /// Return the default value of FPOptions that's used when trailing
+ /// storage isn't required.
+ static FPOptions defaultWithoutTrailingStorage(const LangOptions &LangOpts) {
+ FPOptions result;
+ return result;
+ }
+ // Does this FPOptions require trailing storage when stored in various
+ // AST nodes, or can it be recreated using `defaultWithoutTrailingStorage`?
+ bool requiresTrailingStorage(const LangOptions &LangOpts) {
+ return getInt() != defaultWithoutTrailingStorage(LangOpts).getInt();
+ }
+ static FPOptions defaultWithoutTrailingStorage() {
+ FPOptions result;
+ return result;
+ }
+ bool requiresTrailingStorage() {
+ return getInt() != defaultWithoutTrailingStorage().getInt();
+ }
+
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
}
@@ -430,8 +447,8 @@
/// Used to serialize this.
unsigned getInt() const {
- return fp_contract | (fenv_access << 2) | (rounding << 3)
- | (exceptions << 6);
+ return fp_contract | (fenv_access << 2) | (rounding << 3) |
+ (exceptions << 6);
}
private:
Index: clang/include/clang/AST/TextNodeDumper.h
===================================================================
--- clang/include/clang/AST/TextNodeDumper.h
+++ clang/include/clang/AST/TextNodeDumper.h
@@ -247,7 +247,6 @@
void VisitMemberExpr(const MemberExpr *Node);
void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
void VisitBinaryOperator(const BinaryOperator *Node);
- void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
void VisitAddrLabelExpr(const AddrLabelExpr *Node);
void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
Index: clang/include/clang/AST/StmtVisitor.h
===================================================================
--- clang/include/clang/AST/StmtVisitor.h
+++ clang/include/clang/AST/StmtVisitor.h
@@ -70,16 +70,16 @@
case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator);
case BO_LOr : DISPATCH(BinLOr, BinaryOperator);
case BO_Assign: DISPATCH(BinAssign, BinaryOperator);
- case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
- case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
- case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
- case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
- case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
- case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
- case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
- case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
- case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator);
- case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
+ case BO_MulAssign: DISPATCH(BinMulAssign, BinaryOperator);
+ case BO_DivAssign: DISPATCH(BinDivAssign, BinaryOperator);
+ case BO_RemAssign: DISPATCH(BinRemAssign, BinaryOperator);
+ case BO_AddAssign: DISPATCH(BinAddAssign, BinaryOperator);
+ case BO_SubAssign: DISPATCH(BinSubAssign, BinaryOperator);
+ case BO_ShlAssign: DISPATCH(BinShlAssign, BinaryOperator);
+ case BO_ShrAssign: DISPATCH(BinShrAssign, BinaryOperator);
+ case BO_AndAssign: DISPATCH(BinAndAssign, BinaryOperator);
+ case BO_OrAssign: DISPATCH(BinOrAssign, BinaryOperator);
+ case BO_XorAssign: DISPATCH(BinXorAssign, BinaryOperator);
case BO_Comma: DISPATCH(BinComma, BinaryOperator);
}
} else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
@@ -141,9 +141,9 @@
// If the implementation doesn't implement compound assignment operator
// methods, fall back on VisitCompoundAssignOperator.
-#define CAO_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S, ParamTys... P) { \
- DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
+#define CAO_FALLBACK(NAME) \
+ RetTy VisitBin##NAME(PTR(BinaryOperator) S, ParamTys... P) { \
+ DISPATCH(BinAssign, BinaryOperator); \
}
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
Index: clang/include/clang/AST/Stmt.h
===================================================================
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -523,10 +523,6 @@
unsigned Opc : 6;
- /// This is only meaningful for operations on floating point
- /// types and 0 otherwise.
- unsigned FPFeatures : 8;
-
SourceLocation OpLoc;
};
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -424,10 +424,10 @@
// assignment methods. Compound assignment operators are not
// classes in themselves (they're all opcodes in
// CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME##Assign, BinaryOperator)
CAO_LIST()
+
#undef OPERATOR
#undef GENERAL_BINOP_FALLBACK
@@ -567,7 +567,7 @@
#define OPERATOR(NAME) \
case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+ DISPATCH_STMT(Bin##NAME##Assign, BinaryOperator, S);
CAO_LIST()
#undef OPERATOR
@@ -2677,7 +2677,6 @@
DEF_TRAVERSE_STMT(ConditionalOperator, {})
DEF_TRAVERSE_STMT(UnaryOperator, {})
DEF_TRAVERSE_STMT(BinaryOperator, {})
-DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
DEF_TRAVERSE_STMT(PackExpansionExpr, {})
DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
Index: clang/include/clang/AST/JSONNodeDumper.h
===================================================================
--- clang/include/clang/AST/JSONNodeDumper.h
+++ clang/include/clang/AST/JSONNodeDumper.h
@@ -262,7 +262,7 @@
void VisitPredefinedExpr(const PredefinedExpr *PE);
void VisitUnaryOperator(const UnaryOperator *UO);
void VisitBinaryOperator(const BinaryOperator *BO);
- void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
+ void VisitCompoundAssignOperator(const BinaryOperator *CAO);
void VisitMemberExpr(const MemberExpr *ME);
void VisitCXXNewExpr(const CXXNewExpr *NE);
void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -3462,32 +3462,54 @@
/// value-dependent). If either x or y is type-dependent, or if the
/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
/// be used to express the computation.
-class BinaryOperator : public Expr {
+class BinaryOperator final
+ : public Expr,
+ private llvm::TrailingObjects<BinaryOperator, FPOptions, QualType> {
enum { LHS, RHS, END_EXPR };
Stmt *SubExprs[END_EXPR];
+ bool hasFPFeatures;
+
+ /// Return the size in bytes needed for the trailing objects.
+ /// Used by the derived classes to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(bool hasFP, bool isCompound) {
+ return (hasFP ? 1 : 0) * sizeof(unsigned) +
+ (isCompound ? 2 : 0) * sizeof(QualType);
+ }
+ unsigned numTrailingObjects(OverloadToken<FPOptions>) const {
+ return hasFPFeatures ? 1 : 0;
+ }
+ unsigned numTrailingObjects(OverloadToken<QualType>) const {
+ auto opc = static_cast<Opcode>(BinaryOperatorBits.Opc);
+ return isCompoundAssignmentOp(opc) ? 2 : 0;
+ }
public:
typedef BinaryOperatorKind Opcode;
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
- FPOptions FPFeatures)
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation opLoc, FPOptions FPFeatures,
+ QualType *CompLHSType = nullptr,
+ QualType *CompResultType = nullptr)
: Expr(BinaryOperatorClass, ResTy, VK, OK) {
BinaryOperatorBits.Opc = opc;
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
- assert(!isCompoundAssignmentOp() &&
- "Use CompoundAssignOperator for compound assignments");
+ assert(((isCompoundAssignmentOp() && CompLHSType && CompResultType) ||
+ (!isCompoundAssignmentOp() && !CompLHSType && !CompResultType)) &&
+ "Expected binaryoperator opcode");
+ hasFPFeatures = true;
+ if (hasFPFeatures) {
+ *getTrailingObjects<FPOptions>() = FPFeatures;
+ }
+ if (isCompoundAssignmentOp()) {
+ setComputationLHSType(*CompLHSType);
+ setComputationResultType(*CompResultType);
+ }
setDependence(computeDependence(this));
}
- /// Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
- BinaryOperatorBits.Opc = BO_Comma;
- }
-
SourceLocation getExprLoc() const { return getOperatorLoc(); }
SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3616,8 +3638,7 @@
Expr *LHS, Expr *RHS);
static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstBinaryOperatorConstant &&
- S->getStmtClass() <= lastBinaryOperatorConstant;
+ return S->getStmtClass() == BinaryOperatorClass;
}
// Iterators
@@ -3631,11 +3652,36 @@
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
void setFPFeatures(FPOptions F) {
- BinaryOperatorBits.FPFeatures = F.getInt();
+ assert(hasFPFeatures);
+ *getTrailingObjects<FPOptions>() = FPOptions(F.getInt());
}
+ static BinaryOperator *
+ CreateEmpty(const ASTContext &C, unsigned hasFPFeatures, unsigned isCompound);
+
+ static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
+ Opcode opc, QualType ResTy, ExprValueKind VK,
+ ExprObjectKind OK,
+ SourceLocation opLoc, FPOptions FPFeatures,
+ QualType *CompLHSType = nullptr,
+ QualType *CompResultType = nullptr);
+
+ bool IsCompoundAssign() const {
+ auto opc = static_cast<Opcode>(BinaryOperatorBits.Opc);
+ return isCompoundAssignmentOp(opc);
+ }
+
+ void setHasFPFeatures(bool B) { hasFPFeatures = B; }
+ bool HasFPFeatures() const { return hasFPFeatures; }
FPOptions getFPFeatures() const {
- return FPOptions(BinaryOperatorBits.FPFeatures);
+ assert(hasFPFeatures);
+ return *getTrailingObjects<FPOptions>();
+ }
+ FPOptions getFPFeatures(const LangOptions &Opts) const {
+ if (hasFPFeatures)
+ return *getTrailingObjects<FPOptions>();
+ else
+ return FPOptions(Opts);
}
// Get the FP contractability status of this operator. Only meaningful for
@@ -3648,62 +3694,54 @@
// operations on floating point types.
bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
+ /// For compound assignments (e.g. +=), we keep
+ /// track of the type the operation is performed in. Due to the semantics of
+ /// these operators, the operands are promoted, the arithmetic performed, an
+ /// implicit conversion back to the result type done, then the assignment
+ /// takes place. This captures the intermediate type which the computation
+ /// is done in.
+ /// The two computation types are the type the LHS is converted
+ /// to for the computation and the type of the result; the two are
+ /// distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
+ QualType getComputationLHSType() const {
+ assert(isCompoundAssignmentOp() &&
+ "Expected compound assignment operator");
+ return getTrailingObjects<QualType>()[0];
+ }
+ void setComputationLHSType(QualType T) {
+ assert(isCompoundAssignmentOp() &&
+ "Expected compound assignment operator");
+ getTrailingObjects<QualType>()[0] = T;
+ }
+ QualType getComputationResultType() const {
+ assert(isCompoundAssignmentOp() &&
+ "Expected compound assignment operator");
+ return getTrailingObjects<QualType>()[1];
+ }
+ void setComputationResultType(QualType T) {
+ assert(isCompoundAssignmentOp() &&
+ "Expected compound assignment operator");
+ getTrailingObjects<QualType>()[1] = T;
+ }
+
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
FPOptions FPFeatures, bool dead2)
- : Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
+ : Expr(BinaryOperatorClass, ResTy, VK, OK) {
BinaryOperatorBits.Opc = opc;
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
setDependence(computeDependence(this));
}
- BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
- BinaryOperatorBits.Opc = BO_MulAssign;
- }
-};
-
-/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
-/// track of the type the operation is performed in. Due to the semantics of
-/// these operators, the operands are promoted, the arithmetic performed, an
-/// implicit conversion back to the result type done, then the assignment takes
-/// place. This captures the intermediate type which the computation is done
-/// in.
-class CompoundAssignOperator : public BinaryOperator {
- QualType ComputationLHSType;
- QualType ComputationResultType;
-public:
- CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
- ExprValueKind VK, ExprObjectKind OK,
- QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc, FPOptions FPFeatures)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
- true),
- ComputationLHSType(CompLHSType),
- ComputationResultType(CompResultType) {
- assert(isCompoundAssignmentOp() &&
- "Only should be used for compound assignments");
- }
-
- /// Build an empty compound assignment operator expression.
- explicit CompoundAssignOperator(EmptyShell Empty)
- : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
-
- // The two computation types are the type the LHS is converted
- // to for the computation and the type of the result; the two are
- // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
- QualType getComputationLHSType() const { return ComputationLHSType; }
- void setComputationLHSType(QualType T) { ComputationLHSType = T; }
-
- QualType getComputationResultType() const { return ComputationResultType; }
- void setComputationResultType(QualType T) { ComputationResultType = T; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CompoundAssignOperatorClass;
+ BinaryOperator(EmptyShell Empty, unsigned hasFPFeatures, unsigned isCompound)
+ : Expr(BinaryOperatorClass, Empty) {
+ if (isCompound)
+ BinaryOperatorBits.Opc = BO_MulAssign;
}
+ friend TrailingObjects;
};
/// AbstractConditionalOperator - An abstract base class for
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits