-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathTypeCheckRuntimeMetadataAttr.cpp
100 lines (79 loc) · 3.38 KB
/
TypeCheckRuntimeMetadataAttr.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//===--- TypeCheckRuntimeMetadataAttr.cpp - type wrappers -----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for @runtimeMetadata attributes.
//
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/Attr.h"
#include "swift/AST/Decl.h"
#include "swift/AST/NameLookupRequests.h"
#include "swift/AST/TypeCheckRequests.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/SmallString.h"
using namespace swift;
ArrayRef<CustomAttr *> ValueDecl::getRuntimeDiscoverableAttrs() const {
auto *mutableSelf = const_cast<ValueDecl *>(this);
return evaluateOrDefault(getASTContext().evaluator,
GetRuntimeDiscoverableAttributes{mutableSelf},
nullptr);
}
static BraceStmt *
deriveGeneratorBody(FuncDecl *generator,
std::pair<CustomAttr *, ValueDecl *> content) {
auto &ctx = generator->getASTContext();
// return nil
ASTNode body = new (ctx) ReturnStmt(
SourceLoc(),
new (ctx) NilLiteralExpr(/*Loc=*/SourceLoc(), /*Implicit=*/true),
/*isImplicit=*/true);
return BraceStmt::create(ctx, /*lbloc=*/SourceLoc(), body,
/*rbloc=*/SourceLoc(), /*implicit=*/true);
}
FuncDecl *SynthesizeRuntimeMetadataAttrGenerator::evaluate(
Evaluator &evaluator, CustomAttr *attr, ValueDecl *parent) const {
auto &ctx = parent->getASTContext();
auto *attrType = evaluateOrDefault(
ctx.evaluator, CustomAttrNominalRequest{attr, parent->getDeclContext()},
nullptr);
if (!attrType)
return nullptr;
assert(attrType->getAttrs().hasAttribute<RuntimeMetadataAttr>());
Mangle::ASTMangler mangler;
SmallString<32> nameScratch;
nameScratch.append("generator$");
nameScratch.append(mangler.mangleAnyDecl(attrType, /*prefix=*/false));
nameScratch.append("$");
nameScratch.append(mangler.mangleAnyDecl(parent, /*prefix=*/false));
DeclName generatorName(ctx, ctx.getIdentifier(nameScratch.str()),
/*argumentNames=*/ArrayRef<Identifier>());
auto resultType = OptionalType::get(attrType->getInterfaceType());
// () -> Optional<<#Attribute#>>
auto *generator = FuncDecl::createImplicit(
ctx, StaticSpellingKind::None, generatorName, /*NameLoc=*/SourceLoc(),
/*Async=*/false,
/*Throws=*/false,
/*GenericParams=*/nullptr, ParameterList::createEmpty(ctx), resultType,
/*DC=*/parent->getDeclContext()->getParentModule());
generator->setSynthesized(true);
generator->copyFormalAccessFrom(parent, /*sourceIsParentContext=*/false);
ASTNode body = deriveGeneratorBody(generator, std::make_pair(attr, parent));
if (!body)
return nullptr;
TypeChecker::typeCheckASTNode(body, generator);
generator->setBody(cast<BraceStmt>(body.get<Stmt *>()),
FuncDecl::BodyKind::TypeChecked);
return generator;
}