mibintc updated this revision to Diff 251699.
mibintc retitled this revision from "Move FPFeatures from BinaryOperator
bitfields to Trailing storage - preliminary" to "Move FPFeatures from
BinaryOperator bitfields to Trailing storage".
mibintc added a comment.
This revision has been rebased, the LIT test failures seen in the previous
revision have been corrected: check-all passes. Still owe you some polishing.
I'm going to add a couple inline comments.
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/ExprCXX.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/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/SemaAttr.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/Analysis/loopexit-cfg-output.cpp
clang/test/Import/compound-assign-op/test.cpp
clang/test/Sema/warn-unreachable.c
clang/tools/libclang/CXCursor.cpp
Index: clang/tools/libclang/CXCursor.cpp
===================================================================
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -383,10 +383,6 @@
K = CXCursor_BinaryOperator;
break;
- case Stmt::CompoundAssignOperatorClass:
- K = CXCursor_CompoundAssignOperator;
- break;
-
case Stmt::ConditionalOperatorClass:
K = CXCursor_ConditionalOperator;
break;
Index: clang/test/Sema/warn-unreachable.c
===================================================================
--- clang/test/Sema/warn-unreachable.c
+++ clang/test/Sema/warn-unreachable.c
@@ -83,8 +83,8 @@
- // expected-warning {{will never be executed}}
halt();
case 8:
- i
- += // expected-warning {{will never be executed}}
+ i // expected-warning {{will never be executed}}
+ +=
halt();
case 9:
halt()
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/Analysis/loopexit-cfg-output.cpp
===================================================================
--- clang/test/Analysis/loopexit-cfg-output.cpp
+++ clang/test/Analysis/loopexit-cfg-output.cpp
@@ -208,9 +208,9 @@
// CHECK-NEXT: Succs (2): B4 B1
// CHECK: [B3]
-// CHECK-NEXT: 1: j
-// CHECK-NEXT: 2: 2
-// CHECK-NEXT: 3: [B3.1] += [B3.2]
+// CHECK-NEXT: 1: 2
+// CHECK-NEXT: 2: j
+// CHECK-NEXT: 3: [B3.2] += [B3.1]
// CHECK-NEXT: Preds (2): B4 B5
// CHECK-NEXT: Succs (1): B2
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
@@ -417,7 +417,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,
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
@@ -1664,12 +1664,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
@@ -778,6 +778,7 @@
VisitExpr(E);
Record.push_back(E->getNumArgs());
Record.AddSourceLocation(E->getRParenLoc());
+ Record.push_back(E->getFPFeatures().getInt());
Record.AddStmt(E->getCallee());
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
Arg != ArgEnd; ++Arg)
@@ -868,21 +869,24 @@
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->isCompoundAssignmentOp());
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());
@@ -1463,7 +1467,6 @@
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
Record.push_back(E->getOperator());
- Record.push_back(E->getFPFeatures().getInt());
Record.AddSourceRange(E->Range);
Code = serialization::EXPR_CXX_OPERATOR_CALL;
}
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -582,7 +582,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
@@ -915,6 +915,7 @@
unsigned NumArgs = Record.readInt();
assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
E->setRParenLoc(readSourceLocation());
+ E->setFPFeatures(FPOptions(Record.readInt()));
E->setCallee(Record.readSubExpr());
for (unsigned I = 0; I != NumArgs; ++I)
E->setArg(I, Record.readSubExpr());
@@ -1006,18 +1007,23 @@
}
void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
+ bool hasFP_Features;
+ bool isCompoundAssign;
VisitExpr(E);
+ E->setHasFPFeatures(hasFP_Features = Record.readInt());
+ E->setIsCompoundAssign(isCompoundAssign = 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 (isCompoundAssign) {
+ E->setComputationLHSType(Record.readType());
+ E->setComputationResultType(Record.readType());
+ }
}
void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
@@ -1579,7 +1585,6 @@
void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
E->CXXOperatorCallExprBits.OperatorKind = Record.readInt();
- E->CXXOperatorCallExprBits.FPFeatures = Record.readInt();
E->Range = Record.readSourceRange();
}
@@ -2865,11 +2870,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
@@ -3372,7 +3372,8 @@
// Build the CallExpr
ExprResult TheCall = CallExpr::Create(
SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
- Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc);
+ Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
+ FPOptions());
// Type-check the __builtin_shufflevector expression.
return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
@@ -10069,7 +10070,10 @@
return E;
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
- getSema().FPFeatures = E->getFPFeatures();
+ if (E->HasFPFeatures())
+ getSema().FPFeatures = E->getFPFeatures();
+ else
+ getSema().FPFeatures = FPOptions();
return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
LHS.get(), RHS.get());
@@ -10120,13 +10124,6 @@
}
template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformCompoundAssignOperator(
- CompoundAssignOperator *E) {
- return getDerived().TransformBinaryOperator(E);
-}
-
-template<typename Derived>
ExprResult TreeTransform<Derived>::
TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
// Just rebuild the common and RHS expressions and see whether we
Index: clang/lib/Sema/SemaPseudoObject.cpp
===================================================================
--- clang/lib/Sema/SemaPseudoObject.cpp
+++ clang/lib/Sema/SemaPseudoObject.cpp
@@ -448,11 +448,12 @@
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 +464,14 @@
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());
+ syntactic = BinaryOperator::Create(S.Context,
+ syntacticLHS, capturedRHS, opcode,
+ result.get()->getType(),
+ result.get()->getValueKind(),
+ OK_Ordinary,
+ opLHS.get()->getType(),
+ result.get()->getType(),
+ opcLoc, FPOptions());
}
// The result of the assignment, if not void, is the value set into
@@ -1586,9 +1587,10 @@
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,30 +1641,30 @@
/// 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();
- return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
- bop->getType(), bop->getValueKind(),
- bop->getObjectKind(),
- bop->getOperatorLoc(), FPOptions());
+ return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(),
+ bop->getType(),
+ bop->getValueKind(),
+ bop->getObjectKind(),
+ bop->getComputationLHSType(),
+ bop->getComputationResultType(),
+ bop->getOperatorLoc(),
+ FPOptions());
+ } else if (bop) {
+ Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
+ Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
+ return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(),
+ bop->getType(), bop->getValueKind(),
+ bop->getObjectKind(),
+ bop->getOperatorLoc(), FPOptions());
} else {
assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -12719,7 +12719,7 @@
// lookup to instantiation time to be able to search into type dependent
// base classes.
CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy,
- VK_RValue, RParenLoc);
+ VK_RValue, RParenLoc, FPFeatures);
CE->markDependentForPostponedNameLookup();
*Result = CE;
return true;
@@ -13006,7 +13006,7 @@
Args[0] = Input;
CallExpr *TheCall = CXXOperatorCallExpr::Create(
Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc,
- FPOptions(), Best->IsADLCandidate);
+ FPFeatures, Best->IsADLCandidate);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
return ExprError();
@@ -13175,11 +13175,11 @@
// 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(
+ return BinaryOperator::Create(Context,
Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
OpLoc, FPFeatures);
- return new (Context) CompoundAssignOperator(
+ return BinaryOperator::Create(Context,
Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
Context.DependentTy, Context.DependentTy, OpLoc,
FPFeatures);
@@ -13856,7 +13856,7 @@
if (isa<CXXPseudoDestructorExpr>(NakedMemExpr))
return CallExpr::Create(Context, MemExprE, Args, Context.VoidTy, VK_RValue,
- RParenLoc);
+ RParenLoc, FPFeatures);
UnbridgedCastsSet UnbridgedCasts;
if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
@@ -14459,7 +14459,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
@@ -9042,20 +9042,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>(
+ if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
AtomicBody->IgnoreParenImpCasts())) {
- // Check for Binary Operation
- if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
+ 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
@@ -14620,7 +14618,8 @@
S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Expr *Args[] = {LHS.get(), RHS.get()};
ReductionOp =
- CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
+ CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
+ S.FPFeatures);
} 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
@@ -6998,9 +6998,10 @@
return ExprError();
if (RHS.get() == BO->getRHS())
return E;
- return new (Context) BinaryOperator(
+ return BinaryOperator::Create(Context,
BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
- BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures());
+ BO->getObjectKind(), BO->getOperatorLoc(),
+ BO->HasFPFeatures() ? BO->getFPFeatures() : FPOptions());
}
}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -5756,7 +5756,7 @@
}
return CallExpr::Create(Context, Fn, /*Args=*/{}, Context.VoidTy,
- VK_RValue, RParenLoc);
+ VK_RValue, RParenLoc, FPFeatures);
}
if (Fn->getType() == Context.PseudoObjectTy) {
ExprResult result = CheckPlaceholderExpr(Fn);
@@ -5778,7 +5778,7 @@
Fn->getBeginLoc());
return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
- VK_RValue, RParenLoc);
+ VK_RValue, RParenLoc, FPFeatures);
}
}
@@ -5807,7 +5807,7 @@
if (!find.HasFormOfMemberPointer) {
if (Expr::hasAnyTypeDependentArguments(ArgExprs))
return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
- VK_RValue, RParenLoc);
+ VK_RValue, RParenLoc, FPFeatures);
OverloadExpr *ovl = find.Expression;
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl))
return BuildOverloadedCallExpr(
@@ -6003,7 +6003,7 @@
ResultTy, VK_RValue, RParenLoc, NumParams);
} else {
TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue,
- RParenLoc, NumParams, UsesADL);
+ RParenLoc, FPFeatures, NumParams, UsesADL);
}
if (!getLangOpts().CPlusPlus) {
@@ -6033,7 +6033,7 @@
RParenLoc, NumParams);
else
TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue,
- RParenLoc, NumParams, UsesADL);
+ RParenLoc, FPFeatures, NumParams, UsesADL);
}
// We can now handle the nulled arguments for the default arguments.
TheCall->setNumArgsUnsafe(std::max<unsigned>(Args.size(), NumParams));
@@ -12890,12 +12890,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,
+ BinOpResTy, BinOpResTy, OpLoc, FPFeatures);
LHS = convertVector(LHS.get(), Context.FloatTy, S);
- auto *BO = new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, BinOpResTy,
+ auto *BO = BinaryOperator::Create(Context,
+ LHS.get(), RHS.get(), Opc, BinOpResTy,
VK, OK, OpLoc, FPFeatures);
return convertVector(BO, ResultTy->castAs<VectorType>()->getElementType(), S);
}
@@ -13210,8 +13211,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.
@@ -13225,9 +13226,13 @@
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,
+ CompLHSTy, CompResultTy, OpLoc, FPFeatures);
}
/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -18320,7 +18325,7 @@
CK_BuiltinFnToFnPtr)
.get();
return CallExpr::Create(Context, E, /*Args=*/{}, Context.IntTy,
- VK_RValue, SourceLocation());
+ VK_RValue, SourceLocation(), FPFeatures);
}
}
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
@@ -10853,7 +10853,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());
@@ -10864,9 +10865,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;
@@ -11722,7 +11721,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);
}
@@ -12529,7 +12528,7 @@
Region = LHSRegion;
Visit(BO->getLHS());
- if (O && isa<CompoundAssignOperator>(BO))
+ if (O && BO->isCompoundAssignmentOp())
notePostUse(O, BO);
} else {
@@ -12537,7 +12536,7 @@
Region = LHSRegion;
Visit(BO->getLHS());
- if (O && isa<CompoundAssignOperator>(BO))
+ if (O && BO->isCompoundAssignmentOp())
notePostUse(O, BO);
Region = RHSRegion;
@@ -12559,10 +12558,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/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -930,12 +930,15 @@
switch (FPC) {
case LangOptions::FPC_On:
FPFeatures.setAllowFPContractWithinStatement();
+ FPFeatures.setHasPragmaFPFeatures();
break;
case LangOptions::FPC_Fast:
FPFeatures.setAllowFPContractAcrossStatement();
+ FPFeatures.setHasPragmaFPFeatures();
break;
case LangOptions::FPC_Off:
FPFeatures.setDisallowFPContract();
+ FPFeatures.setHasPragmaFPFeatures();
break;
}
}
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,10 @@
if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
Roles |= (unsigned)SymbolRole::Write;
+ if (BO->isCompoundAssignmentOp()) {
+ Roles |= (unsigned)SymbolRole::Read;
+ Roles |= (unsigned)SymbolRole::Write;
+ }
} else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
if (UO->isIncrementDecrementOp()) {
@@ -84,12 +88,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
@@ -2027,7 +2027,8 @@
const auto *FT = msgSendType->castAs<FunctionType>();
CallExpr *Exp = CallExpr::Create(
- *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
+ *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc,
+ FPOptions());
return Exp;
}
@@ -2613,7 +2614,7 @@
const auto *FT = msgSendType->castAs<FunctionType>();
CallExpr *STCE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, SourceLocation());
+ VK_RValue, SourceLocation(), FPOptions());
return STCE;
}
@@ -2706,7 +2707,7 @@
DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
VK_LValue, SourceLocation());
SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
- VK_LValue, SourceLocation());
+ VK_LValue, SourceLocation(), FPOptions());
// The code for super is a little tricky to prevent collision with
// the structure definition in the header. The rewriter has it's own
// internal definition (__rw_objc_super) that is uses. This is why
@@ -2801,7 +2802,7 @@
DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
VK_LValue, SourceLocation());
SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
- VK_LValue, SourceLocation());
+ VK_LValue, SourceLocation(), FPOptions());
// The code for super is a little tricky to prevent collision with
// the structure definition in the header. The rewriter has it's own
// internal definition (__rw_objc_super) that is uses. This is why
@@ -2966,7 +2967,7 @@
const auto *FT = msgSendType->castAs<FunctionType>();
CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, EndLoc);
+ VK_RValue, EndLoc, FPOptions());
Stmt *ReplacingStmt = CE;
if (MsgSendStretFlavor) {
// We have the method which returns a struct/union. Must also generate
@@ -3816,7 +3817,7 @@
BlkExprs.push_back(*I);
}
CallExpr *CE = CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(),
- VK_RValue, SourceLocation());
+ VK_RValue, SourceLocation(), FPOptions());
return CE;
}
@@ -4526,7 +4527,7 @@
InitExprs.push_back(FlagExp);
}
NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
- SourceLocation());
+ SourceLocation(), FPOptions());
NewRep = new (Context) UnaryOperator(
NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue,
OK_Ordinary, SourceLocation(), false);
Index: clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
===================================================================
--- clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -2109,7 +2109,8 @@
const auto *FT = msgSendType->castAs<FunctionType>();
CallExpr *Exp = CallExpr::Create(
- *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc);
+ *Context, ICE, Args, FT->getCallResultType(*Context), VK_RValue, EndLoc,
+ FPOptions());
return Exp;
}
@@ -2690,7 +2691,7 @@
auto *FT = msgSendType->castAs<FunctionType>();
CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, EndLoc);
+ VK_RValue, EndLoc, FPOptions());
ReplaceStmt(Exp, CE);
return CE;
}
@@ -2730,7 +2731,7 @@
InitExprs.push_back(Exp->getElement(i));
Expr *NSArrayCallExpr =
CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
- SourceLocation());
+ SourceLocation(), FPOptions());
FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
SourceLocation(),
@@ -2811,7 +2812,7 @@
const FunctionType *FT = msgSendType->castAs<FunctionType>();
CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, EndLoc);
+ VK_RValue, EndLoc, FPOptions());
ReplaceStmt(Exp, CE);
return CE;
}
@@ -2859,7 +2860,7 @@
// (const id [])objects
Expr *NSValueCallExpr =
CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
- SourceLocation());
+ SourceLocation(), FPOptions());
FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
SourceLocation(),
@@ -2878,7 +2879,8 @@
DictLiteralValueME);
// (const id <NSCopying> [])keys
Expr *NSKeyCallExpr = CallExpr::Create(
- *Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue, SourceLocation());
+ *Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue, SourceLocation(),
+ FPOptions());
MemberExpr *DictLiteralKeyME =
MemberExpr::CreateImplicit(*Context, NSKeyCallExpr, false, ARRFD,
@@ -2962,7 +2964,7 @@
const FunctionType *FT = msgSendType->castAs<FunctionType>();
CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, EndLoc);
+ VK_RValue, EndLoc, FPOptions());
ReplaceStmt(Exp, CE);
return CE;
}
@@ -3174,7 +3176,7 @@
DeclRefExpr *DRE = new (Context)
DeclRefExpr(*Context, FD, false, castType, VK_RValue, SourceLocation());
CallExpr *STCE = CallExpr::Create(*Context, DRE, MsgExprs, castType,
- VK_LValue, SourceLocation());
+ VK_LValue, SourceLocation(), FPOptions());
FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
SourceLocation(),
@@ -3275,7 +3277,7 @@
DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
VK_LValue, SourceLocation());
SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
- VK_LValue, SourceLocation());
+ VK_LValue, SourceLocation(), FPOptions());
// The code for super is a little tricky to prevent collision with
// the structure definition in the header. The rewriter has it's own
// internal definition (__rw_objc_super) that is uses. This is why
@@ -3370,7 +3372,7 @@
DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType,
VK_LValue, SourceLocation());
SuperRep = CallExpr::Create(*Context, DRE, InitExprs, superType,
- VK_LValue, SourceLocation());
+ VK_LValue, SourceLocation(), FPOptions());
// The code for super is a little tricky to prevent collision with
// the structure definition in the header. The rewriter has it's own
// internal definition (__rw_objc_super) that is uses. This is why
@@ -3535,7 +3537,7 @@
const FunctionType *FT = msgSendType->castAs<FunctionType>();
CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
- VK_RValue, EndLoc);
+ VK_RValue, EndLoc, FPOptions());
Stmt *ReplacingStmt = CE;
if (MsgSendStretFlavor) {
// We have the method which returns a struct/union. Must also generate
@@ -4646,7 +4648,7 @@
BlkExprs.push_back(*I);
}
CallExpr *CE = CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(),
- VK_RValue, SourceLocation());
+ VK_RValue, SourceLocation(), FPOptions());
return CE;
}
@@ -5388,7 +5390,7 @@
InitExprs.push_back(FlagExp);
}
NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
- SourceLocation());
+ SourceLocation(), FPOptions());
if (GlobalBlockExpr) {
assert (!GlobalConstructionExp &&
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
@@ -91,6 +91,7 @@
Value *RHS;
QualType Ty; // Computation Type.
BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
+ bool HasFPFeatures;
FPOptions FPFeatures;
const Expr *E; // Entire expr, for error unsupported. May not be binop.
@@ -777,11 +778,11 @@
Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
BinOpInfo EmitBinOps(const BinaryOperator *E);
- LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
+ 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.
@@ -789,7 +790,7 @@
Value *VisitBin ## OP(const BinaryOperator *E) { \
return Emit ## OP(EmitBinOps(E)); \
} \
- Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
+ Value *VisitBin ## OP ## Assign(const BinaryOperator *E) { \
return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
}
HANDLEBINOP(Mul)
@@ -2897,13 +2898,17 @@
Result.RHS = Visit(E->getRHS());
Result.Ty = E->getType();
Result.Opcode = E->getOpcode();
- Result.FPFeatures = E->getFPFeatures();
+ Result.HasFPFeatures = E->HasFPFeatures();
+ if (Result.HasFPFeatures)
+ Result.FPFeatures = E->getFPFeatures();
+ else
+ Result.FPFeatures = FPOptions(CGF.getLangOpts());
Result.E = E;
return Result;
}
LValue ScalarExprEmitter::EmitCompoundAssignLValue(
- const CompoundAssignOperator *E,
+ const BinaryOperator *E,
Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
Value *&Result) {
QualType LHSTy = E->getLHS()->getType();
@@ -2917,7 +2922,11 @@
OpInfo.RHS = Visit(E->getRHS());
OpInfo.Ty = E->getComputationResultType();
OpInfo.Opcode = E->getOpcode();
- OpInfo.FPFeatures = E->getFPFeatures();
+ OpInfo.HasFPFeatures = E->HasFPFeatures();
+ if (OpInfo.HasFPFeatures)
+ OpInfo.FPFeatures = E->getFPFeatures();
+ else
+ OpInfo.FPFeatures = FPOptions(CGF.getLangOpts());
OpInfo.E = E;
// Load/convert the LHS.
LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
@@ -3032,7 +3041,7 @@
return LHSLV;
}
-Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
+Value *ScalarExprEmitter::EmitCompoundAssign(const BinaryOperator *E,
Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
bool Ignore = TestAndClearIgnoreResultAssign();
Value *RHS = nullptr;
@@ -4625,7 +4634,7 @@
LValue CodeGenFunction::EmitCompoundAssignmentLValue(
- const CompoundAssignOperator *E) {
+ 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,11 +251,11 @@
};
BinOpInfo EmitBinOps(const BinaryOperator *E);
- LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
+ LValue EmitCompoundAssignLValue(const BinaryOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)
(const BinOpInfo &),
RValue &Val);
- ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
+ ComplexPairTy EmitCompoundAssign(const BinaryOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)
(const BinOpInfo &));
@@ -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);
}
@@ -886,7 +886,7 @@
LValue ComplexExprEmitter::
-EmitCompoundAssignLValue(const CompoundAssignOperator *E,
+EmitCompoundAssignLValue(const BinaryOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
RValue &Val) {
TestAndClearIgnoreReal();
@@ -956,7 +956,7 @@
// Compound assignments.
ComplexPairTy ComplexExprEmitter::
-EmitCompoundAssign(const CompoundAssignOperator *E,
+EmitCompoundAssign(const BinaryOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
RValue Val;
LValue LV = EmitCompoundAssignLValue(E, Func, Val);
@@ -1161,14 +1161,14 @@
}
LValue CodeGenFunction::
-EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
+EmitComplexCompoundAssignmentLValue(const BinaryOperator *E) {
CompoundFunc Op = getComplexOp(E->getOpcode());
RValue Val;
return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
}
LValue CodeGenFunction::
-EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
+EmitScalarCompoundAssignWithComplex(const BinaryOperator *E,
llvm::Value *&Result) {
CompoundFunc Op = getComplexOp(E->getOpcode());
RValue Val;
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -1272,15 +1272,18 @@
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));
- }
+ {
+ auto 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:
case Expr::CXXOperatorCallExprClass:
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/BodyFarm.cpp
===================================================================
--- clang/lib/Analysis/BodyFarm.cpp
+++ clang/lib/Analysis/BodyFarm.cpp
@@ -114,7 +114,8 @@
BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
QualType Ty) {
- return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
+ return BinaryOperator::Create(C, const_cast<Expr*>(LHS),
+ const_cast<Expr*>(RHS),
BO_Assign, Ty, VK_RValue,
OK_Ordinary, SourceLocation(), FPOptions());
}
@@ -123,7 +124,7 @@
BinaryOperator::Opcode Op) {
assert(BinaryOperator::isLogicalOp(Op) ||
BinaryOperator::isComparisonOp(Op));
- return new (C) BinaryOperator(const_cast<Expr*>(LHS),
+ return BinaryOperator::Create(C, const_cast<Expr*>(LHS),
const_cast<Expr*>(RHS),
Op,
C.getLogicalOperationType(),
@@ -269,7 +270,7 @@
}
return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
- SourceLocation());
+ SourceLocation(), FPOptions());
}
static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
@@ -514,7 +515,7 @@
/*Args=*/None,
/*QualType=*/C.VoidTy,
/*ExprValueType=*/VK_RValue,
- /*SourceLocation=*/SourceLocation());
+ /*SourceLocation=*/SourceLocation(), FPOptions());
// (2) Create the assignment to the predicate.
Expr *DoneValue =
@@ -579,7 +580,8 @@
DeclRefExpr *DR = M.makeDeclRefExpr(PV);
ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
CallExpr *CE =
- CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation());
+ CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation(),
+ FPOptions());
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
@@ -1228,11 +1228,6 @@
ID.AddInteger(S->getOpcode());
}
-void
-StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
- VisitBinaryOperator(S);
-}
-
void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
VisitExpr(S);
}
@@ -1501,35 +1496,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;
@@ -1541,11 +1536,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;
@@ -1632,8 +1627,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
@@ -4127,7 +4127,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
@@ -7480,7 +7480,6 @@
return VisitUnaryPreIncDec(UO);
}
bool VisitBinAssign(const BinaryOperator *BO);
- bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
bool VisitCastExpr(const CastExpr *E) {
switch (E->getCastKind()) {
@@ -7781,32 +7780,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;
@@ -14155,7 +14150,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
@@ -295,7 +295,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
@@ -528,14 +528,11 @@
FPOptions FPFeatures,
ADLCallKind UsesADL)
: CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
- OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
+ OperatorLoc, FPFeatures, /*MinNumArgs=*/0, UsesADL) {
CXXOperatorCallExprBits.OperatorKind = OpKind;
- CXXOperatorCallExprBits.FPFeatures = FPFeatures.getInt();
assert(
(CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
"OperatorKind overflow!");
- assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
- "FPFeatures overflow!");
Range = getSourceRangeImpl();
}
@@ -595,7 +592,7 @@
QualType Ty, ExprValueKind VK,
SourceLocation RP, unsigned MinNumArgs)
: CallExpr(CXXMemberCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK, RP,
- MinNumArgs, NotADL) {}
+ FPOptions(), MinNumArgs, NotADL) {}
CXXMemberCallExpr::CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty)
: CallExpr(CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
@@ -834,7 +831,7 @@
SourceLocation LitEndLoc,
SourceLocation SuffixLoc)
: CallExpr(UserDefinedLiteralClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
- LitEndLoc, /*MinNumArgs=*/0, NotADL),
+ LitEndLoc, FPOptions(), /*MinNumArgs=*/0, NotADL),
UDSuffixLoc(SuffixLoc) {}
UserDefinedLiteral::UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty)
@@ -1611,7 +1608,7 @@
ExprValueKind VK, SourceLocation RP,
unsigned MinNumArgs)
: CallExpr(CUDAKernelCallExprClass, Fn, /*PreArgs=*/Config, Args, Ty, VK,
- RP, MinNumArgs, NotADL) {}
+ RP, FPOptions(), MinNumArgs, NotADL) {}
CUDAKernelCallExpr::CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty)
: CallExpr(CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1221,11 +1221,13 @@
CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation RParenLoc, unsigned MinNumArgs,
+ SourceLocation RParenLoc, FPOptions FP_Features,
+ unsigned MinNumArgs,
ADLCallKind UsesADL)
: Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) {
NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
unsigned NumPreArgs = PreArgs.size();
+ FPFeatures = FP_Features;
CallExprBits.NumPreArgs = NumPreArgs;
assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
@@ -1261,7 +1263,8 @@
CallExpr *CallExpr::Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation RParenLoc, unsigned MinNumArgs,
+ SourceLocation RParenLoc, FPOptions FP_Features,
+ unsigned MinNumArgs,
ADLCallKind UsesADL) {
unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
unsigned SizeOfTrailingObjects =
@@ -1269,7 +1272,7 @@
void *Mem =
Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
- RParenLoc, MinNumArgs, UsesADL);
+ RParenLoc, FP_Features, MinNumArgs, UsesADL);
}
CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
@@ -1278,7 +1281,7 @@
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);
+ VK, RParenLoc, FPOptions(), /*MinNumArgs=*/0, UsesADL);
}
CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
@@ -2283,7 +2286,6 @@
R2 = BO->getRHS()->getSourceRange();
return true;
}
- case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
return false;
@@ -3293,7 +3295,6 @@
case MSPropertyRefExprClass:
case MSPropertySubscriptExprClass:
- case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
case CXXThrowExprClass:
@@ -4263,6 +4264,45 @@
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) {
+ bool hasFPFeatures = FPFeatures.hasPragmaFPFeatures();
+ unsigned SizeOfTrailingObjects =
+ BinaryOperator::sizeOfTrailingObjects(hasFPFeatures, 0);
+ void *Mem = C.Allocate(sizeof(BinaryOperator) + SizeOfTrailingObjects,
+ alignof(BinaryOperator));
+ return new (Mem) BinaryOperator(lhs, rhs, opc, ResTy, VK, OK,
+ opLoc, FPFeatures);
+}
+
+BinaryOperator *
+BinaryOperator::Create(const ASTContext &C,
+ Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK,
+ QualType CompLHSType, QualType CompResultType,
+ SourceLocation opLoc, FPOptions FPFeatures){
+ bool hasFPFeatures = FPFeatures.hasPragmaFPFeatures();
+ unsigned SizeOfTrailingObjects =
+ BinaryOperator::sizeOfTrailingObjects(hasFPFeatures, 1);
+ void *Mem = C.Allocate(sizeof(BinaryOperator) + SizeOfTrailingObjects,
+ alignof(BinaryOperator));
+ return new (Mem) BinaryOperator(lhs, rhs, opc, ResTy, VK, OK,
+ CompLHSType, CompResultType, opLoc, FPFeatures);
+}
+
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);
@@ -6685,12 +6684,26 @@
auto ToRHS = importChecked(Err, E->getRHS());
auto ToType = importChecked(Err, E->getType());
auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
+ auto HasFPFeatures = E->HasFPFeatures();
if (Err)
return std::move(Err);
- return new (Importer.getToContext()) BinaryOperator(
+ 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(), ToComputationLHSType, ToComputationResultType,
+ ToOperatorLoc,
+ HasFPFeatures ? E->getFPFeatures() : FPOptions());
+ }
+ return BinaryOperator::Create(Importer.getToContext(),
ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
- E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
+ E->getObjectKind(), ToOperatorLoc,
+ HasFPFeatures ? E->getFPFeatures() : FPOptions());
}
ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
@@ -6785,25 +6798,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;
@@ -7555,8 +7549,8 @@
}
return CallExpr::Create(Importer.getToContext(), ToCallee, ToArgs, ToType,
- E->getValueKind(), ToRParenLoc, /*MinNumArgs=*/0,
- E->getADLCallKind());
+ E->getValueKind(), ToRParenLoc, FPOptions(),
+ /*MinNumArgs=*/0, E->getADLCallKind());
}
ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -1556,9 +1556,6 @@
/// A BinaryOperator record.
EXPR_BINARY_OPERATOR,
- /// A CompoundAssignOperator record.
- EXPR_COMPOUND_ASSIGN_OPERATOR,
-
/// A ConditionOperator record.
EXPR_CONDITIONAL_OPERATOR,
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
@@ -359,7 +359,8 @@
FPOptions() : fp_contract(LangOptions::FPC_Off),
fenv_access(LangOptions::FEA_Off),
rounding(LangOptions::FPR_ToNearest),
- exceptions(LangOptions::FPE_Ignore)
+ exceptions(LangOptions::FPE_Ignore),
+ has_pragma_features(0)
{}
// Used for serializing.
@@ -367,17 +368,25 @@
: fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)),
fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1)),
rounding(static_cast<LangOptions::FPRoundingModeKind>((I >> 3) & 7)),
- exceptions(static_cast<LangOptions::FPExceptionModeKind>((I >> 6) & 3))
+ exceptions(static_cast<LangOptions::FPExceptionModeKind>((I >> 6) & 3)),
+ has_pragma_features((I >> 7) & 1)
{}
explicit FPOptions(const LangOptions &LangOpts)
: fp_contract(LangOpts.getDefaultFPContractMode()),
fenv_access(LangOptions::FEA_Off),
rounding(LangOptions::FPR_ToNearest),
- exceptions(LangOptions::FPE_Ignore)
+ exceptions(LangOptions::FPE_Ignore),
+ has_pragma_features(0)
{}
// FIXME: Use getDefaultFEnvAccessMode() when available.
+ bool hasPragmaFPFeatures() const { return has_pragma_features;; }
+ void setHasPragmaFPFeatures(bool B = true) {
+ has_pragma_features = B;
+ }
+
+
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
}
@@ -431,7 +440,8 @@
/// Used to serialize this.
unsigned getInt() const {
return fp_contract | (fenv_access << 2) | (rounding << 3)
- | (exceptions << 6);
+ | (exceptions << 6)
+ | (has_pragma_features << 7);
}
private:
@@ -442,6 +452,7 @@
unsigned fenv_access : 1;
unsigned rounding : 3;
unsigned exceptions : 2;
+ unsigned has_pragma_features : 1;
};
/// Describes the kind of translation unit being processed.
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)) {
@@ -142,8 +142,8 @@
// 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); \
+ 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;
};
@@ -606,9 +602,6 @@
/// The kind of this overloaded operator. One of the enumerator
/// value of OverloadedOperatorKind.
unsigned OperatorKind : 6;
-
- // Only meaningful for floating point types.
- unsigned FPFeatures : 8;
};
class CXXRewrittenBinaryOperatorBitfields {
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -425,9 +425,10 @@
// classes in themselves (they're all opcodes in
// CompoundAssignOperator) but do have visitors.
#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+ GENERAL_BINOP_FALLBACK(NAME##Assign, BinaryOperator)
CAO_LIST()
+
#undef OPERATOR
#undef GENERAL_BINOP_FALLBACK
@@ -567,7 +568,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
@@ -2676,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/ExprCXX.h
===================================================================
--- clang/include/clang/AST/ExprCXX.h
+++ clang/include/clang/AST/ExprCXX.h
@@ -166,16 +166,16 @@
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
void setFPFeatures(FPOptions F) {
- CXXOperatorCallExprBits.FPFeatures = F.getInt();
+ FPFeatures = F;
}
FPOptions getFPFeatures() const {
- return FPOptions(CXXOperatorCallExprBits.FPFeatures);
+ return FPFeatures;
}
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement() const {
- return getFPFeatures().allowFPContractWithinStatement();
+ return FPFeatures.allowFPContractWithinStatement();
}
};
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -2567,12 +2567,15 @@
static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
+ FPOptions FPFeatures;
+
protected:
/// Build a call expression, assuming that appropriate storage has been
/// allocated for the trailing objects.
CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+ SourceLocation RParenLoc, FPOptions FP_Features,
+ unsigned MinNumArgs, ADLCallKind UsesADL);
/// Build an empty call expression, for deserialization.
CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
@@ -2614,7 +2617,8 @@
/// expression on the stack.
static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation RParenLoc, unsigned MinNumArgs = 0,
+ SourceLocation RParenLoc, FPOptions FP_Features,
+ unsigned MinNumArgs = 0,
ADLCallKind UsesADL = NotADL);
/// Create a temporary call expression with no arguments in the memory
@@ -2658,6 +2662,21 @@
return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
}
+ // Set the FPFeatures status of this CallExpr. Only meaningful for
+ // operations on floating point types. e.g. intrinsics
+ void setFPFeatures(FPOptions F) {
+ FPFeatures = F;
+ }
+ FPOptions getFPFeatures() const {
+ return FPFeatures;
+ }
+
+ // Get the FP contractability status of this CallExpr. Only meaningful for
+ // operations on floating point types. e.g. intrinsics
+ bool isFPContractableWithinStatement() const {
+ return FPFeatures.allowFPContractWithinStatement();
+ }
+
/// getNumArgs - Return the number of actual arguments to this call.
unsigned getNumArgs() const { return NumArgs; }
@@ -3394,9 +3413,24 @@
/// 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, unsigned, QualType> {
enum { LHS, RHS, END_EXPR };
Stmt *SubExprs[END_EXPR];
+ bool hasFPFeatures;
+ bool isCompoundAssign;
+
+ /// 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<unsigned>) const {
+ return hasFPFeatures ? 1 : 0; }
+ unsigned numTrailingObjects(OverloadToken<QualType>) const {
+ return isCompoundAssign ? 2 : 0; }
public:
typedef BinaryOperatorKind Opcode;
@@ -3406,18 +3440,37 @@
FPOptions FPFeatures)
: Expr(BinaryOperatorClass, ResTy, VK, OK) {
BinaryOperatorBits.Opc = opc;
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
BinaryOperatorBits.OpLoc = opLoc;
+ hasFPFeatures = FPFeatures.hasPragmaFPFeatures();
+ isCompoundAssign = 0;
+ if (hasFPFeatures) {
+ *getTrailingObjects<unsigned>() = FPFeatures.getInt();
+ }
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
- "Use CompoundAssignOperator for compound assignments");
+ "Use BinaryOperator for compound assignments");
setDependence(computeDependence(this));
}
-
- /// Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
- BinaryOperatorBits.Opc = BO_Comma;
+ BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK,
+ QualType CompLHSType, QualType CompResultType,
+ SourceLocation opLoc, FPOptions FPFeatures)
+ : Expr(BinaryOperatorClass, ResTy, VK, OK) {
+ BinaryOperatorBits.Opc = opc;
+ BinaryOperatorBits.OpLoc = opLoc;
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ hasFPFeatures = FPFeatures.hasPragmaFPFeatures();
+ isCompoundAssign = 1;
+ if (hasFPFeatures) {
+ *getTrailingObjects<unsigned>() = FPFeatures.getInt();
+ }
+ assert(isCompoundAssignmentOp() &&
+ "Expected CompoundAssignOperator for compound assignments");
+ setComputationLHSType(CompLHSType);
+ setComputationResultType(CompResultType);
+ setDependence(computeDependence(this));
}
SourceLocation getExprLoc() const { return getOperatorLoc(); }
@@ -3548,8 +3601,7 @@
Expr *LHS, Expr *RHS);
static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstBinaryOperatorConstant &&
- S->getStmtClass() <= lastBinaryOperatorConstant;
+ return S->getStmtClass() == BinaryOperatorClass;
}
// Iterators
@@ -3563,11 +3615,49 @@
// 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<unsigned>() = 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);
+ static BinaryOperator *Create(const ASTContext &C,
+ Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK,
+ QualType CompLHSType, QualType CompResultType,
+ SourceLocation opLoc, FPOptions FPFeatures);
+
+ unsigned getFPFeat() const {
+ assert(HasFPFeatures());
+ return *getTrailingObjects<unsigned>();
+ }
+ unsigned getFPFeat() {
+ assert(HasFPFeatures());
+ return *getTrailingObjects<unsigned>();
}
+ void setIsCompoundAssign(bool B) {
+ isCompoundAssign = B;
+ }
+ bool IsCompoundAssign() const {
+ return isCompoundAssign;
+ }
+
+ void setHasFPFeatures(bool B) {
+ hasFPFeatures = B;
+ }
+ bool HasFPFeatures() const {
+ return hasFPFeatures;
+ }
FPOptions getFPFeatures() const {
- return FPOptions(BinaryOperatorBits.FPFeatures);
+ assert(HasFPFeatures());
+ return FPOptions(*getTrailingObjects<unsigned>());
}
// Get the FP contractability status of this operator. Only meaningful for
@@ -3580,62 +3670,37 @@
// operations on floating point types.
bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
+ QualType getComputationLHSType() const {
+ return getTrailingObjects<QualType>()[0];
+ }
+ void setComputationLHSType(QualType T) {
+ getTrailingObjects<QualType>()[0] = T;
+ }
+ QualType getComputationResultType() const {
+ return getTrailingObjects<QualType>()[1];
+ }
+ void setComputationResultType(QualType T) {
+ 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