Skip to content

Commit 032e8d5

Browse files
CodaFiDougGregor
authored andcommitted
Start Lowering Generic ASTs
Lower generic argument lists and generic parameter lists, then expand the lowering for identifiers to take generic arguments into account.
1 parent f4f7f7f commit 032e8d5

File tree

6 files changed

+215
-5
lines changed

6 files changed

+215
-5
lines changed

include/swift/AST/CASTBridging.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,33 @@ typedef struct {
5858
void *Type;
5959
void *_Nullable TrailingCommaLoc;
6060
} BridgedTupleTypeElement;
61+
62+
typedef enum __attribute__((enum_extensibility(open))) BridgedRequirementReprKind : long {
63+
/// A type bound T : P, where T is a type that depends on a generic
64+
/// parameter and P is some type that should bound T, either as a concrete
65+
/// supertype or a protocol to which T must conform.
66+
BridgedRequirementReprKindTypeConstraint,
67+
68+
/// A same-type requirement T == U, where T and U are types that shall be
69+
/// equivalent.
70+
BridgedRequirementReprKindSameType,
71+
72+
/// A layout bound T : L, where T is a type that depends on a generic
73+
/// parameter and L is some layout specification that should bound T.
74+
BridgedRequirementReprKindLayoutConstraint,
75+
76+
// Note: there is code that packs this enum in a 2-bit bitfield. Audit users
77+
// when adding enumerators.
78+
} BridgedRequirementReprKind;
79+
80+
typedef struct {
81+
void *_Nullable SeparatorLoc;
82+
BridgedRequirementReprKind Kind;
83+
void *FirstType;
84+
void *SecondType;
85+
// FIXME: Handle Layout Requirements
86+
} BridgedRequirementRepr;
87+
6188
#ifdef __cplusplus
6289
extern "C" {
6390

@@ -133,7 +160,7 @@ struct DeclContextAndDecl {
133160
};
134161

135162
struct DeclContextAndDecl StructDecl_create(
136-
void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *dc);
163+
void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams, void *dc);
137164
struct DeclContextAndDecl ClassDecl_create(
138165
void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *dc);
139166

@@ -152,11 +179,19 @@ void *FunctionTypeRepr_create(void *ctx, void *argsTy, void *_Nullable asyncLoc,
152179
void *NamedOpaqueReturnTypeRepr_create(void *ctx, void *baseTy);
153180
void *OpaqueReturnTypeRepr_create(void *ctx, void *opaqueLoc, void *baseTy);
154181
void *ExistentialTypeRepr_create(void *ctx, void *anyLoc, void *baseTy);
182+
void *GenericParamList_create(void *ctx, void *lAngleLoc, BridgedArrayRef params, void *_Nullable whereLoc, BridgedArrayRef reqs, void *rAngleLoc);
183+
void *GenericTypeParamDecl_create(void *ctx, void *declContext, BridgedIdentifier name, void *nameLoc, void *_Nullable ellipsisLoc, long index, _Bool isParameterPack);
184+
void GenericTypeParamDecl_setInheritedType(void *ctx, void *Param, void *ty);
185+
186+
struct DeclContextAndDecl TypeAliasDecl_create(void *ctx, void *declContext, void *aliasLoc, void *equalLoc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams);
187+
void TypeAliasDecl_setUnderlyingTypeRepr(void *decl, void *underlyingType);
188+
155189

156190
void TopLevelCodeDecl_dump(void *);
157191
void Expr_dump(void *);
158192
void Decl_dump(void *);
159193
void Stmt_dump(void *);
194+
void TypeRepr_dump(void *);
160195

161196
#ifdef __cplusplus
162197
}

lib/AST/CASTBridging.cpp

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "swift/AST/ASTNode.h"
55
#include "swift/AST/Decl.h"
66
#include "swift/AST/Expr.h"
7+
#include "swift/AST/GenericParamList.h"
78
#include "swift/AST/Stmt.h"
89
#include "swift/AST/Identifier.h"
910
#include "swift/AST/ParameterList.h"
@@ -268,12 +269,13 @@ void NominalTypeDecl_setMembers(void *decl, BridgedArrayRef members) {
268269
}
269270

270271
DeclContextAndDecl StructDecl_create(
271-
void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *dc) {
272+
void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams, void *dc) {
272273
ASTContext &Context = *static_cast<ASTContext *>(ctx);
273274
auto *out = new (Context) StructDecl(getSourceLocFromPointer(loc),
274275
Identifier::getFromOpaquePointer(name),
275276
getSourceLocFromPointer(nameLoc),
276-
{}, nullptr,
277+
{},
278+
(GenericParamList *)genericParams,
277279
(DeclContext *)dc);
278280
out->setImplicit(); // TODO: remove this.
279281
return {(DeclContext *)out, (NominalTypeDecl *)out, (Decl *)out};
@@ -389,8 +391,71 @@ void *ExistentialTypeRepr_create(void *ctx, void *anyLoc, void *baseTy) {
389391
return new (Context) ExistentialTypeRepr(getSourceLocFromPointer(anyLoc), (TypeRepr *)baseTy);
390392
}
391393

394+
void *GenericParamList_create(void *ctx, void *lAngleLoc, BridgedArrayRef params, void *_Nullable whereLoc, BridgedArrayRef reqs, void *rAngleLoc) {
395+
ASTContext &Context = *static_cast<ASTContext *>(ctx);
396+
SmallVector<RequirementRepr> requirements;
397+
for (auto req : getArrayRef<BridgedRequirementRepr>(reqs)) {
398+
switch (req.Kind) {
399+
case BridgedRequirementReprKindTypeConstraint:
400+
requirements.push_back(
401+
RequirementRepr::getTypeConstraint((TypeRepr *)req.FirstType,
402+
getSourceLocFromPointer(req.SeparatorLoc),
403+
(TypeRepr *)req.SecondType));
404+
break;
405+
case BridgedRequirementReprKindSameType:
406+
requirements.push_back(
407+
RequirementRepr::getSameType((TypeRepr *)req.FirstType,
408+
getSourceLocFromPointer(req.SeparatorLoc),
409+
(TypeRepr *)req.SecondType));
410+
break;
411+
case BridgedRequirementReprKindLayoutConstraint:
412+
llvm_unreachable("cannot handle layout constraints!");
413+
}
414+
}
415+
return GenericParamList::create(Context,
416+
getSourceLocFromPointer(lAngleLoc),
417+
getArrayRef<GenericTypeParamDecl *>(params),
418+
getSourceLocFromPointer(whereLoc),
419+
requirements,
420+
getSourceLocFromPointer(rAngleLoc));
421+
}
422+
423+
void *GenericTypeParamDecl_create(void *ctx, void *declContext, BridgedIdentifier name, void *nameLoc, void *_Nullable ellipsisLoc, long index, bool isParameterPack) {
424+
return GenericTypeParamDecl::createParsed(static_cast<DeclContext *>(declContext),
425+
Identifier::getFromOpaquePointer(name),
426+
getSourceLocFromPointer(nameLoc),
427+
getSourceLocFromPointer(ellipsisLoc),
428+
/*index*/ index,
429+
isParameterPack);
430+
}
431+
432+
void GenericTypeParamDecl_setInheritedType(void *ctx, void *Param, void *ty) {
433+
ASTContext &Context = *static_cast<ASTContext *>(ctx);
434+
auto entries = Context.AllocateCopy(ArrayRef<InheritedEntry>{
435+
InheritedEntry{(TypeRepr *)ty}
436+
});
437+
((GenericTypeParamDecl *)Param)->setInherited(entries);
438+
}
439+
440+
441+
DeclContextAndDecl TypeAliasDecl_create(void *ctx, void *declContext, void *aliasLoc, void *equalLoc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams) {
442+
ASTContext &Context = *static_cast<ASTContext *>(ctx);
443+
auto *out = new (Context) TypeAliasDecl(getSourceLocFromPointer(aliasLoc),
444+
getSourceLocFromPointer(equalLoc),
445+
Identifier::getFromOpaquePointer(name),
446+
getSourceLocFromPointer(nameLoc),
447+
(GenericParamList *)genericParams,
448+
(DeclContext *)declContext);
449+
return {(DeclContext *)out, (TypeAliasDecl *)out, (Decl *)out};
450+
}
451+
452+
void TypeAliasDecl_setUnderlyingTypeRepr(void *decl, void *underlyingType) {
453+
((TypeAliasDecl *)decl)->setUnderlyingTypeRepr((TypeRepr *)underlyingType);
454+
}
455+
392456
void TopLevelCodeDecl_dump(void *decl) { ((TopLevelCodeDecl *)decl)->dump(llvm::errs()); }
393457

394458
void Expr_dump(void *expr) { ((Expr *)expr)->dump(llvm::errs()); }
395459
void Decl_dump(void *expr) { ((Decl *)expr)->dump(llvm::errs()); }
396460
void Stmt_dump(void *expr) { ((Stmt *)expr)->dump(llvm::errs()); }
461+
void TypeRepr_dump(void *repr) { ((TypeRepr *)repr)->dump(); }

lib/ASTGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ if (SWIFT_SWIFT_PARSER)
33
Sources/ASTGen/ASTGen.swift
44
Sources/ASTGen/Decls.swift
55
Sources/ASTGen/Exprs.swift
6+
Sources/ASTGen/Generics.swift
67
Sources/ASTGen/Literals.swift
78
Sources/ASTGen/Macros.swift
89
Sources/ASTGen/Misc.swift

lib/ASTGen/Sources/ASTGen/Decls.swift

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,36 @@ import SwiftSyntax
44
import CASTBridging
55

66
extension ASTGenVisitor {
7+
public func visit(_ node: TypealiasDeclSyntax) -> UnsafeMutableRawPointer {
8+
let aliasLoc = self.base.advanced(by: node.typealiasKeyword.position.utf8Offset).raw
9+
let equalLoc = self.base.advanced(by: node.initializer.equal.position.utf8Offset).raw
10+
var nameText = node.identifier.text
11+
let name = nameText.withUTF8 { buf in
12+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
13+
}
14+
let nameLoc = self.base.advanced(by: node.identifier.position.utf8Offset).raw
15+
let genericParams = node.genericParameterClause.map(self.visit)
16+
let out = TypeAliasDecl_create(self.ctx, self.declContext, aliasLoc, equalLoc, name, nameLoc, genericParams)
17+
18+
let oldDeclContext = declContext
19+
declContext = out.declContext
20+
defer { declContext = oldDeclContext }
21+
22+
let underlying = self.visit(node.initializer.value)
23+
TypeAliasDecl_setUnderlyingTypeRepr(out.nominalDecl, underlying)
24+
25+
return out.decl
26+
}
27+
728
public func visit(_ node: StructDeclSyntax) -> UnsafeMutableRawPointer {
829
let loc = self.base.advanced(by: node.position.utf8Offset).raw
930
var nameText = node.identifier.text
1031
let name = nameText.withUTF8 { buf in
1132
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
1233
}
13-
14-
let out = StructDecl_create(ctx, loc, name, loc, declContext)
34+
35+
let genericParams = node.genericParameterClause.map(self.visit)
36+
let out = StructDecl_create(ctx, loc, name, loc, genericParams, declContext)
1537
let oldDeclContext = declContext
1638
declContext = out.declContext
1739
defer { declContext = oldDeclContext }
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import SwiftParser
2+
import SwiftSyntax
3+
4+
import CASTBridging
5+
6+
extension ASTGenVisitor {
7+
func visit(_ node: GenericParameterClauseSyntax) -> UnsafeMutableRawPointer {
8+
let lAngleLoc = self.base.advanced(by: node.leftAngleBracket.position.utf8Offset).raw
9+
let whereLoc = node.genericWhereClause.map { self.base.advanced(by: $0.whereKeyword.position.utf8Offset).raw }
10+
let rAngleLoc = self.base.advanced(by: node.rightAngleBracket.position.utf8Offset).raw
11+
return self.withBridgedParametersAndRequirements(node) { params, reqs in
12+
return GenericParamList_create(self.ctx, lAngleLoc, params, whereLoc, reqs, rAngleLoc)
13+
}
14+
}
15+
16+
func visit(_ node: GenericParameterSyntax) -> UnsafeMutableRawPointer {
17+
var nodeName = node.name.text
18+
let name = nodeName.withUTF8 { buf in
19+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
20+
}
21+
let nameLoc = self.base.advanced(by: node.name.position.utf8Offset).raw
22+
let ellipsisLoc = node.ellipsis.map { self.base.advanced(by: $0.position.utf8Offset).raw }
23+
24+
return GenericTypeParamDecl_create(self.ctx, self.declContext, name, nameLoc, ellipsisLoc, node.indexInParent / 2, ellipsisLoc != nil)
25+
}
26+
}
27+
28+
extension ASTGenVisitor {
29+
private func withBridgedParametersAndRequirements<T>(
30+
_ node: GenericParameterClauseSyntax,
31+
action: (BridgedArrayRef, BridgedArrayRef) -> T
32+
) -> T {
33+
var params = [UnsafeMutableRawPointer]()
34+
var requirements = [BridgedRequirementRepr]()
35+
for param in node.genericParameterList {
36+
let loweredParameter = self.visit(param)
37+
params.append(loweredParameter)
38+
39+
guard let requirement = param.inheritedType else {
40+
continue
41+
}
42+
43+
let loweredRequirement = self.visit(requirement)
44+
GenericTypeParamDecl_setInheritedType(self.ctx, loweredParameter, loweredRequirement);
45+
}
46+
47+
if let nodeRequirements = node.genericWhereClause?.requirementList {
48+
for requirement in nodeRequirements {
49+
switch requirement.body {
50+
case .conformanceRequirement(let conformance):
51+
let firstType = self.visit(conformance.leftTypeIdentifier)
52+
let separatorLoc = self.base.advanced(by: conformance.colon.position.utf8Offset).raw
53+
let secondType = self.visit(conformance.rightTypeIdentifier)
54+
requirements.append(BridgedRequirementRepr(
55+
SeparatorLoc: separatorLoc,
56+
Kind: .typeConstraint,
57+
FirstType: firstType,
58+
SecondType: secondType))
59+
case .sameTypeRequirement(let sameType):
60+
let firstType = self.visit(sameType.leftTypeIdentifier)
61+
let separatorLoc = self.base.advanced(by: sameType.equalityToken.position.utf8Offset).raw
62+
let secondType = self.visit(sameType.rightTypeIdentifier)
63+
requirements.append(BridgedRequirementRepr(
64+
SeparatorLoc: separatorLoc,
65+
Kind: .sameType,
66+
FirstType: firstType,
67+
SecondType: secondType))
68+
case .layoutRequirement(_):
69+
fatalError("Cannot handle layout requirements!")
70+
}
71+
}
72+
}
73+
return params.withBridgedArrayRef { params in
74+
return requirements.withBridgedArrayRef { reqs in
75+
return action(params, reqs)
76+
}
77+
}
78+
}
79+
}

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ extension ASTGenVisitor {
3535
}
3636
let nameLoc = self.base.advanced(by: pathElement.position.utf8Offset).raw
3737

38+
if let generics = generics {
39+
let lAngle = self.base.advanced(by: generics.leftAngleBracket.position.utf8Offset).raw
40+
let rAngle = self.base.advanced(by: generics.rightAngleBracket.position.utf8Offset).raw
41+
elements.append(generics.arguments.map({ self.visit($0.argumentType) }).withBridgedArrayRef { genericArgs in
42+
GenericIdentTypeRepr_create(self.ctx, name, nameLoc, genericArgs, lAngle, rAngle)
43+
})
44+
} else {
3845
elements.append(SimpleIdentTypeRepr_create(self.ctx, nameLoc, name))
46+
}
3947
}
4048

4149
return elements.withBridgedArrayRef { elements in

0 commit comments

Comments
 (0)