#include "swift/AST/CASTBridging.h" #include "swift/AST/ASTContext.h" #include "swift/AST/ASTNode.h" #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" #include "swift/AST/GenericParamList.h" #include "swift/AST/Identifier.h" #include "swift/AST/ParameterList.h" #include "swift/AST/Pattern.h" #include "swift/AST/Stmt.h" #include "swift/AST/TypeRepr.h" using namespace swift; template inline llvm::ArrayRef getArrayRef(BridgedArrayRef bridged) { return {static_cast(bridged.data), size_t(bridged.numElements)}; } static SourceLoc getSourceLocFromPointer(void *loc) { auto smLoc = llvm::SMLoc::getFromPointer((const char *)loc); return SourceLoc(smLoc); } BridgedIdentifier SwiftASTContext_getIdentifier(void *ctx, const uint8_t *_Nullable str, long len) { return const_cast( static_cast(ctx) ->getIdentifier( StringRef{reinterpret_cast(str), size_t(len)}) .getAsOpaquePointer()); } void *SwiftImportDecl_create(void *ctx, void *dc, void *importLoc, char kind, void *kindLoc, BridgedArrayRef path, BridgedArrayRef pathLocs) { assert(path.numElements == pathLocs.numElements); ASTContext &Context = *static_cast(ctx); ImportPath::Builder importPath; for (auto p : llvm::zip(getArrayRef(path), getArrayRef(pathLocs))) { Identifier ident; SourceLoc loc; std::tie(ident, loc) = p; importPath.push_back(ident, loc); } return ImportDecl::create( Context, static_cast(dc), getSourceLocFromPointer(importLoc), static_cast(kind), getSourceLocFromPointer(kindLoc), std::move(importPath).get()); } void *BridgedSourceLoc_advanced(void *loc, long len) { SourceLoc l = getSourceLocFromPointer(loc).getAdvancedLoc(len); return const_cast(l.getOpaquePointerValue()); } void *SwiftTopLevelCodeDecl_createStmt(void *ctx, void *DC, void *startLoc, void *element, void *endLoc) { ASTContext &Context = *static_cast(ctx); auto *S = static_cast(element); auto Brace = BraceStmt::create(Context, getSourceLocFromPointer(startLoc), {S}, getSourceLocFromPointer(endLoc), /*Implicit=*/true); auto *TLCD = new (Context) TopLevelCodeDecl(static_cast(DC), Brace); return (Decl *)TLCD; } void *SwiftTopLevelCodeDecl_createExpr(void *ctx, void *DC, void *startLoc, void *element, void *endLoc) { ASTContext &Context = *static_cast(ctx); auto *E = static_cast(element); auto Brace = BraceStmt::create(Context, getSourceLocFromPointer(startLoc), {E}, getSourceLocFromPointer(endLoc), /*Implicit=*/true); auto *TLCD = new (Context) TopLevelCodeDecl(static_cast(DC), Brace); return (Decl *)TLCD; } void *SwiftSequenceExpr_create(void *ctx, BridgedArrayRef exprs) { return SequenceExpr::create(*static_cast(ctx), getArrayRef(exprs)); } void *SwiftTupleExpr_create(void *ctx, void *lparen, BridgedArrayRef subs, void *rparen) { return TupleExpr::create( *static_cast(ctx), getSourceLocFromPointer(lparen), getArrayRef(subs), {}, {}, getSourceLocFromPointer(rparen), /*Implicit*/ false); } void *SwiftFunctionCallExpr_create(void *ctx, void *fn, void *args) { ASTContext &Context = *static_cast(ctx); TupleExpr *TE = static_cast(args); SmallVector arguments; for (unsigned i = 0; i < TE->getNumElements(); ++i) { arguments.emplace_back(TE->getElementNameLoc(i), TE->getElementName(i), TE->getElement(i)); } auto *argList = ArgumentList::create(Context, TE->getLParenLoc(), arguments, TE->getRParenLoc(), None, /*isImplicit*/ false); return CallExpr::create(Context, static_cast(fn), argList, /*implicit*/ false); } void *SwiftIdentifierExpr_create(void *ctx, BridgedIdentifier base, void *loc) { ASTContext &Context = *static_cast(ctx); auto name = DeclNameRef{swift::Identifier::getFromOpaquePointer(base)}; Expr *E = new (Context) UnresolvedDeclRefExpr( name, DeclRefKind::Ordinary, DeclNameLoc{getSourceLocFromPointer(loc)}); return E; } void *SwiftStringLiteralExpr_create(void *ctx, const uint8_t *_Nullable string, long len, void *TokenLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) StringLiteralExpr( StringRef{reinterpret_cast(string), size_t(len)}, getSourceLocFromPointer(TokenLoc)); } void *SwiftIntegerLiteralExpr_create(void *ctx, const uint8_t *_Nullable string, long len, void *TokenLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) IntegerLiteralExpr( StringRef{reinterpret_cast(string), size_t(len)}, getSourceLocFromPointer(TokenLoc)); } void *SwiftBooleanLiteralExpr_create(void *ctx, bool value, void *TokenLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) BooleanLiteralExpr(value, getSourceLocFromPointer(TokenLoc)); } void *SwiftVarDecl_create(void *ctx, BridgedIdentifier _Nullable nameId, void *initExpr, void *loc, bool isStatic, bool isLet, void *dc) { ASTContext &Context = *static_cast(ctx); auto name = (UnresolvedDeclRefExpr *)nameId; auto sourceLoc = getSourceLocFromPointer(loc); auto varDecl = new (Context) VarDecl( isStatic, isLet ? VarDecl::Introducer::Let : VarDecl::Introducer::Var, sourceLoc, name->getName().getBaseIdentifier(), reinterpret_cast(dc)); auto pattern = NamedPattern::createImplicit(Context, varDecl); return PatternBindingDecl::create( Context, sourceLoc, isStatic ? StaticSpellingKind::KeywordStatic : StaticSpellingKind::None, sourceLoc, pattern, sourceLoc, (Expr *)initExpr, reinterpret_cast(dc)); } void *IfStmt_create(void *ctx, void *ifLoc, void *cond, void *_Nullable then, void *_Nullable elseLoc, void *_Nullable elseStmt) { ASTContext &Context = *static_cast(ctx); return new (Context) IfStmt(getSourceLocFromPointer(ifLoc), (Expr *)cond, (Stmt *)then, getSourceLocFromPointer(elseLoc), (Stmt *)elseStmt, None, Context); } void *ReturnStmt_create(void *ctx, void *loc, void *_Nullable expr) { ASTContext &Context = *static_cast(ctx); return new (Context) ReturnStmt(getSourceLocFromPointer(loc), (Expr *)expr); } void *BraceStmt_create(void *ctx, void *lbloc, BridgedArrayRef elements, void *rbloc) { llvm::SmallVector nodes; for (auto node : getArrayRef(elements)) { if (node.kind == ASTNodeKindExpr) { auto expr = (Expr *)node.ptr; nodes.push_back(expr); } else if (node.kind == ASTNodeKindStmt) { auto stmt = (Stmt *)node.ptr; nodes.push_back(stmt); } else { assert(node.kind == ASTNodeKindDecl); auto decl = (Decl *)node.ptr; nodes.push_back(decl); } } ASTContext &Context = *static_cast(ctx); return BraceStmt::create(Context, getSourceLocFromPointer(lbloc), Context.AllocateCopy(nodes), getSourceLocFromPointer(rbloc)); } void *ParamDecl_create(void *ctx, void *loc, void *_Nullable argLoc, BridgedIdentifier _Nullable argName, void *_Nullable paramLoc, BridgedIdentifier _Nullable paramName, void *_Nullable type, void *declContext) { ASTContext &Context = *static_cast(ctx); if (!paramName) paramName = argName; auto paramDecl = new (Context) ParamDecl( getSourceLocFromPointer(loc), getSourceLocFromPointer(argLoc), Identifier::getFromOpaquePointer(argName), getSourceLocFromPointer(paramLoc), Identifier::getFromOpaquePointer(paramName), (DeclContext *)declContext); paramDecl->setTypeRepr((TypeRepr *)type); return paramDecl; } void *FuncDecl_create(void *ctx, void *staticLoc, bool isStatic, void *funcLoc, BridgedIdentifier name, void *nameLoc, bool isAsync, void *_Nullable asyncLoc, bool throws, void *_Nullable throwsLoc, void *paramLLoc, BridgedArrayRef params, void *paramRLoc, void *_Nullable body, void *_Nullable returnType, void *declContext) { auto *paramList = ParameterList::create( *static_cast(ctx), getSourceLocFromPointer(paramLLoc), getArrayRef(params), getSourceLocFromPointer(paramRLoc)); auto declName = DeclName(*static_cast(ctx), Identifier::getFromOpaquePointer(name), paramList); auto *out = FuncDecl::create( *static_cast(ctx), getSourceLocFromPointer(staticLoc), isStatic ? StaticSpellingKind::KeywordStatic : StaticSpellingKind::None, getSourceLocFromPointer(funcLoc), declName, getSourceLocFromPointer(nameLoc), isAsync, getSourceLocFromPointer(asyncLoc), throws, getSourceLocFromPointer(throwsLoc), nullptr, paramList, (TypeRepr *)returnType, (DeclContext *)declContext); out->setBody((BraceStmt *)body, FuncDecl::BodyKind::Parsed); return static_cast(out); } void *SimpleIdentTypeRepr_create(void *ctx, void *loc, BridgedIdentifier id) { ASTContext &Context = *static_cast(ctx); return new (Context) SimpleIdentTypeRepr(DeclNameLoc(getSourceLocFromPointer(loc)), DeclNameRef(Identifier::getFromOpaquePointer(id))); } void *GenericIdentTypeRepr_create(void *ctx, BridgedIdentifier name, void *nameLoc, BridgedArrayRef genericArgs, void *lAngle, void *rAngle) { ASTContext &Context = *static_cast(ctx); auto Loc = DeclNameLoc(getSourceLocFromPointer(nameLoc)); auto Name = DeclNameRef(Identifier::getFromOpaquePointer(name)); SourceLoc lAngleLoc = getSourceLocFromPointer(lAngle); SourceLoc rAngleLoc = getSourceLocFromPointer(rAngle); return GenericIdentTypeRepr::create(Context, Loc, Name, getArrayRef(genericArgs), SourceRange{lAngleLoc, rAngleLoc}); } void *UnresolvedDotExpr_create(void *ctx, void *base, void *dotLoc, BridgedIdentifier name, void *nameLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) UnresolvedDotExpr((Expr *)base, getSourceLocFromPointer(dotLoc), DeclNameRef(Identifier::getFromOpaquePointer(name)), DeclNameLoc(getSourceLocFromPointer(nameLoc)), false); } void *ClosureExpr_create(void *ctx, void *body, void *dc) { DeclAttributes attributes; SourceRange bracketRange; SourceLoc asyncLoc; SourceLoc throwsLoc; SourceLoc arrowLoc; SourceLoc inLoc; ASTContext &Context = *static_cast(ctx); auto *out = new (Context) ClosureExpr(attributes, bracketRange, nullptr, nullptr, asyncLoc, throwsLoc, arrowLoc, inLoc, nullptr, 0, (DeclContext *)dc); out->setBody((BraceStmt *)body, true); return (Expr *)out; } void NominalTypeDecl_setMembers(void *decl, BridgedArrayRef members) { auto declMembers = getArrayRef(members); for (auto m : declMembers) ((NominalTypeDecl *)decl)->addMember(m); } DeclContextAndDecl StructDecl_create(void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams, void *dc) { ASTContext &Context = *static_cast(ctx); auto *out = new (Context) StructDecl( getSourceLocFromPointer(loc), Identifier::getFromOpaquePointer(name), getSourceLocFromPointer(nameLoc), {}, (GenericParamList *)genericParams, (DeclContext *)dc); out->setImplicit(); // TODO: remove this. return {(DeclContext *)out, (NominalTypeDecl *)out, (Decl *)out}; } DeclContextAndDecl ClassDecl_create(void *ctx, void *loc, BridgedIdentifier name, void *nameLoc, void *dc) { ASTContext &Context = *static_cast(ctx); auto *out = new (Context) ClassDecl( getSourceLocFromPointer(loc), Identifier::getFromOpaquePointer(name), getSourceLocFromPointer(nameLoc), {}, nullptr, (DeclContext *)dc, false); out->setImplicit(); // TODO: remove this. return {(DeclContext *)out, (NominalTypeDecl *)out, (Decl *)out}; } void *OptionalTypeRepr_create(void *ctx, void *base, void *questionLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) OptionalTypeRepr((TypeRepr *)base, getSourceLocFromPointer(questionLoc)); } void *ImplicitlyUnwrappedOptionalTypeRepr_create(void *ctx, void *base, void *exclamationLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) ImplicitlyUnwrappedOptionalTypeRepr( (TypeRepr *)base, getSourceLocFromPointer(exclamationLoc)); } void *ArrayTypeRepr_create(void *ctx, void *base, void *lsquareLoc, void *rsquareLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc lSquareLoc = getSourceLocFromPointer(lsquareLoc); SourceLoc rSquareLoc = getSourceLocFromPointer(rsquareLoc); return new (Context) ArrayTypeRepr((TypeRepr *)base, SourceRange{lSquareLoc, rSquareLoc}); } void *DictionaryTypeRepr_create(void *ctx, void *keyType, void *valueType, void *lsquareLoc, void *colonloc, void *rsquareLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc lSquareLoc = getSourceLocFromPointer(lsquareLoc); SourceLoc colonLoc = getSourceLocFromPointer(colonloc); SourceLoc rSquareLoc = getSourceLocFromPointer(rsquareLoc); return new (Context) DictionaryTypeRepr((TypeRepr *)keyType, (TypeRepr *)valueType, colonLoc, SourceRange{lSquareLoc, rSquareLoc}); } void *MetatypeTypeRepr_create(void *ctx, void *baseType, void *typeLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc tyLoc = getSourceLocFromPointer(typeLoc); return new (Context) MetatypeTypeRepr((TypeRepr *)baseType, tyLoc); } void *ProtocolTypeRepr_create(void *ctx, void *baseType, void *protoLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc protocolLoc = getSourceLocFromPointer(protoLoc); return new (Context) ProtocolTypeRepr((TypeRepr *)baseType, protocolLoc); } void *PackExpansionTypeRepr_create(void *ctx, void *base, void *ellipsisLoc) { ASTContext &Context = *static_cast(ctx); return new (Context) PackExpansionTypeRepr( (TypeRepr *)base, getSourceLocFromPointer(ellipsisLoc)); } void *TupleTypeRepr_create(void *ctx, BridgedArrayRef elements, void *lParenLoc, void *rParenLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc lParen = getSourceLocFromPointer(lParenLoc); SourceLoc rParen = getSourceLocFromPointer(rParenLoc); SmallVector tupleElements; for (auto element : getArrayRef(elements)) { TupleTypeReprElement elementRepr; elementRepr.Name = Identifier::getFromOpaquePointer(element.Name); elementRepr.NameLoc = getSourceLocFromPointer(element.NameLoc); elementRepr.SecondName = Identifier::getFromOpaquePointer(element.SecondName); elementRepr.SecondNameLoc = getSourceLocFromPointer(element.SecondNameLoc); elementRepr.UnderscoreLoc = getSourceLocFromPointer(element.UnderscoreLoc); elementRepr.ColonLoc = getSourceLocFromPointer(element.ColonLoc); elementRepr.Type = (TypeRepr *)element.Type; elementRepr.TrailingCommaLoc = getSourceLocFromPointer(element.TrailingCommaLoc); tupleElements.emplace_back(elementRepr); } return TupleTypeRepr::create(Context, tupleElements, SourceRange{lParen, rParen}); } void *IdentTypeRepr_create(void *ctx, BridgedArrayRef components) { ASTContext &Context = *static_cast(ctx); return IdentTypeRepr::create( Context, getArrayRef(components)); } void *CompositionTypeRepr_create(void *ctx, BridgedArrayRef types, void *firstTypeLoc) { ASTContext &Context = *static_cast(ctx); SourceLoc firstType = getSourceLocFromPointer(firstTypeLoc); return CompositionTypeRepr::create(Context, getArrayRef(types), firstType, SourceRange{}); } void *FunctionTypeRepr_create(void *ctx, void *argsTy, void *_Nullable asyncLoc, void *_Nullable throwsLoc, void *arrowLoc, void *returnType) { ASTContext &Context = *static_cast(ctx); return new (Context) FunctionTypeRepr( nullptr, (TupleTypeRepr *)argsTy, getSourceLocFromPointer(asyncLoc), getSourceLocFromPointer(throwsLoc), getSourceLocFromPointer(arrowLoc), (TypeRepr *)returnType); } void *NamedOpaqueReturnTypeRepr_create(void *ctx, void *baseTy) { ASTContext &Context = *static_cast(ctx); return new (Context) NamedOpaqueReturnTypeRepr((TypeRepr *)baseTy, nullptr); } void *OpaqueReturnTypeRepr_create(void *ctx, void *opaqueLoc, void *baseTy) { ASTContext &Context = *static_cast(ctx); return new (Context) OpaqueReturnTypeRepr(getSourceLocFromPointer(opaqueLoc), (TypeRepr *)baseTy); } void *ExistentialTypeRepr_create(void *ctx, void *anyLoc, void *baseTy) { ASTContext &Context = *static_cast(ctx); return new (Context) ExistentialTypeRepr(getSourceLocFromPointer(anyLoc), (TypeRepr *)baseTy); } void *GenericParamList_create(void *ctx, void *lAngleLoc, BridgedArrayRef params, void *_Nullable whereLoc, BridgedArrayRef reqs, void *rAngleLoc) { ASTContext &Context = *static_cast(ctx); SmallVector requirements; for (auto req : getArrayRef(reqs)) { switch (req.Kind) { case BridgedRequirementReprKindTypeConstraint: requirements.push_back(RequirementRepr::getTypeConstraint( (TypeRepr *)req.FirstType, getSourceLocFromPointer(req.SeparatorLoc), (TypeRepr *)req.SecondType)); break; case BridgedRequirementReprKindSameType: requirements.push_back(RequirementRepr::getSameType( (TypeRepr *)req.FirstType, getSourceLocFromPointer(req.SeparatorLoc), (TypeRepr *)req.SecondType)); break; case BridgedRequirementReprKindLayoutConstraint: llvm_unreachable("cannot handle layout constraints!"); } } return GenericParamList::create(Context, getSourceLocFromPointer(lAngleLoc), getArrayRef(params), getSourceLocFromPointer(whereLoc), requirements, getSourceLocFromPointer(rAngleLoc)); } void *GenericTypeParamDecl_create(void *ctx, void *declContext, BridgedIdentifier name, void *nameLoc, void *_Nullable ellipsisLoc, long index, bool isParameterPack) { return GenericTypeParamDecl::createParsed( static_cast(declContext), Identifier::getFromOpaquePointer(name), getSourceLocFromPointer(nameLoc), getSourceLocFromPointer(ellipsisLoc), /*index*/ index, isParameterPack); } void GenericTypeParamDecl_setInheritedType(void *ctx, void *Param, void *ty) { ASTContext &Context = *static_cast(ctx); auto entries = Context.AllocateCopy( ArrayRef{InheritedEntry{(TypeRepr *)ty}}); ((GenericTypeParamDecl *)Param)->setInherited(entries); } DeclContextAndDecl TypeAliasDecl_create(void *ctx, void *declContext, void *aliasLoc, void *equalLoc, BridgedIdentifier name, void *nameLoc, void *_Nullable genericParams) { ASTContext &Context = *static_cast(ctx); auto *out = new (Context) TypeAliasDecl( getSourceLocFromPointer(aliasLoc), getSourceLocFromPointer(equalLoc), Identifier::getFromOpaquePointer(name), getSourceLocFromPointer(nameLoc), (GenericParamList *)genericParams, (DeclContext *)declContext); return {(DeclContext *)out, (TypeAliasDecl *)out, (Decl *)out}; } void TypeAliasDecl_setUnderlyingTypeRepr(void *decl, void *underlyingType) { ((TypeAliasDecl *)decl)->setUnderlyingTypeRepr((TypeRepr *)underlyingType); } void TopLevelCodeDecl_dump(void *decl) { ((TopLevelCodeDecl *)decl)->dump(llvm::errs()); } void Expr_dump(void *expr) { ((Expr *)expr)->dump(llvm::errs()); } void Decl_dump(void *expr) { ((Decl *)expr)->dump(llvm::errs()); } void Stmt_dump(void *expr) { ((Stmt *)expr)->dump(llvm::errs()); }