r256659 - [TrailingObjects] Convert classes in ExprObjC.h

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 30 20:43:19 PST 2015


Author: jyknight
Date: Wed Dec 30 22:43:19 2015
New Revision: 256659

URL: http://llvm.org/viewvc/llvm-project?rev=256659&view=rev
Log:
[TrailingObjects] Convert classes in ExprObjC.h

Modified:
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/lib/AST/ExprObjC.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=256659&r1=256658&r2=256659&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Wed Dec 30 22:43:19 2015
@@ -141,15 +141,17 @@ public:
 
 /// ObjCArrayLiteral - used for objective-c array containers; as in:
 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
-class ObjCArrayLiteral : public Expr {
+class ObjCArrayLiteral final
+    : public Expr,
+      private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
   unsigned NumElements;
   SourceRange Range;
   ObjCMethodDecl *ArrayWithObjectsMethod;
-  
+
   ObjCArrayLiteral(ArrayRef<Expr *> Elements,
                    QualType T, ObjCMethodDecl * Method,
                    SourceRange SR);
-  
+
   explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
     : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
 
@@ -171,11 +173,11 @@ public:
   }
 
   /// \brief Retrieve elements of array of literals.
-  Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
+  Expr **getElements() { return getTrailingObjects<Expr *>(); }
 
   /// \brief Retrieve elements of array of literals.
-  const Expr * const *getElements() const { 
-    return reinterpret_cast<const Expr * const*>(this + 1); 
+  const Expr * const *getElements() const {
+    return getTrailingObjects<Expr *>();
   }
 
   /// getNumElements - Return number of elements of objective-c array literal.
@@ -196,11 +198,12 @@ public:
   }
     
   // Iterators
-  child_range children() { 
-    return child_range((Stmt **)getElements(), 
-                       (Stmt **)getElements() + NumElements);
+  child_range children() {
+    return child_range(reinterpret_cast<Stmt **>(getElements()),
+                       reinterpret_cast<Stmt **>(getElements()) + NumElements);
   }
-    
+
+  friend TrailingObjects;
   friend class ASTStmtReader;
 };
 
@@ -230,32 +233,35 @@ template <> struct isPodLike<clang::ObjC
 }
 
 namespace clang {
-/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 
-/// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] };
-class ObjCDictionaryLiteral : public Expr {
-  /// \brief Key/value pair used to store the key and value of a given element.
-  ///
-  /// Objects of this type are stored directly after the expression.
-  struct KeyValuePair {
-    Expr *Key;
-    Expr *Value;
-  };
-  
-  /// \brief Data that describes an element that is a pack expansion, used if any
-  /// of the elements in the dictionary literal are pack expansions.
-  struct ExpansionData {
-    /// \brief The location of the ellipsis, if this element is a pack
-    /// expansion.
-    SourceLocation EllipsisLoc;
-
-    /// \brief If non-zero, the number of elements that this pack
-    /// expansion will expand to (+1).
-    unsigned NumExpansionsPlusOne;
-  };
+/// \brief Internal struct for storing Key/value pair.
+struct ObjCDictionaryLiteral_KeyValuePair {
+  Expr *Key;
+  Expr *Value;
+};
+
+/// \brief Internal struct to describes an element that is a pack
+/// expansion, used if any of the elements in the dictionary literal
+/// are pack expansions.
+struct ObjCDictionaryLiteral_ExpansionData {
+  /// \brief The location of the ellipsis, if this element is a pack
+  /// expansion.
+  SourceLocation EllipsisLoc;
 
+  /// \brief If non-zero, the number of elements that this pack
+  /// expansion will expand to (+1).
+  unsigned NumExpansionsPlusOne;
+};
+
+/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
+/// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] };
+class ObjCDictionaryLiteral final
+    : public Expr,
+      private llvm::TrailingObjects<ObjCDictionaryLiteral,
+                                    ObjCDictionaryLiteral_KeyValuePair,
+                                    ObjCDictionaryLiteral_ExpansionData> {
   /// \brief The number of elements in this dictionary literal.
   unsigned NumElements : 31;
-  
+
   /// \brief Determine whether this dictionary literal has any pack expansions.
   ///
   /// If the dictionary literal has pack expansions, then there will
@@ -264,10 +270,17 @@ class ObjCDictionaryLiteral : public Exp
   /// any) and number of elements in the expansion (if known). If
   /// there are no pack expansions, we optimize away this storage.
   unsigned HasPackExpansions : 1;
-  
+
   SourceRange Range;
   ObjCMethodDecl *DictWithObjectsMethod;
-    
+
+  typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair;
+  typedef ObjCDictionaryLiteral_ExpansionData ExpansionData;
+
+  size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
+    return NumElements;
+  }
+
   ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 
                         bool HasPackExpansions,
                         QualType T, ObjCMethodDecl *method,
@@ -278,28 +291,6 @@ class ObjCDictionaryLiteral : public Exp
     : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
       HasPackExpansions(HasPackExpansions) {}
 
-  KeyValuePair *getKeyValues() {
-    return reinterpret_cast<KeyValuePair *>(this + 1);
-  }
-  
-  const KeyValuePair *getKeyValues() const {
-    return reinterpret_cast<const KeyValuePair *>(this + 1);
-  }
-
-  ExpansionData *getExpansionData() {
-    if (!HasPackExpansions)
-      return nullptr;
-    
-    return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
-  }
-
-  const ExpansionData *getExpansionData() const {
-    if (!HasPackExpansions)
-      return nullptr;
-    
-    return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
-  }
-
 public:
   static ObjCDictionaryLiteral *Create(const ASTContext &C,
                                        ArrayRef<ObjCDictionaryElement> VK, 
@@ -317,10 +308,11 @@ public:
 
   ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
     assert((Index < NumElements) && "Arg access out of range!");
-    const KeyValuePair &KV = getKeyValues()[Index];
+    const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
     ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
     if (HasPackExpansions) {
-      const ExpansionData &Expansion = getExpansionData()[Index];
+      const ExpansionData &Expansion =
+          getTrailingObjects<ExpansionData>()[Index];
       Result.EllipsisLoc = Expansion.EllipsisLoc;
       if (Expansion.NumExpansionsPlusOne > 0)
         Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
@@ -340,17 +332,20 @@ public:
   }
     
   // Iterators
-  child_range children() { 
+  child_range children() {
     // Note: we're taking advantage of the layout of the KeyValuePair struct
     // here. If that struct changes, this code will need to change as well.
     static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
                   "KeyValuePair is expected size");
-    return child_range(reinterpret_cast<Stmt **>(this + 1),
-                       reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
+    return child_range(
+        reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
+        reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
+            NumElements * 2);
   }
     
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
+  friend TrailingObjects;
 };
 
 
@@ -797,13 +792,6 @@ public:
   explicit ObjCSubscriptRefExpr(EmptyShell Empty)
     : Expr(ObjCSubscriptRefExprClass, Empty) {}
   
-  static ObjCSubscriptRefExpr *Create(const ASTContext &C,
-                                      Expr *base,
-                                      Expr *key, QualType T, 
-                                      ObjCMethodDecl *getMethod,
-                                      ObjCMethodDecl *setMethod, 
-                                      SourceLocation RB);
-  
   SourceLocation getRBracket() const { return RBracket; }
   void setRBracket(SourceLocation RB) { RBracket = RB; }
 
@@ -865,7 +853,13 @@ private:
 /// All four kinds of message sends are modeled by the ObjCMessageExpr
 /// class, and can be distinguished via \c getReceiverKind(). Example:
 ///
-class ObjCMessageExpr : public Expr {
+/// The "void *" trailing objects are actually ONE void * (the
+/// receiver pointer), and NumArgs Expr *. But due to the
+/// implementation of children(), these must be together contiguously.
+
+class ObjCMessageExpr final
+    : public Expr,
+      private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
   /// \brief Stores either the selector that this message is sending
   /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
   /// referring to the method that we type-checked against.
@@ -877,11 +871,6 @@ class ObjCMessageExpr : public Expr {
   /// including the receiver.
   unsigned NumArgs : NumArgsBitWidth;
   
-  void setNumArgs(unsigned Num) {
-    assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
-    NumArgs = Num;
-  }
-
   /// \brief The kind of message send this is, which is one of the
   /// ReceiverKind values.
   ///
@@ -915,6 +904,13 @@ class ObjCMessageExpr : public Expr {
   /// brackets ('[' and ']', respectively).
   SourceLocation LBracLoc, RBracLoc;
 
+  size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
+
+  void setNumArgs(unsigned Num) {
+    assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
+    NumArgs = Num;
+  }
+
   ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
     : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), 
       HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
@@ -959,14 +955,11 @@ class ObjCMessageExpr : public Expr {
                           SelectorLocationsKind SelLocsK);
 
   /// \brief Retrieve the pointer value of the message receiver.
-  void *getReceiverPointer() const {
-    return *const_cast<void **>(
-                             reinterpret_cast<const void * const*>(this + 1));
-  }
+  void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
 
   /// \brief Set the pointer value of the message receiver.
   void setReceiverPointer(void *Value) {
-    *reinterpret_cast<void **>(this + 1) = Value;
+    *getTrailingObjects<void *>() = Value;
   }
 
   SelectorLocationsKind getSelLocsKind() const {
@@ -979,10 +972,10 @@ class ObjCMessageExpr : public Expr {
   /// \brief Get a pointer to the stored selector identifiers locations array.
   /// No locations will be stored if HasStandardSelLocs is true.
   SourceLocation *getStoredSelLocs() {
-    return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
+    return getTrailingObjects<SourceLocation>();
   }
   const SourceLocation *getStoredSelLocs() const {
-    return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
+    return getTrailingObjects<SourceLocation>();
   }
 
   /// \brief Get the number of stored selector identifiers locations.
@@ -1286,20 +1279,21 @@ public:
   /// \brief Retrieve the arguments to this message, not including the
   /// receiver.
   Expr **getArgs() {
-    return reinterpret_cast<Expr **>(this + 1) + 1;
+    return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
   }
   const Expr * const *getArgs() const {
-    return reinterpret_cast<const Expr * const *>(this + 1) + 1;
+    return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
+                                                 1);
   }
 
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(getArgs()[Arg]);
+    return getArgs()[Arg];
   }
   const Expr *getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(getArgs()[Arg]);
+    return getArgs()[Arg];
   }
   /// setArg - Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
@@ -1379,6 +1373,7 @@ public:
     return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 
   }
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 };

Modified: cfe/trunk/lib/AST/ExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprObjC.cpp?rev=256659&r1=256658&r2=256659&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprObjC.cpp (original)
+++ cfe/trunk/lib/AST/ExprObjC.cpp Wed Dec 30 22:43:19 2015
@@ -39,16 +39,14 @@ ObjCArrayLiteral *ObjCArrayLiteral::Crea
                                            ArrayRef<Expr *> Elements,
                                            QualType T, ObjCMethodDecl *Method,
                                            SourceRange SR) {
-  void *Mem =
-      C.Allocate(sizeof(ObjCArrayLiteral) + Elements.size() * sizeof(Expr *));
+  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
   return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
 }
 
 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
                                                 unsigned NumElements) {
 
-  void *Mem =
-      C.Allocate(sizeof(ObjCArrayLiteral) + NumElements * sizeof(Expr *));
+  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
   return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
 }
 
@@ -60,8 +58,8 @@ ObjCDictionaryLiteral::ObjCDictionaryLit
            false, false),
       NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
       DictWithObjectsMethod(method) {
-  KeyValuePair *KeyValues = getKeyValues();
-  ExpansionData *Expansions = getExpansionData();
+  KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
+  ExpansionData *Expansions = getTrailingObjects<ExpansionData>();
   for (unsigned I = 0; I < NumElements; I++) {
     if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
         VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
@@ -91,23 +89,16 @@ ObjCDictionaryLiteral::Create(const ASTC
                               ArrayRef<ObjCDictionaryElement> VK,
                               bool HasPackExpansions, QualType T,
                               ObjCMethodDecl *method, SourceRange SR) {
-  unsigned ExpansionsSize = 0;
-  if (HasPackExpansions)
-    ExpansionsSize = sizeof(ExpansionData) * VK.size();
-
-  void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
-                         sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
+  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
+      VK.size(), HasPackExpansions ? VK.size() : 0));
   return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
 }
 
 ObjCDictionaryLiteral *
 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
                                    bool HasPackExpansions) {
-  unsigned ExpansionsSize = 0;
-  if (HasPackExpansions)
-    ExpansionsSize = sizeof(ExpansionData) * NumElements;
-  void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
-                         sizeof(KeyValuePair) * NumElements + ExpansionsSize);
+  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
+      NumElements, HasPackExpansions ? NumElements : 0));
   return new (Mem)
       ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
 }
@@ -122,15 +113,6 @@ QualType ObjCPropertyRefExpr::getReceive
   return getBase()->getType();
 }
 
-ObjCSubscriptRefExpr *
-ObjCSubscriptRefExpr::Create(const ASTContext &C, Expr *base, Expr *key,
-                             QualType T, ObjCMethodDecl *getMethod,
-                             ObjCMethodDecl *setMethod, SourceLocation RB) {
-  void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr));
-  return new (Mem) ObjCSubscriptRefExpr(
-      base, key, T, VK_LValue, OK_ObjCSubscript, getMethod, setMethod, RB);
-}
-
 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
                                  SourceLocation LBracLoc,
                                  SourceLocation SuperLoc, bool IsInstanceSuper,
@@ -293,11 +275,9 @@ ObjCMessageExpr *ObjCMessageExpr::alloc(
 
 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
                                         unsigned NumStoredSelLocs) {
-  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
-                  NumArgs * sizeof(Expr *) +
-                  NumStoredSelLocs * sizeof(SourceLocation);
   return (ObjCMessageExpr *)C.Allocate(
-      Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+      totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
+      llvm::AlignOf<ObjCMessageExpr>::Alignment);
 }
 
 void ObjCMessageExpr::getSelectorLocs(
@@ -358,7 +338,7 @@ ObjCInterfaceDecl *ObjCMessageExpr::getR
 Stmt::child_range ObjCMessageExpr::children() {
   Stmt **begin;
   if (getReceiverKind() == Instance)
-    begin = reinterpret_cast<Stmt **>(this + 1);
+    begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
   else
     begin = reinterpret_cast<Stmt **>(getArgs());
   return child_range(begin,

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=256659&r1=256658&r2=256659&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Dec 30 22:43:19 2015
@@ -756,9 +756,9 @@ ExprResult Sema::BuildObjCSubscriptExpre
   BaseExpr = Result.get();
 
   // Build the pseudo-object expression.
-  return ObjCSubscriptRefExpr::Create(Context, BaseExpr, IndexExpr,
-                                      Context.PseudoObjectTy, getterMethod,
-                                      setterMethod, RB);
+  return new (Context) ObjCSubscriptRefExpr(
+      BaseExpr, IndexExpr, Context.PseudoObjectTy, VK_LValue, OK_ObjCSubscript,
+      getterMethod, setterMethod, RB);
 }
 
 ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=256659&r1=256658&r2=256659&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Wed Dec 30 22:43:19 2015
@@ -987,8 +987,10 @@ void ASTStmtReader::VisitObjCDictionaryL
   assert(NumElements == E->getNumElements() && "Wrong number of elements");
   bool HasPackExpansions = Record[Idx++];
   assert(HasPackExpansions == E->HasPackExpansions &&"Pack expansion mismatch");
-  ObjCDictionaryLiteral::KeyValuePair *KeyValues = E->getKeyValues();
-  ObjCDictionaryLiteral::ExpansionData *Expansions = E->getExpansionData();
+  ObjCDictionaryLiteral::KeyValuePair *KeyValues =
+      E->getTrailingObjects<ObjCDictionaryLiteral::KeyValuePair>();
+  ObjCDictionaryLiteral::ExpansionData *Expansions =
+      E->getTrailingObjects<ObjCDictionaryLiteral::ExpansionData>();
   for (unsigned I = 0; I != NumElements; ++I) {
     KeyValues[I].Key = Reader.ReadSubExpr();
     KeyValues[I].Value = Reader.ReadSubExpr();




More information about the cfe-commits mailing list