Skip to content

Commit

Permalink
[AST][FPEnv] Keep FP options in trailing storage of CastExpr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
spavloff committed Sep 12, 2020
1 parent 0680a3d commit 6c8041a
Show file tree
Hide file tree
Showing 34 changed files with 462 additions and 253 deletions.
117 changes: 88 additions & 29 deletions clang/include/clang/AST/Expr.h
Expand Up @@ -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;
Expand All @@ -3451,17 +3453,27 @@ class CastExpr : public Expr {
"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; }
Expand Down Expand Up @@ -3506,6 +3518,28 @@ class CastExpr : public Expr {
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,
Expand Down Expand Up @@ -3543,21 +3577,35 @@ class CastExpr : public Expr {
/// @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; }
Expand All @@ -3568,10 +3616,10 @@ class ImplicitCastExpr final
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();
Expand Down Expand Up @@ -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
Expand All @@ -3640,29 +3690,38 @@ class ExplicitCastExpr : public CastExpr {
/// (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; }
Expand Down

0 comments on commit 6c8041a

Please sign in to comment.