anemet created this revision.
Sema holds the current FPOptions which is adjusted by 'pragma STDC
FP_CONTRACT'. This then gets propagated into expression nodes as they are
built.
This encapsulates FPOptions so that this propagation happens opaquely rather
than directly with the fp_contractable on/off bit. This allows controlled
transitioning of fp_contractable to a ternary value (off, on, fast). It will
also allow adding more fast-math flags later.
This is toward moving fp-contraction=fast from an LLVM TargetOption to a
FastMathFlag in order to fix PR25721.
https://reviews.llvm.org/D31166
Files:
include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
include/clang/Basic/LangOptions.h
include/clang/Sema/Sema.h
lib/AST/ASTImporter.cpp
lib/Analysis/BodyFarm.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CGStmtOpenMP.cpp
lib/Frontend/Rewrite/RewriteModernObjC.cpp
lib/Frontend/Rewrite/RewriteObjC.cpp
lib/Sema/SemaAttr.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaPseudoObject.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriter.cpp
lib/Serialization/ASTWriterStmt.cpp
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -650,7 +650,7 @@
Record.AddStmt(E->getRHS());
Record.push_back(E->getOpcode()); // FIXME: stable encoding
Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->isFPContractable());
+ Record.push_back(E->getFPFeatures().getInt());
Code = serialization::EXPR_BINARY_OPERATOR;
}
@@ -1218,7 +1218,7 @@
VisitCallExpr(E);
Record.push_back(E->getOperator());
Record.AddSourceRange(E->Range);
- Record.push_back(E->isFPContractable());
+ Record.push_back(E->getFPFeatures().getInt());
Code = serialization::EXPR_CXX_OPERATOR_CALL;
}
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3975,7 +3975,7 @@
/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) {
- RecordData::value_type Record[] = {Opts.fp_contract};
+ RecordData::value_type Record[] = {Opts.getInt()};
Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
}
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -670,7 +670,7 @@
E->setRHS(Record.readSubExpr());
E->setOpcode((BinaryOperator::Opcode)Record.readInt());
E->setOperatorLoc(ReadSourceLocation());
- E->setFPContractable((bool)Record.readInt());
+ E->setFPFeatures(FPOptions(Record.readInt()));
}
void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
@@ -1225,7 +1225,7 @@
VisitCallExpr(E);
E->Operator = (OverloadedOperatorKind)Record.readInt();
E->Range = Record.readSourceRange();
- E->setFPContractable((bool)Record.readInt());
+ E->setFPFeatures(FPOptions(Record.readInt()));
}
void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -7215,7 +7215,7 @@
// FIXME: What happens if these are changed by a module import?
if (!FPPragmaOptions.empty()) {
assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
- SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
+ SemaObj->FPFeatures = FPOptions(FPPragmaOptions[0]);
}
SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -9146,7 +9146,7 @@
return E;
Sema::FPContractStateRAII FPContractState(getSema());
- getSema().FPFeatures.fp_contract = E->isFPContractable();
+ getSema().FPFeatures = E->getFPFeatures();
return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
LHS.get(), RHS.get());
@@ -9626,7 +9626,7 @@
return SemaRef.MaybeBindToTemporary(E);
Sema::FPContractStateRAII FPContractState(getSema());
- getSema().FPFeatures.fp_contract = E->isFPContractable();
+ getSema().FPFeatures = E->getFPFeatures();
return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
E->getOperatorLoc(),
Index: lib/Sema/SemaPseudoObject.cpp
===================================================================
--- lib/Sema/SemaPseudoObject.cpp
+++ lib/Sema/SemaPseudoObject.cpp
@@ -447,7 +447,8 @@
syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
opcode, capturedRHS->getType(),
capturedRHS->getValueKind(),
- OK_Ordinary, opcLoc, false);
+ OK_Ordinary, opcLoc,
+ FPOptions());
} else {
ExprResult opLHS = buildGet();
if (opLHS.isInvalid()) return ExprError();
@@ -465,7 +466,7 @@
OK_Ordinary,
opLHS.get()->getType(),
result.get()->getType(),
- opcLoc, false);
+ opcLoc, FPOptions());
}
// The result of the assignment, if not void, is the value set into
@@ -1587,7 +1588,8 @@
// 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, false);
+ VK_RValue, OK_Ordinary, opcLoc,
+ FPOptions());
// Filter out non-overload placeholder types in the RHS.
if (RHS->getType()->isNonOverloadPlaceholderType()) {
@@ -1652,14 +1654,15 @@
cop->getObjectKind(),
cop->getComputationLHSType(),
cop->getComputationResultType(),
- cop->getOperatorLoc(), false);
+ cop->getOperatorLoc(),
+ FPOptions());
} else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
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(), false);
+ bop->getOperatorLoc(), FPOptions());
} else {
assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -11963,7 +11963,7 @@
Fns.begin(), Fns.end());
return new (Context)
CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
- VK_RValue, OpLoc, false);
+ VK_RValue, OpLoc, FPOptions());
}
// Build an empty overload set.
@@ -12033,7 +12033,7 @@
Args[0] = Input;
CallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray,
- ResultTy, VK, OpLoc, false);
+ ResultTy, VK, OpLoc, FPOptions());
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
return ExprError();
@@ -12131,12 +12131,12 @@
if (Opc <= BO_Assign || Opc > BO_OrAssign)
return new (Context) BinaryOperator(
Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
- OpLoc, FPFeatures.fp_contract);
+ OpLoc, FPFeatures);
return new (Context) CompoundAssignOperator(
Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
Context.DependentTy, Context.DependentTy, OpLoc,
- FPFeatures.fp_contract);
+ FPFeatures);
}
// FIXME: save results of ADL from here?
@@ -12150,7 +12150,7 @@
Fns.begin(), Fns.end());
return new (Context)
CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
- VK_RValue, OpLoc, FPFeatures.fp_contract);
+ VK_RValue, OpLoc, FPFeatures);
}
// Always do placeholder-like conversions on the RHS.
@@ -12265,7 +12265,7 @@
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),
Args, ResultTy, VK, OpLoc,
- FPFeatures.fp_contract);
+ FPFeatures);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,
FnDecl))
@@ -12413,7 +12413,7 @@
return new (Context)
CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
- Context.DependentTy, VK_RValue, RLoc, false);
+ Context.DependentTy, VK_RValue, RLoc, FPOptions());
}
// Handle placeholders on both operands.
@@ -12489,7 +12489,7 @@
new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
FnExpr.get(), Args,
ResultTy, VK, RLoc,
- false);
+ FPOptions());
if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
return ExprError();
@@ -13052,7 +13052,7 @@
CXXOperatorCallExpr *TheCall = new (Context)
CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy,
- VK, RParenLoc, false);
+ VK, RParenLoc, FPOptions());
if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
return true;
@@ -13232,7 +13232,7 @@
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
- Base, ResultTy, VK, OpLoc, false);
+ Base, ResultTy, VK, OpLoc, FPOptions());
if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
return ExprError();
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -6177,7 +6177,7 @@
return E;
return new (Context) BinaryOperator(
BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
- BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable());
+ BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures());
}
}
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -11240,15 +11240,15 @@
if (CompResultTy.isNull())
return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
- OK, OpLoc, FPFeatures.fp_contract);
+ OK, OpLoc, FPFeatures);
if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
OK_ObjCProperty) {
VK = VK_LValue;
OK = LHS.get()->getObjectKind();
}
return new (Context) CompoundAssignOperator(
LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
- OpLoc, FPFeatures.fp_contract);
+ OpLoc, FPFeatures);
}
/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -11111,7 +11111,7 @@
= new (S.Context) BinaryOperator(IterationVarRefRVal.build(S, Loc),
IntegerLiteral::Create(S.Context, Upper, SizeType, Loc),
BO_NE, S.Context.BoolTy,
- VK_RValue, OK_Ordinary, Loc, false);
+ VK_RValue, OK_Ordinary, Loc, FPOptions());
// Create the pre-increment of the iteration variable.
Expr *Increment
Index: lib/Sema/SemaAttr.cpp
===================================================================
--- lib/Sema/SemaAttr.cpp
+++ lib/Sema/SemaAttr.cpp
@@ -450,13 +450,13 @@
void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
switch (OOS) {
case tok::OOS_ON:
- FPFeatures.fp_contract = 1;
+ FPFeatures.setFPContractable(true);
break;
case tok::OOS_OFF:
- FPFeatures.fp_contract = 0;
+ FPFeatures.setFPContractable(false);
break;
case tok::OOS_DEFAULT:
- FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
+ FPFeatures.setFPContractable(getLangOpts().DefaultFPContract);
break;
}
}
Index: lib/Frontend/Rewrite/RewriteObjC.cpp
===================================================================
--- lib/Frontend/Rewrite/RewriteObjC.cpp
+++ lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2992,7 +2992,7 @@
BinaryOperator *lessThanExpr =
new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
VK_RValue, OK_Ordinary, SourceLocation(),
- false);
+ FPOptions());
// (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
ConditionalOperator *CondExpr =
new (Context) ConditionalOperator(lessThanExpr,
Index: lib/Frontend/Rewrite/RewriteModernObjC.cpp
===================================================================
--- lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -7500,7 +7500,7 @@
BinaryOperator *addExpr =
new (Context) BinaryOperator(castExpr, DRE, BO_Add,
Context->getPointerType(Context->CharTy),
- VK_RValue, OK_Ordinary, SourceLocation(), false);
+ VK_RValue, OK_Ordinary, SourceLocation(), FPOptions());
// Don't forget the parens to enforce the proper binding.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
SourceLocation(),
Index: lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- lib/CodeGen/CGStmtOpenMP.cpp
+++ lib/CodeGen/CGStmtOpenMP.cpp
@@ -2346,8 +2346,7 @@
CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
// Generate condition for loop.
BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
- OK_Ordinary, S.getLocStart(),
- /*fpContractable=*/false);
+ OK_Ordinary, S.getLocStart(), FPOptions());
// Increment for loop counter.
UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
S.getLocStart());
Index: lib/CodeGen/CGObjC.cpp
===================================================================
--- lib/CodeGen/CGObjC.cpp
+++ lib/CodeGen/CGObjC.cpp
@@ -1316,7 +1316,7 @@
BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
ivarRef.getType(), VK_RValue, OK_Ordinary,
- SourceLocation(), false);
+ SourceLocation(), FPOptions());
EmitStmt(&assign);
}
@@ -3263,7 +3263,7 @@
CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
Args, DestTy->getPointeeType(),
- VK_LValue, SourceLocation(), false);
+ VK_LValue, SourceLocation(), FPOptions());
EmitStmt(&TheCall);
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -49,7 +49,7 @@
Value *RHS;
QualType Ty; // Computation Type.
BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
- bool FPContractable;
+ FPOptions FPFeatures;
const Expr *E; // Entire expr, for error unsupported. May not be binop.
};
@@ -1709,7 +1709,7 @@
BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
BinOp.Ty = E->getType();
BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
- BinOp.FPContractable = false;
+ // FIXME: once UnaryOperator carries FPFeatures, copy it here.
BinOp.E = E;
return BinOp;
}
@@ -1975,7 +1975,7 @@
BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
BinOp.Ty = E->getType();
BinOp.Opcode = BO_Sub;
- BinOp.FPContractable = false;
+ // FIXME: once UnaryOperator carries FPFeatures, copy it here.
BinOp.E = E;
return EmitSub(BinOp);
}
@@ -2196,7 +2196,7 @@
Result.RHS = Visit(E->getRHS());
Result.Ty = E->getType();
Result.Opcode = E->getOpcode();
- Result.FPContractable = E->isFPContractable();
+ Result.FPFeatures = E->getFPFeatures();
Result.E = E;
return Result;
}
@@ -2216,7 +2216,7 @@
OpInfo.RHS = Visit(E->getRHS());
OpInfo.Ty = E->getComputationResultType();
OpInfo.Opcode = E->getOpcode();
- OpInfo.FPContractable = E->isFPContractable();
+ OpInfo.FPFeatures = E->getFPFeatures();
OpInfo.E = E;
// Load/convert the LHS.
LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
@@ -2663,7 +2663,7 @@
"Only fadd/fsub can be the root of an fmuladd.");
// Check whether this op is marked as fusable.
- if (!op.FPContractable)
+ if (!op.FPFeatures.isFPContractable())
return nullptr;
// Check whether -ffp-contract=on. (If -ffp-contract=off/fast, fusing is
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -87,7 +87,7 @@
QualType Ty) {
return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
BO_Assign, Ty, VK_RValue,
- OK_Ordinary, SourceLocation(), false);
+ OK_Ordinary, SourceLocation(), FPOptions());
}
BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
@@ -99,7 +99,7 @@
Op,
C.getLogicalOperationType(),
VK_RValue,
- OK_Ordinary, SourceLocation(), false);
+ OK_Ordinary, SourceLocation(), FPOptions());
}
CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -6068,7 +6068,7 @@
T, E->getValueKind(),
E->getObjectKind(),
Importer.Import(E->getOperatorLoc()),
- E->isFPContractable());
+ E->getFPFeatures());
}
Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
@@ -6218,7 +6218,7 @@
E->getObjectKind(),
CompLHSType, CompResultType,
Importer.Import(E->getOperatorLoc()),
- E->isFPContractable());
+ E->getFPFeatures());
}
bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) {
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -1065,14 +1065,12 @@
/// statements.
class FPContractStateRAII {
public:
- FPContractStateRAII(Sema& S)
- : S(S), OldFPContractState(S.FPFeatures.fp_contract) {}
- ~FPContractStateRAII() {
- S.FPFeatures.fp_contract = OldFPContractState;
- }
+ FPContractStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.FPFeatures) {}
+ ~FPContractStateRAII() { S.FPFeatures = OldFPFeaturesState; }
+
private:
Sema& S;
- bool OldFPContractState : 1;
+ FPOptions OldFPFeaturesState;
};
void addImplicitTypedef(StringRef Name, QualType T);
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h
+++ include/clang/Basic/LangOptions.h
@@ -175,12 +175,22 @@
/// \brief Floating point control options
class FPOptions {
public:
- unsigned fp_contract : 1;
-
FPOptions() : fp_contract(0) {}
- FPOptions(const LangOptions &LangOpts) :
- fp_contract(LangOpts.DefaultFPContract) {}
+ explicit FPOptions(uint64_t I) : fp_contract(I) {}
+
+ FPOptions(const LangOptions &LangOpts)
+ : fp_contract(LangOpts.DefaultFPContract) {}
+
+ void setFPContractable(bool V) { fp_contract = V; }
+ bool isFPContractable() const { return fp_contract; }
+
+ /// Used to serialize this.
+ uint64_t getInt() const { return fp_contract; }
+
+private:
+ /// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
+ unsigned fp_contract : 1;
};
/// \brief Describes the kind of translation unit being processed.
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -54,18 +54,17 @@
OverloadedOperatorKind Operator;
SourceRange Range;
- // Record the FP_CONTRACT state that applies to this operator call. Only
- // meaningful for floating point types. For other types this value can be
+ // Only meaningful for floating point types. For other types this value can be
// set to false.
- unsigned FPContractable : 1;
+ FPOptions FPFeatures;
SourceRange getSourceRangeImpl() const LLVM_READONLY;
public:
CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, bool fpContractable)
+ SourceLocation operatorloc, FPOptions FPFeatures)
: CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
- Operator(Op), FPContractable(fpContractable) {
+ Operator(Op), FPFeatures(FPFeatures) {
Range = getSourceRangeImpl();
}
explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
@@ -113,11 +112,13 @@
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
+ void setFPFeatures(FPOptions F) { FPFeatures = F; }
+
+ FPOptions getFPFeatures() const { return FPFeatures; }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
+ bool isFPContractable() const { return FPFeatures.isFPContractable(); }
friend class ASTStmtReader;
friend class ASTStmtWriter;
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -2917,28 +2917,26 @@
private:
unsigned Opc : 6;
- // Records the FP_CONTRACT pragma status at the point that this binary
- // operator was parsed. This bit is only meaningful for operations on
- // floating point types. For all other types it should default to
- // false.
- unsigned FPContractable : 1;
+ // This is only meaningful for operations on floating point types and 0
+ // otherwise.
+ unsigned FPFeatures : 1;
SourceLocation OpLoc;
enum { LHS, RHS, END_EXPR };
Stmt* SubExprs[END_EXPR];
public:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable)
+ SourceLocation opLoc, FPOptions FPFeatures)
: Expr(BinaryOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+ Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
@@ -3073,24 +3071,28 @@
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
+ void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
+
+ FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
+ bool isFPContractable() const {
+ return FPOptions(FPFeatures).isFPContractable();
+ }
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable, bool dead2)
+ SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+ Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
}
@@ -3112,8 +3114,8 @@
CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
ExprValueKind VK, ExprObjectKind OK,
QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc, bool fpContractable)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
+ SourceLocation OpLoc, FPOptions FPFeatures)
+ : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
true),
ComputationLHSType(CompLHSType),
ComputationResultType(CompResultType) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits