Skip to content

Commit 6e7f307

Browse files
committed
Add rudimentary emission of compile-time-known default-initialized property values of specific conformances.
1 parent b23e5dc commit 6e7f307

File tree

12 files changed

+572
-11
lines changed

12 files changed

+572
-11
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//===--- ConstTypeInfo.h - Const Nominal Type Info Structure ----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_AST_CONST_TYPE_INFO_H
14+
#define SWIFT_AST_CONST_TYPE_INFO_H
15+
16+
#include <string>
17+
#include <vector>
18+
#include <memory>
19+
20+
namespace swift {
21+
class NominalTypeDecl;
22+
class VarDecl;
23+
class Type;
24+
} // namespace swift
25+
26+
/// Representation of a compile-time-known value, for example
27+
/// in a type property initializer expression
28+
class CompileTimeValue {
29+
public:
30+
enum ValueKind { RawLiteral, InitCall, Builder, Dictionary, Runtime };
31+
32+
ValueKind getKind() const { return Kind; }
33+
34+
protected:
35+
CompileTimeValue(ValueKind ValueKind) : Kind(ValueKind) {}
36+
37+
private:
38+
ValueKind Kind;
39+
};
40+
41+
/// A string representation of a raw literal value,
42+
/// for example an integer or string or float literal.
43+
class RawLiteralValue : public CompileTimeValue {
44+
public:
45+
RawLiteralValue(std::string Value)
46+
: CompileTimeValue(ValueKind::RawLiteral), Value(Value) {}
47+
48+
std::string getValue() const { return Value; }
49+
50+
static bool classof(const CompileTimeValue *T) {
51+
return T->getKind() == ValueKind::RawLiteral;
52+
}
53+
54+
private:
55+
std::string Value;
56+
};
57+
58+
struct FunctionParameter {
59+
public:
60+
std::string getLabel() { return Label; }
61+
swift::Type *getType() { return Type; }
62+
63+
private:
64+
std::string Label;
65+
swift::Type *Type;
66+
};
67+
68+
/// A representation of a call to a type's initializer
69+
/// with a collection of (potentially compile-time-known) parameters
70+
class InitCallValue : public CompileTimeValue {
71+
public:
72+
InitCallValue(std::string Name, std::vector<FunctionParameter> Parameters)
73+
: CompileTimeValue(ValueKind::InitCall), Name(Name),
74+
Parameters(Parameters) {}
75+
76+
static bool classof(const CompileTimeValue *T) {
77+
return T->getKind() == ValueKind::InitCall;
78+
}
79+
80+
std::string getName() const { return Name; }
81+
82+
private:
83+
std::string Name;
84+
std::vector<FunctionParameter> Parameters;
85+
};
86+
87+
/// A representation of a Builder pattern initialization expression
88+
class BuilderValue : public CompileTimeValue {
89+
public:
90+
BuilderValue() : CompileTimeValue(ValueKind::Builder) {}
91+
92+
static bool classof(const CompileTimeValue *T) {
93+
return T->getKind() == ValueKind::Builder;
94+
}
95+
96+
private:
97+
std::vector<CompileTimeValue> Members;
98+
};
99+
100+
/// A dictionary literal value representation
101+
class DictionaryValue : public CompileTimeValue {
102+
public:
103+
DictionaryValue() : CompileTimeValue(ValueKind::Dictionary) {}
104+
105+
static bool classof(const CompileTimeValue *T) {
106+
return T->getKind() == ValueKind::Dictionary;
107+
}
108+
};
109+
110+
/// A representation of an arbitrary value that does not fall under
111+
/// any of the above categories.
112+
class RuntimeValue : public CompileTimeValue {
113+
public:
114+
RuntimeValue() : CompileTimeValue(ValueKind::Runtime) {}
115+
116+
static bool classof(const CompileTimeValue *T) {
117+
return T->getKind() == ValueKind::Runtime;
118+
}
119+
};
120+
121+
struct ConstValueTypePropertyInfo {
122+
swift::VarDecl *VarDecl;
123+
std::shared_ptr<CompileTimeValue> Value;
124+
};
125+
126+
struct ConstValueTypeInfo {
127+
swift::NominalTypeDecl *TypeDecl;
128+
std::vector<ConstValueTypePropertyInfo> Properties;
129+
};
130+
131+
#endif

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,18 @@ ERROR(batch_scan_input_file_missing,none,
305305
"cannot open batch dependencies scan input file from %0",
306306
(StringRef))
307307

308+
ERROR(const_extract_protocol_list_input_file_missing,none,
309+
"cannot open constant extraction protocol list input file from %0",
310+
(StringRef))
311+
308312
ERROR(batch_scan_input_file_corrupted,none,
309313
"batch dependencies scan input file from %0 is malformed",
310314
(StringRef))
311315

316+
ERROR(const_extract_protocol_list_input_file_corrupted,none,
317+
"constant extraction protocol list input file from %0 is malformed",
318+
(StringRef))
319+
312320
ERROR(unknown_platform_name, none,
313321
"unknown platform name %0", (StringRef))
314322

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "swift/AST/ActorIsolation.h"
2020
#include "swift/AST/AnyFunctionRef.h"
21+
#include "swift/AST/ConstTypeInfo.h"
2122
#include "swift/AST/ASTNode.h"
2223
#include "swift/AST/ASTTypeIDs.h"
2324
#include "swift/AST/Effects.h"
@@ -693,6 +694,26 @@ class PropertyWrapperTypeInfoRequest
693694
bool isCached() const { return true; }
694695
};
695696

697+
/// Retrieve information about compile-time-known
698+
class ConstantValueInfoRequest
699+
: public SimpleRequest<ConstantValueInfoRequest,
700+
ConstValueTypeInfo(NominalTypeDecl *),
701+
RequestFlags::Cached> {
702+
public:
703+
using SimpleRequest::SimpleRequest;
704+
705+
private:
706+
friend SimpleRequest;
707+
708+
// Evaluation.
709+
ConstValueTypeInfo
710+
evaluate(Evaluator &eval, NominalTypeDecl *nominal) const;
711+
712+
public:
713+
// Caching
714+
bool isCached() const { return true; }
715+
};
716+
696717
/// Request the nominal type declaration to which the given custom attribute
697718
/// refers.
698719
class AttachedPropertyWrappersRequest :

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ SWIFT_REQUEST(TypeChecker, PropertyWrapperMutabilityRequest,
260260
SWIFT_REQUEST(TypeChecker, PropertyWrapperTypeInfoRequest,
261261
PropertyWrapperTypeInfo(NominalTypeDecl *), Cached,
262262
NoLocationInfo)
263+
SWIFT_REQUEST(TypeChecker, ConstantValueInfoRequest,
264+
ConstValueTypeInfo(NominalTypeDecl *), Cached,
265+
NoLocationInfo)
263266
SWIFT_REQUEST(TypeChecker, ProtocolRequiresClassRequest, bool(ProtocolDecl *),
264267
SeparatelyCached, NoLocationInfo)
265268
SWIFT_REQUEST(TypeChecker, PrimaryAssociatedTypesRequest,
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===-------- ConstExtract.h -- Gather Compile-Time-Known Values ----------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_CONST_EXTRACT_H
14+
#define SWIFT_CONST_EXTRACT_H
15+
16+
#include "swift/AST/ConstTypeInfo.h"
17+
#include "llvm/ADT/ArrayRef.h"
18+
#include <string>
19+
#include <unordered_set>
20+
#include <vector>
21+
22+
namespace llvm {
23+
class StringRef;
24+
class raw_fd_ostream;
25+
}
26+
27+
namespace swift {
28+
class SourceFile;
29+
class DiagnosticEngine;
30+
class ModuleDecl;
31+
} // namespace swift
32+
33+
namespace swift {
34+
/// Parse a list of string identifiers from a file at the given path,
35+
/// representing names of protocols.
36+
bool
37+
parseProtocolListFromFile(llvm::StringRef protocolListFilePath,
38+
DiagnosticEngine &diags,
39+
std::unordered_set<std::string> &protocols);
40+
41+
/// Gather compile-time-known values of properties in nominal type declarations
42+
/// in this file, of types which conform to one of the protocols listed in
43+
/// \c Protocols
44+
std::vector<ConstValueTypeInfo>
45+
gatherConstValuesForPrimary(const std::unordered_set<std::string> &Protocols,
46+
const SourceFile *File);
47+
48+
/// Gather compile-time-known values of properties in nominal type declarations
49+
/// in this module, of types which conform to one of the protocols listed in
50+
/// \c Protocols
51+
std::vector<ConstValueTypeInfo>
52+
gatherConstValuesForModule(const std::unordered_set<std::string> &Protocols,
53+
ModuleDecl *Module);
54+
55+
/// Serialize a collection of \c ConstValueInfos to JSON at the
56+
/// provided output stream.
57+
bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
58+
llvm::raw_fd_ostream &OS);
59+
60+
} // namespace swift
61+
62+
#endif

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_subdirectory(APIDigester)
1818
add_subdirectory(AST)
1919
add_subdirectory(ASTSectionImporter)
2020
add_subdirectory(Basic)
21+
add_subdirectory(ConstExtract)
2122
add_subdirectory(ClangImporter)
2223
add_subdirectory(Demangling)
2324
add_subdirectory(DependencyScan)

lib/ConstExtract/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
add_swift_host_library(swiftConstExtract STATIC
2+
ConstExtract.cpp
3+
)
4+
target_link_libraries(swiftConstExtract PRIVATE
5+
swiftClangImporter
6+
swiftAST)
7+
8+
set_swift_llvm_is_available(swiftConstExtract)

0 commit comments

Comments
 (0)