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