Merge pull request #13625 from rintaro/syntax-cleanup

[Syntax] Fix miscellaneous round trip failures
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index d4b007c..f4707e8 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -1061,23 +1061,18 @@
   }
 };
 
-/// A template base class for instructions that take a single regular SILValue
-/// operand, a set of type dependent operands and has no result
-/// or a single value result. The operands are tail allocated after the
-/// instruction. Further trailing data can be allocated as well if
-/// TRAILING_TYPES are provided.
+/// A template base class for instructions that a variable number of SILValue
+/// operands, and has zero or one value results. The operands are tail allocated
+/// after the instruction. Further trailing data can be allocated as well if
+/// OtherTrailingTypes are provided.
 template<SILInstructionKind Kind,
          typename Derived,
          typename Base,
          typename... OtherTrailingTypes>
-class UnaryInstructionWithTypeDependentOperandsBase
+class InstructionBaseWithTrailingOperands
     : public InstructionBase<Kind, Base>,
       protected llvm::TrailingObjects<Derived, Operand, OtherTrailingTypes...> {
 
-  unsigned getNumOperandsStorage() const {
-    return SILInstruction::Bits.UIWTDOB.NumOperands;
-  }
-
 protected:
   friend llvm::TrailingObjects<Derived, Operand, OtherTrailingTypes...>;
 
@@ -1088,54 +1083,112 @@
 
 public:
   template <typename... Args>
-  UnaryInstructionWithTypeDependentOperandsBase(
-      SILDebugLocation debugLoc, SILValue operand,
-      ArrayRef<SILValue> typeDependentOperands,
-      Args &&...args)
-        : InstructionBase<Kind, Base>(debugLoc, std::forward<Args>(args)...) {
-    SILInstruction::Bits.UIWTDOB.NumOperands = 1 + typeDependentOperands.size();
+  InstructionBaseWithTrailingOperands(ArrayRef<SILValue> Operands,
+                                      Args &&...args)
+        : InstructionBase<Kind, Base>(std::forward<Args>(args)...) {
+    SILInstruction::Bits.IBWTO.NumOperands = Operands.size();
     TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                           operand, typeDependentOperands);
+                                           Operands);
+  }
+
+  template <typename... Args>
+  InstructionBaseWithTrailingOperands(SILValue Operand0,
+                                      ArrayRef<SILValue> Operands,
+                                      Args &&...args)
+        : InstructionBase<Kind, Base>(std::forward<Args>(args)...) {
+    SILInstruction::Bits.IBWTO.NumOperands = Operands.size() + 1;
+    TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
+                                           Operand0, Operands);
+  }
+
+  template <typename... Args>
+  InstructionBaseWithTrailingOperands(SILValue Operand0,
+                                      SILValue Operand1,
+                                      ArrayRef<SILValue> Operands,
+                                      Args &&...args)
+        : InstructionBase<Kind, Base>(std::forward<Args>(args)...) {
+    SILInstruction::Bits.IBWTO.NumOperands = Operands.size() + 2;
+    TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
+                                           Operand0, Operand1, Operands);
   }
 
   // Destruct tail allocated objects.
-  ~UnaryInstructionWithTypeDependentOperandsBase() {
-    Operand *Operands = &getAllOperands()[0];
-    for (unsigned i = 0, end = getNumOperandsStorage(); i < end; ++i) {
+  ~InstructionBaseWithTrailingOperands() {
+    Operand *Operands = TrailingObjects::template getTrailingObjects<Operand>();
+    auto end = SILInstruction::Bits.IBWTO.NumOperands;
+    for (unsigned i = 0; i < end; ++i) {
       Operands[i].~Operand();
     }
   }
 
-  size_t numTrailingObjects(
-    typename TrailingObjects::template OverloadToken<Operand>) const {
-    return getNumOperandsStorage();
+  size_t numTrailingObjects(typename TrailingObjects::template
+                            OverloadToken<Operand>) const {
+    return SILInstruction::Bits.IBWTO.NumOperands;
   }
 
-  unsigned getNumTypeDependentOperands() const {
-    return getNumOperandsStorage() - 1;
-  }
-
-  SILValue getOperand() const { return getAllOperands()[0].get(); }
-  void setOperand(SILValue V) { getAllOperands()[0].set(V); }
-
-  Operand &getOperandRef() { return getAllOperands()[0]; }
-
   ArrayRef<Operand> getAllOperands() const {
     return {TrailingObjects::template getTrailingObjects<Operand>(),
-            static_cast<size_t>(getNumOperandsStorage())};
+            SILInstruction::Bits.IBWTO.NumOperands};
   }
 
   MutableArrayRef<Operand> getAllOperands() {
     return {TrailingObjects::template getTrailingObjects<Operand>(),
-            static_cast<size_t>(getNumOperandsStorage())};
+            SILInstruction::Bits.IBWTO.NumOperands};
+  }
+};
+
+/// A template base class for instructions that take a single regular SILValue
+/// operand, a set of type dependent operands and has no result
+/// or a single value result. The operands are tail allocated after the
+/// instruction. Further trailing data can be allocated as well if
+/// TRAILING_TYPES are provided.
+template<SILInstructionKind Kind,
+         typename Derived,
+         typename Base,
+         typename... OtherTrailingTypes>
+class UnaryInstructionWithTypeDependentOperandsBase
+    : public InstructionBaseWithTrailingOperands<Kind, Derived, Base,
+                                                 OtherTrailingTypes...> {
+protected:
+  friend InstructionBaseWithTrailingOperands<Kind, Derived, Operand,
+                                             OtherTrailingTypes...>;
+
+  typedef InstructionBaseWithTrailingOperands<
+      Kind, Derived, Operand, OtherTrailingTypes...> TrailingObjects;
+
+public:
+  template <typename... Args>
+  UnaryInstructionWithTypeDependentOperandsBase(SILDebugLocation debugLoc,
+                                       SILValue operand,
+                                       ArrayRef<SILValue> typeDependentOperands,
+                                       Args &&...args)
+      : InstructionBaseWithTrailingOperands<Kind, Derived, Base,
+                                            OtherTrailingTypes...>(
+                                              operand, typeDependentOperands,
+                                              debugLoc,
+                                              std::forward<Args>(args)...) {}
+
+  unsigned getNumTypeDependentOperands() const {
+    return this->getAllOperands().size() - 1;
+  }
+
+  SILValue getOperand() const {
+    return this->getAllOperands()[0].get();
+  }
+  void setOperand(SILValue V) {
+    this->getAllOperands()[0].set(V);
+  }
+
+  Operand &getOperandRef() {
+    return this->getAllOperands()[0];
   }
 
   ArrayRef<Operand> getTypeDependentOperands() const {
-    return getAllOperands().slice(1);
+    return this->getAllOperands().slice(1);
   }
 
   MutableArrayRef<Operand> getTypeDependentOperands() {
-    return getAllOperands().slice(1);
+    return this->getAllOperands().slice(1);
   }
 };
 
@@ -1282,6 +1335,9 @@
 };
 
 /// The base class for AllocRefInst and AllocRefDynamicInst.
+///
+/// The first NumTailTypes operands are counts for the tail allocated
+/// elements, the remaining operands are opened archetype operands.
 class AllocRefInstBase : public AllocationInst {
 protected:
 
@@ -1289,19 +1345,11 @@
                    SILDebugLocation DebugLoc,
                    SILType ObjectType,
                    bool objc, bool canBeOnStack,
-                   ArrayRef<SILType> ElementTypes,
-                   ArrayRef<SILValue> AllOperands);
+                   ArrayRef<SILType> ElementTypes);
 
-  /// The first NumTailTypes operands are counts for the tail allocated
-  /// elements, the remaining operands are opened archetype operands.
-  TailAllocatedOperandList<0> Operands;
-
-  SILType *getTypeStorage() {
-    return reinterpret_cast<SILType*>(Operands.asArray().end());
-  }
-
+  SILType *getTypeStorage();
   const SILType *getTypeStorage() const {
-    return reinterpret_cast<const SILType*>(Operands.asArray().end());
+    return const_cast<AllocRefInstBase*>(this)->getTypeStorage();
   }
 
   unsigned getNumTailTypes() const {
@@ -1333,13 +1381,8 @@
     return getAllOperands().slice(0, getNumTailTypes());
   }
 
-  ArrayRef<Operand> getAllOperands() const {
-    return Operands.asArray();
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return Operands.asArray();
-  }
+  ArrayRef<Operand> getAllOperands() const;
+  MutableArrayRef<Operand> getAllOperands();
   
   /// Whether to use Objective-C's allocation mechanism (+allocWithZone:).
   bool isObjC() const {
@@ -1353,8 +1396,11 @@
 /// Optionally, the allocated instance contains space for one or more tail-
 /// allocated arrays.
 class AllocRefInst final
-    : public InstructionBase<SILInstructionKind::AllocRefInst,
-                             AllocRefInstBase> {
+    : public InstructionBaseWithTrailingOperands<
+                                               SILInstructionKind::AllocRefInst,
+                                               AllocRefInst,
+                                               AllocRefInstBase, SILType> {
+  friend AllocRefInstBase;
   friend SILBuilder;
 
   AllocRefInst(SILDebugLocation DebugLoc, SILFunction &F,
@@ -1362,10 +1408,11 @@
                bool objc, bool canBeOnStack,
                ArrayRef<SILType> ElementTypes,
                ArrayRef<SILValue> AllOperands)
-      : InstructionBase(DebugLoc, ObjectType, objc,
-                        canBeOnStack, ElementTypes, AllOperands) {
-    static_assert(sizeof(AllocRefInst) == sizeof(AllocRefInstBase),
-                  "subclass has extra storage");
+      : InstructionBaseWithTrailingOperands(AllOperands, DebugLoc, ObjectType,
+                        objc, canBeOnStack, ElementTypes) {
+    assert(AllOperands.size() >= ElementTypes.size());
+    std::uninitialized_copy(ElementTypes.begin(), ElementTypes.end(),
+                            getTrailingObjects<SILType>());
   }
 
   static AllocRefInst *create(SILDebugLocation DebugLoc, SILFunction &F,
@@ -1392,8 +1439,11 @@
 /// Optionally, the allocated instance contains space for one or more tail-
 /// allocated arrays.
 class AllocRefDynamicInst final
-    : public InstructionBase<SILInstructionKind::AllocRefDynamicInst,
-                             AllocRefInstBase> {
+    : public InstructionBaseWithTrailingOperands<
+                                        SILInstructionKind::AllocRefDynamicInst,
+                                        AllocRefDynamicInst,
+                                        AllocRefInstBase, SILType> {
+  friend AllocRefInstBase;
   friend SILBuilder;
 
   AllocRefDynamicInst(SILDebugLocation DebugLoc,
@@ -1401,9 +1451,11 @@
                       bool objc,
                       ArrayRef<SILType> ElementTypes,
                       ArrayRef<SILValue> AllOperands)
-      : InstructionBase(DebugLoc, ty, objc, false, ElementTypes, AllOperands) {
-    static_assert(sizeof(AllocRefInst) == sizeof(AllocRefInstBase),
-                  "subclass has extra storage");
+      : InstructionBaseWithTrailingOperands(AllOperands, DebugLoc, ty, objc,
+                                            false, ElementTypes) {
+    assert(AllOperands.size() >= ElementTypes.size() + 1);
+    std::uninitialized_copy(ElementTypes.begin(), ElementTypes.end(),
+                            getTrailingObjects<SILType>());
   }
 
   static AllocRefDynamicInst *
@@ -1453,14 +1505,11 @@
 /// is an address pointing to the contained element. The contained
 /// element is uninitialized.
 class AllocBoxInst final
-    : public InstructionBase<SILInstructionKind::AllocBoxInst,
-                             AllocationInst>,
-      private llvm::TrailingObjects<AllocBoxInst, Operand, char> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<
+                                           SILInstructionKind::AllocBoxInst,
+                                           AllocBoxInst, AllocationInst, char> {
   friend SILBuilder;
 
-  unsigned NumOperands;
-
   TailAllocatedDebugVariable VarInfo;
 
   AllocBoxInst(SILDebugLocation DebugLoc, CanSILBoxType BoxType,
@@ -1472,18 +1521,7 @@
                               SILOpenedArchetypesState &OpenedArchetypes,
                               SILDebugVariable Var);
 
-  size_t numTrailingObjects(OverloadToken<Operand>) const {
-    return NumOperands;
-  }
-
 public:
-  ~AllocBoxInst() {
-    Operand *Operands = getTrailingObjects<Operand>();
-    for (unsigned i = 0, end = NumOperands; i < end; ++i) {
-      Operands[i].~Operand();
-    }
-  }
-  
   CanSILBoxType getBoxType() const {
     return getType().castTo<SILBoxType>();
   }
@@ -1502,14 +1540,6 @@
     return VarInfo.get(getDecl(), getTrailingObjects<char>());
   };
 
-  ArrayRef<Operand> getAllOperands() const {
-    return {getTrailingObjects<Operand>(), NumOperands};
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return {getTrailingObjects<Operand>(), NumOperands};
-  }
-
   ArrayRef<Operand> getTypeDependentOperands() const {
     return getAllOperands();
   }
@@ -1525,12 +1555,10 @@
 /// is an address pointing to the contained element. The contained
 /// value is uninitialized.
 class AllocExistentialBoxInst final
-    : public InstructionBase<SILInstructionKind::AllocExistentialBoxInst,
-                             AllocationInst>,
-      private llvm::TrailingObjects<AllocExistentialBoxInst, Operand> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<
+                                   SILInstructionKind::AllocExistentialBoxInst,
+                                   AllocExistentialBoxInst, AllocationInst> {
   friend SILBuilder;
-  unsigned NumOperands;
   CanType ConcreteType;
   ArrayRef<ProtocolConformanceRef> Conformances;
 
@@ -1538,7 +1566,10 @@
                           CanType ConcreteType,
                           ArrayRef<ProtocolConformanceRef> Conformances,
                           ArrayRef<SILValue> TypeDependentOperands,
-                          SILFunction *Parent);
+                          SILFunction *Parent)
+    : InstructionBaseWithTrailingOperands(TypeDependentOperands, DebugLoc,
+                                          ExistentialType.getObjectType()),
+      ConcreteType(ConcreteType), Conformances(Conformances) {}
 
   static AllocExistentialBoxInst *
   create(SILDebugLocation DebugLoc, SILType ExistentialType,
@@ -1546,13 +1577,6 @@
          SILFunction *Parent, SILOpenedArchetypesState &OpenedArchetypes);
 
 public:
-  ~AllocExistentialBoxInst() {
-    Operand *Operands = getTrailingObjects<Operand>();
-    for (unsigned i = 0, end = NumOperands; i < end; ++i) {
-      Operands[i].~Operand();
-    }
-  }
-
   CanType getFormalConcreteType() const { return ConcreteType; }
 
   SILType getExistentialType() const { return getType(); }
@@ -1561,14 +1585,6 @@
     return Conformances;
   }
 
-  ArrayRef<Operand> getAllOperands() const {
-    return {getTrailingObjects<Operand>(), NumOperands};
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return {getTrailingObjects<Operand>(), NumOperands};
-  }
-
   ArrayRef<Operand> getTypeDependentOperands() const {
     return getAllOperands();
   }
@@ -2605,22 +2621,14 @@
 /// Represents an invocation of builtin functionality provided by the code
 /// generator.
 class BuiltinInst final
-    : public InstructionBase<SILInstructionKind::BuiltinInst,
-                             SingleValueInstruction>,
-      private llvm::TrailingObjects<BuiltinInst, Operand, Substitution> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<
+                                   SILInstructionKind::BuiltinInst, BuiltinInst,
+                                   SingleValueInstruction, Substitution> {
   friend SILBuilder;
 
   /// The name of the builtin to invoke.
   Identifier Name;
 
-  size_t numTrailingObjects(OverloadToken<Operand>) const {
-    return SILInstruction::Bits.BuiltinInst.NumOperands;
-  }
-  size_t numTrailingObjects(OverloadToken<Substitution>) const {
-    return SILInstruction::Bits.BuiltinInst.NumSubstitutions;
-  }
-
   BuiltinInst(SILDebugLocation DebugLoc, Identifier Name, SILType ReturnType,
               SubstitutionList Substitutions, ArrayRef<SILValue> Args);
 
@@ -2630,12 +2638,6 @@
                              ArrayRef<SILValue> Args, SILModule &M);
 
 public:
-  ~BuiltinInst() {
-    for (auto &op : getAllOperands()) {
-      op.~Operand();
-    }
-  }
-
   /// Return the name of the builtin operation.
   Identifier getName() const { return Name; }
   void setName(Identifier I) { Name = I; }
@@ -2686,16 +2688,6 @@
   }
   
   /// The arguments to the builtin.
-  ArrayRef<Operand> getAllOperands() const {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.BuiltinInst.NumOperands};
-  }
-  /// The arguments to the builtin.
-  MutableArrayRef<Operand> getAllOperands() {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.BuiltinInst.NumOperands};
-  }
-  /// The arguments to the builtin.
   OperandValueArrayRef getArguments() const {
     return OperandValueArrayRef(getAllOperands());
   }
@@ -3524,17 +3516,16 @@
 /// MarkFunctionEscape - Represents the escape point of set of variables due to
 /// a function definition which uses the variables.  This is only valid in Raw
 /// SIL.
-class MarkFunctionEscapeInst
-    : public InstructionBase<SILInstructionKind::MarkFunctionEscapeInst,
-                             NonValueInstruction> {
+class MarkFunctionEscapeInst final
+    : public InstructionBaseWithTrailingOperands<
+                                  SILInstructionKind::MarkFunctionEscapeInst,
+                                  MarkFunctionEscapeInst, NonValueInstruction> {
   friend SILBuilder;
 
-  TailAllocatedOperandList<0> Operands;
-
   /// Private constructor.  Because this is variadic, object creation goes
   /// through 'create()'.
-  MarkFunctionEscapeInst(SILDebugLocation DebugLoc,
-                         ArrayRef<SILValue> Elements);
+  MarkFunctionEscapeInst(SILDebugLocation DebugLoc, ArrayRef<SILValue> Elements)
+    : InstructionBaseWithTrailingOperands(Elements, DebugLoc) {}
 
   /// Construct a MarkFunctionEscapeInst.
   static MarkFunctionEscapeInst *create(SILDebugLocation DebugLoc,
@@ -3544,16 +3535,13 @@
 public:
   /// The elements referenced by this instruction.
   MutableArrayRef<Operand> getElementOperands() {
-    return Operands.getDynamicAsArray();
+    return getAllOperands();
   }
 
   /// The elements referenced by this instruction.
   OperandValueArrayRef getElements() const {
-    return Operands.getDynamicValuesAsArray();
+    return OperandValueArrayRef(getAllOperands());
   }
-
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
 };
 
 /// Define the start or update to a symbolic variable value (for loadable
@@ -3774,68 +3762,38 @@
 /// Binds memory at the raw pointer %0 to type $T with enough capacity
 /// to hold $1 values.
 class BindMemoryInst final :
-    public InstructionBase<SILInstructionKind::BindMemoryInst,
-                           NonValueInstruction>,
-    protected llvm::TrailingObjects<BindMemoryInst, Operand> {
-
-  typedef llvm::TrailingObjects<BindMemoryInst, Operand> TrailingObjects;
-  friend TrailingObjects;
-  using TrailingObjects::totalSizeToAlloc;
-
+    public InstructionBaseWithTrailingOperands<
+                                          SILInstructionKind::BindMemoryInst,
+                                          BindMemoryInst, NonValueInstruction> {
   friend SILBuilder;
 
   enum { BaseOperIdx, IndexOperIdx, NumFixedOpers };
 
   SILType BoundType;
 
-  // Fixed operands + opened archetype operands.
-  unsigned NumOperands;
-
   static BindMemoryInst *create(
     SILDebugLocation Loc, SILValue Base, SILValue Index, SILType BoundType,
     SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
 
   BindMemoryInst(SILDebugLocation Loc, SILValue Base, SILValue Index,
                  SILType BoundType,
-                 ArrayRef<SILValue> TypeDependentOperands);
+                 ArrayRef<SILValue> TypeDependentOperands)
+    : InstructionBaseWithTrailingOperands(Base, Index, TypeDependentOperands,
+                                          Loc), BoundType(BoundType) {}
 
 public:
-  // Destruct tail allocated objects.
-  ~BindMemoryInst() {
-    Operand *Operands = &getAllOperands()[0];
-    for (unsigned i = 0, end = NumOperands; i < end; ++i) {
-      Operands[i].~Operand();
-    }
-  }
-
   SILValue getBase() const { return getAllOperands()[BaseOperIdx].get(); }
 
   SILValue getIndex() const { return getAllOperands()[IndexOperIdx].get(); }
 
-  SILType getBoundType() const { return BoundType ; }
-
-  // Implement llvm::TrailingObjects.
-  size_t numTrailingObjects(
-    typename TrailingObjects::template OverloadToken<Operand>) const {
-    return NumOperands;
-  }
-
-  ArrayRef<Operand> getAllOperands() const {
-    return {TrailingObjects::template getTrailingObjects<Operand>(),
-            static_cast<size_t>(NumOperands)};
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return {TrailingObjects::template getTrailingObjects<Operand>(),
-            static_cast<size_t>(NumOperands)};
-  }
+  SILType getBoundType() const { return BoundType; }
 
   ArrayRef<Operand> getTypeDependentOperands() const {
-    return getAllOperands().slice(2);
+    return getAllOperands().slice(NumFixedOpers);
   }
 
   MutableArrayRef<Operand> getTypeDependentOperands() {
-    return getAllOperands().slice(2);
+    return getAllOperands().slice(NumFixedOpers);
   }
 };
 
@@ -4390,10 +4348,8 @@
 
 /// StructInst - Represents a constructed loadable struct.
 class StructInst final
-    : public InstructionBase<SILInstructionKind::StructInst,
-                             SingleValueInstruction>,
-      private llvm::TrailingObjects<StructInst, Operand> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<SILInstructionKind::StructInst,
+                                           StructInst, SingleValueInstruction> {
   friend SILBuilder;
 
   /// Because of the storage requirements of StructInst, object
@@ -4406,31 +4362,14 @@
                             ArrayRef<SILValue> Elements, SILModule &M);
 
 public:
-  ~StructInst() {
-    for (auto &op : getAllOperands()) {
-      op.~Operand();
-    }
-  }
-
   /// The elements referenced by this StructInst.
   MutableArrayRef<Operand> getElementOperands() {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.StructInst.NumOperands};
+    return getAllOperands();
   }
 
   /// The elements referenced by this StructInst.
   OperandValueArrayRef getElements() const {
-    return OperandValueArrayRef({getTrailingObjects<Operand>(),
-                                 SILInstruction::Bits.StructInst.NumOperands});
-  }
-
-  ArrayRef<Operand> getAllOperands() const {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.StructInst.NumOperands};
-  }
-  MutableArrayRef<Operand> getAllOperands() {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.StructInst.NumOperands};
+    return OperandValueArrayRef(getAllOperands());
   }
 
   SILValue getFieldValue(const VarDecl *V) const {
@@ -4715,19 +4654,19 @@
 ///
 /// This instruction can only appear at the end of a gobal variable's
 /// static initializer list.
-class ObjectInst
-    : public InstructionBase<SILInstructionKind::ObjectInst,
-                             SingleValueInstruction> {
+class ObjectInst final
+    : public InstructionBaseWithTrailingOperands<SILInstructionKind::ObjectInst,
+                                                 ObjectInst,
+                                                 SingleValueInstruction> {
   friend SILBuilder;
 
-  unsigned NumBaseElements;
-
-  TailAllocatedOperandList<0> Operands;
-
   /// Because of the storage requirements of ObjectInst, object
   /// creation goes through 'create()'.
   ObjectInst(SILDebugLocation DebugLoc, SILType Ty,
-            ArrayRef<SILValue> Elements, unsigned NumBaseElements);
+            ArrayRef<SILValue> Elements, unsigned NumBaseElements)
+    : InstructionBaseWithTrailingOperands(Elements, DebugLoc, Ty) {
+      SILInstruction::Bits.ObjectInst.NumBaseElements = NumBaseElements;
+  }
 
   /// Construct an ObjectInst.
   static ObjectInst *create(SILDebugLocation DebugLoc, SILType Ty,
@@ -4737,63 +4676,52 @@
 public:
   /// All elements referenced by this ObjectInst.
   MutableArrayRef<Operand> getElementOperands() {
-    return Operands.getDynamicAsArray();
+    return getAllOperands();
   }
 
   /// All elements referenced by this ObjectInst.
   OperandValueArrayRef getAllElements() const {
-    return Operands.getDynamicValuesAsArray();
+    return OperandValueArrayRef(getAllOperands());
   }
 
   /// The elements which initialize the stored properties of the object itself.
   OperandValueArrayRef getBaseElements() const {
-    return Operands.getDynamicValuesAsArray().slice(0, NumBaseElements);
+    return OperandValueArrayRef(getAllOperands().slice(0,
+                              SILInstruction::Bits.ObjectInst.NumBaseElements));
   }
 
   /// The elements which initialize the tail allocated elements.
   OperandValueArrayRef getTailElements() const {
-    return Operands.getDynamicValuesAsArray().slice(NumBaseElements);
+    return OperandValueArrayRef(getAllOperands().slice(
+                              SILInstruction::Bits.ObjectInst.NumBaseElements));
   }
-
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
 };
 
-
 /// TupleInst - Represents a constructed loadable tuple.
 class TupleInst final
-    : public InstructionBase<SILInstructionKind::TupleInst,
-                             SingleValueInstruction>,
-      private llvm::TrailingObjects<TupleInst, Operand> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<SILInstructionKind::TupleInst,
+                                                  TupleInst,
+                                                  SingleValueInstruction> {
   friend SILBuilder;
 
   /// Because of the storage requirements of TupleInst, object
   /// creation goes through 'create()'.
-  TupleInst(SILDebugLocation DebugLoc, SILType Ty,
-            ArrayRef<SILValue> Elements);
+  TupleInst(SILDebugLocation DebugLoc, SILType Ty, ArrayRef<SILValue> Elems)
+    : InstructionBaseWithTrailingOperands(Elems, DebugLoc, Ty) {}
 
   /// Construct a TupleInst.
   static TupleInst *create(SILDebugLocation DebugLoc, SILType Ty,
                            ArrayRef<SILValue> Elements, SILModule &M);
 
 public:
-  ~TupleInst() {
-    for (auto &op : getAllOperands()) {
-      op.~Operand();
-    }
-  }
-
   /// The elements referenced by this TupleInst.
   MutableArrayRef<Operand> getElementOperands() {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.TupleInst.NumOperands};
+    return getAllOperands();
   }
 
   /// The elements referenced by this TupleInst.
   OperandValueArrayRef getElements() const {
-    return OperandValueArrayRef({getTrailingObjects<Operand>(),
-                                 SILInstruction::Bits.TupleInst.NumOperands});
+    return OperandValueArrayRef(getAllOperands());
   }
 
   /// Return the i'th value referenced by this TupleInst.
@@ -4806,15 +4734,6 @@
     return operand->getOperandNumber();
   }
 
-  ArrayRef<Operand> getAllOperands() const {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.TupleInst.NumOperands};
-  }
-  MutableArrayRef<Operand> getAllOperands() {
-    return {getTrailingObjects<Operand>(),
-            SILInstruction::Bits.TupleInst.NumOperands};
-  }
-
   TupleType *getTupleType() const {
     return getType().getSwiftRValueType()->castTo<TupleType>();
   }
@@ -4995,38 +4914,39 @@
   }
 };
 
-// Base class of all select instructions like select_enum, select_value, etc.
-// The template parameter represents a type of case values to be compared
-// with the operand of a select instruction.
+// Abstract base class of all select instructions like select_enum,
+// select_value, etc. The template parameter represents a type of case values
+// to be compared with the operand of a select instruction.
+//
+// Subclasses must provide tail allocated storage.
+// The first operand is the operand of select_xxx instruction. The rest of
+// the operands are the case values and results of a select instruction.
 template <class Derived, class T>
 class SelectInstBase : public SingleValueInstruction {
-protected:
-  unsigned NumCases : 31;
-  unsigned HasDefault : 1;
-
-  /// The first operand is the operand of select_xxx instruction. The rest of
-  /// the operands are the case values and results of a select instruction.
-  TailAllocatedOperandList<1> Operands;
-
 public:
-  SelectInstBase(SILInstructionKind kind, SILDebugLocation DebugLoc,
-                 SILType type, unsigned numCases, bool hasDefault,
-                 ArrayRef<SILValue> operands, SILValue operand)
-      : SingleValueInstruction(kind, DebugLoc, type), NumCases(numCases),
-        HasDefault(hasDefault), Operands(this, operands, operand) {}
+  SelectInstBase(SILInstructionKind kind, SILDebugLocation Loc, SILType type)
+      : SingleValueInstruction(kind, Loc, type) {}
 
-  SILValue getOperand() const { return Operands[0].get(); }
+  SILValue getOperand() const { return getAllOperands()[0].get(); }
 
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+  ArrayRef<Operand> getAllOperands() const {
+    return static_cast<const Derived *>(this)->getAllOperands();
+  }
+  MutableArrayRef<Operand> getAllOperands() {
+    return static_cast<Derived *>(this)->getAllOperands();
+  }
 
-  std::pair<T, SILValue> getCase(unsigned i) {
+  std::pair<T, SILValue> getCase(unsigned i) const {
     return static_cast<const Derived *>(this)->getCase(i);
   }
 
-  unsigned getNumCases() const { return NumCases; }
+  unsigned getNumCases() const {
+    return static_cast<const Derived *>(this)->getNumCases();
+  }
 
-  bool hasDefault() const { return HasDefault; }
+  bool hasDefault() const {
+    return static_cast<const Derived *>(this)->hasDefault();
+  }
 
   SILValue getDefaultResult() const {
     return static_cast<const Derived *>(this)->getDefaultResult();
@@ -5041,19 +4961,19 @@
   // EnumElementDecl* pointers, referencing the case discriminators for each
   // operand.
   
-  EnumElementDecl **getCaseBuf() {
-    return reinterpret_cast<EnumElementDecl**>(Operands.asArray().end());
-  }
-  EnumElementDecl * const* getCaseBuf() const {
-    return reinterpret_cast<EnumElementDecl* const*>(Operands.asArray().end());
+  EnumElementDecl **getEnumElementDeclStorage();
+  EnumElementDecl * const* getEnumElementDeclStorage() const {
+    return const_cast<SelectEnumInstBase*>(this)->getEnumElementDeclStorage();
   }
 
 protected:
   SelectEnumInstBase(SILInstructionKind kind, SILDebugLocation debugLoc,
-                     SILType type, SILValue enumValue, SILValue defaultValue,
-                     ArrayRef<std::pair<EnumElementDecl *, SILValue>> cases,
+                     SILType type, bool defaultValue,
                      Optional<ArrayRef<ProfileCounter>> CaseCounts,
-                     ProfileCounter DefaultCount);
+                     ProfileCounter DefaultCount)
+      : SelectInstBase(kind, debugLoc, type) {
+    SILInstruction::Bits.SelectEnumInstBase.HasDefault = defaultValue;
+  }
   template <typename SELECT_ENUM_INST>
   static SELECT_ENUM_INST *
   createSelectEnum(SILDebugLocation DebugLoc, SILValue Enum, SILType Type,
@@ -5064,12 +4984,16 @@
                    ProfileCounter DefaultCount);
 
 public:
+  ArrayRef<Operand> getAllOperands() const;
+  MutableArrayRef<Operand> getAllOperands();
+
+  SILValue getOperand() const { return getAllOperands()[0].get(); }
   SILValue getEnumOperand() const { return getOperand(); }
   
   std::pair<EnumElementDecl*, SILValue>
   getCase(unsigned i) const {
-    assert(i < NumCases && "case out of bounds");
-    return std::make_pair(getCaseBuf()[i], Operands[i+1].get());
+    return std::make_pair(getEnumElementDeclStorage()[i],
+                          getAllOperands()[i+1].get());
   }
   
   /// Return the value that will be used as the result for the specified enum
@@ -5087,9 +5011,17 @@
   /// \brief If the default refers to exactly one case decl, return it.
   NullablePtr<EnumElementDecl> getUniqueCaseForDefault();
 
+  bool hasDefault() const {
+    return SILInstruction::Bits.SelectEnumInstBase.HasDefault;
+  }
+
   SILValue getDefaultResult() const {
-    assert(HasDefault && "doesn't have a default");
-    return Operands[NumCases + 1].get();
+    assert(hasDefault() && "doesn't have a default");
+    return getAllOperands().back().get();
+  }
+
+  unsigned getNumCases() const {
+    return getAllOperands().size() - 1 - hasDefault();
   }
 
   /// If there is a single case that returns a literal "true" value (an
@@ -5102,21 +5034,29 @@
 };
   
 /// Select one of a set of values based on the case of an enum.
-class SelectEnumInst
-    : public InstructionBase<SILInstructionKind::SelectEnumInst,
-                             SelectEnumInstBase> {
+class SelectEnumInst final
+    : public InstructionBaseWithTrailingOperands<
+                                        SILInstructionKind::SelectEnumInst,
+                                        SelectEnumInst,
+                                        SelectEnumInstBase, EnumElementDecl *> {
   friend SILBuilder;
 
 private:
   friend SelectEnumInstBase;
 
   SelectEnumInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
-                 SILValue DefaultValue,
-                 ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
+                 bool DefaultValue,
+                 ArrayRef<SILValue> CaseValues,
+                 ArrayRef<EnumElementDecl *> CaseDecls,
                  Optional<ArrayRef<ProfileCounter>> CaseCounts,
                  ProfileCounter DefaultCount)
-      : InstructionBase(DebugLoc, Type, Operand, DefaultValue, CaseValues,
-                        CaseCounts, DefaultCount) {}
+      : InstructionBaseWithTrailingOperands(Operand, CaseValues, DebugLoc, Type,
+                                            bool(DefaultValue), CaseCounts,
+                                            DefaultCount) {
+    assert(CaseValues.size() - DefaultValue == CaseDecls.size());
+    std::uninitialized_copy(CaseDecls.begin(), CaseDecls.end(),
+                            getTrailingObjects<EnumElementDecl *>());
+  }
   static SelectEnumInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
@@ -5126,20 +5066,28 @@
 };
 
 /// Select one of a set of values based on the case of an enum.
-class SelectEnumAddrInst
-    : public InstructionBase<SILInstructionKind::SelectEnumAddrInst,
-                             SelectEnumInstBase> {
+class SelectEnumAddrInst final
+    : public InstructionBaseWithTrailingOperands<
+                                        SILInstructionKind::SelectEnumAddrInst,
+                                        SelectEnumAddrInst,
+                                        SelectEnumInstBase, EnumElementDecl *> {
   friend SILBuilder;
   friend SelectEnumInstBase;
 
   SelectEnumAddrInst(
       SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
-      SILValue DefaultValue,
-      ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
+      bool DefaultValue,
+      ArrayRef<SILValue> CaseValues,
+      ArrayRef<EnumElementDecl *> CaseDecls,
       Optional<ArrayRef<ProfileCounter>> CaseCounts,
       ProfileCounter DefaultCount)
-      : InstructionBase(DebugLoc, Type, Operand, DefaultValue, CaseValues,
-                        CaseCounts, DefaultCount) {}
+      : InstructionBaseWithTrailingOperands(Operand, CaseValues, DebugLoc, Type,
+                                            bool(DefaultValue), CaseCounts,
+                                            DefaultCount) {
+    assert(CaseValues.size() - DefaultValue == CaseDecls.size());
+    std::uninitialized_copy(CaseDecls.begin(), CaseDecls.end(),
+                            getTrailingObjects<EnumElementDecl *>());
+  }
   static SelectEnumAddrInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
@@ -5149,82 +5097,77 @@
 };
 
 /// Select on a value of a builtin integer type.
-class SelectValueInst
-    : public InstructionBase<SILInstructionKind::SelectValueInst,
-                             SelectInstBase<SelectValueInst, SILValue>> {
+///
+/// There is 'the' operand, followed by pairs of operands for each case,
+/// followed by an optional default operand.
+class SelectValueInst final
+    : public InstructionBaseWithTrailingOperands<
+                                    SILInstructionKind::SelectValueInst,
+                                    SelectValueInst,
+                                    SelectInstBase<SelectValueInst, SILValue>> {
   friend SILBuilder;
 
   SelectValueInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
                   SILValue DefaultResult,
-                  ArrayRef<SILValue> CaseValuesAndResults);
+                  ArrayRef<SILValue> CaseValuesAndResults)
+      : InstructionBaseWithTrailingOperands(Operand, CaseValuesAndResults,
+                                            DebugLoc, Type) {}
 
   static SelectValueInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
          ArrayRef<std::pair<SILValue, SILValue>> CaseValues, SILFunction &F);
 
-  OperandValueArrayRef getCaseBuf() const {
-    return Operands.getDynamicValuesAsArray();
-  }
-
 public:
-  ~SelectValueInst();
-
   std::pair<SILValue, SILValue>
   getCase(unsigned i) const {
-    assert(i < NumCases && "case out of bounds");
-    return {getCaseBuf()[i*2], getCaseBuf()[i*2+1]};
+    auto cases = getAllOperands().slice(1);
+    return {cases[i*2].get(), cases[i*2+1].get()};
+  }
+
+  unsigned getNumCases() const {
+    // Ignore the first non-case operand.
+    auto count = getAllOperands().size() - 1;
+    // This implicitly ignore the optional default operand.
+    return count / 2;
+  }
+
+  bool hasDefault() const {
+    // If the operand count is even, then we have a default value.
+    return (getAllOperands().size() & 1) == 0;
   }
 
   SILValue getDefaultResult() const {
-    assert(HasDefault && "doesn't have a default");
-    return getCaseBuf()[NumCases*2];
+    assert(hasDefault() && "doesn't have a default");
+    return getAllOperands().back().get();
   }
 };
 
 /// MetatypeInst - Represents the production of an instance of a given metatype
 /// named statically.
 class MetatypeInst final
-    : public InstructionBase<SILInstructionKind::MetatypeInst,
-                             SingleValueInstruction>,
-      private llvm::TrailingObjects<MetatypeInst, Operand> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<
+                                         SILInstructionKind::MetatypeInst,
+                                         MetatypeInst, SingleValueInstruction> {
   friend SILBuilder;
 
-  unsigned _getNumOperands() const {
-    return SILInstruction::Bits.MetatypeInst.NumOperands;
-  };
-
   /// Constructs a MetatypeInst
   MetatypeInst(SILDebugLocation DebugLoc, SILType Metatype,
-               ArrayRef<SILValue> TypeDependentOperands);
+               ArrayRef<SILValue> TypeDependentOperands)
+    : InstructionBaseWithTrailingOperands(TypeDependentOperands, DebugLoc,
+                                          Metatype) {}
 
   static MetatypeInst *create(SILDebugLocation DebugLoc, SILType Metatype,
                               SILFunction *F,
                               SILOpenedArchetypesState &OpenedArchetypes);
 
 public:
-  ~MetatypeInst() {
-    Operand *Operands = getTrailingObjects<Operand>();
-    for (unsigned i = 0, end = _getNumOperands(); i < end; ++i) {
-      Operands[i].~Operand();
-    }
-  }
-
-  ArrayRef<Operand> getAllOperands() const {
-    return { getTrailingObjects<Operand>(), _getNumOperands() };
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return { getTrailingObjects<Operand>(), _getNumOperands() };
-  }
-
   ArrayRef<Operand> getTypeDependentOperands() const {
-    return { getTrailingObjects<Operand>(), _getNumOperands() };
+    return getAllOperands();
   }
 
   MutableArrayRef<Operand> getTypeDependentOperands() {
-    return { getTrailingObjects<Operand>(), _getNumOperands() };
+    return getAllOperands();
   }
 };
 
@@ -5523,29 +5466,20 @@
 /// and a protocol method constant, extracts the implementation of that method
 /// for the type.
 class WitnessMethodInst final
-    : public InstructionBase<SILInstructionKind::WitnessMethodInst,
-                             MethodInst>,
-      llvm::TrailingObjects<WitnessMethodInst, Operand> {
-  friend TrailingObjects;
+    : public InstructionBaseWithTrailingOperands<
+                                          SILInstructionKind::WitnessMethodInst,
+                                          WitnessMethodInst, MethodInst> {
   friend SILBuilder;
 
   CanType LookupType;
   ProtocolConformanceRef Conformance;
 
-  unsigned getNumOperands() const {
-    return SILInstruction::Bits.WitnessMethodInst.NumOperands;
-  }
-
   WitnessMethodInst(SILDebugLocation DebugLoc, CanType LookupType,
                     ProtocolConformanceRef Conformance, SILDeclRef Member,
                     SILType Ty, ArrayRef<SILValue> TypeDependentOperands)
-      : InstructionBase(DebugLoc, Ty, Member),
-        LookupType(LookupType), Conformance(Conformance) {
-    SILInstruction::Bits.WitnessMethodInst.NumOperands =
-      TypeDependentOperands.size();
-    TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                           TypeDependentOperands);
-  }
+      : InstructionBaseWithTrailingOperands(TypeDependentOperands,
+                                            DebugLoc, Ty, Member),
+        LookupType(LookupType), Conformance(Conformance) {}
 
   /// Create a witness method call of a protocol requirement, passing in a lookup
   /// type and conformance.
@@ -5565,13 +5499,6 @@
          SILFunction *Parent, SILOpenedArchetypesState &OpenedArchetypes);
 
 public:
-  ~WitnessMethodInst() {
-    Operand *Operands = getTrailingObjects<Operand>();
-    for (unsigned i = 0, end = getNumOperands(); i < end; ++i) {
-      Operands[i].~Operand();
-    }
-  }
-
   CanType getLookupType() const { return LookupType; }
   ProtocolDecl *getLookupProtocol() const {
     return getMember().getDecl()->getDeclContext()
@@ -5580,20 +5507,12 @@
 
   ProtocolConformanceRef getConformance() const { return Conformance; }
 
-  ArrayRef<Operand> getAllOperands() const {
-    return { getTrailingObjects<Operand>(), getNumOperands() };
-  }
-
-  MutableArrayRef<Operand> getAllOperands() {
-    return { getTrailingObjects<Operand>(), getNumOperands() };
-  }
-
   ArrayRef<Operand> getTypeDependentOperands() const {
-    return { getTrailingObjects<Operand>(), getNumOperands() };
+    return getAllOperands();
   }
 
   MutableArrayRef<Operand> getTypeDependentOperands() {
-    return { getTrailingObjects<Operand>(), getNumOperands() };
+    return getAllOperands();
   }
 };
 
@@ -5793,8 +5712,6 @@
          ArrayRef<ProtocolConformanceRef> Conformances, SILFunction *Parent,
          SILOpenedArchetypesState &OpenedArchetypes);
 
-  //size_t numTrailingObjects(OverloadToken<Operand>) const { return NumOperands; }
-
 public:
   CanType getFormalConcreteType() const {
     return ConcreteType;
@@ -6641,17 +6558,17 @@
 ///
 /// This is a terminator because the caller can abort the coroutine,
 /// e.g. if an error is thrown and an unwind is provoked.
-class YieldInst
-  : public InstructionBase<SILInstructionKind::YieldInst,
-                           TermInst> {
+class YieldInst final
+  : public InstructionBaseWithTrailingOperands<SILInstructionKind::YieldInst,
+                                               YieldInst, TermInst> {
   friend SILBuilder;
 
   SILSuccessor DestBBs[2];
 
-  TailAllocatedOperandList<0> Operands;
-
   YieldInst(SILDebugLocation loc, ArrayRef<SILValue> yieldedValues,
-            SILBasicBlock *normalBB, SILBasicBlock *unwindBB);
+            SILBasicBlock *normalBB, SILBasicBlock *unwindBB)
+    : InstructionBaseWithTrailingOperands(yieldedValues, loc),
+      DestBBs{{this, normalBB}, {this, unwindBB}} {}
 
   static YieldInst *create(SILDebugLocation loc,
                            ArrayRef<SILValue> yieldedValues,
@@ -6683,29 +6600,26 @@
   SILBasicBlock *getUnwindBB() const { return DestBBs[1]; }
 
   OperandValueArrayRef getYieldedValues() const {
-    return Operands.asValueArray();
+    return OperandValueArrayRef(getAllOperands());
   }
 
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
-
   SuccessorListTy getSuccessors() {
     return DestBBs;
   }
 };
 
 /// BranchInst - An unconditional branch.
-class BranchInst
-    : public InstructionBase<SILInstructionKind::BranchInst,
-                             TermInst> {
+class BranchInst final
+    : public InstructionBaseWithTrailingOperands<SILInstructionKind::BranchInst,
+                                                 BranchInst, TermInst> {
   friend SILBuilder;
 
   SILSuccessor DestBB;
-  // FIXME: probably needs dynamic adjustment
-  TailAllocatedOperandList<0> Operands;
 
   BranchInst(SILDebugLocation DebugLoc, SILBasicBlock *DestBB,
-             ArrayRef<SILValue> Args);
+             ArrayRef<SILValue> Args)
+    : InstructionBaseWithTrailingOperands(Args, DebugLoc),
+      DestBB(this, DestBB) {}
 
   /// Construct a BranchInst that will branch to the specified block.
   /// The destination block must take no parameters.
@@ -6722,29 +6636,31 @@
   SILBasicBlock *getDestBB() const { return DestBB; }
 
   /// The arguments for the destination BB.
-  OperandValueArrayRef getArgs() const { return Operands.asValueArray(); }
+  OperandValueArrayRef getArgs() const {
+    return OperandValueArrayRef(getAllOperands());
+  }
 
   SuccessorListTy getSuccessors() {
     return SuccessorListTy(&DestBB, 1);
   }
 
-  unsigned getNumArgs() const { return Operands.size(); }
-  SILValue getArg(unsigned i) const { return Operands[i].get(); }
-
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+  unsigned getNumArgs() const { return getAllOperands().size(); }
+  SILValue getArg(unsigned i) const { return getAllOperands()[i].get(); }
 };
 
 /// A conditional branch.
-class CondBranchInst
-    : public InstructionBase<SILInstructionKind::CondBranchInst,
-                             TermInst> {
+class CondBranchInst final
+    : public InstructionBaseWithTrailingOperands<
+                                             SILInstructionKind::CondBranchInst,
+                                             CondBranchInst,
+                                             TermInst> {
   friend SILBuilder;
 
 public:
   enum {
     /// The operand index of the condition value used for the branch.
-    ConditionIdx
+    ConditionIdx,
+    NumFixedOpers,
   };
   enum {
     // Map branch targets to block successor indices.
@@ -6754,12 +6670,15 @@
 private:
   SILSuccessor DestBBs[2];
   /// The number of arguments for the True branch.
-  unsigned NumTrueArgs;
+  unsigned getNumTrueArgs() const {
+    return SILInstruction::Bits.CondBranchInst.NumTrueArgs;
+  }
   /// The number of arguments for the False branch.
-  unsigned NumFalseArgs;
+  unsigned getNumFalseArgs() const {
+    return getAllOperands().size() - NumFixedOpers -
+        SILInstruction::Bits.CondBranchInst.NumTrueArgs;
+  }
 
-  /// The first argument is the condition; the rest are BB arguments.
-  TailAllocatedOperandList<1> Operands;
   CondBranchInst(SILDebugLocation DebugLoc, SILValue Condition,
                  SILBasicBlock *TrueBB, SILBasicBlock *FalseBB,
                  ArrayRef<SILValue> Args, unsigned NumTrue, unsigned NumFalse,
@@ -6782,9 +6701,9 @@
          ProfileCounter FalseBBCount, SILFunction &F);
 
 public:
-  SILValue getCondition() const { return Operands[ConditionIdx].get(); }
+  SILValue getCondition() const { return getAllOperands()[ConditionIdx].get(); }
   void setCondition(SILValue newCondition) {
-    Operands[ConditionIdx].set(newCondition);
+    getAllOperands()[ConditionIdx].set(newCondition);
   }
 
   SuccessorListTy getSuccessors() {
@@ -6802,17 +6721,31 @@
   ProfileCounter getFalseBBCount() const { return DestBBs[1].getCount(); }
 
   /// Get the arguments to the true BB.
-  OperandValueArrayRef getTrueArgs() const;
+  OperandValueArrayRef getTrueArgs() const {
+    return OperandValueArrayRef(getTrueOperands());
+  }
   /// Get the arguments to the false BB.
-  OperandValueArrayRef getFalseArgs() const;
+  OperandValueArrayRef getFalseArgs() const {
+    return OperandValueArrayRef(getFalseOperands());
+  }
 
   /// Get the operands to the true BB.
-  ArrayRef<Operand> getTrueOperands() const;
-  MutableArrayRef<Operand> getTrueOperands();
+  ArrayRef<Operand> getTrueOperands() const {
+    return getAllOperands().slice(NumFixedOpers, getNumTrueArgs());
+  }
+  MutableArrayRef<Operand> getTrueOperands() {
+    return getAllOperands().slice(NumFixedOpers, getNumTrueArgs());
+  }
 
   /// Get the operands to the false BB.
-  ArrayRef<Operand> getFalseOperands() const;
-  MutableArrayRef<Operand> getFalseOperands();
+  ArrayRef<Operand> getFalseOperands() const {
+    // The remaining arguments are 'false' operands.
+    return getAllOperands().slice(NumFixedOpers + getNumTrueArgs());
+  }
+  MutableArrayRef<Operand> getFalseOperands() {
+    // The remaining arguments are 'false' operands.
+    return getAllOperands().slice(NumFixedOpers + getNumTrueArgs());
+  }
 
   bool isConditionOperandIndex(unsigned OpIndex) const {
     assert(OpIndex < getNumOperands() &&
@@ -6824,7 +6757,7 @@
   bool isTrueOperandIndex(unsigned OpIndex) const {
     assert(OpIndex < getNumOperands() &&
            "OpIndex must be an index for an actual operand");
-    if (NumTrueArgs == 0)
+    if (getNumTrueArgs() == 0)
       return false;
 
     auto Operands = getTrueOperands();
@@ -6836,7 +6769,7 @@
   bool isFalseOperandIndex(unsigned OpIndex) const {
     assert(OpIndex < getNumOperands() &&
            "OpIndex must be an index for an actual operand");
-    if (NumFalseArgs == 0)
+    if (getNumFalseArgs() == 0)
       return false;
 
     auto Operands = getFalseOperands();
@@ -6855,19 +6788,15 @@
                            unsigned ArgIndex) const;
 
   void swapSuccessors();
-
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
 };
 
 /// A switch on a value of a builtin type.
-class SwitchValueInst
-    : public InstructionBase<SILInstructionKind::SwitchValueInst,
-                             TermInst> {
+class SwitchValueInst final
+    : public InstructionBaseWithTrailingOperands<
+                                      SILInstructionKind::SwitchValueInst,
+                                      SwitchValueInst, TermInst, SILSuccessor> {
   friend SILBuilder;
 
-  TailAllocatedOperandList<1> Operands;
-
   SwitchValueInst(SILDebugLocation DebugLoc, SILValue Operand,
                   SILBasicBlock *DefaultBB, ArrayRef<SILValue> Cases,
                   ArrayRef<SILBasicBlock *> BBs);
@@ -6879,16 +6808,15 @@
   //   destinations for each case, ending with the default destination if
   //   present.
 
-
   OperandValueArrayRef getCaseBuf() const {
-    return Operands.getDynamicValuesAsArray();
+    return OperandValueArrayRef(getAllOperands().slice(1));
   }
 
   SILSuccessor *getSuccessorBuf() {
-    return reinterpret_cast<SILSuccessor*>(Operands.asArray().end());
+    return getTrailingObjects<SILSuccessor>();
   }
   const SILSuccessor *getSuccessorBuf() const {
-    return reinterpret_cast<const SILSuccessor *>(Operands.asArray().end());
+    return getTrailingObjects<SILSuccessor>();
   }
 
   static SwitchValueInst *
@@ -6900,10 +6828,7 @@
   /// Clean up tail-allocated successor records for the switch cases.
   ~SwitchValueInst();
 
-  SILValue getOperand() const { return Operands[0].get(); }
-
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+  SILValue getOperand() const { return getAllOperands()[0].get(); }
 
   SuccessorListTy getSuccessors() {
     return MutableArrayRef<SILSuccessor>{getSuccessorBuf(),
@@ -6911,7 +6836,7 @@
   }
 
   unsigned getNumCases() const {
-    return SILInstruction::Bits.SwitchValueInst.NumCases;
+    return getAllOperands().size() - 1;
   }
   std::pair<SILValue, SILBasicBlock*>
   getCase(unsigned i) const {
@@ -7833,6 +7758,60 @@
   return cast<DestructureTupleInst>(Parent);
 }
 
+inline SILType *AllocRefInstBase::getTypeStorage() {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<AllocRefInst>(this))
+    return I->getTrailingObjects<SILType>();
+  if (auto I = dyn_cast<AllocRefDynamicInst>(this))
+    return I->getTrailingObjects<SILType>();
+  llvm_unreachable("Unhandled AllocRefInstBase subclass");
+}
+
+inline ArrayRef<Operand> AllocRefInstBase::getAllOperands() const {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<AllocRefInst>(this))
+    return I->getAllOperands();
+  if (auto I = dyn_cast<AllocRefDynamicInst>(this))
+    return I->getAllOperands();
+  llvm_unreachable("Unhandled AllocRefInstBase subclass");
+}
+
+inline MutableArrayRef<Operand> AllocRefInstBase::getAllOperands() {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<AllocRefInst>(this))
+    return I->getAllOperands();
+  if (auto I = dyn_cast<AllocRefDynamicInst>(this))
+    return I->getAllOperands();
+  llvm_unreachable("Unhandled AllocRefInstBase subclass");
+}
+
+inline ArrayRef<Operand> SelectEnumInstBase::getAllOperands() const {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<SelectEnumInst>(this))
+    return I->getAllOperands();
+  if (auto I = dyn_cast<SelectEnumAddrInst>(this))
+    return I->getAllOperands();
+  llvm_unreachable("Unhandled SelectEnumInstBase subclass");
+}
+
+inline MutableArrayRef<Operand> SelectEnumInstBase::getAllOperands() {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<SelectEnumInst>(this))
+    return I->getAllOperands();
+  if (auto I = dyn_cast<SelectEnumAddrInst>(this))
+    return I->getAllOperands();
+  llvm_unreachable("Unhandled SelectEnumInstBase subclass");
+}
+
+inline EnumElementDecl **SelectEnumInstBase::getEnumElementDeclStorage() {
+  // If the size of the subclasses are equal, then all of this compiles away.
+  if (auto I = dyn_cast<SelectEnumInst>(this))
+    return I->getTrailingObjects<EnumElementDecl*>();
+  if (auto I = dyn_cast<SelectEnumAddrInst>(this))
+    return I->getTrailingObjects<EnumElementDecl*>();
+  llvm_unreachable("Unhandled SelectEnumInstBase subclass");
+}
+
 } // end swift namespace
 
 //===----------------------------------------------------------------------===//
diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h
index d2e91a4..2babb2e 100644
--- a/include/swift/SIL/SILNode.h
+++ b/include/swift/SIL/SILNode.h
@@ -123,10 +123,10 @@
   SWIFT_INLINE_BITFIELD_EMPTY(SILInstruction, SILNode);
 
   // Special handling for UnaryInstructionWithTypeDependentOperandsBase
-  SWIFT_INLINE_BITFIELD(UIWTDOB, SILNode, 32,
+  SWIFT_INLINE_BITFIELD(IBWTO, SILNode, 32,
     // DO NOT allocate bits at the front!
-    // UIWTDOB is a template, and must allocate bits from back to front and
-    // update UIWTDOB_BITFIELD().
+    // IBWTO is a template, and must allocate bits from back to front and
+    // update IBWTO_BITFIELD().
 
     /*pad*/ : 32-NumSILNodeBits,
 
@@ -134,31 +134,37 @@
     // It is number of type dependent operands + 1.
     NumOperands : 32;
     template<SILInstructionKind Kind, typename, typename, typename...>
-    friend class UnaryInstructionWithTypeDependentOperandsBase
+    friend class InstructionBaseWithTrailingOperands
   );
 
-#define UIWTDOB_BITFIELD(T, U, C, ...) \
+#define IBWTO_BITFIELD(T, U, C, ...) \
   SWIFT_INLINE_BITFIELD_FULL(T, U, (C)+32, __VA_ARGS__)
+#define UIWTDOB_BITFIELD(T, U, C, ...) \
+  IBWTO_BITFIELD(T, U, (C), __VA_ARGS__)
 
   SWIFT_INLINE_BITFIELD_EMPTY(SingleValueInstruction, SILInstruction);
   SWIFT_INLINE_BITFIELD_EMPTY(DeallocationInst, SILInstruction);
   SWIFT_INLINE_BITFIELD_EMPTY(LiteralInst, SingleValueInstruction);
   SWIFT_INLINE_BITFIELD_EMPTY(AllocationInst, SingleValueInstruction);
 
-  SWIFT_INLINE_BITFIELD_FULL(StructInst, SingleValueInstruction, 32,
-    : NumPadBits,
-    NumOperands : 32
+  // Ensure that StructInst bitfield does not overflow.
+  IBWTO_BITFIELD(StructInst, SingleValueInstruction, 0, : NumPadBits);
+
+  // Ensure that TupleInst bitfield does not overflow.
+  IBWTO_BITFIELD(TupleInst, SingleValueInstruction, 0, : NumPadBits);
+
+  IBWTO_BITFIELD(BuiltinInst, SingleValueInstruction,
+                             32-NumSingleValueInstructionBits,
+    NumSubstitutions : 32-NumSingleValueInstructionBits
   );
 
-  SWIFT_INLINE_BITFIELD_FULL(TupleInst, SingleValueInstruction, 32,
-    : NumPadBits,
-    NumOperands : 32
+  IBWTO_BITFIELD(ObjectInst, SingleValueInstruction,
+                             32-NumSingleValueInstructionBits,
+    NumBaseElements : 32-NumSingleValueInstructionBits
   );
 
-  SWIFT_INLINE_BITFIELD_FULL(BuiltinInst, SingleValueInstruction,
-                             64-NumSingleValueInstructionBits,
-    NumSubstitutions : 32-NumSingleValueInstructionBits,
-    NumOperands : 32
+  IBWTO_BITFIELD(SelectEnumInstBase, SingleValueInstruction, 1,
+    HasDefault : 1
   );
 
   SWIFT_INLINE_BITFIELD_FULL(IntegerLiteralInst, LiteralInst, 32,
@@ -187,18 +193,22 @@
     OnStack : 1
   );
 
+  // Ensure that AllocBoxInst bitfield does not overflow.
+  IBWTO_BITFIELD(AllocBoxInst, AllocationInst, 0, : NumPadBits);
+  // Ensure that AllocExistentialBoxInst bitfield does not overflow.
+  IBWTO_BITFIELD(AllocExistentialBoxInst, AllocationInst, 0, : NumPadBits);
   SWIFT_INLINE_BITFIELD_FULL(AllocStackInst, AllocationInst,
                              64-NumAllocationInstBits,
     NumOperands : 32-NumAllocationInstBits,
     VarInfo : 32
   );
-  SWIFT_INLINE_BITFIELD_FULL(AllocRefInstBase, AllocationInst, 1+1+32,
+  IBWTO_BITFIELD(AllocRefInstBase, AllocationInst, 32-NumAllocationInstBits,
     ObjC : 1,
     OnStack : 1,
-    : NumPadBits,
-    // Number of tail-allocated arrays.
-    NumTailTypes : 32
+    NumTailTypes : 32-1-1-NumAllocationInstBits
   );
+  static_assert(32-1-1-NumAllocationInstBits >= 16, "Reconsider bitfield use?");
+
   UIWTDOB_BITFIELD(AllocValueBufferInst, AllocationInst, 0, : NumPadBits);
 
   // TODO: Sort the following in SILNodes.def order
@@ -211,10 +221,14 @@
       atomicity : 1
   );
 
-  SWIFT_INLINE_BITFIELD_FULL(MetatypeInst, SingleValueInstruction, 32,
-      : NumPadBits,
-      NumOperands : 32
-  );
+  // Ensure that BindMemoryInst bitfield does not overflow.
+  IBWTO_BITFIELD(BindMemoryInst, NonValueInstruction, 0, : NumPadBits);
+
+  // Ensure that MarkFunctionEscapeInst bitfield does not overflow.
+  IBWTO_BITFIELD(MarkFunctionEscapeInst, NonValueInstruction, 0, : NumPadBits);
+
+  // Ensure that MetatypeInst bitfield does not overflow.
+  IBWTO_BITFIELD(MetatypeInst, SingleValueInstruction, 0, : NumPadBits);
 
   SWIFT_INLINE_BITFIELD(CopyAddrInst, NonValueInstruction, 1+1,
     /// IsTakeOfSrc - True if ownership will be taken from the value at the
@@ -272,10 +286,8 @@
   );
 
   SWIFT_INLINE_BITFIELD_EMPTY(MethodInst, SingleValueInstruction);
-  SWIFT_INLINE_BITFIELD_FULL(WitnessMethodInst, MethodInst, 32,
-    : NumPadBits,
-    NumOperands : 32
-  );
+  // Ensure that WitnessMethodInst bitfield does not overflow.
+  IBWTO_BITFIELD(WitnessMethodInst, MethodInst, 0, : NumPadBits);
   UIWTDOB_BITFIELD(ObjCMethodInst, MethodInst, 0, : NumPadBits);
 
   SWIFT_INLINE_BITFIELD_EMPTY(ConversionInst, SingleValueInstruction);
@@ -303,10 +315,15 @@
   UIWTDOB_BITFIELD(CheckedCastBranchInst, SingleValueInstruction, 0, : NumPadBits);
   UIWTDOB_BITFIELD(CheckedCastValueBranchInst, SingleValueInstruction, 0, : NumPadBits);
 
-  SWIFT_INLINE_BITFIELD_FULL(SwitchValueInst, TermInst, 1+32,
-    HasDefault : 1,
-    : NumPadBits,
-    NumCases : 32
+  // Ensure that BranchInst bitfield does not overflow.
+  IBWTO_BITFIELD(BranchInst, TermInst, 0, : NumPadBits);
+  // Ensure that YieldInst bitfield does not overflow.
+  IBWTO_BITFIELD(YieldInst, TermInst, 0, : NumPadBits);
+  IBWTO_BITFIELD(CondBranchInst, TermInst, 32-NumTermInstBits,
+    NumTrueArgs : 32-NumTermInstBits
+  );
+  IBWTO_BITFIELD(SwitchValueInst, TermInst, 1,
+    HasDefault : 1
   );
   SWIFT_INLINE_BITFIELD_FULL(SwitchEnumInstBase, TermInst, 1+32,
     HasDefault : 1,
@@ -326,7 +343,7 @@
     SWIFT_INLINE_BITS(SILNode);
     SWIFT_INLINE_BITS(SILArgument);
     SWIFT_INLINE_BITS(MultipleValueInstructionResult);
-    SWIFT_INLINE_BITS(UIWTDOB);
+    SWIFT_INLINE_BITS(IBWTO);
     SWIFT_INLINE_BITS(AllocStackInst);
     SWIFT_INLINE_BITS(AllocRefInstBase);
     SWIFT_INLINE_BITS(AllocValueBufferInst);
@@ -372,6 +389,9 @@
     SWIFT_INLINE_BITS(ConstStringLiteralInst);
     SWIFT_INLINE_BITS(StructInst);
     SWIFT_INLINE_BITS(TupleInst);
+    SWIFT_INLINE_BITS(ObjectInst);
+    SWIFT_INLINE_BITS(CondBranchInst);
+    SWIFT_INLINE_BITS(SelectEnumInstBase);
   } Bits;
 
 private:
diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h
index 44039a9..f66d8d4 100644
--- a/include/swift/SIL/SILValue.h
+++ b/include/swift/SIL/SILValue.h
@@ -412,7 +412,6 @@
   friend class ValueBaseUseIterator;
   friend class ValueUseIterator;
   template <unsigned N> friend class FixedOperandList;
-  template <unsigned N> friend class TailAllocatedOperandList;
   friend class TrailingOperandsList;
 };
 
@@ -590,176 +589,6 @@
   const Operand &operator[](unsigned i) const { return asArray()[i]; }
 };
 
-/// An operator list with a fixed number of known operands
-/// (possibly zero) and a dynamically-determined set of extra
-/// operands (also possibly zero).  The number of dynamic operands
-/// is permanently set at initialization time.
-///
-/// 'N' is the number of static operands.
-///
-/// This class assumes that a number of bytes of extra storage have
-/// been allocated immediately after it.  This means that this class
-/// must always be the final data member in a class.
-template <unsigned N> class TailAllocatedOperandList {
-  unsigned NumExtra;
-  Operand Buffer[N];
-
-  TailAllocatedOperandList(const TailAllocatedOperandList &) = delete;
-  TailAllocatedOperandList &operator=(const TailAllocatedOperandList &) =delete;
-
-public:
-  /// Given the number of dynamic operands required, returns the
-  /// number of bytes of extra storage to allocate.
-  static size_t getExtraSize(unsigned numExtra) {
-    return sizeof(Operand) * numExtra;
-  }
-
-  /// Initialize this operand list.
-  ///
-  /// The dynamic operands are actually out of order: logically they
-  /// will placed after the fixed operands, not before them.  But
-  /// the variadic arguments have to come last.
-  template <class... T>
-  TailAllocatedOperandList(SILInstruction *user,
-                           ArrayRef<SILValue> dynamicArgs,
-                           T&&... fixedArgs)
-      : NumExtra(dynamicArgs.size()),
-        Buffer{ { user, std::forward<T>(fixedArgs) }... } {
-    static_assert(sizeof...(fixedArgs) == N, "wrong number of initializers");
-
-    Operand *dynamicSlot = Buffer + N;
-    for (auto value : dynamicArgs) {
-      new (dynamicSlot++) Operand(user, value);
-    }
-  }
-
-  /// Initialize this operand list.
-  ///
-  /// The dynamic operands are actually out of order: logically they
-  /// will placed after the fixed operands, not before them.  But
-  /// the variadic arguments have to come last.
-  template <class... T>
-  TailAllocatedOperandList(SILInstruction *user,
-                           ArrayRef<SILValue> dynamicArgs,
-                           ArrayRef<SILValue> additionalDynamicArgs,
-                           T&&... fixedArgs)
-      : NumExtra(dynamicArgs.size() + additionalDynamicArgs.size()),
-        Buffer{ { user, std::forward<T>(fixedArgs) }... } {
-    static_assert(sizeof...(fixedArgs) == N, "wrong number of initializers");
-
-    Operand *dynamicSlot = Buffer + N;
-    for (auto value : dynamicArgs) {
-      new (dynamicSlot++) Operand(user, value);
-    }
-
-    for (auto value : additionalDynamicArgs) {
-      new (dynamicSlot++) Operand(user, value);
-    }
- }
-
-
-  ~TailAllocatedOperandList() {
-    for (auto &op : getDynamicAsArray()) {
-      op.~Operand();
-    }
-  }
-
-  /// Returns the full list of operands.
-  MutableArrayRef<Operand> asArray() {
-    return MutableArrayRef<Operand>(Buffer, N+NumExtra);
-  }
-  ArrayRef<Operand> asArray() const {
-    return ArrayRef<Operand>(Buffer, N+NumExtra);
-  }
-
-  /// Returns the full list of operand values.
-  OperandValueArrayRef asValueArray() const {
-    return OperandValueArrayRef(asArray());
-  }
-
-  /// Returns the list of the dynamic operands.
-  MutableArrayRef<Operand> getDynamicAsArray() {
-    return MutableArrayRef<Operand>(Buffer+N, NumExtra);
-  }
-  ArrayRef<Operand> getDynamicAsArray() const {
-    return ArrayRef<Operand>(Buffer+N, NumExtra);
-  }
-
-  /// Returns the list of the dynamic operand values.
-  OperandValueArrayRef getDynamicValuesAsArray() const {
-    return OperandValueArrayRef(getDynamicAsArray());
-  }
-
-  unsigned size() const { return N+NumExtra; }
-
-  /// Indexes into the full list of operands.
-  Operand &operator[](unsigned i) { return asArray()[i]; }
-  const Operand &operator[](unsigned i) const { return asArray()[i]; }
-};
-
-/// A specialization of TailAllocatedOperandList for zero static operands.
-template<> class TailAllocatedOperandList<0> {
-  unsigned NumExtra;
-  union { // suppress value semantics
-    Operand Buffer[1];
-  };
-
-  TailAllocatedOperandList(const TailAllocatedOperandList &) = delete;
-  TailAllocatedOperandList &operator=(const TailAllocatedOperandList &) =delete;
-
-public:
-  static size_t getExtraSize(unsigned numExtra) {
-    return sizeof(Operand) * (numExtra > 0 ? numExtra - 1 : 0);
-  }
-
-  TailAllocatedOperandList(SILInstruction *user, ArrayRef<SILValue> dynamicArgs)
-      : NumExtra(dynamicArgs.size()) {
-
-    Operand *dynamicSlot = Buffer;
-    for (auto value : dynamicArgs) {
-      new (dynamicSlot++) Operand(user, value);
-    }
-  }
-
-  ~TailAllocatedOperandList() {
-    for (auto &op : getDynamicAsArray()) {
-      op.~Operand();
-    }
-  }
-
-  /// Returns the full list of operands.
-  MutableArrayRef<Operand> asArray() {
-    return MutableArrayRef<Operand>(Buffer, NumExtra);
-  }
-  ArrayRef<Operand> asArray() const {
-    return ArrayRef<Operand>(Buffer, NumExtra);
-  }
-
-  /// Returns the full list of operand values.
-  OperandValueArrayRef asValueArray() const {
-    return OperandValueArrayRef(asArray());
-  }
-
-  /// Returns the list of the dynamic operands.
-  MutableArrayRef<Operand> getDynamicAsArray() {
-    return MutableArrayRef<Operand>(Buffer, NumExtra);
-  }
-  ArrayRef<Operand> getDynamicAsArray() const {
-    return ArrayRef<Operand>(Buffer, NumExtra);
-  }
-
-  /// Returns the list of the dynamic operand values.
-  OperandValueArrayRef getDynamicValuesAsArray() const {
-    return OperandValueArrayRef(getDynamicAsArray());
-  }
-
-  unsigned size() const { return NumExtra; }
-
-  /// Indexes into the full list of operands.
-  Operand &operator[](unsigned i) { return asArray()[i]; }
-  const Operand &operator[](unsigned i) const { return asArray()[i]; }
-};
-
 /// A helper class for initializing the list of trailing operands.
 class TrailingOperandsList {
 public:
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 60871f3..f582123 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -188,9 +188,9 @@
     .StartsWith("\xEF\xBB\xBF", 3)
     .Default(0);
 
-  // Since the UTF-8 BOM doesn't carry information (UTF-8 has no dependency
-  // on byte order), throw it away.
-  CurPtr = BufferStart + BOMLength;
+  // Keep information about existance of UTF-8 BOM for transparency source code
+  // editing with libSyntax.
+  CurPtr = BufferStart;
   ContentStart = BufferStart + BOMLength;
 
   // Initialize code completion.
@@ -278,7 +278,7 @@
   while (Ptr >= ContentStart + 1) {
     char C = Ptr[-1];
     if (C == ' ' || C == '\t') {
-      Ptr--;
+      --Ptr;
       continue;
     }
     if (C == 0) {
@@ -286,11 +286,11 @@
       // completion token.
       if (Ptr - 1 == CodeCompletionPtr)
         break;
-      Ptr--;
+      --Ptr;
       continue;
     }
     if (C == '\n' || C == '\r') {
-      Ptr--;
+      --Ptr;
       break;
     }
     break;
@@ -598,13 +598,13 @@
 
   // NOTE: legacy punctuator.  Remove in the future.
   if (*CurPtr == ']') { // #]
-     CurPtr++;
+     ++CurPtr;
      return formToken(tok::r_square_lit, TokStart);
   }
   
   // Allow a hashbang #! line at the beginning of the file.
   if (CurPtr - 1 == ContentStart && *CurPtr == '!') {
-    CurPtr--;
+    --CurPtr;
     if (BufferID != SourceMgr.getHashbangBufferID())
       diagnose(CurPtr, diag::lex_hashbang_not_allowed);
     skipHashbang(/*EatNewline=*/true);
@@ -1153,7 +1153,7 @@
       continue;
     case '\r':
       if (*TmpPtr == '\n')
-        TmpPtr++;
+        ++TmpPtr;
       LLVM_FALLTHROUGH;
     case '\n':
       CurPtr = TmpPtr;
@@ -1423,7 +1423,7 @@
 static size_t commonPrefixLength(StringRef shorter, StringRef longer) {
   size_t offset = 0;
   while (offset < shorter.size() && offset < longer.size() && shorter[offset] == longer[offset]) {
-    offset++;
+    ++offset;
   }
   
   return offset;
@@ -1445,7 +1445,7 @@
       continue;
     case '\n':
     case '\r': {
-      start++;
+      ++start;
       auto startLoc = Lexer::getSourceLoc(start);
       auto string = StringRef(start, end - start);
 
@@ -1654,7 +1654,7 @@
     // If this is the end of string, we are done.  If it is a normal character
     // or an already-diagnosed error, just munch it.
     if (CharValue == ~0U) {
-      CurPtr++;
+      ++CurPtr;
       if (wasErroneous)
         return formToken(tok::unknown, TokStart);
 
@@ -1890,7 +1890,7 @@
       bool stripNewline = IsEscapedNewline ||
         (IsFirstSegment && BytesPtr - 1 == Bytes.begin());
       if (CurChar == '\r' && *BytesPtr == '\n')
-        BytesPtr++;
+        ++BytesPtr;
       if (*BytesPtr != '\r' && *BytesPtr != '\n')
         BytesPtr += IndentToStrip;
       if (IsLastSegment && BytesPtr == Bytes.end())
@@ -1925,7 +1925,7 @@
     case ' ': case '\t': case '\n': case '\r':
       if (maybeConsumeNewlineEscape(BytesPtr, -1)) {
         IsEscapedNewline = true;
-        BytesPtr--;
+        --BytesPtr;
       }
       continue;
 
@@ -2036,7 +2036,20 @@
     LeadingTrivia.clear();
     TrailingTrivia.clear();
   }
-  NextToken.setAtStartOfLine(CurPtr == ContentStart);
+  if (CurPtr == BufferStart) {
+    if (BufferStart < ContentStart) {
+      size_t BOMLen = ContentStart - BufferStart;
+      assert(BOMLen == 3 && "UTF-8 BOM is 3 bytes");
+      if (TriviaRetention == TriviaRetentionMode::WithTrivia) {
+        // Add UTF-8 BOM to LeadingTrivia.
+        LeadingTrivia.push_back(TriviaPiece::garbageText({CurPtr, BOMLen}));
+      }
+      CurPtr += BOMLen;
+    }
+    NextToken.setAtStartOfLine(true);
+  } else {
+    NextToken.setAtStartOfLine(false);
+  }
 
   // Remember where we started so that we can find the comment range.
   LastCommentBlockStart = CurPtr;
@@ -2149,7 +2162,7 @@
 
     // Otherwise, this is the real end of the buffer.  Put CurPtr back into
     // buffer bounds.
-    CurPtr--;
+    --CurPtr;
     // Return EOF.
     return formToken(tok::eof, TokStart);
 
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index d5a0e78..a9833f9 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -177,19 +177,14 @@
                                    SILDebugLocation Loc,
                                    SILType ObjectType,
                                    bool objc, bool canBeOnStack,
-                                   ArrayRef<SILType> ElementTypes,
-                                   ArrayRef<SILValue> AllOperands)
-    : AllocationInst(Kind, Loc, ObjectType), Operands(this, AllOperands) {
+                                   ArrayRef<SILType> ElementTypes)
+    : AllocationInst(Kind, Loc, ObjectType) {
   SILInstruction::Bits.AllocRefInstBase.ObjC = objc;
   SILInstruction::Bits.AllocRefInstBase.OnStack = canBeOnStack;
   SILInstruction::Bits.AllocRefInstBase.NumTailTypes = ElementTypes.size();
-  static_assert(IsTriviallyCopyable<SILType>::value,
-                "assuming SILType is trivially copyable");
+  assert(SILInstruction::Bits.AllocRefInstBase.NumTailTypes ==
+         ElementTypes.size() && "Truncation");
   assert(!objc || ElementTypes.size() == 0);
-  assert(AllOperands.size() >= ElementTypes.size());
-
-  memcpy(getTypeStorage(), ElementTypes.begin(),
-         sizeof(SILType) * ElementTypes.size());
 }
 
 AllocRefInst *AllocRefInst::create(SILDebugLocation Loc, SILFunction &F,
@@ -208,11 +203,9 @@
   }
   collectTypeDependentOperands(AllOperands, OpenedArchetypes, F,
                                ObjectType.getSwiftRValueType());
-  void *Buffer = F.getModule().allocateInst(
-                      sizeof(AllocRefInst)
-                        + decltype(Operands)::getExtraSize(AllOperands.size())
-                        + sizeof(SILType) * ElementTypes.size(),
-                      alignof(AllocRefInst));
+  auto Size = totalSizeToAlloc<swift::Operand, SILType>(AllOperands.size(),
+                                                        ElementTypes.size());
+  auto Buffer = F.getModule().allocateInst(Size, alignof(AllocRefInst));
   return ::new (Buffer) AllocRefInst(Loc, F, ObjectType, objc, canBeOnStack,
                                      ElementTypes, AllOperands);
 }
@@ -232,11 +225,9 @@
     collectTypeDependentOperands(AllOperands, OpenedArchetypes, F,
                                  ElemType.getSwiftRValueType());
   }
-  void *Buffer = F.getModule().allocateInst(
-                      sizeof(AllocRefDynamicInst)
-                        + decltype(Operands)::getExtraSize(AllOperands.size())
-                        + sizeof(SILType) * ElementTypes.size(),
-                      alignof(AllocRefDynamicInst));
+  auto Size = totalSizeToAlloc<swift::Operand, SILType>(AllOperands.size(),
+                                                        ElementTypes.size());
+  auto Buffer = F.getModule().allocateInst(Size, alignof(AllocRefDynamicInst));
   return ::new (Buffer)
       AllocRefDynamicInst(DebugLoc, ty, objc, ElementTypes, AllOperands);
 }
@@ -244,11 +235,9 @@
 AllocBoxInst::AllocBoxInst(SILDebugLocation Loc, CanSILBoxType BoxType,
                            ArrayRef<SILValue> TypeDependentOperands,
                            SILFunction &F, SILDebugVariable Var)
-    : InstructionBase(Loc, SILType::getPrimitiveObjectType(BoxType)),
-      NumOperands(TypeDependentOperands.size()),
+    : InstructionBaseWithTrailingOperands(TypeDependentOperands, Loc,
+                                      SILType::getPrimitiveObjectType(BoxType)),
       VarInfo(Var, getTrailingObjects<char>()) {
-  TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                         TypeDependentOperands);
 }
 
 AllocBoxInst *AllocBoxInst::create(SILDebugLocation Loc,
@@ -259,10 +248,10 @@
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
                                BoxType);
-  void *Buffer = allocateDebugVarCarryingInst<AllocBoxInst>(
-      F.getModule(), Var, TypeDependentOperands);
-  return ::new (Buffer)
-      AllocBoxInst(Loc, BoxType, TypeDependentOperands, F, Var);
+  auto Sz = totalSizeToAlloc<swift::Operand, char>(TypeDependentOperands.size(),
+                                                   Var.Name.size());
+  auto Buf = F.getModule().allocateInst(Sz, alignof(AllocBoxInst));
+  return ::new (Buf) AllocBoxInst(Loc, BoxType, TypeDependentOperands, F, Var);
 }
 
 /// getDecl - Return the underlying variable declaration associated with this
@@ -302,17 +291,6 @@
   return getLoc().getAsASTNode<VarDecl>();
 }
 
-AllocExistentialBoxInst::AllocExistentialBoxInst(
-    SILDebugLocation Loc, SILType ExistentialType, CanType ConcreteType,
-    ArrayRef<ProtocolConformanceRef> Conformances,
-    ArrayRef<SILValue> TypeDependentOperands, SILFunction *Parent)
-    : InstructionBase(Loc, ExistentialType.getObjectType()),
-      NumOperands(TypeDependentOperands.size()),
-      ConcreteType(ConcreteType), Conformances(Conformances) {
-  TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                         TypeDependentOperands);
-}
-
 static void declareWitnessTable(SILModule &Mod,
                                 ProtocolConformanceRef conformanceRef) {
   if (conformanceRef.isAbstract()) return;
@@ -332,10 +310,8 @@
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, *F,
                                ConcreteType);
   SILModule &Mod = F->getModule();
-  void *Buffer =
-      Mod.allocateInst(sizeof(AllocExistentialBoxInst) +
-                           sizeof(Operand) * (TypeDependentOperands.size()),
-                       alignof(AllocExistentialBoxInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(TypeDependentOperands.size());
+  auto Buffer = Mod.allocateInst(Size, alignof(AllocExistentialBoxInst));
   for (ProtocolConformanceRef C : Conformances)
     declareWitnessTable(Mod, C);
   return ::new (Buffer) AllocExistentialBoxInst(Loc,
@@ -383,15 +359,10 @@
 BuiltinInst::BuiltinInst(SILDebugLocation Loc, Identifier Name,
                          SILType ReturnType, SubstitutionList Subs,
                          ArrayRef<SILValue> Args)
-    : InstructionBase(Loc, ReturnType), Name(Name) {
+    : InstructionBaseWithTrailingOperands(Args, Loc, ReturnType), Name(Name) {
   SILInstruction::Bits.BuiltinInst.NumSubstitutions = Subs.size();
   assert(SILInstruction::Bits.BuiltinInst.NumSubstitutions == Subs.size() &&
          "Truncation");
-  SILInstruction::Bits.BuiltinInst.NumOperands = Args.size();
-  Operand *dynamicSlot = getTrailingObjects<Operand>();
-  for (auto value : Args) {
-    new (dynamicSlot++) Operand(this, value);
-  }
   std::uninitialized_copy(Subs.begin(), Subs.end(),
                           getTrailingObjects<Substitution>());
 }
@@ -836,17 +807,11 @@
 MarkFunctionEscapeInst *
 MarkFunctionEscapeInst::create(SILDebugLocation Loc,
                                ArrayRef<SILValue> Elements, SILFunction &F) {
-  void *Buffer = F.getModule().allocateInst(sizeof(MarkFunctionEscapeInst) +
-                              decltype(Operands)::getExtraSize(Elements.size()),
-                                        alignof(MarkFunctionEscapeInst));
-  return ::new(Buffer) MarkFunctionEscapeInst(Loc, Elements);
+  auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
+  auto Buf = F.getModule().allocateInst(Size, alignof(MarkFunctionEscapeInst));
+  return ::new(Buf) MarkFunctionEscapeInst(Loc, Elements);
 }
 
-MarkFunctionEscapeInst::MarkFunctionEscapeInst(SILDebugLocation Loc,
-                                               ArrayRef<SILValue> Elems)
-    : InstructionBase(Loc),
-      Operands(this, Elems) {}
-
 static SILType getPinResultType(SILType operandType) {
   return SILType::getPrimitiveObjectType(
     OptionalType::get(operandType.getSwiftRValueType())->getCanonicalType());
@@ -874,23 +839,11 @@
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
                                BoundType.getSwiftRValueType());
-  void *Buffer = F.getModule().allocateInst(
-      sizeof(BindMemoryInst) +
-          sizeof(Operand) * (TypeDependentOperands.size() + NumFixedOpers),
-      alignof(BindMemoryInst));
-  return ::new (Buffer)
-    BindMemoryInst(Loc, Base, Index, BoundType, TypeDependentOperands);
-}
-
-BindMemoryInst::BindMemoryInst(SILDebugLocation Loc, SILValue Base,
-                               SILValue Index,
-                               SILType BoundType,
-                               ArrayRef<SILValue> TypeDependentOperands)
-  : InstructionBase(Loc),
-    BoundType(BoundType),
-    NumOperands(NumFixedOpers + TypeDependentOperands.size()) {
-  TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                         Base, Index, TypeDependentOperands);
+  auto Size = totalSizeToAlloc<swift::Operand>(TypeDependentOperands.size() +
+                                               NumFixedOpers);
+  auto Buffer = F.getModule().allocateInst(Size, alignof(BindMemoryInst));
+  return ::new (Buffer) BindMemoryInst(Loc, Base, Index, BoundType,
+                                       TypeDependentOperands);
 }
 
 UncheckedRefCastAddrInst::UncheckedRefCastAddrInst(SILDebugLocation Loc,
@@ -916,29 +869,18 @@
 
 StructInst::StructInst(SILDebugLocation Loc, SILType Ty,
                        ArrayRef<SILValue> Elems)
-    : InstructionBase(Loc, Ty) {
-  SILInstruction::Bits.StructInst.NumOperands = Elems.size();
-  Operand *dynamicSlot = getTrailingObjects<Operand>();
-  for (auto value : Elems) {
-    new (dynamicSlot++) Operand(this, value);
-  }
+    : InstructionBaseWithTrailingOperands(Elems, Loc, Ty) {
   assert(!Ty.getStructOrBoundGenericStruct()->hasUnreferenceableStorage());
 }
 
 ObjectInst *ObjectInst::create(SILDebugLocation Loc, SILType Ty,
                                ArrayRef<SILValue> Elements,
                                unsigned NumBaseElements, SILModule &M) {
-  void *Buffer = M.allocateInst(sizeof(ObjectInst) +
-                            decltype(Operands)::getExtraSize(Elements.size()),
-                            alignof(ObjectInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
+  auto Buffer = M.allocateInst(Size, alignof(ObjectInst));
   return ::new(Buffer) ObjectInst(Loc, Ty, Elements, NumBaseElements);
 }
 
-ObjectInst::ObjectInst(SILDebugLocation Loc, SILType Ty,
-                       ArrayRef<SILValue> Elems, unsigned NumBaseElements)
-    : InstructionBase(Loc, Ty),
-      NumBaseElements(NumBaseElements), Operands(this, Elems) {}
-
 TupleInst *TupleInst::create(SILDebugLocation Loc, SILType Ty,
                              ArrayRef<SILValue> Elements, SILModule &M) {
   auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
@@ -946,24 +888,6 @@
   return ::new(Buffer) TupleInst(Loc, Ty, Elements);
 }
 
-TupleInst::TupleInst(SILDebugLocation Loc, SILType Ty,
-                     ArrayRef<SILValue> Elems)
-    : InstructionBase(Loc, Ty) {
-  SILInstruction::Bits.TupleInst.NumOperands = Elems.size();
-  Operand *dynamicSlot = getTrailingObjects<Operand>();
-  for (auto value : Elems) {
-    new (dynamicSlot++) Operand(this, value);
-  }
-}
-
-MetatypeInst::MetatypeInst(SILDebugLocation Loc, SILType Metatype,
-                           ArrayRef<SILValue> TypeDependentOperands)
-    : InstructionBase(Loc, Metatype) {
-  SILInstruction::Bits.MetatypeInst.NumOperands = TypeDependentOperands.size();
-  TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this,
-                                         TypeDependentOperands);
-}
-
 bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const {
   SILModule &Mod = getModule();
 
@@ -1166,27 +1090,15 @@
   llvm_unreachable("Unhandled TermKind in switch.");
 }
 
-YieldInst::YieldInst(SILDebugLocation loc, ArrayRef<SILValue> yieldedValues,
-                     SILBasicBlock *normalBB, SILBasicBlock *unwindBB)
-  : InstructionBase(loc),
-    DestBBs{{this, normalBB}, {this, unwindBB}},
-    Operands(this, yieldedValues) {}
-
 YieldInst *YieldInst::create(SILDebugLocation loc,
                              ArrayRef<SILValue> yieldedValues,
                              SILBasicBlock *normalBB, SILBasicBlock *unwindBB,
                              SILFunction &F) {
-  void *buffer = F.getModule().allocateInst(sizeof(YieldInst) +
-                        decltype(Operands)::getExtraSize(yieldedValues.size()),
-                                            alignof(YieldInst));
-  return ::new (buffer) YieldInst(loc, yieldedValues, normalBB, unwindBB);
+  auto Size = totalSizeToAlloc<swift::Operand>(yieldedValues.size());
+  void *Buffer = F.getModule().allocateInst(Size, alignof(YieldInst));
+  return ::new (Buffer) YieldInst(loc, yieldedValues, normalBB, unwindBB);
 }
 
-BranchInst::BranchInst(SILDebugLocation Loc, SILBasicBlock *DestBB,
-                       ArrayRef<SILValue> Args)
-    : InstructionBase(Loc), DestBB(this, DestBB),
-      Operands(this, Args) {}
-
 BranchInst *BranchInst::create(SILDebugLocation Loc, SILBasicBlock *DestBB,
                                SILFunction &F) {
   return create(Loc, DestBB, {}, F);
@@ -1195,9 +1107,8 @@
 BranchInst *BranchInst::create(SILDebugLocation Loc,
                                SILBasicBlock *DestBB, ArrayRef<SILValue> Args,
                                SILFunction &F) {
-  void *Buffer = F.getModule().allocateInst(sizeof(BranchInst) +
-                              decltype(Operands)::getExtraSize(Args.size()),
-                            alignof(BranchInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(Args.size());
+  auto Buffer = F.getModule().allocateInst(Size, alignof(BranchInst));
   return ::new (Buffer) BranchInst(Loc, DestBB, Args);
 }
 
@@ -1206,12 +1117,13 @@
                                ArrayRef<SILValue> Args, unsigned NumTrue,
                                unsigned NumFalse, ProfileCounter TrueBBCount,
                                ProfileCounter FalseBBCount)
-    : InstructionBase(Loc), DestBBs{{this, TrueBB, TrueBBCount},
-                                    {this, FalseBB, FalseBBCount}},
-      NumTrueArgs(NumTrue), NumFalseArgs(NumFalse),
-      Operands(this, Args, Condition) {
-  assert(Args.size() == (NumTrueArgs + NumFalseArgs) &&
-         "Invalid number of args");
+    : InstructionBaseWithTrailingOperands(Condition, Args, Loc),
+                                        DestBBs{{this, TrueBB, TrueBBCount},
+                                                {this, FalseBB, FalseBBCount}} {
+  assert(Args.size() == (NumTrue + NumFalse) && "Invalid number of args");
+  SILInstruction::Bits.CondBranchInst.NumTrueArgs = NumTrue;
+  assert(SILInstruction::Bits.CondBranchInst.NumTrueArgs == NumTrue &&
+         "Truncation");
   assert(TrueBB != FalseBB && "Identical destinations");
 }
 
@@ -1235,22 +1147,13 @@
   Args.append(TrueArgs.begin(), TrueArgs.end());
   Args.append(FalseArgs.begin(), FalseArgs.end());
 
-  void *Buffer = F.getModule().allocateInst(sizeof(CondBranchInst) +
-                              decltype(Operands)::getExtraSize(Args.size()),
-                            alignof(CondBranchInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(Args.size() + NumFixedOpers);
+  auto Buffer = F.getModule().allocateInst(Size, alignof(CondBranchInst));
   return ::new (Buffer) CondBranchInst(Loc, Condition, TrueBB, FalseBB, Args,
                                        TrueArgs.size(), FalseArgs.size(),
                                        TrueBBCount, FalseBBCount);
 }
 
-OperandValueArrayRef CondBranchInst::getTrueArgs() const {
-  return Operands.asValueArray().slice(1, NumTrueArgs);
-}
-
-OperandValueArrayRef CondBranchInst::getFalseArgs() const {
-  return Operands.asValueArray().slice(1 + NumTrueArgs, NumFalseArgs);
-}
-
 SILValue CondBranchInst::getArgForDestBB(const SILBasicBlock *DestBB,
                                          const SILArgument *Arg) const {
   return getArgForDestBB(DestBB, Arg->getIndex());
@@ -1266,35 +1169,11 @@
   }
 
   if (DestBB == getTrueBB())
-    return Operands[1 + ArgIndex].get();
+    return getAllOperands()[NumFixedOpers + ArgIndex].get();
 
   assert(DestBB == getFalseBB()
          && "By process of elimination BB must be false BB");
-  return Operands[1 + NumTrueArgs + ArgIndex].get();
-}
-
-ArrayRef<Operand> CondBranchInst::getTrueOperands() const {
-  if (NumTrueArgs == 0)
-    return ArrayRef<Operand>();
-  return ArrayRef<Operand>(&Operands[1], NumTrueArgs);
-}
-
-MutableArrayRef<Operand> CondBranchInst::getTrueOperands() {
-  if (NumTrueArgs == 0)
-    return MutableArrayRef<Operand>();
-  return MutableArrayRef<Operand>(&Operands[1], NumTrueArgs);
-}
-
-ArrayRef<Operand> CondBranchInst::getFalseOperands() const {
-  if (NumFalseArgs == 0)
-    return ArrayRef<Operand>();
-  return ArrayRef<Operand>(&Operands[1+NumTrueArgs], NumFalseArgs);
-}
-
-MutableArrayRef<Operand> CondBranchInst::getFalseOperands() {
-  if (NumFalseArgs == 0)
-    return MutableArrayRef<Operand>();
-  return MutableArrayRef<Operand>(&Operands[1+NumTrueArgs], NumFalseArgs);
+  return getAllOperands()[NumFixedOpers + getNumTrueArgs() + ArgIndex].get();
 }
 
 void CondBranchInst::swapSuccessors() {
@@ -1304,7 +1183,7 @@
   DestBBs[1] = First;
 
   // If we don't have any arguments return.
-  if (!NumTrueArgs && !NumFalseArgs)
+  if (!getNumTrueArgs() && !getNumFalseArgs())
     return;
 
   // Otherwise swap our true and false arguments.
@@ -1314,25 +1193,25 @@
     TrueOps.push_back(V);
 
   auto FalseArgs = getFalseArgs();
-  for (unsigned i = 0, e = NumFalseArgs; i < e; ++i) {
-    Ops[1+i].set(FalseArgs[i]);
+  for (unsigned i = 0, e = getNumFalseArgs(); i < e; ++i) {
+    Ops[NumFixedOpers+i].set(FalseArgs[i]);
   }
 
-  for (unsigned i = 0, e = NumTrueArgs; i < e; ++i) {
-    Ops[1+i+NumFalseArgs].set(TrueOps[i]);
+  for (unsigned i = 0, e = getNumTrueArgs(); i < e; ++i) {
+    Ops[NumFixedOpers+i+getNumFalseArgs()].set(TrueOps[i]);
   }
 
-  // Finally swap the number of arguments that we have.
-  std::swap(NumTrueArgs, NumFalseArgs);
+  // Finally swap the number of arguments that we have. The number of false
+  // arguments is derived from the number of true arguments, therefore:
+  SILInstruction::Bits.CondBranchInst.NumTrueArgs = getNumFalseArgs();
 }
 
 SwitchValueInst::SwitchValueInst(SILDebugLocation Loc, SILValue Operand,
                                  SILBasicBlock *DefaultBB,
                                  ArrayRef<SILValue> Cases,
                                  ArrayRef<SILBasicBlock *> BBs)
-    : InstructionBase(Loc), Operands(this, Cases, Operand) {
+    : InstructionBaseWithTrailingOperands(Operand, Cases, Loc) {
   SILInstruction::Bits.SwitchValueInst.HasDefault = bool(DefaultBB);
-  SILInstruction::Bits.SwitchValueInst.NumCases = Cases.size();
   // Initialize the successor array.
   auto *succs = getSuccessorBuf();
   unsigned OperandBitWidth = 0;
@@ -1392,30 +1271,12 @@
     Cases.push_back(pair.first);
     BBs.push_back(pair.second);
   }
-  size_t bufSize = sizeof(SwitchValueInst) +
-                   decltype(Operands)::getExtraSize(Cases.size()) +
-                   sizeof(SILSuccessor) * numSuccessors;
-  void *buf = F.getModule().allocateInst(bufSize, alignof(SwitchValueInst));
+  auto size = totalSizeToAlloc<swift::Operand, SILSuccessor>(numCases + 1,
+                                                             numSuccessors);
+  auto buf = F.getModule().allocateInst(size, alignof(SwitchValueInst));
   return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs);
 }
 
-SelectValueInst::SelectValueInst(SILDebugLocation Loc, SILValue Operand,
-                                 SILType Type, SILValue DefaultResult,
-                                 ArrayRef<SILValue> CaseValuesAndResults)
-    : InstructionBase(Loc, Type,
-                      CaseValuesAndResults.size() / 2, bool(DefaultResult),
-                      CaseValuesAndResults, Operand) {
-
-  unsigned OperandBitWidth = 0;
-
-  if (auto OperandTy = Operand->getType().getAs<BuiltinIntegerType>()) {
-    OperandBitWidth = OperandTy->getGreatestWidth();
-  }
-}
-
-SelectValueInst::~SelectValueInst() {
-}
-
 SelectValueInst *
 SelectValueInst::create(SILDebugLocation Loc, SILValue Operand, SILType Type,
                         SILValue DefaultResult,
@@ -1433,58 +1294,40 @@
   if ((bool)DefaultResult)
     CaseValuesAndResults.push_back(DefaultResult);
 
-  size_t bufSize = sizeof(SelectValueInst) + decltype(Operands)::getExtraSize(
-                                               CaseValuesAndResults.size());
-  void *buf = F.getModule().allocateInst(bufSize, alignof(SelectValueInst));
-  return ::new (buf)
-      SelectValueInst(Loc, Operand, Type, DefaultResult, CaseValuesAndResults);
-}
-
-static SmallVector<SILValue, 4>
-getCaseOperands(ArrayRef<std::pair<EnumElementDecl*, SILValue>> CaseValues,
-                SILValue DefaultValue) {
-  SmallVector<SILValue, 4> result;
-
-  for (auto &pair : CaseValues)
-    result.push_back(pair.second);
-  if (DefaultValue)
-    result.push_back(DefaultValue);
-
-  return result;
-}
-
-SelectEnumInstBase::SelectEnumInstBase(
-    SILInstructionKind Kind, SILDebugLocation Loc, SILType Ty, SILValue Operand,
-    SILValue DefaultValue,
-    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
-    Optional<ArrayRef<ProfileCounter>> CaseCounts, ProfileCounter DefaultCount)
-    : SelectInstBase(Kind, Loc, Ty, CaseValues.size(), bool(DefaultValue),
-                     getCaseOperands(CaseValues, DefaultValue), Operand) {
-  // Initialize the case and successor arrays.
-  auto *cases = getCaseBuf();
-  for (unsigned i = 0, size = CaseValues.size(); i < size; ++i) {
-    cases[i] = CaseValues[i].first;
-  }
+  auto Size = totalSizeToAlloc<swift::Operand>(CaseValuesAndResults.size() + 1);
+  auto Buf = F.getModule().allocateInst(Size, alignof(SelectValueInst));
+  return ::new (Buf) SelectValueInst(Loc, Operand, Type, DefaultResult,
+                                     CaseValuesAndResults);
 }
 
 template <typename SELECT_ENUM_INST>
 SELECT_ENUM_INST *SelectEnumInstBase::createSelectEnum(
     SILDebugLocation Loc, SILValue Operand, SILType Ty, SILValue DefaultValue,
-    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues, SILFunction &F,
-    Optional<ArrayRef<ProfileCounter>> CaseCounts,
+    ArrayRef<std::pair<EnumElementDecl *, SILValue>> DeclsAndValues,
+    SILFunction &F, Optional<ArrayRef<ProfileCounter>> CaseCounts,
     ProfileCounter DefaultCount) {
   // Allocate enough room for the instruction with tail-allocated
   // EnumElementDecl and operand arrays. There are `CaseBBs.size()` decls
   // and `CaseBBs.size() + (DefaultBB ? 1 : 0)` values.
-  unsigned numCases = CaseValues.size();
+  unsigned numCases = DeclsAndValues.size();
+  SmallVector<SILValue, 4> CaseValues;
+  SmallVector<EnumElementDecl*, 4> CaseDecls;
+  for (auto &pair : DeclsAndValues) {
+    CaseValues.push_back(pair.second);
+    CaseDecls.push_back(pair.first);
+  }
 
-  void *buf = F.getModule().allocateInst(
-      sizeof(SELECT_ENUM_INST) + sizeof(EnumElementDecl *) * numCases +
-          sizeof(ProfileCounter) + TailAllocatedOperandList<1>::getExtraSize(
-                                       numCases + (bool)DefaultValue),
-      alignof(SELECT_ENUM_INST));
-  return ::new (buf) SELECT_ENUM_INST(Loc, Operand, Ty, DefaultValue,
-                                      CaseValues, CaseCounts, DefaultCount);
+  if (DefaultValue)
+    CaseValues.push_back(DefaultValue);
+
+  auto Size = SELECT_ENUM_INST::template
+    totalSizeToAlloc<swift::Operand, EnumElementDecl*>(CaseValues.size() + 1,
+                                                       CaseDecls.size());
+  auto Buf = F.getModule().allocateInst(Size + sizeof(ProfileCounter),
+                                        alignof(SELECT_ENUM_INST));
+  return ::new (Buf) SELECT_ENUM_INST(Loc, Operand, Ty, bool(DefaultValue),
+                                      CaseValues, CaseDecls, CaseCounts,
+                                      DefaultCount);
 }
 
 SelectEnumInst *SelectEnumInst::create(
@@ -1723,10 +1566,8 @@
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, *F,
                                LookupType);
-  void *Buffer =
-      Mod.allocateInst(sizeof(WitnessMethodInst) +
-                           sizeof(Operand) * TypeDependentOperands.size(),
-                       alignof(WitnessMethodInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(TypeDependentOperands.size());
+  auto Buffer = Mod.allocateInst(Size, alignof(WitnessMethodInst));
 
   declareWitnessTable(Mod, Conformance);
   return ::new (Buffer) WitnessMethodInst(Loc, LookupType, Conformance, Member,
@@ -2070,11 +1911,8 @@
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, *F,
                                Ty.castTo<MetatypeType>().getInstanceType());
-  void *Buffer =
-      Mod.allocateInst(sizeof(MetatypeInst) +
-                           sizeof(Operand) * TypeDependentOperands.size(),
-                       alignof(MetatypeInst));
-
+  auto Size = totalSizeToAlloc<swift::Operand>(TypeDependentOperands.size());
+  auto Buffer = Mod.allocateInst(Size, alignof(MetatypeInst));
   return ::new (Buffer) MetatypeInst(Loc, Ty, TypeDependentOperands);
 }
 
diff --git a/unittests/Parse/LexerTests.cpp b/unittests/Parse/LexerTests.cpp
index 75cc8d3..76172d8 100644
--- a/unittests/Parse/LexerTests.cpp
+++ b/unittests/Parse/LexerTests.cpp
@@ -260,6 +260,208 @@
   ASSERT_TRUE(Tok.isAtStartOfLine());
 }
 
+TEST_F(LexerTest, BOMNoCommentNoTrivia) {
+  const char *Source = "\xEF\xBB\xBF" "// comment\naaa //xx \n/* x */";
+  
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source));
+  
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::None, TriviaRetentionMode::WithoutTrivia);
+  
+  Token Tok;
+  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+}
+
+TEST_F(LexerTest, BOMTokenCommentNoTrivia) {
+  const char *Source = "\xEF\xBB\xBF" "// comment\naaa //xx \n/* x */";
+  
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source));
+  
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::ReturnAsTokens, TriviaRetentionMode::WithoutTrivia);
+  
+  Token Tok;
+  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::comment, Tok.getKind());
+  ASSERT_EQ("// comment\n", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::comment, Tok.getKind());
+  ASSERT_EQ("//xx \n", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::comment, Tok.getKind());
+  ASSERT_EQ("/* x */", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 24), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 24), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+}
+
+TEST_F(LexerTest, BOMAttachCommentNoTrivia) {
+  const char *Source = "\xEF\xBB\xBF" "// comment\naaa //xx \n/* x */";
+  
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source));
+  
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::AttachToNextToken, TriviaRetentionMode::WithoutTrivia);
+  
+  Token Tok;
+  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
+  ASSERT_EQ(10u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
+  ASSERT_EQ(13u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+}
+
+TEST_F(LexerTest, BOMNoCommentTrivia) {
+  const char *Source = "\xEF\xBB\xBF" "// comment\naaa //xx \n/* x */";
+  
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source));
+  
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::None, TriviaRetentionMode::WithTrivia);
+  
+  Token Tok;
+  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::garbageText("\xEF\xBB\xBF"),
+    syntax::TriviaPiece::lineComment("// comment"),
+    syntax::TriviaPiece::newlines(1)
+  }}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::spaces(1)
+  }}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
+  ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::lineComment("//xx "),
+    syntax::TriviaPiece::newlines(1),
+    syntax::TriviaPiece::blockComment("/* x */")
+  }}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+}
+
+TEST_F(LexerTest, BOMAttachCommentTrivia) {
+  const char *Source = "\xEF\xBB\xBF" "// comment\naaa //xx \n/* x */";
+  
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source));
+  
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::AttachToNextToken, TriviaRetentionMode::WithTrivia);
+  
+  Token Tok;
+  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
+  ASSERT_EQ(10u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::garbageText("\xEF\xBB\xBF"),
+    syntax::TriviaPiece::lineComment("// comment"),
+    syntax::TriviaPiece::newlines(1)
+  }}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::spaces(1)
+  }}), TrailingTrivia);
+  
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
+  ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
+  ASSERT_EQ(13u, Tok.getCommentRange().getByteLength());
+  ASSERT_EQ((syntax::Trivia{{
+    syntax::TriviaPiece::lineComment("//xx "),
+    syntax::TriviaPiece::newlines(1),
+    syntax::TriviaPiece::blockComment("/* x */")
+  }}), LeadingTrivia);
+  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+}
+
 TEST_F(LexerTest, RestoreBasic) {
   const char *Source = "aaa \t\0 bbb ccc";
 
diff --git a/unittests/Parse/LexerTriviaTests.cpp b/unittests/Parse/LexerTriviaTests.cpp
index e1c7d08..5373691 100644
--- a/unittests/Parse/LexerTriviaTests.cpp
+++ b/unittests/Parse/LexerTriviaTests.cpp
@@ -102,9 +102,9 @@
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
 
-  // FIXME: This should include UTF8-BOM as a GarbargeText trivia.
   ASSERT_EQ(LeadingTrivia,
-            (Trivia{{TriviaPiece::garbageText("#!/bin/swift"),
+            (Trivia{{TriviaPiece::garbageText("\xEF\xBB\xBF"),
+                     TriviaPiece::garbageText("#!/bin/swift"),
                      TriviaPiece::newlines(1)}}));
 }
 
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 782f167..716194c 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -371,7 +371,7 @@
              Child('Pattern', kind='Pattern'),
              Child('TypeAnnotation', kind='TypeAnnotation', is_optional=True),
              Child('Initializer', kind='InitializerClause', is_optional=True),
-             Child('Accesor', kind='AccessorBlock', is_optional=True),
+             Child('Accessor', kind='AccessorBlock', is_optional=True),
              Child('TrailingComma', kind='CommaToken', is_optional=True),
          ]),