Merge pull request #13631 from omochi/lex-escape-backtick
[Parse] Lexer build backtick trivia around espaced identifier token
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index ff1fdd5..22c77e0 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -236,6 +236,9 @@
/// Decl - Base class for all declarations in Swift.
class alignas(1 << DeclAlignInBits) Decl {
+protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+1+1+1,
Kind : bitmax(NumDeclKindBits,8),
@@ -587,34 +590,6 @@
NumberOfVTableEntries : 2
);
-protected:
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(Decl);
- SWIFT_INLINE_BITS(PatternBindingDecl);
- SWIFT_INLINE_BITS(EnumCaseDecl);
- SWIFT_INLINE_BITS(ValueDecl);
- SWIFT_INLINE_BITS(AbstractStorageDecl);
- SWIFT_INLINE_BITS(AbstractFunctionDecl);
- SWIFT_INLINE_BITS(VarDecl);
- SWIFT_INLINE_BITS(ParamDecl);
- SWIFT_INLINE_BITS(EnumElementDecl);
- SWIFT_INLINE_BITS(FuncDecl);
- SWIFT_INLINE_BITS(ConstructorDecl);
- SWIFT_INLINE_BITS(TypeDecl);
- SWIFT_INLINE_BITS(GenericTypeParamDecl);
- SWIFT_INLINE_BITS(TypeAliasDecl);
- SWIFT_INLINE_BITS(NominalTypeDecl);
- SWIFT_INLINE_BITS(ProtocolDecl);
- SWIFT_INLINE_BITS(ClassDecl);
- SWIFT_INLINE_BITS(StructDecl);
- SWIFT_INLINE_BITS(EnumDecl);
- SWIFT_INLINE_BITS(AssociatedTypeDecl);
- SWIFT_INLINE_BITS(PrecedenceGroupDecl);
- SWIFT_INLINE_BITS(ImportDecl);
- SWIFT_INLINE_BITS(ExtensionDecl);
- SWIFT_INLINE_BITS(IfConfigDecl);
- SWIFT_INLINE_BITS(MissingMemberDecl);
} Bits;
// Storage for the declaration attributes.
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index fcef79d..f293d08 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -130,6 +130,9 @@
Expr(const Expr&) = delete;
void operator=(const Expr&) = delete;
+protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(Expr, bitmax(NumExprKindBits,8)+2+1,
/// The subclass of Expr that this is.
Kind : bitmax(NumExprKindBits,8),
@@ -363,41 +366,6 @@
NumElements : 32
);
-protected:
- union {
- SWIFT_INLINE_BITS(Expr);
- SWIFT_INLINE_BITS(NumberLiteralExpr);
- SWIFT_INLINE_BITS(StringLiteralExpr);
- SWIFT_INLINE_BITS(DeclRefExpr);
- SWIFT_INLINE_BITS(UnresolvedDeclRefExpr);
- SWIFT_INLINE_BITS(TupleExpr);
- SWIFT_INLINE_BITS(TupleElementExpr);
- SWIFT_INLINE_BITS(MemberRefExpr);
- SWIFT_INLINE_BITS(UnresolvedDotExpr);
- SWIFT_INLINE_BITS(SubscriptExpr);
- SWIFT_INLINE_BITS(DynamicSubscriptExpr);
- SWIFT_INLINE_BITS(UnresolvedMemberExpr);
- SWIFT_INLINE_BITS(OverloadSetRefExpr);
- SWIFT_INLINE_BITS(BooleanLiteralExpr);
- SWIFT_INLINE_BITS(MagicIdentifierLiteralExpr);
- SWIFT_INLINE_BITS(ObjectLiteralExpr);
- SWIFT_INLINE_BITS(AbstractClosureExpr);
- SWIFT_INLINE_BITS(ClosureExpr);
- SWIFT_INLINE_BITS(BindOptionalExpr);
- SWIFT_INLINE_BITS(ApplyExpr);
- SWIFT_INLINE_BITS(CallExpr);
- SWIFT_INLINE_BITS(CheckedCastExpr);
- SWIFT_INLINE_BITS(TupleShuffleExpr);
- SWIFT_INLINE_BITS(InOutToPointerExpr);
- SWIFT_INLINE_BITS(ArrayToPointerExpr);
- SWIFT_INLINE_BITS(ObjCSelectorExpr);
- SWIFT_INLINE_BITS(KeyPathExpr);
- SWIFT_INLINE_BITS(ParenExpr);
- SWIFT_INLINE_BITS(SequenceExpr);
- SWIFT_INLINE_BITS(CollectionExpr);
- SWIFT_INLINE_BITS(ErasureExpr);
- SWIFT_INLINE_BITS(UnresolvedSpecializeExpr);
- SWIFT_INLINE_BITS(CaptureListExpr);
} Bits;
private:
@@ -410,6 +378,7 @@
protected:
Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) {
+ Bits.OpaqueBits = 0;
Bits.Expr.Kind = unsigned(Kind);
Bits.Expr.Implicit = Implicit;
Bits.Expr.LValueAccessKind = 0;
diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h
index 95019ba..7d5cfe7 100644
--- a/include/swift/AST/Pattern.h
+++ b/include/swift/AST/Pattern.h
@@ -49,6 +49,9 @@
/// Pattern - Base class for all patterns in Swift.
class alignas(8) Pattern {
+protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(Pattern, bitmax(NumPatternKindBits,8)+1+1,
Kind : bitmax(NumPatternKindBits,8),
isImplicit : 1,
@@ -64,12 +67,15 @@
IsPropagatedType : 1
);
-protected:
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(Pattern);
- SWIFT_INLINE_BITS(TuplePattern);
- SWIFT_INLINE_BITS(TypedPattern);
+ SWIFT_INLINE_BITFIELD(BoolPattern, Pattern, 1,
+ Value : 1
+ );
+
+ SWIFT_INLINE_BITFIELD(VarPattern, Pattern, 1,
+ /// True if this is a let pattern, false if a var pattern.
+ IsLet : 1
+ );
+
} Bits;
Pattern(PatternKind kind) {
@@ -584,15 +590,15 @@
/// matched against the associated value for the case.
class BoolPattern : public Pattern {
SourceLoc NameLoc;
- bool Value;
public:
BoolPattern(SourceLoc NameLoc, bool Value)
- : Pattern(PatternKind::Bool), NameLoc(NameLoc), Value(Value) {
+ : Pattern(PatternKind::Bool), NameLoc(NameLoc) {
+ Bits.BoolPattern.Value = Value;
}
- bool getValue() const { return Value; }
- void setValue(bool v) { Value = v; }
+ bool getValue() const { return Bits.BoolPattern.Value; }
+ void setValue(bool v) { Bits.BoolPattern.Value = v; }
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc; }
@@ -706,17 +712,17 @@
/// parsed as expressions referencing existing entities.
class VarPattern : public Pattern {
SourceLoc VarLoc;
- bool IsLet; // True if this is a let pattern, false if a var pattern.
Pattern *SubPattern;
public:
VarPattern(SourceLoc loc, bool isLet, Pattern *sub,
Optional<bool> implicit = None)
- : Pattern(PatternKind::Var), VarLoc(loc), IsLet(isLet), SubPattern(sub) {
+ : Pattern(PatternKind::Var), VarLoc(loc), SubPattern(sub) {
+ Bits.VarPattern.IsLet = isLet;
if (implicit.hasValue() ? *implicit : !loc.isValid())
setImplicit();
}
- bool isLet() const { return IsLet; }
+ bool isLet() const { return Bits.VarPattern.IsLet; }
SourceLoc getLoc() const { return VarLoc; }
SourceRange getSourceRange() const {
diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h
index 51aadd4..73f4039 100644
--- a/include/swift/AST/Stmt.h
+++ b/include/swift/AST/Stmt.h
@@ -51,6 +51,9 @@
Stmt(const Stmt&) = delete;
Stmt& operator=(const Stmt&) = delete;
+protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(Stmt, bitmax(NumStmtKindBits,8) + 1,
/// Kind - The subclass of Stmt that this is.
Kind : bitmax(NumStmtKindBits,8),
@@ -81,14 +84,6 @@
CaseCount : 32
);
-protected:
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(Stmt);
- SWIFT_INLINE_BITS(BraceStmt);
- SWIFT_INLINE_BITS(DoCatchStmt);
- SWIFT_INLINE_BITS(CaseStmt);
- SWIFT_INLINE_BITS(SwitchStmt);
} Bits;
/// Return the given value for the 'implicit' flag if present, or if None,
diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h
index 6fd4ff0..b4ed480 100644
--- a/include/swift/AST/TypeRepr.h
+++ b/include/swift/AST/TypeRepr.h
@@ -49,6 +49,9 @@
TypeRepr(const TypeRepr&) = delete;
void operator=(const TypeRepr&) = delete;
+protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(TypeRepr, bitmax(NumTypeReprKindBits,8)+1+1,
/// The subclass of TypeRepr that this is.
Kind : bitmax(NumTypeReprKindBits,8),
@@ -71,11 +74,6 @@
NumElements : 16
);
-protected:
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(TypeRepr);
- SWIFT_INLINE_BITS(TupleTypeRepr);
} Bits;
TypeRepr(TypeReprKind K) {
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index d7167bc..c0b7519 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -259,14 +259,6 @@
/// form of a non-canonical type is requested.
llvm::PointerUnion<TypeBase *, const ASTContext *> CanonicalType;
- SWIFT_INLINE_BITFIELD_BASE(TypeBase, bitmax(NumTypeKindBits,8) +
- RecursiveTypeProperties::BitWidth,
- /// Kind - The discriminator that indicates what subclass of type this is.
- Kind : bitmax(NumTypeKindBits,8),
-
- Properties : RecursiveTypeProperties::BitWidth
- );
-
/// Returns true if the given type is a sugared type.
///
/// Only intended for use in compile-time assertions.
@@ -277,6 +269,18 @@
}
protected:
+ enum { NumAFTExtInfoBits = 7 };
+ enum { NumSILExtInfoBits = 6 };
+ union { uint64_t OpaqueBits;
+
+ SWIFT_INLINE_BITFIELD_BASE(TypeBase, bitmax(NumTypeKindBits,8) +
+ RecursiveTypeProperties::BitWidth,
+ /// Kind - The discriminator that indicates what subclass of type this is.
+ Kind : bitmax(NumTypeKindBits,8),
+
+ Properties : RecursiveTypeProperties::BitWidth
+ );
+
SWIFT_INLINE_BITFIELD(ErrorType, TypeBase, 1,
/// Whether there is an original type.
HasOriginalType : 1
@@ -288,7 +292,6 @@
Flags : NumFlagBits
);
- enum { NumAFTExtInfoBits = 7 };
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+16,
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
@@ -318,7 +321,6 @@
GraphIndex : 29
);
- enum { NumSILExtInfoBits = 6 };
SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+3+1+2,
ExtInfo : NumSILExtInfoBits,
CalleeConvention : 3,
@@ -367,20 +369,6 @@
GenericArgCount : 32
);
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(TypeBase);
- SWIFT_INLINE_BITS(ErrorType);
- SWIFT_INLINE_BITS(ParenType);
- SWIFT_INLINE_BITS(AnyFunctionType);
- SWIFT_INLINE_BITS(TypeVariableType);
- SWIFT_INLINE_BITS(ArchetypeType);
- SWIFT_INLINE_BITS(SILFunctionType);
- SWIFT_INLINE_BITS(SILBoxType);
- SWIFT_INLINE_BITS(AnyMetatypeType);
- SWIFT_INLINE_BITS(ProtocolCompositionType);
- SWIFT_INLINE_BITS(TupleType);
- SWIFT_INLINE_BITS(BoundGenericType);
} Bits;
protected:
diff --git a/include/swift/Basic/ArrayRefView.h b/include/swift/Basic/ArrayRefView.h
index 89edd8d..7eaab97 100644
--- a/include/swift/Basic/ArrayRefView.h
+++ b/include/swift/Basic/ArrayRefView.h
@@ -44,6 +44,7 @@
typedef std::random_access_iterator_tag iterator_category;
Projected operator*() const { return Project(*Ptr); }
+ Projected operator->() const { return operator*(); }
iterator &operator++() { Ptr++; return *this; }
iterator operator++(int) { return iterator(Ptr++); }
bool operator==(iterator rhs) const { return Ptr == rhs.Ptr; }
diff --git a/include/swift/Basic/InlineBitfield.h b/include/swift/Basic/InlineBitfield.h
index 23acdfb..bb506be 100644
--- a/include/swift/Basic/InlineBitfield.h
+++ b/include/swift/Basic/InlineBitfield.h
@@ -38,10 +38,10 @@
class T##Bitfield { \
friend class T; \
uint64_t __VA_ARGS__; \
- uint64_t : 64 - (C); /* Pad and error if C > 64 */ \
- }; \
+ } T; \
LLVM_PACKED_END \
- enum { Num##T##Bits = (C) }
+ enum { Num##T##Bits = (C) }; \
+ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow")
/// Define an bitfield for type 'T' with parent class 'U' and 'C' bits used.
#define SWIFT_INLINE_BITFIELD(T, U, C, ...) \
@@ -49,10 +49,10 @@
class T##Bitfield { \
friend class T; \
uint64_t : Num##U##Bits, __VA_ARGS__; \
- uint64_t : 64 - (Num##U##Bits + (C)); /* Pad and error if C > 64 */ \
- }; \
+ } T; \
LLVM_PACKED_END \
- enum { Num##T##Bits = Num##U##Bits + (C) }
+ enum { Num##T##Bits = Num##U##Bits + (C) }; \
+ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow")
/// Define a full bitfield for type 'T' that uses all of the remaining bits in
/// the inline bitfield.
@@ -72,7 +72,7 @@
friend class T; \
enum { NumPadBits = 64 - (Num##U##Bits + (C)) }; \
uint64_t : Num##U##Bits, __VA_ARGS__; \
- }; \
+ } T; \
LLVM_PACKED_END \
static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow")
@@ -80,8 +80,6 @@
#define SWIFT_INLINE_BITFIELD_EMPTY(T, U) \
enum { Num##T##Bits = Num##U##Bits }
-#define SWIFT_INLINE_BITS(T) T##Bitfield T
-
// XXX/HACK: templated max() doesn't seem to work in a bitfield size context.
constexpr unsigned bitmax(unsigned a, unsigned b) {
return a > b ? a : b;
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index f72e0c4..2f49325 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -925,9 +925,9 @@
SourceLoc &LAngleLoc,
SourceLoc &RAngleLoc);
- SyntaxParserResult<syntax::TypeSyntax, TypeRepr> parseTypeIdentifier();
+ ParserResult<TypeRepr> parseTypeIdentifier();
ParserResult<TypeRepr> parseOldStyleProtocolComposition();
- SyntaxParserResult<syntax::TypeSyntax, CompositionTypeRepr> parseAnyType();
+ ParserResult<CompositionTypeRepr> parseAnyType();
ParserResult<TypeRepr> parseSILBoxType(GenericParamList *generics,
const TypeAttributes &attrs,
Optional<Scope> &GenericsScope);
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..c6caef3 100644
--- a/include/swift/SIL/SILNode.h
+++ b/include/swift/SIL/SILNode.h
@@ -98,7 +98,10 @@
enum { NumLoadOwnershipQualifierBits = 2 };
enum { NumSILAccessKindBits = 2 };
enum { NumSILAccessEnforcementBits = 2 };
+
protected:
+ union { uint64_t OpaqueBits;
+
SWIFT_INLINE_BITFIELD_BASE(SILNode, bitmax(NumSILNodeKindBits,8)+1+1,
Kind : bitmax(NumSILNodeKindBits,8),
StorageLoc : 1,
@@ -123,10 +126,11 @@
SWIFT_INLINE_BITFIELD_EMPTY(SILInstruction, SILNode);
// Special handling for UnaryInstructionWithTypeDependentOperandsBase
- SWIFT_INLINE_BITFIELD(UIWTDOB, SILNode, 32,
+ SWIFT_INLINE_BITFIELD(IBWTO, SILNode, 64-NumSILNodeBits,
// 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 templates must allocate bits from back to front
+ // so that "normal" subclassing can allocate bits from front to back.
+ // If you update this, then you must update the IBWTO_BITFIELD macros.
/*pad*/ : 32-NumSILNodeBits,
@@ -134,31 +138,42 @@
// It is number of type dependent operands + 1.
NumOperands : 32;
template<SILInstructionKind Kind, typename, typename, typename...>
- friend class UnaryInstructionWithTypeDependentOperandsBase
+ friend class InstructionBaseWithTrailingOperands
);
+#define IBWTO_BITFIELD(T, U, C, ...) \
+ SWIFT_INLINE_BITFIELD(T, U, (C), __VA_ARGS__, : 32)
+#define IBWTO_BITFIELD_EMPTY(T, U) \
+ SWIFT_INLINE_BITFIELD_EMPTY(T, U)
+
#define UIWTDOB_BITFIELD(T, U, C, ...) \
- SWIFT_INLINE_BITFIELD_FULL(T, U, (C)+32, __VA_ARGS__)
+ IBWTO_BITFIELD(T, U, (C), __VA_ARGS__)
+#define UIWTDOB_BITFIELD_EMPTY(T, U) \
+ IBWTO_BITFIELD_EMPTY(T, U)
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_EMPTY(StructInst, SingleValueInstruction);
+
+ // Ensure that TupleInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(TupleInst, SingleValueInstruction);
+
+ 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,19 +202,23 @@
OnStack : 1
);
+ // Ensure that AllocBoxInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(AllocBoxInst, AllocationInst);
+ // Ensure that AllocExistentialBoxInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(AllocExistentialBoxInst, AllocationInst);
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
);
- UIWTDOB_BITFIELD(AllocValueBufferInst, AllocationInst, 0, : NumPadBits);
+ static_assert(32-1-1-NumAllocationInstBits >= 16, "Reconsider bitfield use?");
+
+ UIWTDOB_BITFIELD_EMPTY(AllocValueBufferInst, AllocationInst);
// TODO: Sort the following in SILNodes.def order
@@ -211,10 +230,14 @@
atomicity : 1
);
- SWIFT_INLINE_BITFIELD_FULL(MetatypeInst, SingleValueInstruction, 32,
- : NumPadBits,
- NumOperands : 32
- );
+ // Ensure that BindMemoryInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(BindMemoryInst, NonValueInstruction);
+
+ // Ensure that MarkFunctionEscapeInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(MarkFunctionEscapeInst, NonValueInstruction);
+
+ // Ensure that MetatypeInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(MetatypeInst, SingleValueInstruction);
SWIFT_INLINE_BITFIELD(CopyAddrInst, NonValueInstruction, 1+1,
/// IsTakeOfSrc - True if ownership will be taken from the value at the
@@ -272,11 +295,9 @@
);
SWIFT_INLINE_BITFIELD_EMPTY(MethodInst, SingleValueInstruction);
- SWIFT_INLINE_BITFIELD_FULL(WitnessMethodInst, MethodInst, 32,
- : NumPadBits,
- NumOperands : 32
- );
- UIWTDOB_BITFIELD(ObjCMethodInst, MethodInst, 0, : NumPadBits);
+ // Ensure that WitnessMethodInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(WitnessMethodInst, MethodInst);
+ UIWTDOB_BITFIELD_EMPTY(ObjCMethodInst, MethodInst);
SWIFT_INLINE_BITFIELD_EMPTY(ConversionInst, SingleValueInstruction);
SWIFT_INLINE_BITFIELD(PointerToAddressInst, ConversionInst, 1+1,
@@ -284,29 +305,34 @@
IsInvariant : 1
);
- UIWTDOB_BITFIELD(ConvertFunctionInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(PointerToThinFunctionInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UnconditionalCheckedCastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UpcastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UncheckedRefCastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UncheckedAddrCastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UncheckedTrivialBitCastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UncheckedBitwiseCastInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(ThinToThickFunctionInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(UnconditionalCheckedCastValueInst, ConversionInst, 0, : NumPadBits);
- UIWTDOB_BITFIELD(InitExistentialAddrInst, SingleValueInstruction, 0, : NumPadBits);
- UIWTDOB_BITFIELD(InitExistentialValueInst, SingleValueInstruction, 0, : NumPadBits);
- UIWTDOB_BITFIELD(InitExistentialRefInst, SingleValueInstruction, 0, : NumPadBits);
- UIWTDOB_BITFIELD(InitExistentialMetatypeInst, SingleValueInstruction, 0, : NumPadBits);
+ UIWTDOB_BITFIELD_EMPTY(ConvertFunctionInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(PointerToThinFunctionInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UnconditionalCheckedCastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UpcastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UncheckedRefCastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UncheckedAddrCastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UncheckedTrivialBitCastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UncheckedBitwiseCastInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(ThinToThickFunctionInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(UnconditionalCheckedCastValueInst, ConversionInst);
+ UIWTDOB_BITFIELD_EMPTY(InitExistentialAddrInst, SingleValueInstruction);
+ UIWTDOB_BITFIELD_EMPTY(InitExistentialValueInst, SingleValueInstruction);
+ UIWTDOB_BITFIELD_EMPTY(InitExistentialRefInst, SingleValueInstruction);
+ UIWTDOB_BITFIELD_EMPTY(InitExistentialMetatypeInst, SingleValueInstruction);
SWIFT_INLINE_BITFIELD_EMPTY(TermInst, SILInstruction);
- UIWTDOB_BITFIELD(CheckedCastBranchInst, SingleValueInstruction, 0, : NumPadBits);
- UIWTDOB_BITFIELD(CheckedCastValueBranchInst, SingleValueInstruction, 0, : NumPadBits);
+ UIWTDOB_BITFIELD_EMPTY(CheckedCastBranchInst, SingleValueInstruction);
+ UIWTDOB_BITFIELD_EMPTY(CheckedCastValueBranchInst, SingleValueInstruction);
- SWIFT_INLINE_BITFIELD_FULL(SwitchValueInst, TermInst, 1+32,
- HasDefault : 1,
- : NumPadBits,
- NumCases : 32
+ // Ensure that BranchInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(BranchInst, TermInst);
+ // Ensure that YieldInst bitfield does not overflow.
+ IBWTO_BITFIELD_EMPTY(YieldInst, TermInst);
+ 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,
@@ -314,6 +340,8 @@
NumCases : 32
);
+ } Bits;
+
enum class SILNodeStorageLocation : uint8_t { Value, Instruction };
enum class IsRepresentative : bool {
@@ -321,59 +349,6 @@
Yes = true,
};
- union {
- uint64_t OpaqueBits;
- SWIFT_INLINE_BITS(SILNode);
- SWIFT_INLINE_BITS(SILArgument);
- SWIFT_INLINE_BITS(MultipleValueInstructionResult);
- SWIFT_INLINE_BITS(UIWTDOB);
- SWIFT_INLINE_BITS(AllocStackInst);
- SWIFT_INLINE_BITS(AllocRefInstBase);
- SWIFT_INLINE_BITS(AllocValueBufferInst);
- SWIFT_INLINE_BITS(ConvertFunctionInst);
- SWIFT_INLINE_BITS(PointerToThinFunctionInst);
- SWIFT_INLINE_BITS(UpcastInst);
- SWIFT_INLINE_BITS(UncheckedRefCastInst);
- SWIFT_INLINE_BITS(UncheckedAddrCastInst);
- SWIFT_INLINE_BITS(UncheckedTrivialBitCastInst);
- SWIFT_INLINE_BITS(UncheckedBitwiseCastInst);
- SWIFT_INLINE_BITS(ThinToThickFunctionInst);
- SWIFT_INLINE_BITS(UnconditionalCheckedCastInst);
- SWIFT_INLINE_BITS(UnconditionalCheckedCastValueInst);
- SWIFT_INLINE_BITS(ObjCMethodInst);
- SWIFT_INLINE_BITS(InitExistentialAddrInst);
- SWIFT_INLINE_BITS(InitExistentialValueInst);
- SWIFT_INLINE_BITS(InitExistentialRefInst);
- SWIFT_INLINE_BITS(InitExistentialMetatypeInst);
- SWIFT_INLINE_BITS(CheckedCastBranchInst);
- SWIFT_INLINE_BITS(CheckedCastValueBranchInst);
- SWIFT_INLINE_BITS(UncheckedOwnershipConversionInst);
- SWIFT_INLINE_BITS(RefCountingInst);
- SWIFT_INLINE_BITS(StoreReferenceInstBaseT);
- SWIFT_INLINE_BITS(LoadReferenceInstBaseT);
- SWIFT_INLINE_BITS(StrongPinInst);
- SWIFT_INLINE_BITS(CopyAddrInst);
- SWIFT_INLINE_BITS(StoreInst);
- SWIFT_INLINE_BITS(LoadInst);
- SWIFT_INLINE_BITS(IntegerLiteralInst);
- SWIFT_INLINE_BITS(FloatLiteralInst);
- SWIFT_INLINE_BITS(DeallocRefInst);
- SWIFT_INLINE_BITS(WitnessMethodInst);
- SWIFT_INLINE_BITS(TupleExtractInst);
- SWIFT_INLINE_BITS(TupleElementAddrInst);
- SWIFT_INLINE_BITS(SwitchValueInst);
- SWIFT_INLINE_BITS(SwitchEnumInstBase);
- SWIFT_INLINE_BITS(PointerToAddressInst);
- SWIFT_INLINE_BITS(BeginAccessInst);
- SWIFT_INLINE_BITS(EndAccessInst);
- SWIFT_INLINE_BITS(MetatypeInst);
- SWIFT_INLINE_BITS(BuiltinInst);
- SWIFT_INLINE_BITS(StringLiteralInst);
- SWIFT_INLINE_BITS(ConstStringLiteralInst);
- SWIFT_INLINE_BITS(StructInst);
- SWIFT_INLINE_BITS(TupleInst);
- } Bits;
-
private:
SILNodeStorageLocation getStorageLoc() const {
diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h
index 44039a9..48fa897 100644
--- a/include/swift/SIL/SILValue.h
+++ b/include/swift/SIL/SILValue.h
@@ -18,6 +18,7 @@
#define SWIFT_SIL_SILVALUE_H
#include "swift/Basic/Range.h"
+#include "swift/Basic/ArrayRefView.h"
#include "swift/SIL/SILNode.h"
#include "swift/SIL/SILType.h"
#include "llvm/ADT/ArrayRef.h"
@@ -412,7 +413,6 @@
friend class ValueBaseUseIterator;
friend class ValueUseIterator;
template <unsigned N> friend class FixedOperandList;
- template <unsigned N> friend class TailAllocatedOperandList;
friend class TrailingOperandsList;
};
@@ -420,64 +420,10 @@
///
/// The intent is that this should basically act exactly like
/// ArrayRef except projecting away the Operand-ness.
-class OperandValueArrayRef {
- ArrayRef<Operand> Operands;
-public:
- explicit OperandValueArrayRef(ArrayRef<Operand> operands)
- : Operands(operands) {}
-
- /// A simple iterator adapter.
- class iterator : public std::iterator<std::forward_iterator_tag,
- SILValue, ptrdiff_t> {
- const Operand *Ptr;
- public:
- iterator() = default;
- iterator(const Operand *ptr) : Ptr(ptr) {}
- SILValue operator*() const { assert(Ptr); return Ptr->get(); }
- SILValue operator->() const { return operator*(); }
- iterator &operator++() { ++Ptr; return *this; }
- iterator operator++(int) { iterator copy = *this; ++Ptr; return copy; }
-
- friend bool operator==(iterator lhs, iterator rhs) {
- return lhs.Ptr == rhs.Ptr;
- }
- friend bool operator!=(iterator lhs, iterator rhs) {
- return lhs.Ptr != rhs.Ptr;
- }
- };
-
- iterator begin() const { return iterator(Operands.begin()); }
- iterator end() const { return iterator(Operands.end()); }
- size_t size() const { return Operands.size(); }
- bool empty() const { return Operands.empty(); }
-
- SILValue front() const { return Operands.front().get(); }
- SILValue back() const { return Operands.back().get(); }
-
- SILValue operator[](unsigned i) const { return Operands[i].get(); }
- OperandValueArrayRef slice(unsigned begin, unsigned length) const {
- return OperandValueArrayRef(Operands.slice(begin, length));
- }
- OperandValueArrayRef slice(unsigned begin) const {
- return OperandValueArrayRef(Operands.slice(begin));
- }
- OperandValueArrayRef drop_back() const {
- return OperandValueArrayRef(Operands.drop_back());
- }
-
- bool operator==(const OperandValueArrayRef RHS) const {
- if (size() != RHS.size())
- return false;
- for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R)
- if (*L != *R)
- return false;
- return true;
- }
-
- bool operator!=(const OperandValueArrayRef RHS) const {
- return !(*this == RHS);
- }
-};
+inline SILValue getSILValueType(const Operand &op) {
+ return op.get();
+}
+typedef ArrayRefView<Operand,SILValue,getSILValueType> OperandValueArrayRef;
/// An iterator over all uses of a ValueBase.
class ValueBaseUseIterator : public std::iterator<std::forward_iterator_tag,
@@ -590,176 +536,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/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 7c537a7..ab0912e 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -272,8 +272,10 @@
InPoundLineEnvironment);
// If we are done parsing the whole file, finalize the token receiver.
- if (Tok.is(tok::eof))
+ if (Tok.is(tok::eof)) {
+ SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
TokReceiver->finalize();
+ }
return FoundTopLevelCodeToExecute;
}
@@ -1606,13 +1608,13 @@
SyntaxParsingContext TokListContext(SyntaxContext, SyntaxKind::TokenList);
if (Tok.is(tok::l_paren) && getEndOfPreviousLoc() == Tok.getLoc()) {
- ParserPosition LParenPosition = getParserPosition();
+ BacktrackingScope backtrack(*this);
skipSingle();
// If we found '->', or 'throws' after paren, it's likely a parameter
// of function type.
- if (Tok.isAny(tok::arrow, tok::kw_throws, tok::kw_rethrows,
+ if (Tok.isNot(tok::arrow, tok::kw_throws, tok::kw_rethrows,
tok::kw_throw))
- backtrackToPosition(LParenPosition);
+ backtrack.cancelBacktrack();
}
return true;
}
@@ -2414,9 +2416,11 @@
DeclParsingContext.setCreateSyntax(SyntaxKind::ImportDecl);
DeclResult = parseDeclImport(Flags, Attributes);
break;
- case tok::kw_extension:
+ case tok::kw_extension: {
+ DeclParsingContext.setCreateSyntax(SyntaxKind::ExtensionDecl);
DeclResult = parseDeclExtension(Flags, Attributes);
break;
+ }
case tok::kw_let:
case tok::kw_var: {
// Collect all modifiers into a modifier list.
@@ -3061,6 +3065,7 @@
trailingWhereClause);
ext->getAttrs() = Attributes;
+ SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
SourceLoc LBLoc, RBLoc;
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_extension)) {
LBLoc = PreviousLoc;
@@ -3236,6 +3241,10 @@
ParserResult<TypeDecl> Parser::
parseDeclTypeAlias(Parser::ParseDeclOptions Flags, DeclAttributes &Attributes) {
ParserPosition startPosition = getParserPosition();
+ llvm::Optional<SyntaxParsingContext> TmpCtxt;
+ TmpCtxt.emplace(SyntaxContext);
+ TmpCtxt->setTransparent();
+
SourceLoc TypeAliasLoc = consumeToken(tok::kw_typealias);
SourceLoc EqualLoc;
Identifier Id;
@@ -3271,11 +3280,14 @@
}
if (Flags.contains(PD_InProtocol) && !genericParams && !Tok.is(tok::equal)) {
+ TmpCtxt->setDiscard();
+ TmpCtxt.reset();
// If we're in a protocol and don't see an '=' this looks like leftover Swift 2
// code intending to be an associatedtype.
backtrackToPosition(startPosition);
return parseDeclAssociatedType(Flags, Attributes);
}
+ TmpCtxt.reset();
ParserResult<TypeRepr> UnderlyingTy;
@@ -3873,9 +3885,13 @@
// attributes might not be appertaining to the accessor, but to the first
// declaration inside the implicit getter, we need to save the parser
// position and restore it later.
+ llvm::Optional<SyntaxParsingContext> BacktrackCtxt;
ParserPosition BeginParserPosition;
- if (Tok.is(tok::at_sign))
+ if (Tok.is(tok::at_sign)) {
BeginParserPosition = getParserPosition();
+ BacktrackCtxt.emplace(SyntaxContext);
+ BacktrackCtxt->setTransparent();
+ }
// Parse any leading attributes.
DeclAttributes Attributes;
@@ -3912,6 +3928,8 @@
// that the diagnostics point to correct tokens.
if (BeginParserPosition.isValid()) {
backtrackToPosition(BeginParserPosition);
+ BacktrackCtxt->setDiscard();
+ BacktrackCtxt.reset();
Attributes = DeclAttributes();
}
if (!IsFirstAccessor) {
@@ -3925,6 +3943,8 @@
TheDeclPtr = &accessors.Get;
isImplicitGet = true;
}
+ if (BacktrackCtxt)
+ BacktrackCtxt.reset();
// Set the contextual keyword kind properly.
if (AccessorKeywordLoc.isValid()) {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 49a5b07..8276a53 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -576,15 +576,14 @@
if (startsWithSymbol(Tok, '.')) {
llvm::SaveAndRestore<Expr*> S(SwiftKeyPathRoot, rootResult.getPtrOrNull());
+ auto dotLoc = Tok.getLoc();
// For uniformity, \.foo is parsed as if it were MAGIC.foo, so we need to
// make sure the . is there, but parsing the ? in \.? as .? doesn't make
// sense. This is all made more complicated by .?. being considered an
// operator token, and a single one at that (which means
// peekToken().is(tok::identifier) is incorrect: it is true for .?.foo).
- auto position = getParserPosition();
- auto dotLoc = consumeStartingCharacterOfCurrentToken(tok::period);
- if (Tok.is(tok::identifier))
- backtrackToPosition(position);
+ if (Tok.getLength() != 1 || !peekToken().is(tok::identifier))
+ consumeStartingCharacterOfCurrentToken(tok::period);
auto inner = makeParserResult(new (Context) KeyPathDotExpr(dotLoc));
bool unusedHasBindOptional = false;
@@ -1590,13 +1589,9 @@
break;
case tok::kw_Any: { // Any
- auto SynResult = parseAnyType();
- auto expr = new (Context) TypeExpr(TypeLoc(SynResult.getAST()));
- if (SynResult.hasSyntax()) {
- TypeExprSyntaxBuilder Builder;
- Builder.useType(SynResult.getSyntax());
- SyntaxContext->addSyntax(Builder.build());
- }
+ SyntaxParsingContext ExprContext(SyntaxContext, SyntaxKind::TypeExpr);
+ auto TyR = parseAnyType();
+ auto expr = new (Context) TypeExpr(TypeLoc(TyR.get()));
Result = makeParserResult(expr);
break;
}
@@ -2089,6 +2084,8 @@
return baseName;
}
+ // TODO: Support compound name in libSyntax.
+
// Try to parse a compound name.
BacktrackingScope backtrack(*this);
@@ -2097,11 +2094,6 @@
SourceLoc lparenLoc = consumeToken(tok::l_paren);
SourceLoc rparenLoc;
while (true) {
- // The following code may backtrack; so we disable the syntax tree creation
- // in this scope.
- SyntaxParsingContext DisabledContext(SyntaxContext);
- SyntaxContext->disable();
-
// Terminate at ')'.
if (Tok.is(tok::r_paren)) {
rparenLoc = consumeToken(tok::r_paren);
diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp
index 0d79088..36c8120 100644
--- a/lib/Parse/ParseGeneric.cpp
+++ b/lib/Parse/ParseGeneric.cpp
@@ -276,10 +276,7 @@
do {
SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
// Parse the leading type-identifier.
- auto FirstTypeResult = parseTypeIdentifier();
- if (FirstTypeResult.hasSyntax())
- SyntaxContext->addSyntax(FirstTypeResult.getSyntax());
- ParserResult<TypeRepr> FirstType = FirstTypeResult.getASTResult();
+ ParserResult<TypeRepr> FirstType = parseTypeIdentifier();
if (FirstType.hasCodeCompletion()) {
Status.setHasCodeCompletion();
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index a81f93c..d252ad7 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -186,10 +186,7 @@
case tok::kw_Self:
case tok::kw_Any:
case tok::identifier: {
- auto Result = parseTypeIdentifier();
- if (Result.hasSyntax())
- SyntaxContext->addSyntax(Result.getSyntax());
- ty = Result.getASTResult();
+ ty = parseTypeIdentifier();
break;
}
case tok::l_paren:
@@ -547,7 +544,7 @@
/// type-identifier:
/// identifier generic-args? ('.' identifier generic-args?)*
///
-SyntaxParserResult<TypeSyntax, TypeRepr> Parser::parseTypeIdentifier() {
+ParserResult<TypeRepr> Parser::parseTypeIdentifier() {
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_Self)) {
// is this the 'Any' type
if (Tok.is(tok::kw_Any)) {
@@ -557,7 +554,7 @@
CodeCompletion->completeTypeSimpleBeginning();
// Eat the code completion token because we handled it.
consumeToken(tok::code_complete);
- return makeSyntaxCodeCompletionResult<TypeSyntax, IdentTypeRepr>();
+ return makeParserCodeCompletionResult<IdentTypeRepr>();
}
diagnose(Tok, diag::expected_identifier_for_type);
@@ -569,10 +566,10 @@
return nullptr;
}
+ SyntaxParsingContext IdentTypeCtxt(SyntaxContext, SyntaxContextKind::Type);
ParserStatus Status;
SmallVector<ComponentIdentTypeRepr *, 4> ComponentsR;
- llvm::Optional<TypeSyntax> SyntaxNode;
SourceLoc EndLoc;
while (true) {
SourceLoc Loc;
@@ -604,27 +601,10 @@
else
CompT = new (Context) SimpleIdentTypeRepr(Loc, Name);
ComponentsR.push_back(CompT);
-
- if (SyntaxContext->isEnabled()) {
- if (SyntaxNode) {
- MemberTypeIdentifierSyntaxBuilder Builder;
- Builder.useBaseType(*SyntaxNode);
- if (auto Args =
- SyntaxContext->popIf<GenericArgumentClauseSyntax>())
- Builder.useGenericArgumentClause(*Args);
- Builder.useName(SyntaxContext->popToken());
- Builder.usePeriod(SyntaxContext->popToken());
- SyntaxNode.emplace(Builder.build());
- } else {
- SimpleTypeIdentifierSyntaxBuilder Builder;
- if (auto Args =
- SyntaxContext->popIf<GenericArgumentClauseSyntax>())
- Builder.useGenericArgumentClause(*Args);
- Builder.useName(SyntaxContext->popToken());
- SyntaxNode.emplace(Builder.build());
- }
- }
}
+ SyntaxContext->createNodeInPlace(ComponentsR.size() == 1
+ ? SyntaxKind::SimpleTypeIdentifier
+ : SyntaxKind::MemberTypeIdentifier);
// Treat 'Foo.<anything>' as an attempt to write a dotted type
// unless <anything> is 'Type'.
@@ -669,7 +649,7 @@
consumeToken(tok::code_complete);
}
- return makeSyntaxResult(Status, SyntaxNode, ITR);
+ return makeParserResult(Status, ITR);
}
/// parseTypeSimpleOrComposition
@@ -740,18 +720,13 @@
Context, Types, FirstTypeLoc, {FirstAmpersandLoc, PreviousLoc}));
}
-SyntaxParserResult<TypeSyntax, CompositionTypeRepr>
+ParserResult<CompositionTypeRepr>
Parser::parseAnyType() {
+ SyntaxParsingContext IdentTypeCtxt(SyntaxContext,
+ SyntaxKind::SimpleTypeIdentifier);
auto Loc = consumeToken(tok::kw_Any);
auto TyR = CompositionTypeRepr::createEmptyComposition(Context, Loc);
- llvm::Optional<TypeSyntax> SyntaxNode;
-
- if (SyntaxContext->isEnabled()) {
- auto builder = SimpleTypeIdentifierSyntaxBuilder();
- builder.useName(SyntaxContext->popToken());
- SyntaxNode.emplace(builder.build());
- }
- return makeSyntaxResult(SyntaxNode, TyR);
+ return makeParserResult(TyR);
}
/// parseOldStyleProtocolComposition
@@ -779,10 +754,7 @@
if (!IsEmpty) {
do {
// Parse the type-identifier.
- auto Result = parseTypeIdentifier();
- if (Result.hasSyntax())
- SyntaxContext->addSyntax(Result.getSyntax());
- ParserResult<TypeRepr> Protocol = Result.getASTResult();
+ ParserResult<TypeRepr> Protocol = parseTypeIdentifier();
Status |= Protocol;
if (auto *ident =
dyn_cast_or_null<IdentTypeRepr>(Protocol.getPtrOrNull()))
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 27f9fe6..bab7f7e 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -463,9 +463,6 @@
}
Parser::~Parser() {
- if (Tok.is(tok::eof))
- SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
-
delete L;
delete TokReceiver;
delete SyntaxContext;
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index d5a0e78..9d998f0 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,39 @@
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();
+ 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 +1565,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 +1910,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/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
index c0084df..7b93032 100644
--- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
+++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
@@ -360,7 +360,8 @@
"Argument types must match");
Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock, {UED});
} else
- Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock, {});
+ Builder.createBranch(SEI->getLoc(), ThreadedSuccessorBlock,
+ ArrayRef<SILValue>());
SEI->eraseFromParent();
// Split the edge from 'Dest' to 'ThreadedSuccessorBlock' it is now
@@ -2123,7 +2124,8 @@
TermInst *Term = BB->getTerminator();
DEBUG(llvm::dbgs() << "replace term with identical dests: " << *Term);
- SILBuilderWithScope(Term).createBranch(Term->getLoc(), commonDest, {});
+ SILBuilderWithScope(Term).createBranch(Term->getLoc(), commonDest,
+ ArrayRef<SILValue>());
Term->eraseFromParent();
addToWorklist(BB);
addToWorklist(commonDest);
diff --git a/lib/Syntax/Status.md b/lib/Syntax/Status.md
index e5cffeb..5beec35 100644
--- a/lib/Syntax/Status.md
+++ b/lib/Syntax/Status.md
@@ -68,9 +68,9 @@
* IfConfigDecl
* PatternBindingDecl
* VarDecl
+ * ExtensionDecl
### In-progress (UnknownDecl):
- * ExtensionDecl (SR-6572)
### Not-started (UnknownDecl):
* EnumCaseDecl
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 1d64e74..21e4171 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -118,6 +118,8 @@
createNodeInPlace(Kind, Pair.first);
break;
}
+ case SyntaxKind::SimpleTypeIdentifier:
+ case SyntaxKind::MemberTypeIdentifier:
case SyntaxKind::FunctionCallExpr:
case SyntaxKind::SubscriptExpr:
case SyntaxKind::ExprList: {
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index bc7bac7..0c4912b 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -311,4 +311,22 @@
for <ValueBindingPattern>var <IdentifierPattern>i </IdentifierPattern></ValueBindingPattern>in <IdentifierExpr>foo </IdentifierExpr><WhereClause>where <MemberAccessExpr><IdentifierExpr>i</IdentifierExpr>.foo </MemberAccessExpr></WhereClause><CodeBlock>{}</CodeBlock></ForInStmt><ForInStmt>
for case <IsTypePattern>is <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></IsTypePattern>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock></ForInStmt>
-}</CodeBlock></FunctionDecl>
+}</CodeBlock></FunctionDecl><ExtensionDecl>
+
+// MARK: - ExtensionDecl
+
+extension <SimpleTypeIdentifier>ext </SimpleTypeIdentifier><MemberDeclBlock>{<VariableDecl>
+ var <PatternBinding><IdentifierPattern>s</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><AccessorBlock>{<ReturnStmt>
+ return <IntegerLiteralExpr>42</IntegerLiteralExpr></ReturnStmt>
+ }</AccessorBlock></PatternBinding></VariableDecl>
+}</MemberDeclBlock></ExtensionDecl><ExtensionDecl><Attribute>
+
+@available(*, unavailable)</Attribute><DeclModifier>
+fileprivate </DeclModifier>extension <SimpleTypeIdentifier>ext </SimpleTypeIdentifier><MemberDeclBlock>{}</MemberDeclBlock></ExtensionDecl><ExtensionDecl>
+
+extension <SimpleTypeIdentifier>ext </SimpleTypeIdentifier><TypeInheritanceClause>: <InheritedType><SimpleTypeIdentifier>extProtocol </SimpleTypeIdentifier></InheritedType></TypeInheritanceClause><MemberDeclBlock>{}</MemberDeclBlock></ExtensionDecl><ExtensionDecl>
+
+extension <SimpleTypeIdentifier>ext </SimpleTypeIdentifier><GenericWhereClause>where <SameTypeRequirement><SimpleTypeIdentifier>A </SimpleTypeIdentifier>== <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>B</SimpleTypeIdentifier>: <SimpleTypeIdentifier>Numeric </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock></ExtensionDecl><ExtensionDecl>
+
+extension <MemberTypeIdentifier><MemberTypeIdentifier><SimpleTypeIdentifier>ext</SimpleTypeIdentifier>.a</MemberTypeIdentifier>.b </MemberTypeIdentifier><MemberDeclBlock>{}</MemberDeclBlock></ExtensionDecl>
+
diff --git a/test/Syntax/round_trip_misc.swift b/test/Syntax/round_trip_misc.swift
new file mode 100644
index 0000000..1b78860
--- /dev/null
+++ b/test/Syntax/round_trip_misc.swift
@@ -0,0 +1,30 @@
+// RUN: %round-trip-syntax-test --swift-syntax-test %swift-syntax-test --file %s
+
+class C {
+ // Erroneous typealias decl.
+ typealias Inner: Foo = Int
+
+ // Implict accessor with attribute at the top of its body.
+ var x: Int {
+ @objc
+ func f() {}
+ }
+}
+
+// Orphan '}' at top level
+}
+
+// Compound name.
+foo(x:y:)()
+
+// Type identifier with erroneous component.
+let a: Int.)
+
+// Type with unknown attribute followed by parentheses.
+typealias b = @foobar() -> Void
+typealias c = @foobar(a) () -> Void
+
+// keypath expressions.
+let d = \.foo
+let e = \.[1]
+let f = \.?.bar
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index c6f074a..3ca1e0e 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -312,3 +312,21 @@
for var i in foo where i.foo {}
for case is Int in foo {}
}
+
+// MARK: - ExtensionDecl
+
+extension ext {
+ var s: Int {
+ return 42
+ }
+}
+
+@available(*, unavailable)
+fileprivate extension ext {}
+
+extension ext : extProtocol {}
+
+extension ext where A == Int, B: Numeric {}
+
+extension ext.a.b {}
+
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 782f167..db3971b 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -117,7 +117,7 @@
# generic-parameter-clause?
# type-inheritance-clause?
# generic-where-clause?
- # '{' class-members ''
+ # '{' class-members '}'
# class-name -> identifier
Node('ClassDecl', kind='Decl',
children=[
@@ -141,7 +141,7 @@
# generic-parameter-clause?
# type-inheritance-clause?
# generic-where-clause?
- # '{' struct-members ''
+ # '{' struct-members '}'
# struct-name -> identifier
Node('StructDecl', kind='Decl',
children=[
@@ -175,6 +175,27 @@
Child('Members', kind='MemberDeclBlock'),
]),
+ # extension-declaration -> attributes? access-level-modifier?
+ # 'extension' extended-type
+ # type-inheritance-clause?
+ # generic-where-clause?
+ # '{' extension-members '}'
+ # extension-name -> identifier
+ Node('ExtensionDecl', kind='Decl',
+ children=[
+ Child('Attributes', kind='AttributeList',
+ is_optional=True),
+ Child('AccessLevelModifier', kind='DeclModifier',
+ is_optional=True),
+ Child('ExtensionKeyword', kind='ExtensionToken'),
+ Child('ExtendedType', kind='Type'),
+ Child('InheritanceClause', kind='TypeInheritanceClause',
+ is_optional=True),
+ Child('GenericWhereClause', kind='GenericWhereClause',
+ is_optional=True),
+ Child('Members', kind='MemberDeclBlock'),
+ ]),
+
Node('MemberDeclBlock', kind='Syntax',
children=[
Child('LeftBrace', kind='LeftBraceToken'),
@@ -371,7 +392,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),
]),
diff --git a/utils/gyb_syntax_support/StmtNodes.py b/utils/gyb_syntax_support/StmtNodes.py
index 844e0e6..3cfc50e 100644
--- a/utils/gyb_syntax_support/StmtNodes.py
+++ b/utils/gyb_syntax_support/StmtNodes.py
@@ -170,7 +170,7 @@
Node('CodeBlock', kind='Syntax',
children=[
Child('OpenBrace', kind='LeftBraceToken'),
- Child('Statments', kind='StmtList'),
+ Child('Statements', kind='StmtList'),
Child('CloseBrace', kind='RightBraceToken'),
]),