forked from OSchip/llvm-project
[AST][FPEnv] Keep FP options in trailing storage of CastExpr
This change allow a CastExpr to have optional FPOptionsOverride object, stored in trailing storage. Of all cast nodes only ImplicitCastExpr, CStyleCastExpr, CXXFunctionalCastExpr and CXXStaticCastExpr are allowed to have FPOptions. Differential Revision: https://reviews.llvm.org/D85960
This commit is contained in:
parent
0680a3d56d
commit
6c8041aa0f
|
@ -3440,9 +3440,11 @@ class CastExpr : public Expr {
|
|||
}
|
||||
CXXBaseSpecifier **path_buffer();
|
||||
|
||||
friend class ASTStmtReader;
|
||||
|
||||
protected:
|
||||
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
|
||||
Expr *op, unsigned BasePathSize)
|
||||
Expr *op, unsigned BasePathSize, bool HasFPFeatures)
|
||||
: Expr(SC, ty, VK, OK_Ordinary), Op(op) {
|
||||
CastExprBits.Kind = kind;
|
||||
CastExprBits.PartOfExplicitCast = false;
|
||||
|
@ -3451,17 +3453,27 @@ protected:
|
|||
"BasePathSize overflow!");
|
||||
setDependence(computeDependence(this));
|
||||
assert(CastConsistency());
|
||||
CastExprBits.HasFPFeatures = HasFPFeatures;
|
||||
}
|
||||
|
||||
/// Construct an empty cast.
|
||||
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
|
||||
: Expr(SC, Empty) {
|
||||
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize,
|
||||
bool HasFPFeatures)
|
||||
: Expr(SC, Empty) {
|
||||
CastExprBits.PartOfExplicitCast = false;
|
||||
CastExprBits.BasePathSize = BasePathSize;
|
||||
CastExprBits.HasFPFeatures = HasFPFeatures;
|
||||
assert((CastExprBits.BasePathSize == BasePathSize) &&
|
||||
"BasePathSize overflow!");
|
||||
}
|
||||
|
||||
/// Return a pointer to the trailing FPOptions.
|
||||
/// \pre hasStoredFPFeatures() == true
|
||||
FPOptionsOverride *getTrailingFPFeatures();
|
||||
const FPOptionsOverride *getTrailingFPFeatures() const {
|
||||
return const_cast<CastExpr *>(this)->getTrailingFPFeatures();
|
||||
}
|
||||
|
||||
public:
|
||||
CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
|
||||
void setCastKind(CastKind K) { CastExprBits.Kind = K; }
|
||||
|
@ -3506,6 +3518,28 @@ public:
|
|||
return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
|
||||
}
|
||||
|
||||
bool hasStoredFPFeatures() const { return CastExprBits.HasFPFeatures; }
|
||||
|
||||
/// Get FPOptionsOverride from trailing storage.
|
||||
FPOptionsOverride getStoredFPFeatures() const {
|
||||
assert(hasStoredFPFeatures());
|
||||
return *getTrailingFPFeatures();
|
||||
}
|
||||
|
||||
// Get the FP features status of this operation. Only meaningful for
|
||||
// operations on floating point types.
|
||||
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
|
||||
if (hasStoredFPFeatures())
|
||||
return getStoredFPFeatures().applyOverrides(LO);
|
||||
return FPOptions::defaultWithoutTrailingStorage(LO);
|
||||
}
|
||||
|
||||
FPOptionsOverride getFPFeatures() const {
|
||||
if (hasStoredFPFeatures())
|
||||
return getStoredFPFeatures();
|
||||
return FPOptionsOverride();
|
||||
}
|
||||
|
||||
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
|
||||
QualType opType);
|
||||
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
|
||||
|
@ -3543,21 +3577,35 @@ public:
|
|||
/// @endcode
|
||||
class ImplicitCastExpr final
|
||||
: public CastExpr,
|
||||
private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
|
||||
private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *,
|
||||
FPOptionsOverride> {
|
||||
|
||||
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
|
||||
unsigned BasePathLength, ExprValueKind VK)
|
||||
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
|
||||
unsigned BasePathLength, FPOptionsOverride FPO,
|
||||
ExprValueKind VK)
|
||||
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength,
|
||||
FPO.requiresTrailingStorage()) {
|
||||
if (hasStoredFPFeatures())
|
||||
*getTrailingFPFeatures() = FPO;
|
||||
}
|
||||
|
||||
/// Construct an empty implicit cast.
|
||||
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
|
||||
: CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
|
||||
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: CastExpr(ImplicitCastExprClass, Shell, PathSize, HasFPFeatures) {}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
|
||||
return path_size();
|
||||
}
|
||||
|
||||
public:
|
||||
enum OnStack_t { OnStack };
|
||||
ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
|
||||
ExprValueKind VK)
|
||||
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
|
||||
ExprValueKind VK, FPOptionsOverride FPO)
|
||||
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0,
|
||||
FPO.requiresTrailingStorage()) {
|
||||
if (hasStoredFPFeatures())
|
||||
*getTrailingFPFeatures() = FPO;
|
||||
}
|
||||
|
||||
bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; }
|
||||
|
@ -3568,10 +3616,10 @@ public:
|
|||
static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
|
||||
CastKind Kind, Expr *Operand,
|
||||
const CXXCastPath *BasePath,
|
||||
ExprValueKind Cat);
|
||||
ExprValueKind Cat, FPOptionsOverride FPO);
|
||||
|
||||
static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
|
||||
unsigned PathSize);
|
||||
unsigned PathSize, bool HasFPFeatures);
|
||||
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getSubExpr()->getBeginLoc();
|
||||
|
@ -3612,12 +3660,14 @@ class ExplicitCastExpr : public CastExpr {
|
|||
protected:
|
||||
ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
|
||||
CastKind kind, Expr *op, unsigned PathSize,
|
||||
TypeSourceInfo *writtenTy)
|
||||
: CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
|
||||
bool HasFPFeatures, TypeSourceInfo *writtenTy)
|
||||
: CastExpr(SC, exprTy, VK, kind, op, PathSize, HasFPFeatures),
|
||||
TInfo(writtenTy) {}
|
||||
|
||||
/// Construct an empty explicit cast.
|
||||
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
|
||||
: CastExpr(SC, Shell, PathSize) { }
|
||||
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: CastExpr(SC, Shell, PathSize, HasFPFeatures) {}
|
||||
|
||||
public:
|
||||
/// getTypeInfoAsWritten - Returns the type source info for the type
|
||||
|
@ -3640,29 +3690,38 @@ public:
|
|||
/// (Type)expr. For example: @c (int)f.
|
||||
class CStyleCastExpr final
|
||||
: public ExplicitCastExpr,
|
||||
private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
|
||||
private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *,
|
||||
FPOptionsOverride> {
|
||||
SourceLocation LPLoc; // the location of the left paren
|
||||
SourceLocation RPLoc; // the location of the right paren
|
||||
|
||||
CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
|
||||
unsigned PathSize, TypeSourceInfo *writtenTy,
|
||||
SourceLocation l, SourceLocation r)
|
||||
: ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
|
||||
writtenTy), LPLoc(l), RPLoc(r) {}
|
||||
unsigned PathSize, FPOptionsOverride FPO,
|
||||
TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r)
|
||||
: ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
|
||||
FPO.requiresTrailingStorage(), writtenTy),
|
||||
LPLoc(l), RPLoc(r) {
|
||||
if (hasStoredFPFeatures())
|
||||
*getTrailingFPFeatures() = FPO;
|
||||
}
|
||||
|
||||
/// Construct an empty C-style explicit cast.
|
||||
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
|
||||
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
|
||||
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize, HasFPFeatures) {}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
|
||||
return path_size();
|
||||
}
|
||||
|
||||
public:
|
||||
static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
|
||||
ExprValueKind VK, CastKind K,
|
||||
Expr *Op, const CXXCastPath *BasePath,
|
||||
TypeSourceInfo *WrittenTy, SourceLocation L,
|
||||
SourceLocation R);
|
||||
static CStyleCastExpr *
|
||||
Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
|
||||
Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
|
||||
TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R);
|
||||
|
||||
static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
|
||||
unsigned PathSize);
|
||||
unsigned PathSize, bool HasFPFeatures);
|
||||
|
||||
SourceLocation getLParenLoc() const { return LPLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LPLoc = L; }
|
||||
|
|
|
@ -374,16 +374,17 @@ private:
|
|||
protected:
|
||||
friend class ASTStmtReader;
|
||||
|
||||
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
|
||||
CastKind kind, Expr *op, unsigned PathSize,
|
||||
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind,
|
||||
Expr *op, unsigned PathSize, bool HasFPFeatures,
|
||||
TypeSourceInfo *writtenTy, SourceLocation l,
|
||||
SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets)
|
||||
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
|
||||
RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
|
||||
SourceLocation RParenLoc, SourceRange AngleBrackets)
|
||||
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures,
|
||||
writtenTy),
|
||||
Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
|
||||
|
||||
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
|
||||
: ExplicitCastExpr(SC, Shell, PathSize) {}
|
||||
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {}
|
||||
|
||||
public:
|
||||
const char *getCastName() const;
|
||||
|
@ -419,29 +420,39 @@ public:
|
|||
/// \c static_cast<int>(1.0).
|
||||
class CXXStaticCastExpr final
|
||||
: public CXXNamedCastExpr,
|
||||
private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
|
||||
private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *,
|
||||
FPOptionsOverride> {
|
||||
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
|
||||
unsigned pathSize, TypeSourceInfo *writtenTy,
|
||||
SourceLocation l, SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets)
|
||||
FPOptionsOverride FPO, SourceLocation l,
|
||||
SourceLocation RParenLoc, SourceRange AngleBrackets)
|
||||
: CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
|
||||
writtenTy, l, RParenLoc, AngleBrackets) {}
|
||||
FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc,
|
||||
AngleBrackets) {
|
||||
if (hasStoredFPFeatures())
|
||||
*getTrailingFPFeatures() = FPO;
|
||||
}
|
||||
|
||||
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
|
||||
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
|
||||
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize,
|
||||
HasFPFeatures) {}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
|
||||
return path_size();
|
||||
}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
friend TrailingObjects;
|
||||
|
||||
static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
|
||||
ExprValueKind VK, CastKind K, Expr *Op,
|
||||
const CXXCastPath *Path,
|
||||
TypeSourceInfo *Written, SourceLocation L,
|
||||
SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets);
|
||||
static CXXStaticCastExpr *
|
||||
Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
|
||||
Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written,
|
||||
FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets);
|
||||
static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
|
||||
unsigned PathSize);
|
||||
unsigned PathSize, bool hasFPFeatures);
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXStaticCastExprClass;
|
||||
|
@ -456,15 +467,17 @@ public:
|
|||
class CXXDynamicCastExpr final
|
||||
: public CXXNamedCastExpr,
|
||||
private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
|
||||
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
|
||||
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
|
||||
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op,
|
||||
unsigned pathSize, TypeSourceInfo *writtenTy,
|
||||
SourceLocation l, SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets)
|
||||
: CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
|
||||
writtenTy, l, RParenLoc, AngleBrackets) {}
|
||||
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
|
||||
AngleBrackets) {}
|
||||
|
||||
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
|
||||
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
|
||||
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize,
|
||||
/*HasFPFeatures*/ false) {}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
|
@ -499,16 +512,17 @@ class CXXReinterpretCastExpr final
|
|||
: public CXXNamedCastExpr,
|
||||
private llvm::TrailingObjects<CXXReinterpretCastExpr,
|
||||
CXXBaseSpecifier *> {
|
||||
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
|
||||
Expr *op, unsigned pathSize,
|
||||
TypeSourceInfo *writtenTy, SourceLocation l,
|
||||
SourceLocation RParenLoc,
|
||||
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
|
||||
unsigned pathSize, TypeSourceInfo *writtenTy,
|
||||
SourceLocation l, SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets)
|
||||
: CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
|
||||
pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
|
||||
pathSize, /*HasFPFeatures*/ false, writtenTy, l,
|
||||
RParenLoc, AngleBrackets) {}
|
||||
|
||||
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
|
||||
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
|
||||
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize,
|
||||
/*HasFPFeatures*/ false) {}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
|
@ -541,11 +555,13 @@ class CXXConstCastExpr final
|
|||
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
|
||||
TypeSourceInfo *writtenTy, SourceLocation l,
|
||||
SourceLocation RParenLoc, SourceRange AngleBrackets)
|
||||
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
|
||||
0, writtenTy, l, RParenLoc, AngleBrackets) {}
|
||||
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0,
|
||||
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
|
||||
AngleBrackets) {}
|
||||
|
||||
explicit CXXConstCastExpr(EmptyShell Empty)
|
||||
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
|
||||
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0,
|
||||
/*HasFPFeatures*/ false) {}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
|
@ -578,10 +594,12 @@ class CXXAddrspaceCastExpr final
|
|||
TypeSourceInfo *writtenTy, SourceLocation l,
|
||||
SourceLocation RParenLoc, SourceRange AngleBrackets)
|
||||
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
|
||||
writtenTy, l, RParenLoc, AngleBrackets) {}
|
||||
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
|
||||
AngleBrackets) {}
|
||||
|
||||
explicit CXXAddrspaceCastExpr(EmptyShell Empty)
|
||||
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {}
|
||||
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0,
|
||||
/*HasFPFeatures*/ false) {}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
|
@ -1693,34 +1711,43 @@ public:
|
|||
/// \endcode
|
||||
class CXXFunctionalCastExpr final
|
||||
: public ExplicitCastExpr,
|
||||
private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
|
||||
private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *,
|
||||
FPOptionsOverride> {
|
||||
SourceLocation LParenLoc;
|
||||
SourceLocation RParenLoc;
|
||||
|
||||
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
|
||||
TypeSourceInfo *writtenTy,
|
||||
CastKind kind, Expr *castExpr, unsigned pathSize,
|
||||
SourceLocation lParenLoc, SourceLocation rParenLoc)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
|
||||
castExpr, pathSize, writtenTy),
|
||||
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
|
||||
TypeSourceInfo *writtenTy, CastKind kind,
|
||||
Expr *castExpr, unsigned pathSize,
|
||||
FPOptionsOverride FPO, SourceLocation lParenLoc,
|
||||
SourceLocation rParenLoc)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr,
|
||||
pathSize, FPO.requiresTrailingStorage(), writtenTy),
|
||||
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {
|
||||
if (hasStoredFPFeatures())
|
||||
*getTrailingFPFeatures() = FPO;
|
||||
}
|
||||
|
||||
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
|
||||
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize,
|
||||
bool HasFPFeatures)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize,
|
||||
HasFPFeatures) {}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
|
||||
return path_size();
|
||||
}
|
||||
|
||||
public:
|
||||
friend class CastExpr;
|
||||
friend TrailingObjects;
|
||||
|
||||
static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
|
||||
ExprValueKind VK,
|
||||
TypeSourceInfo *Written,
|
||||
CastKind Kind, Expr *Op,
|
||||
const CXXCastPath *Path,
|
||||
SourceLocation LPLoc,
|
||||
SourceLocation RPLoc);
|
||||
static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
|
||||
unsigned PathSize);
|
||||
static CXXFunctionalCastExpr *
|
||||
Create(const ASTContext &Context, QualType T, ExprValueKind VK,
|
||||
TypeSourceInfo *Written, CastKind Kind, Expr *Op,
|
||||
const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc,
|
||||
SourceLocation RPLoc);
|
||||
static CXXFunctionalCastExpr *
|
||||
CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures);
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
|
@ -4828,11 +4855,11 @@ public:
|
|||
BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr,
|
||||
TypeSourceInfo *DstType, SourceLocation KWLoc,
|
||||
SourceLocation RParenLoc)
|
||||
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0,
|
||||
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, false,
|
||||
DstType),
|
||||
KWLoc(KWLoc), RParenLoc(RParenLoc) {}
|
||||
BuiltinBitCastExpr(EmptyShell Empty)
|
||||
: ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {}
|
||||
: ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0, false) {}
|
||||
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
|
||||
|
|
|
@ -1639,12 +1639,12 @@ public:
|
|||
CastKind CK, SourceLocation BridgeKeywordLoc,
|
||||
TypeSourceInfo *TSInfo, Expr *Operand)
|
||||
: ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
|
||||
CK, Operand, 0, TSInfo),
|
||||
CK, Operand, 0, false, TSInfo),
|
||||
LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
|
||||
|
||||
/// Construct an empty Objective-C bridged cast.
|
||||
explicit ObjCBridgedCastExpr(EmptyShell Shell)
|
||||
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
|
||||
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0, false) {}
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
|
|
|
@ -521,6 +521,9 @@ protected:
|
|||
unsigned Kind : 6;
|
||||
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
|
||||
|
||||
/// True if the call expression has some floating-point features.
|
||||
unsigned HasFPFeatures : 1;
|
||||
|
||||
/// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
|
||||
/// here. ([implimits] Direct and indirect base classes [16384]).
|
||||
unsigned BasePathSize;
|
||||
|
|
|
@ -270,6 +270,7 @@ public:
|
|||
void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
|
||||
void VisitCXXThisExpr(const CXXThisExpr *Node);
|
||||
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
|
||||
void VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node);
|
||||
void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
|
||||
void VisitCXXConstructExpr(const CXXConstructExpr *Node);
|
||||
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
|
||||
|
|
|
@ -497,6 +497,8 @@ public:
|
|||
FPOptionsOverride() {}
|
||||
FPOptionsOverride(const LangOptions &LO)
|
||||
: Options(LO), OverrideMask(OverrideMaskBits) {}
|
||||
FPOptionsOverride(FPOptions FPO)
|
||||
: Options(FPO), OverrideMask(OverrideMaskBits) {}
|
||||
|
||||
bool requiresTrailingStorage() const { return OverrideMask != 0; }
|
||||
|
||||
|
|
|
@ -6930,7 +6930,7 @@ ExpectedStmt ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
|||
|
||||
return ImplicitCastExpr::Create(
|
||||
Importer.getToContext(), *ToTypeOrErr, E->getCastKind(), *ToSubExprOrErr,
|
||||
&(*ToBasePathOrErr), E->getValueKind());
|
||||
&(*ToBasePathOrErr), E->getValueKind(), E->getFPFeatures());
|
||||
}
|
||||
|
||||
ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
||||
|
@ -6957,8 +6957,8 @@ ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
|||
return ToRParenLocOrErr.takeError();
|
||||
return CStyleCastExpr::Create(
|
||||
Importer.getToContext(), ToType, E->getValueKind(), E->getCastKind(),
|
||||
ToSubExpr, ToBasePath, ToTypeInfoAsWritten, *ToLParenLocOrErr,
|
||||
*ToRParenLocOrErr);
|
||||
ToSubExpr, ToBasePath, CCE->getFPFeatures(), ToTypeInfoAsWritten,
|
||||
*ToLParenLocOrErr, *ToRParenLocOrErr);
|
||||
}
|
||||
|
||||
case Stmt::CXXFunctionalCastExprClass: {
|
||||
|
@ -6971,8 +6971,8 @@ ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
|||
return ToRParenLocOrErr.takeError();
|
||||
return CXXFunctionalCastExpr::Create(
|
||||
Importer.getToContext(), ToType, E->getValueKind(), ToTypeInfoAsWritten,
|
||||
E->getCastKind(), ToSubExpr, ToBasePath, *ToLParenLocOrErr,
|
||||
*ToRParenLocOrErr);
|
||||
E->getCastKind(), ToSubExpr, ToBasePath, FCE->getFPFeatures(),
|
||||
*ToLParenLocOrErr, *ToRParenLocOrErr);
|
||||
}
|
||||
|
||||
case Stmt::ObjCBridgedCastExprClass: {
|
||||
|
@ -7815,10 +7815,11 @@ ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
|||
if (!ToBasePathOrErr)
|
||||
return ToBasePathOrErr.takeError();
|
||||
|
||||
if (isa<CXXStaticCastExpr>(E)) {
|
||||
if (auto CCE = dyn_cast<CXXStaticCastExpr>(E)) {
|
||||
return CXXStaticCastExpr::Create(
|
||||
Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
|
||||
ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
|
||||
ToTypeInfoAsWritten, CCE->getFPFeatures(), ToOperatorLoc, ToRParenLoc,
|
||||
ToAngleBrackets);
|
||||
} else if (isa<CXXDynamicCastExpr>(E)) {
|
||||
return CXXDynamicCastExpr::Create(
|
||||
Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
|
||||
|
|
|
@ -1892,19 +1892,42 @@ const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
FPOptionsOverride *CastExpr::getTrailingFPFeatures() {
|
||||
assert(hasStoredFPFeatures());
|
||||
switch (getStmtClass()) {
|
||||
case ImplicitCastExprClass:
|
||||
return static_cast<ImplicitCastExpr *>(this)
|
||||
->getTrailingObjects<FPOptionsOverride>();
|
||||
case CStyleCastExprClass:
|
||||
return static_cast<CStyleCastExpr *>(this)
|
||||
->getTrailingObjects<FPOptionsOverride>();
|
||||
case CXXFunctionalCastExprClass:
|
||||
return static_cast<CXXFunctionalCastExpr *>(this)
|
||||
->getTrailingObjects<FPOptionsOverride>();
|
||||
case CXXStaticCastExprClass:
|
||||
return static_cast<CXXStaticCastExpr *>(this)
|
||||
->getTrailingObjects<FPOptionsOverride>();
|
||||
default:
|
||||
llvm_unreachable("Cast does not have FPFeatures");
|
||||
}
|
||||
}
|
||||
|
||||
ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
|
||||
CastKind Kind, Expr *Operand,
|
||||
const CXXCastPath *BasePath,
|
||||
ExprValueKind VK) {
|
||||
ExprValueKind VK,
|
||||
FPOptionsOverride FPO) {
|
||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, FPO.requiresTrailingStorage()));
|
||||
// Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and
|
||||
// std::nullptr_t have special semantics not captured by CK_LValueToRValue.
|
||||
assert((Kind != CK_LValueToRValue ||
|
||||
!(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&
|
||||
"invalid type for lvalue-to-rvalue conversion");
|
||||
ImplicitCastExpr *E =
|
||||
new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
|
||||
new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, FPO, VK);
|
||||
if (PathSize)
|
||||
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
|
||||
E->getTrailingObjects<CXXBaseSpecifier *>());
|
||||
|
@ -1912,21 +1935,26 @@ ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
|
|||
}
|
||||
|
||||
ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,
|
||||
unsigned PathSize) {
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
|
||||
unsigned PathSize,
|
||||
bool HasFPFeatures) {
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, HasFPFeatures));
|
||||
return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize, HasFPFeatures);
|
||||
}
|
||||
|
||||
|
||||
CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
|
||||
ExprValueKind VK, CastKind K, Expr *Op,
|
||||
const CXXCastPath *BasePath,
|
||||
FPOptionsOverride FPO,
|
||||
TypeSourceInfo *WrittenTy,
|
||||
SourceLocation L, SourceLocation R) {
|
||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, FPO.requiresTrailingStorage()));
|
||||
CStyleCastExpr *E =
|
||||
new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
|
||||
new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, FPO, WrittenTy, L, R);
|
||||
if (PathSize)
|
||||
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
|
||||
E->getTrailingObjects<CXXBaseSpecifier *>());
|
||||
|
@ -1934,9 +1962,12 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
|
|||
}
|
||||
|
||||
CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,
|
||||
unsigned PathSize) {
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
|
||||
unsigned PathSize,
|
||||
bool HasFPFeatures) {
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, HasFPFeatures));
|
||||
return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize, HasFPFeatures);
|
||||
}
|
||||
|
||||
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
||||
|
|
|
@ -690,19 +690,18 @@ const char *CXXNamedCastExpr::getCastName() const {
|
|||
}
|
||||
}
|
||||
|
||||
CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
|
||||
ExprValueKind VK,
|
||||
CastKind K, Expr *Op,
|
||||
const CXXCastPath *BasePath,
|
||||
TypeSourceInfo *WrittenTy,
|
||||
SourceLocation L,
|
||||
SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets) {
|
||||
CXXStaticCastExpr *
|
||||
CXXStaticCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
|
||||
CastKind K, Expr *Op, const CXXCastPath *BasePath,
|
||||
TypeSourceInfo *WrittenTy, FPOptionsOverride FPO,
|
||||
SourceLocation L, SourceLocation RParenLoc,
|
||||
SourceRange AngleBrackets) {
|
||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
auto *E =
|
||||
new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
|
||||
RParenLoc, AngleBrackets);
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, FPO.requiresTrailingStorage()));
|
||||
auto *E = new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy,
|
||||
FPO, L, RParenLoc, AngleBrackets);
|
||||
if (PathSize)
|
||||
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
|
||||
E->getTrailingObjects<CXXBaseSpecifier *>());
|
||||
|
@ -710,9 +709,12 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
|
|||
}
|
||||
|
||||
CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,
|
||||
unsigned PathSize) {
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
|
||||
unsigned PathSize,
|
||||
bool HasFPFeatures) {
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, HasFPFeatures));
|
||||
return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize, HasFPFeatures);
|
||||
}
|
||||
|
||||
CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
|
||||
|
@ -823,25 +825,30 @@ CXXAddrspaceCastExpr *CXXAddrspaceCastExpr::CreateEmpty(const ASTContext &C) {
|
|||
return new (C) CXXAddrspaceCastExpr(EmptyShell());
|
||||
}
|
||||
|
||||
CXXFunctionalCastExpr *
|
||||
CXXFunctionalCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
|
||||
TypeSourceInfo *Written, CastKind K, Expr *Op,
|
||||
const CXXCastPath *BasePath,
|
||||
SourceLocation L, SourceLocation R) {
|
||||
CXXFunctionalCastExpr *CXXFunctionalCastExpr::Create(
|
||||
const ASTContext &C, QualType T, ExprValueKind VK, TypeSourceInfo *Written,
|
||||
CastKind K, Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
|
||||
SourceLocation L, SourceLocation R) {
|
||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
auto *E =
|
||||
new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, FPO.requiresTrailingStorage()));
|
||||
auto *E = new (Buffer)
|
||||
CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, FPO, L, R);
|
||||
if (PathSize)
|
||||
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
|
||||
E->getTrailingObjects<CXXBaseSpecifier *>());
|
||||
return E;
|
||||
}
|
||||
|
||||
CXXFunctionalCastExpr *
|
||||
CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
|
||||
void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
|
||||
return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
|
||||
CXXFunctionalCastExpr *CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C,
|
||||
unsigned PathSize,
|
||||
bool HasFPFeatures) {
|
||||
void *Buffer =
|
||||
C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
|
||||
PathSize, HasFPFeatures));
|
||||
return new (Buffer)
|
||||
CXXFunctionalCastExpr(EmptyShell(), PathSize, HasFPFeatures);
|
||||
}
|
||||
|
||||
SourceLocation CXXFunctionalCastExpr::getBeginLoc() const {
|
||||
|
|
|
@ -964,6 +964,8 @@ void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
|
|||
}
|
||||
dumpBasePath(OS, Node);
|
||||
OS << ">";
|
||||
if (Node->hasStoredFPFeatures())
|
||||
printFPOptions(Node->getFPFeatures());
|
||||
}
|
||||
|
||||
void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
|
||||
|
@ -1132,6 +1134,14 @@ void TextNodeDumper::VisitCXXFunctionalCastExpr(
|
|||
const CXXFunctionalCastExpr *Node) {
|
||||
OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
|
||||
<< Node->getCastKindName() << ">";
|
||||
if (Node->hasStoredFPFeatures())
|
||||
printFPOptions(Node->getFPFeatures());
|
||||
}
|
||||
|
||||
void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
|
||||
VisitCXXNamedCastExpr(Node);
|
||||
if (Node->hasStoredFPFeatures())
|
||||
printFPOptions(Node->getFPFeatures());
|
||||
}
|
||||
|
||||
void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
|
||||
|
|
|
@ -166,23 +166,21 @@ ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
|
|||
ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
|
||||
CastKind CK) {
|
||||
return ImplicitCastExpr::Create(C, Ty,
|
||||
/* CastKind=*/ CK,
|
||||
/* Expr=*/ const_cast<Expr *>(Arg),
|
||||
/* CXXCastPath=*/ nullptr,
|
||||
/* ExprValueKind=*/ VK_RValue);
|
||||
/* CastKind=*/CK,
|
||||
/* Expr=*/const_cast<Expr *>(Arg),
|
||||
/* CXXCastPath=*/nullptr,
|
||||
/* ExprValueKind=*/VK_RValue,
|
||||
/* FPFeatures */ FPOptionsOverride());
|
||||
}
|
||||
|
||||
Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
|
||||
if (Arg->getType() == Ty)
|
||||
return const_cast<Expr*>(Arg);
|
||||
|
||||
return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
|
||||
const_cast<Expr*>(Arg), nullptr, VK_RValue);
|
||||
return makeImplicitCast(Arg, Ty, CK_IntegralCast);
|
||||
}
|
||||
|
||||
ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
|
||||
return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
|
||||
const_cast<Expr*>(Arg), nullptr, VK_RValue);
|
||||
return makeImplicitCast(Arg, C.BoolTy, CK_IntegralToBoolean);
|
||||
}
|
||||
|
||||
ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
|
||||
|
|
|
@ -1024,7 +1024,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
|
|||
type, VK_LValue, SourceLocation());
|
||||
|
||||
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
|
||||
&declRef, VK_RValue);
|
||||
&declRef, VK_RValue, CurFPFeatures);
|
||||
// FIXME: Pass a specific location for the expr init so that the store is
|
||||
// attributed to a reasonable location - otherwise it may be attributed to
|
||||
// locations of subexpressions in the initialization.
|
||||
|
|
|
@ -1449,9 +1449,9 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
ValueDecl *selfDecl = setterMethod->getSelfDecl();
|
||||
DeclRefExpr self(getContext(), selfDecl, false, selfDecl->getType(),
|
||||
VK_LValue, SourceLocation());
|
||||
ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
|
||||
selfDecl->getType(), CK_LValueToRValue, &self,
|
||||
VK_RValue);
|
||||
ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack, selfDecl->getType(),
|
||||
CK_LValueToRValue, &self, VK_RValue,
|
||||
FPOptionsOverride(CurFPFeatures));
|
||||
ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
|
||||
SourceLocation(), SourceLocation(),
|
||||
&selfLoad, true, true);
|
||||
|
@ -1462,7 +1462,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
SourceLocation());
|
||||
ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
|
||||
argType.getUnqualifiedType(), CK_LValueToRValue,
|
||||
&arg, VK_RValue);
|
||||
&arg, VK_RValue, CurFPFeatures);
|
||||
|
||||
// The property type can differ from the ivar type in some situations with
|
||||
// Objective-C pointer types, we can always bit cast the RHS in these cases.
|
||||
|
@ -1483,9 +1483,8 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
} else if (ivarRef.getType()->isPointerType()) {
|
||||
argCK = CK_BitCast;
|
||||
}
|
||||
ImplicitCastExpr argCast(ImplicitCastExpr::OnStack,
|
||||
ivarRef.getType(), argCK, &argLoad,
|
||||
VK_RValue);
|
||||
ImplicitCastExpr argCast(ImplicitCastExpr::OnStack, ivarRef.getType(), argCK,
|
||||
&argLoad, VK_RValue, CurFPFeatures);
|
||||
Expr *finalArg = &argLoad;
|
||||
if (!getContext().hasSameUnqualifiedType(ivarRef.getType(),
|
||||
argLoad.getType()))
|
||||
|
|
|
@ -4137,7 +4137,7 @@ createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
|
|||
PrivateVD->setInitStyle(VarDecl::CInit);
|
||||
PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue,
|
||||
InitRef, /*BasePath=*/nullptr,
|
||||
VK_RValue));
|
||||
VK_RValue, FPOptionsOverride()));
|
||||
Data.FirstprivateVars.emplace_back(OrigRef);
|
||||
Data.FirstprivateCopies.emplace_back(PrivateRef);
|
||||
Data.FirstprivateInits.emplace_back(InitRef);
|
||||
|
|
|
@ -586,7 +586,8 @@ namespace {
|
|||
CastKind Kind, Expr *E) {
|
||||
TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
|
||||
return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
|
||||
TInfo, SourceLocation(), SourceLocation());
|
||||
FPOptionsOverride(), TInfo,
|
||||
SourceLocation(), SourceLocation());
|
||||
}
|
||||
|
||||
bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
|
||||
|
@ -2105,8 +2106,8 @@ RewriteModernObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
|
|||
// Now, we cast the reference to a pointer to the objc_msgSend type.
|
||||
QualType pToFunc = Context->getPointerType(msgSendType);
|
||||
ImplicitCastExpr *ICE =
|
||||
ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
|
||||
DRE, nullptr, VK_RValue);
|
||||
ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
|
||||
DRE, nullptr, VK_RValue, FPOptionsOverride());
|
||||
|
||||
const auto *FT = msgSendType->castAs<FunctionType>();
|
||||
CallExpr *Exp =
|
||||
|
|
|
@ -492,7 +492,8 @@ namespace {
|
|||
CastKind Kind, Expr *E) {
|
||||
TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
|
||||
return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
|
||||
TInfo, SourceLocation(), SourceLocation());
|
||||
FPOptionsOverride(), TInfo,
|
||||
SourceLocation(), SourceLocation());
|
||||
}
|
||||
|
||||
StringLiteral *getStringLiteral(StringRef Str) {
|
||||
|
@ -2022,8 +2023,8 @@ RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
|
|||
// Now, we cast the reference to a pointer to the objc_msgSend type.
|
||||
QualType pToFunc = Context->getPointerType(msgSendType);
|
||||
ImplicitCastExpr *ICE =
|
||||
ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
|
||||
DRE, nullptr, VK_RValue);
|
||||
ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
|
||||
DRE, nullptr, VK_RValue, FPOptionsOverride());
|
||||
|
||||
const auto *FT = msgSendType->castAs<FunctionType>();
|
||||
|
||||
|
|
|
@ -586,7 +586,8 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
|
|||
}
|
||||
}
|
||||
|
||||
return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
|
||||
return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK,
|
||||
CurFPFeatureOverrides());
|
||||
}
|
||||
|
||||
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
|
||||
|
|
|
@ -105,10 +105,9 @@ namespace {
|
|||
// If this is an unbridged cast, wrap the result in an implicit
|
||||
// cast that yields the unbridged-cast placeholder type.
|
||||
if (IsARCUnbridgedCast) {
|
||||
castExpr = ImplicitCastExpr::Create(Self.Context,
|
||||
Self.Context.ARCUnbridgedCastTy,
|
||||
CK_Dependent, castExpr, nullptr,
|
||||
castExpr->getValueKind());
|
||||
castExpr = ImplicitCastExpr::Create(
|
||||
Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
|
||||
castExpr, nullptr, castExpr->getValueKind(), FPOptionsOverride());
|
||||
}
|
||||
updatePartOfExplicitCastFlags(castExpr);
|
||||
return castExpr;
|
||||
|
@ -361,11 +360,10 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
|
|||
DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
|
||||
}
|
||||
|
||||
return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
|
||||
Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
|
||||
&Op.BasePath, DestTInfo,
|
||||
OpLoc, Parens.getEnd(),
|
||||
AngleBrackets));
|
||||
return Op.complete(CXXStaticCastExpr::Create(
|
||||
Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
|
||||
&Op.BasePath, DestTInfo, CurFPFeatureOverrides(), OpLoc,
|
||||
Parens.getEnd(), AngleBrackets));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3033,9 +3031,9 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,
|
|||
// -Wcast-qual
|
||||
DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType);
|
||||
|
||||
return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
|
||||
Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
|
||||
&Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
|
||||
return Op.complete(CStyleCastExpr::Create(
|
||||
Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
|
||||
&Op.BasePath, CurFPFeatureOverrides(), CastTypeInfo, LPLoc, RPLoc));
|
||||
}
|
||||
|
||||
ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
|
||||
|
@ -3058,7 +3056,7 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
|
|||
if (auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr))
|
||||
ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc));
|
||||
|
||||
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
|
||||
Op.ValueKind, CastTypeInfo, Op.Kind,
|
||||
Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
|
||||
return Op.complete(CXXFunctionalCastExpr::Create(
|
||||
Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,
|
||||
Op.SrcExpr.get(), &Op.BasePath, CurFPFeatureOverrides(), LPLoc, RPLoc));
|
||||
}
|
||||
|
|
|
@ -18172,11 +18172,9 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
|
|||
// Adjust the Expr initializer and type.
|
||||
if (ECD->getInitExpr() &&
|
||||
!Context.hasSameType(NewTy, ECD->getInitExpr()->getType()))
|
||||
ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
|
||||
CK_IntegralCast,
|
||||
ECD->getInitExpr(),
|
||||
/*base paths*/ nullptr,
|
||||
VK_RValue));
|
||||
ECD->setInitExpr(ImplicitCastExpr::Create(
|
||||
Context, NewTy, CK_IntegralCast, ECD->getInitExpr(),
|
||||
/*base paths*/ nullptr, VK_RValue, CurFPFeatureOverrides()));
|
||||
if (getLangOpts().CPlusPlus)
|
||||
// C++ [dcl.enum]p4: Following the closing brace of an
|
||||
// enum-specifier, each enumerator has the type of its
|
||||
|
|
|
@ -1185,7 +1185,8 @@ static bool checkTupleLikeDecomposition(Sema &S,
|
|||
// an xvalue otherwise
|
||||
if (!Src->getType()->isLValueReferenceType())
|
||||
E = ImplicitCastExpr::Create(S.Context, E.get()->getType(), CK_NoOp,
|
||||
E.get(), nullptr, VK_XValue);
|
||||
E.get(), nullptr, VK_XValue,
|
||||
S.CurFPFeatureOverrides());
|
||||
|
||||
TemplateArgumentListInfo Args(Loc, Loc);
|
||||
Args.addArgument(
|
||||
|
@ -14869,9 +14870,9 @@ void Sema::DefineImplicitLambdaToBlockPointerConversion(
|
|||
// (since it's unusable otherwise); in the case where we inline the
|
||||
// block literal, it has block literal lifetime semantics.
|
||||
if (!BuildBlock.isInvalid() && !getLangOpts().ObjCAutoRefCount)
|
||||
BuildBlock = ImplicitCastExpr::Create(Context, BuildBlock.get()->getType(),
|
||||
CK_CopyAndAutoreleaseBlockObject,
|
||||
BuildBlock.get(), nullptr, VK_RValue);
|
||||
BuildBlock = ImplicitCastExpr::Create(
|
||||
Context, BuildBlock.get()->getType(), CK_CopyAndAutoreleaseBlockObject,
|
||||
BuildBlock.get(), nullptr, VK_RValue, CurFPFeatureOverrides());
|
||||
|
||||
if (BuildBlock.isInvalid()) {
|
||||
Diag(CurrentLocation, diag::note_lambda_to_block_conv);
|
||||
|
|
|
@ -695,7 +695,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
|
|||
// C++ [conv.lval]p3:
|
||||
// If T is cv std::nullptr_t, the result is a null pointer constant.
|
||||
CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;
|
||||
Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue);
|
||||
Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue,
|
||||
CurFPFeatureOverrides());
|
||||
|
||||
// C11 6.3.2.1p2:
|
||||
// ... if the lvalue has atomic type, the value has the non-atomic version
|
||||
|
@ -703,7 +704,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
|
|||
if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
|
||||
T = Atomic->getValueType().getUnqualifiedType();
|
||||
Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(),
|
||||
nullptr, VK_RValue);
|
||||
nullptr, VK_RValue, CurFPFeatureOverrides());
|
||||
}
|
||||
|
||||
return Res;
|
||||
|
@ -6960,9 +6961,9 @@ void Sema::maybeExtendBlockObject(ExprResult &E) {
|
|||
// Only do this in an r-value context.
|
||||
if (!getLangOpts().ObjCAutoRefCount) return;
|
||||
|
||||
E = ImplicitCastExpr::Create(Context, E.get()->getType(),
|
||||
CK_ARCExtendBlockObject, E.get(),
|
||||
/*base path*/ nullptr, VK_RValue);
|
||||
E = ImplicitCastExpr::Create(
|
||||
Context, E.get()->getType(), CK_ARCExtendBlockObject, E.get(),
|
||||
/*base path*/ nullptr, VK_RValue, CurFPFeatureOverrides());
|
||||
Cleanup.setExprNeedsCleanups(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -1503,7 +1503,8 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
|||
: SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
|
||||
Result = CXXFunctionalCastExpr::Create(
|
||||
Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp,
|
||||
Result.get(), /*Path=*/nullptr, Locs.getBegin(), Locs.getEnd());
|
||||
Result.get(), /*Path=*/nullptr, CurFPFeatureOverrides(),
|
||||
Locs.getBegin(), Locs.getEnd());
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
@ -2204,7 +2205,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
SizeTy, SourceLocation());
|
||||
ImplicitCastExpr DesiredAlignment(ImplicitCastExpr::OnStack, AlignValT,
|
||||
CK_IntegralCast, &AlignmentLiteral,
|
||||
VK_RValue);
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
|
||||
// Adjust placement args by prepending conjured size and alignment exprs.
|
||||
llvm::SmallVector<Expr *, 8> CallArgs;
|
||||
|
@ -3915,7 +3916,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
|
|||
// Record usage of conversion in an implicit cast.
|
||||
Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
|
||||
CK_UserDefinedConversion, Result.get(),
|
||||
nullptr, Result.get()->getValueKind());
|
||||
nullptr, Result.get()->getValueKind(),
|
||||
S.CurFPFeatureOverrides());
|
||||
|
||||
return S.MaybeBindToTemporary(Result.get());
|
||||
}
|
||||
|
@ -4096,7 +4098,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
|
|||
if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) {
|
||||
FromType = FromAtomic->getValueType().getUnqualifiedType();
|
||||
From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic,
|
||||
From, /*BasePath=*/nullptr, VK_RValue);
|
||||
From, /*BasePath=*/nullptr, VK_RValue,
|
||||
CurFPFeatureOverrides());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6840,7 +6843,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
|
||||
: CK_ARCReclaimReturnedObject);
|
||||
return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
|
||||
VK_RValue);
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
}
|
||||
|
||||
if (E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
|
||||
|
|
|
@ -4462,8 +4462,8 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
|
|||
// If the result is +1, consume it here.
|
||||
case ACC_plusOne:
|
||||
castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
|
||||
CK_ARCConsumeObject, castExpr,
|
||||
nullptr, VK_RValue);
|
||||
CK_ARCConsumeObject, castExpr, nullptr,
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
Cleanup.setExprNeedsCleanups(true);
|
||||
return ACR_okay;
|
||||
}
|
||||
|
@ -4689,9 +4689,9 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
|
|||
|
||||
case OBC_BridgeRetained:
|
||||
// Produce the object before casting it.
|
||||
SubExpr = ImplicitCastExpr::Create(Context, FromType,
|
||||
CK_ARCProduceObject,
|
||||
SubExpr, nullptr, VK_RValue);
|
||||
SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
|
||||
SubExpr, nullptr, VK_RValue,
|
||||
CurFPFeatureOverrides());
|
||||
break;
|
||||
|
||||
case OBC_BridgeTransfer: {
|
||||
|
@ -4729,8 +4729,9 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
|
|||
|
||||
if (MustConsume) {
|
||||
Cleanup.setExprNeedsCleanups(true);
|
||||
Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
|
||||
nullptr, VK_RValue);
|
||||
Result =
|
||||
ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
|
||||
nullptr, VK_RValue, CurFPFeatureOverrides());
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
|
|
@ -2891,7 +2891,8 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
|
|||
Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
|
||||
if (CharTy != PromotedCharTy)
|
||||
Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
|
||||
Init, nullptr, VK_RValue);
|
||||
Init, nullptr, VK_RValue,
|
||||
SemaRef.CurFPFeatureOverrides());
|
||||
StructuredList->updateInit(Context, i, Init);
|
||||
}
|
||||
} else {
|
||||
|
@ -2913,7 +2914,8 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
|
|||
Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
|
||||
if (CharTy != PromotedCharTy)
|
||||
Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
|
||||
Init, nullptr, VK_RValue);
|
||||
Init, nullptr, VK_RValue,
|
||||
SemaRef.CurFPFeatureOverrides());
|
||||
StructuredList->updateInit(Context, i, Init);
|
||||
}
|
||||
}
|
||||
|
@ -8019,9 +8021,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
|
|||
(Step->Kind == SK_CastDerivedToBaseXValue ?
|
||||
VK_XValue :
|
||||
VK_RValue);
|
||||
CurInit =
|
||||
ImplicitCastExpr::Create(S.Context, Step->Type, CK_DerivedToBase,
|
||||
CurInit.get(), &BasePath, VK);
|
||||
CurInit = ImplicitCastExpr::Create(
|
||||
S.Context, Step->Type, CK_DerivedToBase, CurInit.get(), &BasePath, VK,
|
||||
S.CurFPFeatureOverrides());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8150,9 +8152,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
|
|||
if (CreatedObject && checkAbstractType(CurInit.get()->getType()))
|
||||
return ExprError();
|
||||
|
||||
CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
|
||||
CastKind, CurInit.get(), nullptr,
|
||||
CurInit.get()->getValueKind());
|
||||
CurInit = ImplicitCastExpr::Create(
|
||||
S.Context, CurInit.get()->getType(), CastKind, CurInit.get(), nullptr,
|
||||
CurInit.get()->getValueKind(), S.CurFPFeatureOverrides());
|
||||
|
||||
if (shouldBindAsTemporary(Entity))
|
||||
// The overall entity is temporary, so this expression should be
|
||||
|
@ -8493,9 +8495,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
|
|||
break;
|
||||
|
||||
case SK_ProduceObjCObject:
|
||||
CurInit =
|
||||
ImplicitCastExpr::Create(S.Context, Step->Type, CK_ARCProduceObject,
|
||||
CurInit.get(), nullptr, VK_RValue);
|
||||
CurInit = ImplicitCastExpr::Create(
|
||||
S.Context, Step->Type, CK_ARCProduceObject, CurInit.get(), nullptr,
|
||||
VK_RValue, S.CurFPFeatureOverrides());
|
||||
break;
|
||||
|
||||
case SK_StdInitializerList: {
|
||||
|
@ -8549,9 +8551,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
|
|||
// Case 1b and 1c
|
||||
// No cast from integer to sampler is needed.
|
||||
if (!Var->hasGlobalStorage()) {
|
||||
CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
|
||||
CK_LValueToRValue, Init,
|
||||
/*BasePath=*/nullptr, VK_RValue);
|
||||
CurInit = ImplicitCastExpr::Create(
|
||||
S.Context, Step->Type, CK_LValueToRValue, Init,
|
||||
/*BasePath=*/nullptr, VK_RValue, S.CurFPFeatureOverrides());
|
||||
break;
|
||||
}
|
||||
// Case 1a
|
||||
|
|
|
@ -680,8 +680,9 @@ static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
|
|||
ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue);
|
||||
|
||||
Expr *E = (cleanups ? cleanups->getSubExpr() : retValue);
|
||||
E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast,
|
||||
E, /*base path*/ nullptr, VK_RValue);
|
||||
E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, E,
|
||||
/*base path*/ nullptr, VK_RValue,
|
||||
S.CurFPFeatureOverrides());
|
||||
if (cleanups) {
|
||||
cleanups->setSubExpr(E);
|
||||
} else {
|
||||
|
|
|
@ -1464,10 +1464,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
|||
DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
|
||||
PropertyDiagLoc);
|
||||
MarkDeclRefReferenced(SelfExpr);
|
||||
Expr *LoadSelfExpr =
|
||||
ImplicitCastExpr::Create(Context, SelfDecl->getType(),
|
||||
CK_LValueToRValue, SelfExpr, nullptr,
|
||||
VK_RValue);
|
||||
Expr *LoadSelfExpr = ImplicitCastExpr::Create(
|
||||
Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
Expr *IvarRefExpr =
|
||||
new (Context) ObjCIvarRefExpr(Ivar,
|
||||
Ivar->getUsageType(SelfDecl->getType()),
|
||||
|
@ -1528,10 +1527,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
|||
DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
|
||||
PropertyDiagLoc);
|
||||
MarkDeclRefReferenced(SelfExpr);
|
||||
Expr *LoadSelfExpr =
|
||||
ImplicitCastExpr::Create(Context, SelfDecl->getType(),
|
||||
CK_LValueToRValue, SelfExpr, nullptr,
|
||||
VK_RValue);
|
||||
Expr *LoadSelfExpr = ImplicitCastExpr::Create(
|
||||
Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
Expr *lhs =
|
||||
new (Context) ObjCIvarRefExpr(Ivar,
|
||||
Ivar->getUsageType(SelfDecl->getType()),
|
||||
|
|
|
@ -15388,12 +15388,12 @@ static bool actOnOMPReductionKindClause(
|
|||
if (!BasePath.empty()) {
|
||||
LHS = S.DefaultLvalueConversion(LHS.get());
|
||||
RHS = S.DefaultLvalueConversion(RHS.get());
|
||||
LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
|
||||
CK_UncheckedDerivedToBase, LHS.get(),
|
||||
&BasePath, LHS.get()->getValueKind());
|
||||
RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
|
||||
CK_UncheckedDerivedToBase, RHS.get(),
|
||||
&BasePath, RHS.get()->getValueKind());
|
||||
LHS = ImplicitCastExpr::Create(
|
||||
Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
|
||||
LHS.get()->getValueKind(), S.CurFPFeatureOverrides());
|
||||
RHS = ImplicitCastExpr::Create(
|
||||
Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
|
||||
RHS.get()->getValueKind(), S.CurFPFeatureOverrides());
|
||||
}
|
||||
FunctionProtoType::ExtProtoInfo EPI;
|
||||
QualType Params[] = {PtrRedTy, PtrRedTy};
|
||||
|
|
|
@ -5862,7 +5862,8 @@ diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
|
|||
// Record usage of conversion in an implicit cast.
|
||||
From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
|
||||
CK_UserDefinedConversion, Result.get(),
|
||||
nullptr, Result.get()->getValueKind());
|
||||
nullptr, Result.get()->getValueKind(),
|
||||
SemaRef.CurFPFeatureOverrides());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -5891,7 +5892,8 @@ static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From,
|
|||
// Record usage of conversion in an implicit cast.
|
||||
From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
|
||||
CK_UserDefinedConversion, Result.get(),
|
||||
nullptr, Result.get()->getValueKind());
|
||||
nullptr, Result.get()->getValueKind(),
|
||||
SemaRef.CurFPFeatureOverrides());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7296,8 +7298,8 @@ void Sema::AddConversionCandidate(
|
|||
VK_LValue, From->getBeginLoc());
|
||||
ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
|
||||
Context.getPointerType(Conversion->getType()),
|
||||
CK_FunctionToPointerDecay,
|
||||
&ConversionRef, VK_RValue);
|
||||
CK_FunctionToPointerDecay, &ConversionRef,
|
||||
VK_RValue, CurFPFeatureOverrides());
|
||||
|
||||
QualType ConversionType = Conversion->getConversionType();
|
||||
if (!isCompleteType(From->getBeginLoc(), ConversionType)) {
|
||||
|
@ -14422,9 +14424,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
|
|||
if (Call.isInvalid())
|
||||
return ExprError();
|
||||
// Record usage of conversion in an implicit cast.
|
||||
Call = ImplicitCastExpr::Create(Context, Call.get()->getType(),
|
||||
CK_UserDefinedConversion, Call.get(),
|
||||
nullptr, VK_RValue);
|
||||
Call = ImplicitCastExpr::Create(
|
||||
Context, Call.get()->getType(), CK_UserDefinedConversion, Call.get(),
|
||||
nullptr, VK_RValue, CurFPFeatureOverrides());
|
||||
|
||||
return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
|
||||
}
|
||||
|
@ -14829,10 +14831,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
|
|||
if (SubExpr == ICE->getSubExpr())
|
||||
return ICE;
|
||||
|
||||
return ImplicitCastExpr::Create(Context, ICE->getType(),
|
||||
ICE->getCastKind(),
|
||||
SubExpr, nullptr,
|
||||
ICE->getValueKind());
|
||||
return ImplicitCastExpr::Create(Context, ICE->getType(), ICE->getCastKind(),
|
||||
SubExpr, nullptr, ICE->getValueKind(),
|
||||
CurFPFeatureOverrides());
|
||||
}
|
||||
|
||||
if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
|
||||
|
|
|
@ -3095,7 +3095,8 @@ static void TryMoveInitialization(Sema& S,
|
|||
bool ConvertingConstructorsOnly,
|
||||
ExprResult &Res) {
|
||||
ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, Value->getType(),
|
||||
CK_NoOp, Value, VK_XValue);
|
||||
CK_NoOp, Value, VK_XValue,
|
||||
S.CurFPFeatureOverrides());
|
||||
|
||||
Expr *InitExpr = &AsRvalue;
|
||||
|
||||
|
@ -3150,8 +3151,9 @@ static void TryMoveInitialization(Sema& S,
|
|||
|
||||
// Promote "AsRvalue" to the heap, since we now need this
|
||||
// expression node to persist.
|
||||
Value = ImplicitCastExpr::Create(S.Context, Value->getType(), CK_NoOp,
|
||||
Value, nullptr, VK_XValue);
|
||||
Value =
|
||||
ImplicitCastExpr::Create(S.Context, Value->getType(), CK_NoOp, Value,
|
||||
nullptr, VK_XValue, S.CurFPFeatureOverrides());
|
||||
|
||||
// Complete type-checking the initialization of the return type
|
||||
// using the constructor we found.
|
||||
|
|
|
@ -7478,7 +7478,7 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
|
|||
// FIXME: This is a hack. We need a better way to handle substituted
|
||||
// non-type template parameters.
|
||||
E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E,
|
||||
nullptr,
|
||||
nullptr, CurFPFeatureOverrides(),
|
||||
Context.getTrivialTypeSourceInfo(OrigT, Loc),
|
||||
Loc, Loc);
|
||||
}
|
||||
|
|
|
@ -1082,6 +1082,8 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
|
|||
VisitExpr(E);
|
||||
unsigned NumBaseSpecs = Record.readInt();
|
||||
assert(NumBaseSpecs == E->path_size());
|
||||
unsigned HasFPFeatures = Record.readInt();
|
||||
assert(E->hasStoredFPFeatures() == HasFPFeatures);
|
||||
E->setSubExpr(Record.readSubExpr());
|
||||
E->setCastKind((CastKind)Record.readInt());
|
||||
CastExpr::path_iterator BaseI = E->path_begin();
|
||||
|
@ -1090,6 +1092,8 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
|
|||
*BaseSpec = Record.readCXXBaseSpecifier();
|
||||
*BaseI++ = BaseSpec;
|
||||
}
|
||||
if (HasFPFeatures)
|
||||
*E->getTrailingFPFeatures() = FPOptionsOverride::getFromOpaqueInt(Record.readInt());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
|
||||
|
@ -2893,13 +2897,17 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case EXPR_IMPLICIT_CAST:
|
||||
S = ImplicitCastExpr::CreateEmpty(Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
||||
S = ImplicitCastExpr::CreateEmpty(
|
||||
Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields],
|
||||
/*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
|
||||
break;
|
||||
|
||||
case EXPR_CSTYLE_CAST:
|
||||
S = CStyleCastExpr::CreateEmpty(Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
||||
S = CStyleCastExpr::CreateEmpty(
|
||||
Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields],
|
||||
/*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
|
||||
break;
|
||||
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
|
@ -3501,8 +3509,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case EXPR_CXX_STATIC_CAST:
|
||||
S = CXXStaticCastExpr::CreateEmpty(Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
||||
S = CXXStaticCastExpr::CreateEmpty(
|
||||
Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields],
|
||||
/*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
|
||||
break;
|
||||
|
||||
case EXPR_CXX_DYNAMIC_CAST:
|
||||
|
@ -3524,8 +3534,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case EXPR_CXX_FUNCTIONAL_CAST:
|
||||
S = CXXFunctionalCastExpr::CreateEmpty(Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
||||
S = CXXFunctionalCastExpr::CreateEmpty(
|
||||
Context,
|
||||
/*PathSize*/ Record[ASTStmtReader::NumExprFields],
|
||||
/*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
|
||||
break;
|
||||
|
||||
case EXPR_BUILTIN_BIT_CAST:
|
||||
|
|
|
@ -2346,6 +2346,7 @@ void ASTWriter::WriteDeclAbbrevs() {
|
|||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
|
||||
// CastExpr
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // PathSize
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
|
||||
// ImplicitCastExpr
|
||||
|
|
|
@ -946,12 +946,16 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|||
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->path_size());
|
||||
Record.push_back(E->hasStoredFPFeatures());
|
||||
Record.AddStmt(E->getSubExpr());
|
||||
Record.push_back(E->getCastKind()); // FIXME: stable encoding
|
||||
|
||||
for (CastExpr::path_iterator
|
||||
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
||||
Record.AddCXXBaseSpecifier(**PI);
|
||||
|
||||
if (E->hasStoredFPFeatures())
|
||||
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
||||
|
@ -1003,7 +1007,7 @@ void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
|||
VisitCastExpr(E);
|
||||
Record.push_back(E->isPartOfExplicitCast());
|
||||
|
||||
if (E->path_size() == 0)
|
||||
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
|
||||
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
|
||||
|
||||
Code = serialization::EXPR_IMPLICIT_CAST;
|
||||
|
|
|
@ -36,6 +36,51 @@ float func_03(float x) {
|
|||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
|
||||
|
||||
int func_04(float x) {
|
||||
#pragma STDC FP_CONTRACT ON
|
||||
return x;
|
||||
}
|
||||
|
||||
// CHECK: FunctionDecl {{.*}} func_04 'int (float)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} x 'float'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <FloatingToIntegral> FPContractMode=1
|
||||
|
||||
float func_05(double x) {
|
||||
#pragma STDC FP_CONTRACT ON
|
||||
return (float)x;
|
||||
}
|
||||
|
||||
// CHECK: FunctionDecl {{.*}} func_05 'float (double)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: CStyleCastExpr {{.*}} FPContractMode=1
|
||||
|
||||
float func_06(double x) {
|
||||
#pragma STDC FP_CONTRACT ON
|
||||
return float(x);
|
||||
}
|
||||
|
||||
// CHECK: FunctionDecl {{.*}} func_06 'float (double)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: CXXFunctionalCastExpr {{.*}} FPContractMode=1
|
||||
|
||||
float func_07(double x) {
|
||||
#pragma STDC FP_CONTRACT ON
|
||||
return static_cast<float>(x);
|
||||
}
|
||||
|
||||
// CHECK: FunctionDecl {{.*}} func_07 'float (double)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: CXXStaticCastExpr {{.*}} FPContractMode=1
|
||||
// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue