r339380 - [NFC] Convert ParsedAttr to use llvm::TrailingObjects
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 9 13:25:12 PDT 2018
Author: erichkeane
Date: Thu Aug 9 13:25:12 2018
New Revision: 339380
URL: http://llvm.org/viewvc/llvm-project?rev=339380&view=rev
Log:
[NFC] Convert ParsedAttr to use llvm::TrailingObjects
ParsedAttr is using a hand-rolled trailing-objects
implementation that gets cleaned up quite a bit by
just using llvm::TrailingObjects. This is a large
TrailingObjects list, but most things are length '0'.
Differential Revision: https://reviews.llvm.org/D50531
Modified:
cfe/trunk/include/clang/Sema/ParsedAttr.h
cfe/trunk/lib/Sema/ParsedAttr.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/Sema/ParsedAttr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?rev=339380&r1=339379&r2=339380&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ParsedAttr.h (original)
+++ cfe/trunk/include/clang/Sema/ParsedAttr.h Thu Aug 9 13:25:12 2018
@@ -55,8 +55,7 @@ struct AvailabilityChange {
bool isValid() const { return !Version.empty(); }
};
-namespace {
-
+namespace detail {
enum AvailabilitySlot {
IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
};
@@ -78,6 +77,18 @@ struct AvailabilityData {
}
};
+struct TypeTagForDatatypeData {
+ ParsedType *MatchingCType;
+ unsigned LayoutCompatible : 1;
+ unsigned MustBeNull : 1;
+};
+struct PropertyData {
+ IdentifierInfo *GetterId, *SetterId;
+
+ PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
+ : GetterId(getterId), SetterId(setterId) {}
+};
+
} // namespace
/// Wraps an identifier and optional source location for the identifier.
@@ -103,7 +114,29 @@ using ArgsVector = llvm::SmallVector<Arg
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
-class ParsedAttr {
+class ParsedAttr final
+ : private llvm::TrailingObjects<
+ ParsedAttr, ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
+ friend class llvm::TrailingObjects<
+ ParsedAttr, ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData>;
+
+ size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
+ size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
+ return IsAvailability;
+ }
+ size_t
+ numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
+ return IsTypeTagForDatatype;
+ }
+ size_t numTrailingObjects(OverloadToken<ParsedType>) const {
+ return HasParsedType;
+ }
+ size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
+ return IsProperty;
+ }
+
public:
/// The style used to specify an attribute.
enum Syntax {
@@ -183,34 +216,18 @@ private:
const Expr *MessageExpr;
- /// Arguments, if any, are stored immediately following the object.
- ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
+ ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
ArgsUnion const *getArgsBuffer() const {
- return reinterpret_cast<ArgsUnion const *>(this + 1);
+ return getTrailingObjects<ArgsUnion>();
}
- /// Availability information is stored immediately following the arguments,
- /// if any, at the end of the object.
- AvailabilityData *getAvailabilityData() {
- return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
+ detail::AvailabilityData *getAvailabilityData() {
+ return getTrailingObjects<detail::AvailabilityData>();
}
- const AvailabilityData *getAvailabilityData() const {
- return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
+ const detail::AvailabilityData *getAvailabilityData() const {
+ return getTrailingObjects<detail::AvailabilityData>();
}
-public:
- struct TypeTagForDatatypeData {
- ParsedType *MatchingCType;
- unsigned LayoutCompatible : 1;
- unsigned MustBeNull : 1;
- };
- struct PropertyData {
- IdentifierInfo *GetterId, *SetterId;
-
- PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
- : GetterId(getterId), SetterId(setterId) {}
- };
-
private:
friend class AttributeFactory;
friend class AttributePool;
@@ -245,7 +262,7 @@ private:
MessageExpr(messageExpr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- new (getAvailabilityData()) AvailabilityData(
+ new (getAvailabilityData()) detail::AvailabilityData(
introduced, deprecated, obsoleted, strict, replacementExpr);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -279,7 +296,7 @@ private:
HasProcessingCache(false) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
+ detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
new (&ExtraData.MatchingCType) ParsedType(matchingCType);
ExtraData.LayoutCompatible = layoutCompatible;
ExtraData.MustBeNull = mustBeNull;
@@ -309,39 +326,36 @@ private:
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
HasProcessingCache(false) {
- new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
+ new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
/// Type tag information is stored immediately following the arguments, if
/// any, at the end of the object. They are mutually exclusive with
/// availability slots.
- TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
- return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
+ detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
+ return *getTrailingObjects<detail::TypeTagForDatatypeData>();
}
- const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
- return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
- + NumArgs);
+ const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
+ return *getTrailingObjects<detail::TypeTagForDatatypeData>();
}
/// The type buffer immediately follows the object and are mutually exclusive
/// with arguments.
- ParsedType &getTypeBuffer() {
- return *reinterpret_cast<ParsedType *>(this + 1);
- }
+ ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
const ParsedType &getTypeBuffer() const {
- return *reinterpret_cast<const ParsedType *>(this + 1);
+ return *getTrailingObjects<ParsedType>();
}
/// The property data immediately follows the object is is mutually exclusive
/// with arguments.
- PropertyData &getPropertyDataBuffer() {
+ detail::PropertyData &getPropertyDataBuffer() {
assert(IsProperty);
- return *reinterpret_cast<PropertyData*>(this + 1);
+ return *getTrailingObjects<detail::PropertyData>();
}
- const PropertyData &getPropertyDataBuffer() const {
+ const detail::PropertyData &getPropertyDataBuffer() const {
assert(IsProperty);
- return *reinterpret_cast<const PropertyData*>(this + 1);
+ return *getTrailingObjects<detail::PropertyData>();
}
size_t allocated_size() const;
@@ -452,17 +466,17 @@ public:
const AvailabilityChange &getAvailabilityIntroduced() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[IntroducedSlot];
+ return getAvailabilityData()->Changes[detail::IntroducedSlot];
}
const AvailabilityChange &getAvailabilityDeprecated() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[DeprecatedSlot];
+ return getAvailabilityData()->Changes[detail::DeprecatedSlot];
}
const AvailabilityChange &getAvailabilityObsoleted() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[ObsoletedSlot];
+ return getAvailabilityData()->Changes[detail::ObsoletedSlot];
}
SourceLocation getStrictLoc() const {
@@ -508,9 +522,16 @@ public:
return getTypeBuffer();
}
- const PropertyData &getPropertyData() const {
- assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
- return getPropertyDataBuffer();
+ IdentifierInfo *getPropertyDataGetter() const {
+ assert(isDeclspecPropertyAttribute() &&
+ "Not a __delcspec(property) attribute");
+ return getPropertyDataBuffer().GetterId;
+ }
+
+ IdentifierInfo *getPropertyDataSetter() const {
+ assert(isDeclspecPropertyAttribute() &&
+ "Not a __delcspec(property) attribute");
+ return getPropertyDataBuffer().SetterId;
}
/// Get an index into the attribute spelling list
@@ -553,20 +574,18 @@ class AttributePool;
class AttributeFactory {
public:
enum {
- /// The required allocation size of an availability attribute,
- /// which we want to ensure is a multiple of sizeof(void*).
AvailabilityAllocSize =
- sizeof(ParsedAttr) +
- ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
- sizeof(void *) * sizeof(void *)),
- TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
- (sizeof(ParsedAttr::TypeTagForDatatypeData) +
- sizeof(void *) + sizeof(ArgsUnion) - 1) /
- sizeof(void *) * sizeof(void *),
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(1, 1, 0, 0, 0),
+ TypeTagForDatatypeAllocSize =
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 1, 0, 0),
PropertyAllocSize =
- sizeof(ParsedAttr) +
- (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
- sizeof(void *) * sizeof(void *)
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 0, 0, 1),
};
private:
@@ -657,7 +676,16 @@ public:
ArgsUnion *args, unsigned numArgs,
ParsedAttr::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) {
- void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
+ size_t temp =
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(numArgs, 0, 0, 0, 0);
+ (void)temp;
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(numArgs, 0, 0, 0,
+ 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
args, numArgs, syntax, ellipsisLoc));
}
@@ -680,8 +708,10 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param2,
IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
- size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
- void *memory = allocate(size);
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(3, 0, 0, 0, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax));
}
@@ -703,7 +733,10 @@ public:
IdentifierInfo *scopeName,
SourceLocation scopeLoc, ParsedType typeArg,
ParsedAttr::Syntax syntaxUsed) {
- void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 0, 1, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
typeArg, syntaxUsed));
}
Modified: cfe/trunk/lib/Sema/ParsedAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ParsedAttr.cpp?rev=339380&r1=339379&r2=339380&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/ParsedAttr.cpp (original)
+++ cfe/trunk/lib/Sema/ParsedAttr.cpp Thu Aug 9 13:25:12 2018
@@ -41,8 +41,12 @@ size_t ParsedAttr::allocated_size() cons
else if (IsProperty)
return AttributeFactory::PropertyAllocSize;
else if (HasParsedType)
- return sizeof(ParsedAttr) + sizeof(void *);
- return (sizeof(ParsedAttr) + NumArgs * sizeof(ArgsUnion));
+ return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 0, 1, 0);
+ return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(NumArgs, 0, 0, 0, 0);
}
AttributeFactory::AttributeFactory() {
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=339380&r1=339379&r2=339380&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 9 13:25:12 2018
@@ -15476,9 +15476,10 @@ MSPropertyDecl *Sema::HandleMSProperty(S
PrevDecl = nullptr;
SourceLocation TSSL = D.getLocStart();
- const ParsedAttr::PropertyData &Data = MSPropertyAttr.getPropertyData();
- MSPropertyDecl *NewPD = MSPropertyDecl::Create(
- Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId);
+ MSPropertyDecl *NewPD =
+ MSPropertyDecl::Create(Context, Record, Loc, II, T, TInfo, TSSL,
+ MSPropertyAttr.getPropertyDataGetter(),
+ MSPropertyAttr.getPropertyDataSetter());
ProcessDeclAttributes(TUScope, NewPD, D);
NewPD->setAccess(AS);
More information about the cfe-commits
mailing list