Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions SwiftCompilerSources/Sources/AST/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class Decl: CustomStringConvertible, Hashable {
public class ValueDecl: Decl {
final public var nameLoc: SourceLoc? { SourceLoc(bridged: bridged.Value_getNameLoc()) }
final public var userFacingName: StringRef { StringRef(bridged: bridged.Value_getUserFacingName()) }
final public var baseIdentifier: swift.Identifier { bridged.Value_getBaseIdentifier() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't expose the swift namespace in APIs. Instead add a type alias:

   typealias Identifier = swift.Identifier

final public var isObjC: Bool { bridged.Value_isObjC() }
}

Expand All @@ -56,6 +57,10 @@ public class NominalTypeDecl: GenericTypeDecl {
final public var valueTypeDestructor: DestructorDecl? {
bridged.NominalType_getValueTypeDestructor().getAs(DestructorDecl.self)
}

public var declaredInterfaceType : AST.`Type` {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to qualify Type in the AST module. Just use Type

AST.`Type`(bridged: bridged.NominalType_getDeclaredInterfaceType())
}
}

final public class EnumDecl: NominalTypeDecl {
Expand Down Expand Up @@ -118,6 +123,8 @@ final public class MacroDecl: ValueDecl {}

final public class EnumElementDecl: ValueDecl {
public var hasAssociatedValues: Bool { bridged.EnumElementDecl_hasAssociatedValues() }
public var parameterList: BridgedParameterList { bridged.EnumElementDecl_getParameterList() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't expose bridged data structures in APIs. Create a native swift ParameterList containing a var bridged: BridgedParameterList

public var nameStr: StringRef { StringRef(bridged: bridged.EnumElementDecl_getNameStr()) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just call it name

}

final public class ExtensionDecl: Decl {}
Expand Down
14 changes: 14 additions & 0 deletions SwiftCompilerSources/Sources/AST/GenericSignature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ public struct GenericSignature: CustomStringConvertible, NoReflectionChildren {
}

public var isEmpty: Bool { bridged.impl == nil }

public var canonicalSignature: CanGenericSignature { CanGenericSignature(bridged: bridged.getCanonicalSignature()) }
}

public struct CanGenericSignature {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid abbreviations. Better: CanonicalGenericSignature

We should follow the general swift API design guidelines. You can take a look at https://www.swift.org/documentation/api-design-guidelines/

public let bridged: BridgedCanGenericSignature

public init(bridged: BridgedCanGenericSignature) {
self.bridged = bridged
}

public var isEmpty: Bool { bridged.impl == nil }

public var genericSignature: GenericSignature { GenericSignature(bridged: bridged.getGenericSignature()) }
}
28 changes: 28 additions & 0 deletions SwiftCompilerSources/Sources/AST/Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ public struct Type: TypeProperties, CustomStringConvertible, NoReflectionChildre
public func subst(with substitutionMap: SubstitutionMap) -> Type {
return Type(bridged: bridged.subst(substitutionMap.bridged))
}

public func mapTypeOutOfContext() -> Type {
return Type(bridged: bridged.mapTypeOutOfContext())
}

public func getReducedType(sig: GenericSignature) -> CanonicalType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please copy the comment from the C++ definition here:

  /// Returns a stronger canonicalization which folds away equivalent
  /// associated types, or type parameters that have been made concrete.

Also, a better argument label would be: getReducedType(of signature: GenericSignature)

CanonicalType(bridged: bridged.getReducedType(sig.bridged))
}

public func GenericTypeParam_getName() -> swift.Identifier {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better: var nameOfGenericTypeParameter: Identifier

return bridged.GenericTypeParam_getName()
}

public func GenericTypeParam_getDepth() -> UInt {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better: var depthOfGenericTypeParameter: Int

It's better to return 'Int' instead of 'UInt'. Unlike C/C++, the philosophy of swift is to use plain 'Int' for such counts, indices, etc.

return bridged.GenericTypeParam_getDepth()
}

public func GenericTypeParam_getIndex() -> UInt {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> var indexOfGenericTypeParameter: Int

return bridged.GenericTypeParam_getIndex()
}

public func GenericTypeParam_getParamKind() -> swift.GenericTypeParamKind {
Copy link
Contributor

@eeckstein eeckstein Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> var kindOfGenericTypeParameter: GenericTypeParameterKind

also: add a type alias typealias GenericTypeParameterKind = swift.GenericTypeParamKind

return bridged.GenericTypeParam_getParamKind()
}
}

/// A Type that is statically known to be canonical.
Expand All @@ -86,6 +110,10 @@ public struct CanonicalType: TypeProperties, CustomStringConvertible, NoReflecti
public func subst(with substitutionMap: SubstitutionMap) -> CanonicalType {
return rawType.subst(with: substitutionMap).canonical
}

public func SILFunctionType_getSubstGenericSignature() -> CanGenericSignature {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

->

  /// The generic signature that the component types are specified in terms of, if any.
  public var substitutedGenericSignatureOfFunctionType: CanonicalGenericSignature

Also, it make sense to move this to TypeProperties, so that it's also available for Type and SIL.Type

CanGenericSignature(bridged: bridged.SILFunctionType_getSubstGenericSignature())
}
}

/// Implements the common members of `AST.Type`, `AST.CanonicalType` and `SIL.Type`.
Expand Down
4 changes: 4 additions & 0 deletions SwiftCompilerSources/Sources/SIL/ASTExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ extension CanonicalType {
precondition(isBox)
return BoxFieldsArray(boxType: self, function: function)
}

public func loweredType(in function: Function) -> Type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function already exists (in TypeProperties). See a few lines above

function.bridged.getLoweredType(bridged).type
}
}

extension Decl {
Expand Down
4 changes: 4 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Argument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public class Argument : Value, Hashable {

public var sourceLoc: SourceLoc? { findVarDecl()?.nameLoc }

public func replaceAllUsesWith(newArg: Argument) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this. This API exists for Operand sequences, e.g.

   argument.uses.replaceAll(with: someValue, context)

bridged.replaceAllUsesWith(newArg.bridged)
}

public static func ==(lhs: Argument, rhs: Argument) -> Bool {
lhs === rhs
}
Expand Down
5 changes: 5 additions & 0 deletions SwiftCompilerSources/Sources/SIL/BasicBlock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ final public class BasicBlock : CustomStringConvertible, HasShortDescription, Ha
(decl as Decl?).bridged).argument as! FunctionArgument
}

public func insertPhiArgument(atPosition: Int, type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument {
context.notifyInstructionsChanged()
return bridged.insertPhiArgument(atPosition, type.bridged, ownership._bridged).argument
}

public func eraseArgument(at index: Int, _ context: some MutatingContext) {
context.notifyInstructionsChanged()
bridged.eraseArgument(index)
Expand Down
7 changes: 7 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,13 @@ public struct Builder {
return notifyNew(tuple.getAs(TupleInst.self))
}

public func createTuple(elements: [Value]) -> TupleInst {
Copy link
Contributor

@eeckstein eeckstein Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is dangerous because it works for most cases, but fails if the result type must match a tuple type with element labels. People should use the existing createTuple and think of which result type the tuple should have.

We should also remove this API from SILBuilder (not in this PR).

let tuple = elements.withBridgedValues { valuesRef in
return bridged.createTuple(valuesRef)
}
return notifyNew(tuple.getAs(TupleInst.self))
}

public func createTupleExtract(tuple: Value, elementIndex: Int) -> TupleExtractInst {
return notifyNew(bridged.createTupleExtract(tuple.bridged, elementIndex).getAs(TupleExtractInst.self))
}
Expand Down
14 changes: 14 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ extension Context {
}
}

public func getTupleType(elements: [AST.`Type`]) -> AST.`Type` {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please modify the existing getTupleType (see above) to use this function by mapping the elements argument to AST types.

let bridgedElements = elements.map { $0.bridged }
return bridgedElements.withBridgedArrayRef {
AST.`Type`(bridged: _bridged.getTupleType($0))
}
}

public func getTupleTypeWithLabels(elements: [AST.`Type`], labels: [swift.Identifier]) -> AST.`Type` {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better:

func getTupleType(elements: [(label: Identifier, type: AST.`Type`)]) -> AST.`Type`

assert(elements.count == labels.count)
return elements.withBridgedArrayRef{
eltArr in labels.withBridgedArrayRef{labelsArr in
AST.`Type`(bridged: _bridged.getTupleTypeWithLabels(eltArr, labelsArr))}}
}

public var swiftArrayDecl: NominalTypeDecl {
_bridged.getSwiftArrayDecl().getAs(NominalTypeDecl.self)
}
Expand Down
8 changes: 8 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Function.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
return Location(bridged: bridged.getLocation())
}

public var sourceFile: BridgedNullableSourceFile {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't expose any bridged data structures in APIs. In case sourceFile is only used as is and no members of it are used, it's fine to just add a typealias SourceFile = BridgedSourceFile.

Also:

  • this API should return an optional SourceFile: var sourceFile: SourceFile?
  • please implement this as a member of DeclRef and add var Function.declRef: DeclRef?

return bridged.getSourceFile()
}

final public var description: String {
return String(taking: bridged.getDebugDescription())
}
Expand Down Expand Up @@ -88,6 +92,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
return AST.`Type`(bridged: bridged.mapTypeIntoContext(type.bridged))
}

public func mapTypeIntoContext(_ type: Type) -> Type {
return Type(bridged: bridged.mapTypeIntoContext(type.bridged))
}

/// Returns true if the function is a definition and not only an external declaration.
///
/// This is the case if the function contains a body, i.e. some basic blocks.
Expand Down
6 changes: 6 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ final public class PartialApplyInst : SingleValueInstruction, ApplySite {
public var hasUnknownResultIsolation: Bool { bridged.PartialApplyInst_hasUnknownResultIsolation() }
public var unappliedArgumentCount: Int { bridged.PartialApply_getCalleeArgIndexOfFirstAppliedArg() }
public var calleeConvention: ArgumentConvention { type.bridged.getCalleeConvention().convention }
public var substitutionMap: SubstitutionMap { SubstitutionMap(bridged: bridged.PartialApplyInst_getSubstitutionMap()) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already exists as a property of ApplySite

}

final public class ApplyInst : SingleValueInstruction, FullApplySite {
Expand Down Expand Up @@ -1929,6 +1930,7 @@ final public class SwitchValueInst : TermInst {
final public class SwitchEnumInst : TermInst {

public var enumOp: Value { operands[0].value }
public var numCases: Int { bridged.SwitchEnumInst_getNumCases() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this. Use caseIndices.count


public struct CaseIndexArray : RandomAccessCollection {
fileprivate let switchEnum: SwitchEnumInst
Expand All @@ -1953,6 +1955,10 @@ final public class SwitchEnumInst : TermInst {
cases.first(where: { $0.0 == forCaseIndex })?.1
}

public func getSuccessorForDefault() -> BasicBlock? {
return self.bridged.SwitchEnumInst_getSuccessorForDefault().block
}

// This does not handle the special case where the default covers exactly
// the "missing" case.
public func getUniqueCase(forSuccessor: BasicBlock) -> Int? {
Expand Down
19 changes: 18 additions & 1 deletion SwiftCompilerSources/Sources/SIL/Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public struct Type : TypeProperties, CustomStringConvertible, NoReflectionChildr

public var isAddress: Bool { bridged.isAddress() }
public var isObject: Bool { !isAddress }
public var category: ValueCategory { ValueCategory(bridged: bridged.getCategory()) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't add this. Use isAddress or isObject instead


public var addressType: Type { bridged.getAddressType().type }
public var objectType: Type { bridged.getObjectType().type }
Expand Down Expand Up @@ -214,6 +215,16 @@ public struct Type : TypeProperties, CustomStringConvertible, NoReflectionChildr
}
return false
}

public func getEnumCasePayload(caseIdx: Int, function: Function) -> Type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this. Use getEnumCases instead. If you like you can add a utility function in EnumCases to find the payload type of a specific index. This should have an optional return Type?, though.

bridged.getEnumCasePayload(caseIdx, function.bridged).type
}

public func mapTypeOutOfContext() -> Type { bridged.mapTypeOutOfContext().type }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please implement this using AST.Type.mapTypeOutOfContext and not with bridging


public static func getPrimitiveType(canType: CanonicalType, silValueCategory: ValueCategory) -> Type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this. Use canType.loweredType(in:) instead. To make it an address type use var addressType`.

BridgedType.getPrimitiveType(canType: canType.bridged, silValueCategory: silValueCategory._bridged).type
}
}

extension Type: Equatable {
Expand Down Expand Up @@ -266,6 +277,7 @@ public struct NominalFieldsArray : RandomAccessCollection, FormattedLikeArray {
}

public struct EnumCase {
public let enumElementDecl : EnumElementDecl
public let payload: Type?
public let index: Int
}
Expand All @@ -288,7 +300,8 @@ public struct EnumCases : CollectionLikeSequence, IteratorProtocol {
caseIterator = caseIterator.getNext()
caseIndex += 1
}
return EnumCase(payload: enumType.bridged.getEnumCasePayload(caseIterator, function.bridged).typeOrNil,
return EnumCase(enumElementDecl: enumType.bridged.getEnumElementDecl(caseIterator).getAs(EnumElementDecl.self),
payload: enumType.bridged.getEnumCasePayload(caseIterator, function.bridged).typeOrNil,
index: caseIndex)
}
return nil
Expand All @@ -304,6 +317,10 @@ public struct TupleElementArray : RandomAccessCollection, FormattedLikeArray {
public subscript(_ index: Int) -> Type {
type.bridged.getTupleElementType(index).type
}

public func label(at index: Int) -> swift.Identifier {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swift.Identifier -> Identifier

type.bridged.getTupleElementLabel(index)
}
}

public struct BoxFieldsArray : RandomAccessCollection, FormattedLikeArray {
Expand Down
21 changes: 21 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Value.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ public protocol Value : AnyObject, CustomStringConvertible {
var isLexical: Bool { get }
}

public enum ValueCategory {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't add this. The boolean isAddress/isObject is sufficient.

case address
case object

public init(bridged: BridgedValueCategory) {
switch bridged {
case .Address: self = .address
case .Object: self = .object
default:
fatalError("unsupported value category")
}
}

public var _bridged: BridgedValueCategory {
switch self {
case .address: return BridgedValueCategory.Address
case .object: return BridgedValueCategory.Object
}
}
}

public enum Ownership {
/// A Value with `unowned` ownership kind is an independent value that
/// has a lifetime that is only guaranteed to last until the next program
Expand Down
Loading