bool isValid() const { return !Version.empty(); }
};
+namespace {
+enum AvailabilitySlot {
+ IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
+};
+
+/// Describes the trailing object for Availability attribute in AttributeList.
+struct AvailabilityData {
+ AvailabilityChange Changes[NumAvailabilitySlots];
+ SourceLocation StrictLoc;
+ AvailabilityData(const AvailabilityChange &Introduced,
+ const AvailabilityChange &Deprecated,
+ const AvailabilityChange &Obsoleted,
+ SourceLocation Strict)
+ : StrictLoc(Strict) {
+ Changes[IntroducedSlot] = Introduced;
+ Changes[DeprecatedSlot] = Deprecated;
+ Changes[ObsoletedSlot] = Obsoleted;
+ }
+};
+}
+
/// \brief Wraps an identifier and optional source location for the identifier.
struct IdentifierLoc {
SourceLocation Loc;
return reinterpret_cast<ArgsUnion const *>(this + 1);
}
- enum AvailabilitySlot {
- IntroducedSlot, DeprecatedSlot, ObsoletedSlot
- };
-
/// Availability information is stored immediately following the arguments,
/// if any, at the end of the object.
- AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
- return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
- + NumArgs)[index];
- }
- const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
- return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
- + NumArgs)[index];
+ AvailabilityData *getAvailabilityData() {
+ return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
}
-
- /// The location of the 'strict' keyword in an availability attribute.
- SourceLocation *getStrictSlot() {
- return reinterpret_cast<SourceLocation*>(
- &getAvailabilitySlot(ObsoletedSlot) + 1);
- }
-
- SourceLocation const *getStrictSlot() const {
- return reinterpret_cast<SourceLocation const*>(
- &getAvailabilitySlot(ObsoletedSlot) + 1);
+ const AvailabilityData *getAvailabilityData() const {
+ return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
}
public:
MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
- new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
- new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
- memcpy(getStrictSlot(), &strict, sizeof(SourceLocation));
+ new (getAvailabilityData()) AvailabilityData(
+ introduced, deprecated, obsoleted, strict);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
const AvailabilityChange &getAvailabilityIntroduced() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(IntroducedSlot);
+ return getAvailabilityData()->Changes[IntroducedSlot];
}
const AvailabilityChange &getAvailabilityDeprecated() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(DeprecatedSlot);
+ return getAvailabilityData()->Changes[DeprecatedSlot];
}
const AvailabilityChange &getAvailabilityObsoleted() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilitySlot(ObsoletedSlot);
+ return getAvailabilityData()->Changes[ObsoletedSlot];
}
SourceLocation getStrictLoc() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return *getStrictSlot();
+ return getAvailabilityData()->StrictLoc;
}
SourceLocation getUnavailableLoc() const {
/// which we want to ensure is a multiple of sizeof(void*).
AvailabilityAllocSize =
sizeof(AttributeList)
- + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
- sizeof(ArgsUnion) + sizeof(SourceLocation) - 1)
+ + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
/ sizeof(void*) * sizeof(void*)),
TypeTagForDatatypeAllocSize =
sizeof(AttributeList)