[PATCH] D81869: Modify FPFeatures to use delta not absolute settings to solve PCH compatibility problems
John McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 16 14:19:06 PDT 2020
rjmccall added inline comments.
================
Comment at: clang/include/clang/AST/Expr.h:2280
}
+ FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+ if (UnaryOperatorBits.HasFPFeatures)
----------------
I would call this one getFPOptionOverrides or getOverriddenFPOptions. If you're going to have a getFPFeatures, it really ought to be the other one — although since we're changing pretty much all of the call sites, we might as well rename it to getFPOptions (or getFPOptionsInEffect, that seems fine, too).
================
Comment at: clang/include/clang/Basic/LangOptions.h:758
+ unsigned allow_reciprocal_disabled : 1;
+ unsigned approx_func_disabled : 1;
};
----------------
As an alternative storage strategy, I would suggest:
- in FPOptions, use an integer and masks instead of bit-fields
- in FPOptionsOverride, store the same integer from FPOptions plus the active override mask
This will make the merge and extract operations really painless. It can get a little boilerplate, though, so I'd recommend also introducing an "x-macro" file:
```
// clang/Basic/FPOptions.def
// OPTION(name, type, width, previousName)
OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
OPTION(RoundingMode, RoundingMode, 3, FPContractMode)
...
OPTION(AllowReciprocal, bool, 1, NoSignedZeros)
...
#undef OPTION
...
class FPOptions {
public:
// We start by defining the layout.
using storage_type = uint16_t;
// Define a fake option named "First" so that we have a PREVIOUS even for the real first option.
static constexpr storage_type FirstShift = 0, FirstWidth = 0;
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
static constexpr storage_type NAME#Shift = PREVIOUS#Shift + PREVIOUS#Width; \
static constexpr storage_type NAME#Width = width; \
static constexpr storage_type NAME#Mask = ((1 << NAME#Width) - 1) << NAME#Shift;
#include "clang/Basic/FPOptions.def"
private:
storage_type Value;
public:
// Now you can define constructors and so on.
FPOptions() : Value(0) {}
bool operator==(FPOptions other) const {
return Value == other.Value;
}
bool operator!=(FPOptionsOverride other) const {
return Value != other.Value;
}
storage_type getAsOpaqueInt() const { return Value; }
static FPOptions getFromOpaqueInt(storage_type value) {
FPOptions result;
result.Value = value;
return result;
}
// We can define most of the accessors automatically:
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
TYPE get#NAME() const { \
return TYPE((Value & NAME#Mask) >> NAME#Shift); \
} \
void set#NAME(TYPE value) { \
Value = (Value & ~NAME#Mask) | (storage_type(value) << NAME#Shift); \
}
#include "clang/Basic/FPOptions.def"
};
// The override type is then basically just that, plus a mask about whether fields are actually set in it:
class FPOptionsOverride {
FPOptions Options;
FPOptions::storage_type OverrideMask = 0;
public:
FPOptionsOverride() {}
bool hasAnyOverrides() const {
return OverrideMask != 0;
}
FPOptions applyOverrides(FPOptions base) {
return FPOptions::getFromOpaqueInt(base.getAsOpaqueInt()
| (OverrideMask & Options.getAsOpaqueInt()));
}
bool operator==(FPOptionsOverride other) const {
return Options == other.Options && OverrideMask == other.OverrideMask;
}
bool operator!=(FPOptionsOverride other) const {
return !(*this == other);
}
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
bool has#NAME#Override() const { \
return OverrideMask & NAME#Mask; \
} \
TYPE get#NAME#Override() const { \
assert(has#NAME#Override()); \
return Options.get#NAME();
} \
void clear#NAME#Override() { \
/* Clear the actual value so that we don't have spurious differences when testing equality. */ \
Options.set#NAME(TYPE(0)); \
OverrideMask &= ~NAME#Mask; \
} \
void set#NAME#Override(TYPE value) { \
Options.set#NAME(value); \
OverrideMask |= NAME#Mask; \
}
#include "clang/Basic/FPOptions.def"
};
```
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D81869/new/
https://reviews.llvm.org/D81869
More information about the cfe-commits
mailing list