[TrailingObjects] Convert remaining classes in Expr.h and ExprCXX.h
authorJames Y Knight <jyknight@google.com>
Thu, 31 Dec 2015 04:18:25 +0000 (04:18 +0000)
committerJames Y Knight <jyknight@google.com>
Thu, 31 Dec 2015 04:18:25 +0000 (04:18 +0000)
llvm-svn: 256658

clang/include/clang/AST/Expr.h
clang/include/clang/AST/ExprCXX.h
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/Serialization/ASTReaderStmt.cpp

index f9f1995..095dd6a 100644 (file)
@@ -2190,7 +2190,8 @@ public:
     return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
   }
   const Expr *const *getArgs() const {
-    return const_cast<CallExpr*>(this)->getArgs();
+    return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
+                                     PREARGS_START);
   }
 
   /// getArg - Return the specified argument.
@@ -3926,7 +3927,9 @@ public:
 /// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
 /// designators, one array designator for @c [2] followed by one field
 /// designator for @c .y. The initialization expression will be 1.0.
-class DesignatedInitExpr : public Expr {
+class DesignatedInitExpr final
+    : public Expr,
+      private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
 public:
   /// \brief Forward declaration of the Designator class.
   class Designator;
@@ -4206,12 +4209,12 @@ public:
 
   Expr *getSubExpr(unsigned Idx) const {
     assert(Idx < NumSubExprs && "Subscript out of range");
-    return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
+    return cast<Expr>(getTrailingObjects<Stmt *>()[Idx]);
   }
 
   void setSubExpr(unsigned Idx, Expr *E) {
     assert(Idx < NumSubExprs && "Subscript out of range");
-    reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
+    getTrailingObjects<Stmt *>()[Idx] = E;
   }
 
   /// \brief Replaces the designator at index @p Idx with the series
@@ -4230,9 +4233,11 @@ public:
 
   // Iterators
   child_range children() {
-    Stmt **begin = reinterpret_cast<Stmt**>(this + 1);
+    Stmt **begin = getTrailingObjects<Stmt *>();
     return child_range(begin, begin + NumSubExprs);
   }
+
+  friend TrailingObjects;
 };
 
 /// \brief Represents a place-holder for an object not to be initialized by
@@ -4683,7 +4688,9 @@ public:
 /// equivalent to a particular message send, and this is very much
 /// part of the user model.  The name of this class encourages this
 /// modelling design.
-class PseudoObjectExpr : public Expr {
+class PseudoObjectExpr final
+    : public Expr,
+      private llvm::TrailingObjects<PseudoObjectExpr, Expr *> {
   // PseudoObjectExprBits.NumSubExprs - The number of sub-expressions.
   // Always at least two, because the first sub-expression is the
   // syntactic form.
@@ -4695,13 +4702,11 @@ class PseudoObjectExpr : public Expr {
   // in to Create, which is an index within the semantic forms.
   // Note also that ASTStmtWriter assumes this encoding.
 
-  Expr **getSubExprsBuffer() { return reinterpret_cast<Expr**>(this + 1); }
+  Expr **getSubExprsBuffer() { return getTrailingObjects<Expr *>(); }
   const Expr * const *getSubExprsBuffer() const {
-    return reinterpret_cast<const Expr * const *>(this + 1);
+    return getTrailingObjects<Expr *>();
   }
 
-  friend class ASTStmtReader;
-
   PseudoObjectExpr(QualType type, ExprValueKind VK,
                    Expr *syntactic, ArrayRef<Expr*> semantic,
                    unsigned resultIndex);
@@ -4798,6 +4803,9 @@ public:
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == PseudoObjectExprClass;
   }
+
+  friend TrailingObjects;
+  friend class ASTStmtReader;
 };
 
 /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
index 707aeed..0608aba 100644 (file)
@@ -951,7 +951,9 @@ public:
 /// This wraps up a function call argument that was created from the
 /// corresponding parameter's default argument, when the call did not
 /// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr : public Expr {
+class CXXDefaultArgExpr final
+    : public Expr,
+      private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
   /// \brief The parameter whose default is being used.
   ///
   /// When the bit is set, the subexpression is stored after the
@@ -977,7 +979,7 @@ class CXXDefaultArgExpr : public Expr {
            SubExpr->getValueKind(), SubExpr->getObjectKind(),
            false, false, false, false),
       Param(param, true), Loc(Loc) {
-    *reinterpret_cast<Expr **>(this + 1) = SubExpr;
+    *getTrailingObjects<Expr *>() = SubExpr;
   }
 
 public:
@@ -1002,12 +1004,12 @@ public:
   // Retrieve the actual argument to the function call.
   const Expr *getExpr() const {
     if (Param.getInt())
-      return *reinterpret_cast<Expr const * const*> (this + 1);
+      return *getTrailingObjects<Expr *>();
     return getParam()->getDefaultArg();
   }
   Expr *getExpr() {
     if (Param.getInt())
-      return *reinterpret_cast<Expr **> (this + 1);
+      return *getTrailingObjects<Expr *>();
     return getParam()->getDefaultArg();
   }
 
@@ -1031,6 +1033,7 @@ public:
     return child_range(child_iterator(), child_iterator());
   }
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 };
@@ -1441,7 +1444,9 @@ public:
 /// C++1y introduces a new form of "capture" called an init-capture that
 /// includes an initializing expression (rather than capturing a variable),
 /// and which can never occur implicitly.
-class LambdaExpr : public Expr {
+class LambdaExpr final
+    : public Expr,
+      private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
   /// \brief The source range that covers the lambda introducer ([...]).
   SourceRange IntroducerRange;
 
@@ -1476,23 +1481,21 @@ class LambdaExpr : public Expr {
   /// module file just to determine the source range.
   SourceLocation ClosingBrace;
 
-  // Note: The capture initializers are stored directly after the lambda
-  // expression, along with the index variables used to initialize by-copy
-  // array captures.
+  size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+    return NumCaptures + 1;
+  }
 
-  typedef LambdaCapture Capture;
+  size_t numTrailingObjects(OverloadToken<unsigned>) const {
+    return HasArrayIndexVars ? NumCaptures + 1 : 0;
+  }
 
   /// \brief Construct a lambda expression.
   LambdaExpr(QualType T, SourceRange IntroducerRange,
              LambdaCaptureDefault CaptureDefault,
-             SourceLocation CaptureDefaultLoc,
-             ArrayRef<Capture> Captures,
-             bool ExplicitParams,
-             bool ExplicitResultType,
-             ArrayRef<Expr *> CaptureInits,
-             ArrayRef<VarDecl *> ArrayIndexVars,
-             ArrayRef<unsigned> ArrayIndexStarts,
-             SourceLocation ClosingBrace,
+             SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
+             bool ExplicitParams, bool ExplicitResultType,
+             ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
+             ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
              bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct an empty lambda expression.
@@ -1503,53 +1506,35 @@ class LambdaExpr : public Expr {
     getStoredStmts()[NumCaptures] = nullptr;
   }
 
-  Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
+  Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
 
-  Stmt *const *getStoredStmts() const {
-    return reinterpret_cast<Stmt *const *>(this + 1);
-  }
+  Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
 
   /// \brief Retrieve the mapping from captures to the first array index
   /// variable.
-  unsigned *getArrayIndexStarts() {
-    return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1);
-  }
+  unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
 
   const unsigned *getArrayIndexStarts() const {
-    return reinterpret_cast<const unsigned *>(getStoredStmts() + NumCaptures +
-                                              1);
+    return getTrailingObjects<unsigned>();
   }
 
   /// \brief Retrieve the complete set of array-index variables.
-  VarDecl **getArrayIndexVars() {
-    unsigned ArrayIndexSize = llvm::RoundUpToAlignment(
-        sizeof(unsigned) * (NumCaptures + 1), llvm::alignOf<VarDecl *>());
-    return reinterpret_cast<VarDecl **>(
-        reinterpret_cast<char *>(getArrayIndexStarts()) + ArrayIndexSize);
-  }
+  VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
 
   VarDecl *const *getArrayIndexVars() const {
-    unsigned ArrayIndexSize = llvm::RoundUpToAlignment(
-        sizeof(unsigned) * (NumCaptures + 1), llvm::alignOf<VarDecl *>());
-    return reinterpret_cast<VarDecl *const *>(
-        reinterpret_cast<const char *>(getArrayIndexStarts()) + ArrayIndexSize);
+    return getTrailingObjects<VarDecl *>();
   }
 
 public:
   /// \brief Construct a new lambda expression.
-  static LambdaExpr *Create(const ASTContext &C,
-                            CXXRecordDecl *Class,
-                            SourceRange IntroducerRange,
-                            LambdaCaptureDefault CaptureDefault,
-                            SourceLocation CaptureDefaultLoc,
-                            ArrayRef<Capture> Captures,
-                            bool ExplicitParams,
-                            bool ExplicitResultType,
-                            ArrayRef<Expr *> CaptureInits,
-                            ArrayRef<VarDecl *> ArrayIndexVars,
-                            ArrayRef<unsigned> ArrayIndexStarts,
-                            SourceLocation ClosingBrace,
-                            bool ContainsUnexpandedParameterPack);
+  static LambdaExpr *
+  Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
+         LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
+         ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
+         bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
+         ArrayRef<VarDecl *> ArrayIndexVars,
+         ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
+         bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct a new lambda expression that will be deserialized from
   /// an external source.
@@ -1572,7 +1557,7 @@ public:
 
   /// \brief An iterator that walks over the captures of the lambda,
   /// both implicit and explicit.
-  typedef const Capture *capture_iterator;
+  typedef const LambdaCapture *capture_iterator;
 
   /// \brief An iterator over a range of lambda captures.
   typedef llvm::iterator_range<capture_iterator> capture_range;
@@ -1709,9 +1694,11 @@ public:
   SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
 
   child_range children() {
+    // Includes initialization exprs plus body stmt
     return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
   }
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 };
@@ -2226,7 +2213,9 @@ public:
 ///   __is_enum(std::string) == false
 ///   __is_trivially_constructible(vector<int>, int*, int*)
 /// \endcode
-class TypeTraitExpr : public Expr {
+class TypeTraitExpr final
+    : public Expr,
+      private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
   /// \brief The location of the type trait keyword.
   SourceLocation Loc;
   
@@ -2243,16 +2232,10 @@ class TypeTraitExpr : public Expr {
 
   TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
 
-  /// \brief Retrieve the argument types.
-  TypeSourceInfo **getTypeSourceInfos() {
-    return reinterpret_cast<TypeSourceInfo **>(this+1);
-  }
-  
-  /// \brief Retrieve the argument types.
-  TypeSourceInfo * const *getTypeSourceInfos() const {
-    return reinterpret_cast<TypeSourceInfo * const*>(this+1);
+  size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
+    return getNumArgs();
   }
-  
+
 public:
   /// \brief Create a new type trait expression.
   static TypeTraitExpr *Create(const ASTContext &C, QualType T,
@@ -2284,22 +2267,9 @@ public:
   }
   
   /// \brief Retrieve the argument types.
-  ArrayRef<TypeSourceInfo *> getArgs() const { 
-    return llvm::makeArrayRef(getTypeSourceInfos(), getNumArgs());
-  }
-  
-  typedef TypeSourceInfo **arg_iterator;
-  arg_iterator arg_begin() { 
-    return getTypeSourceInfos(); 
-  }
-  arg_iterator arg_end() { 
-    return getTypeSourceInfos() + getNumArgs(); 
-  }
-
-  typedef TypeSourceInfo const * const *arg_const_iterator;
-  arg_const_iterator arg_begin() const { return getTypeSourceInfos(); }
-  arg_const_iterator arg_end() const { 
-    return getTypeSourceInfos() + getNumArgs(); 
+  ArrayRef<TypeSourceInfo *> getArgs() const {
+    return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
+                              getNumArgs());
   }
 
   SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
@@ -2314,9 +2284,9 @@ public:
     return child_range(child_iterator(), child_iterator());
   }
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
-
 };
 
 /// \brief An Embarcadero array type trait, as used in the implementation of
@@ -2899,7 +2869,9 @@ public:
 /// This expression also tracks whether the sub-expression contains a
 /// potentially-evaluated block literal.  The lifetime of a block
 /// literal is the extent of the enclosing scope.
-class ExprWithCleanups : public Expr {
+class ExprWithCleanups final
+    : public Expr,
+      private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
 public:
   /// The type of objects that are kept in the cleanup.
   /// It's useful to remember the set of blocks;  we could also
@@ -2913,12 +2885,7 @@ private:
   ExprWithCleanups(EmptyShell, unsigned NumObjects);
   ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
 
-  CleanupObject *getObjectsBuffer() {
-    return reinterpret_cast<CleanupObject*>(this + 1);
-  }
-  const CleanupObject *getObjectsBuffer() const {
-    return reinterpret_cast<const CleanupObject*>(this + 1);
-  }
+  friend TrailingObjects;
   friend class ASTStmtReader;
 
 public:
@@ -2929,7 +2896,8 @@ public:
                                   ArrayRef<CleanupObject> objects);
 
   ArrayRef<CleanupObject> getObjects() const {
-    return llvm::makeArrayRef(getObjectsBuffer(), getNumObjects());
+    return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
+                              getNumObjects());
   }
 
   unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
@@ -2981,7 +2949,9 @@ public:
 /// When the returned expression is instantiated, it may resolve to a
 /// constructor call, conversion function call, or some kind of type
 /// conversion.
-class CXXUnresolvedConstructExpr : public Expr {
+class CXXUnresolvedConstructExpr final
+    : public Expr,
+      private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
   /// \brief The type being constructed.
   TypeSourceInfo *Type;
 
@@ -3002,6 +2972,7 @@ class CXXUnresolvedConstructExpr : public Expr {
   CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
     : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
 
 public:
@@ -3036,13 +3007,11 @@ public:
   unsigned arg_size() const { return NumArgs; }
 
   typedef Expr** arg_iterator;
-  arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
+  arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
   arg_iterator arg_end() { return arg_begin() + NumArgs; }
 
   typedef const Expr* const * const_arg_iterator;
-  const_arg_iterator arg_begin() const {
-    return reinterpret_cast<const Expr* const *>(this + 1);
-  }
+  const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
   const_arg_iterator arg_end() const {
     return arg_begin() + NumArgs;
   }
@@ -3075,7 +3044,7 @@ public:
 
   // Iterators
   child_range children() {
-    Stmt **begin = reinterpret_cast<Stmt**>(this+1);
+    Stmt **begin = reinterpret_cast<Stmt **>(arg_begin());
     return child_range(begin, begin + NumArgs);
   }
 };
@@ -3608,7 +3577,9 @@ public:
 ///   static const unsigned value = sizeof...(Types);
 /// };
 /// \endcode
-class SizeOfPackExpr : public Expr {
+class SizeOfPackExpr final
+    : public Expr,
+      private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
   /// \brief The location of the \c sizeof keyword.
   SourceLocation OperatorLoc;
 
@@ -3633,6 +3604,7 @@ class SizeOfPackExpr : public Expr {
   /// \brief The parameter pack.
   NamedDecl *Pack;
 
+  friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 
@@ -3649,7 +3621,7 @@ class SizeOfPackExpr : public Expr {
         Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
     assert((!Length || PartialArgs.empty()) &&
            "have partial args for non-dependent sizeof... expression");
-    TemplateArgument *Args = reinterpret_cast<TemplateArgument *>(this + 1);
+    TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
     std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
   }
 
@@ -3700,8 +3672,7 @@ public:
   /// \brief Get
   ArrayRef<TemplateArgument> getPartialArguments() const {
     assert(isPartiallySubstituted());
-    const TemplateArgument *Args =
-        reinterpret_cast<const TemplateArgument *>(this + 1);
+    const TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
     return llvm::makeArrayRef(Args, Args + Length);
   }
 
@@ -3837,7 +3808,9 @@ public:
 /// };
 /// template struct S<int, int>;
 /// \endcode
-class FunctionParmPackExpr : public Expr {
+class FunctionParmPackExpr final
+    : public Expr,
+      private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> {
   /// \brief The function parameter pack which was referenced.
   ParmVarDecl *ParamPack;
 
@@ -3851,6 +3824,7 @@ class FunctionParmPackExpr : public Expr {
                        SourceLocation NameLoc, unsigned NumParams,
                        ParmVarDecl *const *Params);
 
+  friend TrailingObjects;
   friend class ASTReader;
   friend class ASTStmtReader;
 
@@ -3871,7 +3845,7 @@ public:
   /// \brief Iterators over the parameters which the parameter pack expanded
   /// into.
   typedef ParmVarDecl * const *iterator;
-  iterator begin() const { return reinterpret_cast<iterator>(this+1); }
+  iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
   iterator end() const { return begin() + NumParameters; }
 
   /// \brief Get the number of parameters in this parameter pack.
index bdd7a45..f9757b2 100644 (file)
@@ -3711,8 +3711,7 @@ DesignatedInitExpr::Create(const ASTContext &C, Designator *Designators,
                            ArrayRef<Expr*> IndexExprs,
                            SourceLocation ColonOrEqualLoc,
                            bool UsesColonSyntax, Expr *Init) {
-  void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
-                             sizeof(Stmt *) * (IndexExprs.size() + 1),
+  void *Mem = C.Allocate(totalSizeToAlloc<Stmt *>(IndexExprs.size() + 1),
                          llvm::alignOf<DesignatedInitExpr>());
   return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators,
                                       ColonOrEqualLoc, UsesColonSyntax,
@@ -3721,8 +3720,8 @@ DesignatedInitExpr::Create(const ASTContext &C, Designator *Designators,
 
 DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(const ASTContext &C,
                                                     unsigned NumIndexExprs) {
-  void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
-                         sizeof(Stmt *) * (NumIndexExprs + 1), 8);
+  void *Mem = C.Allocate(totalSizeToAlloc<Stmt *>(NumIndexExprs + 1),
+                         llvm::alignOf<DesignatedInitExpr>());
   return new (Mem) DesignatedInitExpr(NumIndexExprs + 1);
 }
 
@@ -3764,22 +3763,19 @@ SourceLocation DesignatedInitExpr::getLocEnd() const {
 
 Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
   assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
-  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
-  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
+  return getSubExpr(D.ArrayOrRange.Index + 1);
 }
 
 Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const {
   assert(D.Kind == Designator::ArrayRangeDesignator &&
          "Requires array range designator");
-  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
-  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
+  return getSubExpr(D.ArrayOrRange.Index + 1);
 }
 
 Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const {
   assert(D.Kind == Designator::ArrayRangeDesignator &&
          "Requires array range designator");
-  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
-  return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
+  return getSubExpr(D.ArrayOrRange.Index + 2);
 }
 
 /// \brief Replaces the designator at index @p Idx with the series
@@ -3863,9 +3859,9 @@ const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
 PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &Context,
                                            EmptyShell sh,
                                            unsigned numSemanticExprs) {
-  void *buffer = Context.Allocate(sizeof(PseudoObjectExpr) +
-                                    (1 + numSemanticExprs) * sizeof(Expr*),
-                                  llvm::alignOf<PseudoObjectExpr>());
+  void *buffer =
+      Context.Allocate(totalSizeToAlloc<Expr *>(1 + numSemanticExprs),
+                       llvm::alignOf<PseudoObjectExpr>());
   return new(buffer) PseudoObjectExpr(sh, numSemanticExprs);
 }
 
@@ -3892,8 +3888,7 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax,
     assert(semantics[resultIndex]->getObjectKind() == OK_Ordinary);
   }
 
-  void *buffer = C.Allocate(sizeof(PseudoObjectExpr) +
-                              (1 + semantics.size()) * sizeof(Expr*),
+  void *buffer = C.Allocate(totalSizeToAlloc<Expr *>(semantics.size() + 1),
                             llvm::alignOf<PseudoObjectExpr>());
   return new(buffer) PseudoObjectExpr(type, VK, syntax, semantics,
                                       resultIndex);
index 4bb4b50..d35efcb 100644 (file)
@@ -766,7 +766,7 @@ const IdentifierInfo *UserDefinedLiteral::getUDSuffix() const {
 CXXDefaultArgExpr *
 CXXDefaultArgExpr::Create(const ASTContext &C, SourceLocation Loc, 
                           ParmVarDecl *Param, Expr *SubExpr) {
-  void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
+  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(1));
   return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, 
                                      SubExpr);
 }
@@ -924,29 +924,22 @@ LambdaCaptureKind LambdaCapture::getCaptureKind() const {
   return CapByCopy ? LCK_ByCopy : LCK_ByRef;
 }
 
-LambdaExpr::LambdaExpr(QualType T,
-                       SourceRange IntroducerRange,
+LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
                        LambdaCaptureDefault CaptureDefault,
                        SourceLocation CaptureDefaultLoc,
-                       ArrayRef<Capture> Captures,
-                       bool ExplicitParams,
-                       bool ExplicitResultType,
-                       ArrayRef<Expr *> CaptureInits,
+                       ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
+                       bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
                        ArrayRef<VarDecl *> ArrayIndexVars,
                        ArrayRef<unsigned> ArrayIndexStarts,
                        SourceLocation ClosingBrace,
                        bool ContainsUnexpandedParameterPack)
-  : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
-         T->isDependentType(), T->isDependentType(), T->isDependentType(),
-         ContainsUnexpandedParameterPack),
-    IntroducerRange(IntroducerRange),
-    CaptureDefaultLoc(CaptureDefaultLoc),
-    NumCaptures(Captures.size()),
-    CaptureDefault(CaptureDefault),
-    ExplicitParams(ExplicitParams),
-    ExplicitResultType(ExplicitResultType),
-    ClosingBrace(ClosingBrace)
-{
+    : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(),
+           T->isDependentType(), T->isDependentType(),
+           ContainsUnexpandedParameterPack),
+      IntroducerRange(IntroducerRange), CaptureDefaultLoc(CaptureDefaultLoc),
+      NumCaptures(Captures.size()), CaptureDefault(CaptureDefault),
+      ExplicitParams(ExplicitParams), ExplicitResultType(ExplicitResultType),
+      ClosingBrace(ClosingBrace) {
   assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
   CXXRecordDecl *Class = getLambdaClass();
   CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
@@ -957,8 +950,9 @@ LambdaExpr::LambdaExpr(QualType T,
   const ASTContext &Context = Class->getASTContext();
   Data.NumCaptures = NumCaptures;
   Data.NumExplicitCaptures = 0;
-  Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
-  Capture *ToCapture = Data.Captures;
+  Data.Captures =
+      (LambdaCapture *)Context.Allocate(sizeof(LambdaCapture) * NumCaptures);
+  LambdaCapture *ToCapture = Data.Captures;
   for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
     if (Captures[I].isExplicit())
       ++Data.NumExplicitCaptures;
@@ -986,30 +980,20 @@ LambdaExpr::LambdaExpr(QualType T,
   }
 }
 
-LambdaExpr *LambdaExpr::Create(const ASTContext &Context,
-                               CXXRecordDecl *Class,
-                               SourceRange IntroducerRange,
-                               LambdaCaptureDefault CaptureDefault,
-                               SourceLocation CaptureDefaultLoc,
-                               ArrayRef<Capture> Captures,
-                               bool ExplicitParams,
-                               bool ExplicitResultType,
-                               ArrayRef<Expr *> CaptureInits,
-                               ArrayRef<VarDecl *> ArrayIndexVars,
-                               ArrayRef<unsigned> ArrayIndexStarts,
-                               SourceLocation ClosingBrace,
-                               bool ContainsUnexpandedParameterPack) {
+LambdaExpr *LambdaExpr::Create(
+    const ASTContext &Context, CXXRecordDecl *Class,
+    SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault,
+    SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
+    bool ExplicitParams, bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
+    ArrayRef<VarDecl *> ArrayIndexVars, ArrayRef<unsigned> ArrayIndexStarts,
+    SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
   QualType T = Context.getTypeDeclType(Class);
 
-  unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (Captures.size() + 1);
-  if (!ArrayIndexVars.empty()) {
-    Size += sizeof(unsigned) * (Captures.size() + 1);
-    // Realign for following VarDecl array.
-    Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<VarDecl*>());
-    Size += sizeof(VarDecl *) * ArrayIndexVars.size();
-  }
+  unsigned Size = totalSizeToAlloc<Stmt *, unsigned, VarDecl *>(
+      Captures.size() + 1, ArrayIndexVars.empty() ? 0 : Captures.size() + 1,
+      ArrayIndexVars.size());
   void *Mem = Context.Allocate(Size);
   return new (Mem) LambdaExpr(T, IntroducerRange,
                               CaptureDefault, CaptureDefaultLoc, Captures,
@@ -1021,10 +1005,9 @@ LambdaExpr *LambdaExpr::Create(const ASTContext &Context,
 LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
                                            unsigned NumCaptures,
                                            unsigned NumArrayIndexVars) {
-  unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (NumCaptures + 1);
-  if (NumArrayIndexVars)
-    Size += sizeof(VarDecl) * NumArrayIndexVars
-          + sizeof(unsigned) * (NumCaptures + 1);
+  unsigned Size = totalSizeToAlloc<Stmt *, unsigned, VarDecl *>(
+      NumCaptures + 1, NumArrayIndexVars ? NumCaptures + 1 : 0,
+      NumArrayIndexVars);
   void *Mem = C.Allocate(Size);
   return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars > 0);
 }
@@ -1108,7 +1091,7 @@ CompoundStmt *LambdaExpr::getBody() const {
     *const_cast<clang::Stmt **>(&getStoredStmts()[NumCaptures]) =
         getCallOperator()->getBody();
 
-  return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
+  return static_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
 }
 
 bool LambdaExpr::isMutable() const {
@@ -1125,14 +1108,13 @@ ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
     SubExpr(subexpr) {
   ExprWithCleanupsBits.NumObjects = objects.size();
   for (unsigned i = 0, e = objects.size(); i != e; ++i)
-    getObjectsBuffer()[i] = objects[i];
+    getTrailingObjects<CleanupObject>()[i] = objects[i];
 }
 
 ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
                                            ArrayRef<CleanupObject> objects) {
-  size_t size = sizeof(ExprWithCleanups)
-              + objects.size() * sizeof(CleanupObject);
-  void *buffer = C.Allocate(size, llvm::alignOf<ExprWithCleanups>());
+  void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()),
+                            llvm::alignOf<ExprWithCleanups>());
   return new (buffer) ExprWithCleanups(subexpr, objects);
 }
 
@@ -1144,8 +1126,8 @@ ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
 ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
                                            EmptyShell empty,
                                            unsigned numObjects) {
-  size_t size = sizeof(ExprWithCleanups) + numObjects * sizeof(CleanupObject);
-  void *buffer = C.Allocate(size, llvm::alignOf<ExprWithCleanups>());
+  void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(numObjects),
+                            llvm::alignOf<ExprWithCleanups>());
   return new (buffer) ExprWithCleanups(empty, numObjects);
 }
 
@@ -1165,7 +1147,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
     LParenLoc(LParenLoc),
     RParenLoc(RParenLoc),
     NumArgs(Args.size()) {
-  Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
+  Expr **StoredArgs = getTrailingObjects<Expr *>();
   for (unsigned I = 0; I != Args.size(); ++I) {
     if (Args[I]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
@@ -1180,16 +1162,14 @@ CXXUnresolvedConstructExpr::Create(const ASTContext &C,
                                    SourceLocation LParenLoc,
                                    ArrayRef<Expr*> Args,
                                    SourceLocation RParenLoc) {
-  void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
-                         sizeof(Expr *) * Args.size());
+  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
   return new (Mem) CXXUnresolvedConstructExpr(Type, LParenLoc, Args, RParenLoc);
 }
 
 CXXUnresolvedConstructExpr *
 CXXUnresolvedConstructExpr::CreateEmpty(const ASTContext &C, unsigned NumArgs) {
   Stmt::EmptyShell Empty;
-  void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
-                         sizeof(Expr *) * NumArgs);
+  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumArgs));
   return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
 }
 
@@ -1404,16 +1384,16 @@ SizeOfPackExpr::Create(ASTContext &Context, SourceLocation OperatorLoc,
                        SourceLocation RParenLoc,
                        Optional<unsigned> Length,
                        ArrayRef<TemplateArgument> PartialArgs) {
-  void *Storage = Context.Allocate(
-      sizeof(SizeOfPackExpr) + sizeof(TemplateArgument) * PartialArgs.size());
+  void *Storage =
+      Context.Allocate(totalSizeToAlloc<TemplateArgument>(PartialArgs.size()));
   return new (Storage) SizeOfPackExpr(Context.getSizeType(), OperatorLoc, Pack,
                                       PackLoc, RParenLoc, Length, PartialArgs);
 }
 
 SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
                                                    unsigned NumPartialArgs) {
-  void *Storage = Context.Allocate(
-      sizeof(SizeOfPackExpr) + sizeof(TemplateArgument) * NumPartialArgs);
+  void *Storage =
+      Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumPartialArgs));
   return new (Storage) SizeOfPackExpr(EmptyShell(), NumPartialArgs);
 }
 
@@ -1440,24 +1420,22 @@ FunctionParmPackExpr::FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
       ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
   if (Params)
     std::uninitialized_copy(Params, Params + NumParams,
-                            reinterpret_cast<ParmVarDecl **>(this + 1));
+                            getTrailingObjects<ParmVarDecl *>());
 }
 
 FunctionParmPackExpr *
 FunctionParmPackExpr::Create(const ASTContext &Context, QualType T,
                              ParmVarDecl *ParamPack, SourceLocation NameLoc,
                              ArrayRef<ParmVarDecl *> Params) {
-  return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
-                               sizeof(ParmVarDecl*) * Params.size()))
-    FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), Params.data());
+  return new (Context.Allocate(totalSizeToAlloc<ParmVarDecl *>(Params.size())))
+      FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), Params.data());
 }
 
 FunctionParmPackExpr *
 FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
                                   unsigned NumParams) {
-  return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
-                               sizeof(ParmVarDecl*) * NumParams))
-    FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
+  return new (Context.Allocate(totalSizeToAlloc<ParmVarDecl *>(NumParams)))
+      FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
 }
 
 void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
@@ -1494,8 +1472,8 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
   TypeTraitExprBits.Value = Value;
   TypeTraitExprBits.NumArgs = Args.size();
 
-  TypeSourceInfo **ToArgs = getTypeSourceInfos();
-  
+  TypeSourceInfo **ToArgs = getTrailingObjects<TypeSourceInfo *>();
+
   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
     if (Args[I]->getType()->isDependentType())
       setValueDependent(true);
@@ -1514,15 +1492,13 @@ TypeTraitExpr *TypeTraitExpr::Create(const ASTContext &C, QualType T,
                                      ArrayRef<TypeSourceInfo *> Args,
                                      SourceLocation RParenLoc,
                                      bool Value) {
-  unsigned Size = sizeof(TypeTraitExpr) + sizeof(TypeSourceInfo*) * Args.size();
-  void *Mem = C.Allocate(Size);
+  void *Mem = C.Allocate(totalSizeToAlloc<TypeSourceInfo *>(Args.size()));
   return new (Mem) TypeTraitExpr(T, Loc, Kind, Args, RParenLoc, Value);
 }
 
 TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
                                                  unsigned NumArgs) {
-  unsigned Size = sizeof(TypeTraitExpr) + sizeof(TypeSourceInfo*) * NumArgs;
-  void *Mem = C.Allocate(Size);
+  void *Mem = C.Allocate(totalSizeToAlloc<TypeSourceInfo *>(NumArgs));
   return new (Mem) TypeTraitExpr(EmptyShell());
 }
 
index 4082dec..40e0f45 100644 (file)
@@ -1445,7 +1445,8 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
   unsigned NumObjects = Record[Idx++];
   assert(NumObjects == E->getNumObjects());
   for (unsigned i = 0; i != NumObjects; ++i)
-    E->getObjectsBuffer()[i] = ReadDeclAs<BlockDecl>(Record, Idx);
+    E->getTrailingObjects<BlockDecl *>()[i] =
+        ReadDeclAs<BlockDecl>(Record, Idx);
 
   E->SubExpr = Reader.ReadSubExpr();
 }
@@ -1541,7 +1542,7 @@ void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
   E->Loc = Range.getBegin();
   E->RParenLoc = Range.getEnd();
 
-  TypeSourceInfo **Args = E->getTypeSourceInfos();
+  TypeSourceInfo **Args = E->getTrailingObjects<TypeSourceInfo *>();
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     Args[I] = GetTypeSourceInfo(Record, Idx);
 }
@@ -1589,7 +1590,7 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
   E->Pack = Reader.ReadDeclAs<NamedDecl>(F, Record, Idx);
   if (E->isPartiallySubstituted()) {
     assert(E->Length == NumPartialArgs);
-    for (auto *I = reinterpret_cast<TemplateArgument *>(E + 1),
+    for (auto *I = E->getTrailingObjects<TemplateArgument>(),
               *E = I + NumPartialArgs;
          I != E; ++I)
       new (I) TemplateArgument(Reader.ReadTemplateArgument(F, Record, Idx));
@@ -1624,7 +1625,7 @@ void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
   E->NumParameters = Record[Idx++];
   E->ParamPack = ReadDeclAs<ParmVarDecl>(Record, Idx);
   E->NameLoc = ReadSourceLocation(Record, Idx);
-  ParmVarDecl **Parms = reinterpret_cast<ParmVarDecl**>(E+1);
+  ParmVarDecl **Parms = E->getTrailingObjects<ParmVarDecl *>();
   for (unsigned i = 0, n = E->NumParameters; i != n; ++i)
     Parms[i] = ReadDeclAs<ParmVarDecl>(Record, Idx);
 }