Skip to content

Commit ca0e90c

Browse files
Merge pull request #4297 from swiftwasm/main
[pull] swiftwasm from main
2 parents bfc964c + 210e135 commit ca0e90c

27 files changed

+1195
-317
lines changed

include/swift/AST/Expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
491491
return getSemanticsProvidingExpr()->getKind() == ExprKind::InOut;
492492
}
493493

494+
bool printConstExprValue(llvm::raw_ostream *OS) const;
494495
bool isSemanticallyConstExpr() const;
495496

496497
/// Returns false if this expression needs to be wrapped in parens when

include/swift/AST/SearchPathOptions.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ enum class ModuleSearchPathKind {
3636

3737
/// A single module search path that can come from different sources, e.g.
3838
/// framework search paths, import search path etc.
39-
struct ModuleSearchPath {
40-
/// The actual path of the module search path. References a search path string
41-
/// stored inside \c SearchPathOptions, which must outlive this reference.
42-
StringRef Path;
39+
class ModuleSearchPath : public llvm::RefCountedBase<ModuleSearchPath> {
40+
/// The actual path of the module search path.
41+
std::string Path;
4342

4443
/// The kind of the search path.
4544
ModuleSearchPathKind Kind;
@@ -52,6 +51,18 @@ struct ModuleSearchPath {
5251
/// different file names in \c searchPathsContainingFile.
5352
unsigned Index;
5453

54+
public:
55+
ModuleSearchPath(StringRef Path, ModuleSearchPathKind Kind, bool IsSystem,
56+
unsigned Index)
57+
: Path(Path), Kind(Kind), IsSystem(IsSystem), Index(Index) {}
58+
59+
StringRef getPath() const { return Path; }
60+
ModuleSearchPathKind getKind() const { return Kind; }
61+
62+
bool isSystem() const { return IsSystem; }
63+
64+
unsigned getIndex() const { return Index; }
65+
5566
bool operator<(const ModuleSearchPath &Other) const {
5667
if (this->Kind == Other.Kind) {
5768
return this->Index < Other.Index;
@@ -61,6 +72,8 @@ struct ModuleSearchPath {
6172
}
6273
};
6374

75+
using ModuleSearchPathPtr = llvm::IntrusiveRefCntPtr<ModuleSearchPath>;
76+
6477
class SearchPathOptions;
6578

6679
/// Maintains a mapping of filenames to search paths that contain a file with
@@ -97,7 +110,7 @@ class ModuleSearchPathLookup {
97110
const SearchPathOptions *Opts;
98111
} State;
99112

100-
llvm::StringMap<SmallVector<ModuleSearchPath, 4>> LookupTable;
113+
llvm::StringMap<SmallVector<ModuleSearchPathPtr, 4>> LookupTable;
101114

102115
/// Scan the directory at \p SearchPath for files and add those files to the
103116
/// lookup table. \p Kind specifies the search path kind and \p Index the

include/swift/SILOptimizer/Utils/CFGOptUtils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,22 @@ SILBasicBlock *splitBasicBlockAndBranch(SILBuilder &builder,
144144
DominanceInfo *domInfo,
145145
SILLoopInfo *loopInfo);
146146

147+
/// A version of splitBasicBlockAndBranch that takes a SILBuilderContext instead
148+
/// of a SILBuilder. We generally are trying to eliminate APIs that take in
149+
/// SILBuilder directly since that can cause weird downstream mistakes around
150+
/// debug info scopes. So this provides a better choice for engineers.
151+
///
152+
/// TODO: Migrate all callers of splitBasicBlockAndBranch to use this entry
153+
/// point.
154+
inline SILBasicBlock *splitBasicBlockAndBranch(SILBuilderContext &builderCtx,
155+
SILInstruction *splitBeforeInst,
156+
DominanceInfo *domInfo,
157+
SILLoopInfo *loopInfo) {
158+
// Make sure we have the right debug scope from split before inst.
159+
SILBuilderWithScope builder(splitBeforeInst, builderCtx);
160+
return splitBasicBlockAndBranch(builder, splitBeforeInst, domInfo, loopInfo);
161+
}
162+
147163
/// Return true if the function has a critical edge, false otherwise.
148164
bool hasCriticalEdges(SILFunction &f, bool onlyNonCondBr);
149165

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,8 +2220,12 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
22202220
return {std::move(FileBufOrErr.get()), Result};
22212221
}
22222222
enum class ConstKind: uint8_t {
2223-
String = 0,
2224-
Int,
2223+
StringLiteral = 0,
2224+
IntegerLiteral,
2225+
FloatLiteral,
2226+
BooleanLiteral,
2227+
Array,
2228+
Dictionary,
22252229
};
22262230

22272231
struct ConstExprInfo {
@@ -2230,9 +2234,11 @@ struct ConstExprInfo {
22302234
unsigned offset = 0;
22312235
unsigned length = 0;
22322236
StringRef value;
2237+
StringRef referencedD;
22332238
ConstExprInfo(StringRef filePath, ConstKind kind, unsigned offset,
2234-
unsigned length, StringRef value):
2235-
filePath(filePath), kind(kind), offset(offset), length(length), value(value) {}
2239+
unsigned length, StringRef value, StringRef referencedD):
2240+
filePath(filePath), kind(kind), offset(offset), length(length), value(value),
2241+
referencedD(referencedD) {}
22362242
ConstExprInfo() = default;
22372243
};
22382244

@@ -2242,7 +2248,7 @@ class ConstExtractor: public ASTWalker {
22422248
SourceManager &SM;
22432249
std::vector<ConstExprInfo> allConsts;
22442250

2245-
void record(Expr *E, ConstKind kind, StringRef Value) {
2251+
void record(Expr *E, ConstKind kind, StringRef Value, StringRef ReferencedD) {
22462252
auto startLoc = E->getStartLoc();
22472253
// Asserts?
22482254
if (startLoc.isInvalid())
@@ -2254,14 +2260,70 @@ class ConstExtractor: public ASTWalker {
22542260
auto length = SM.getByteDistance(startLoc, endLoc);
22552261
auto file = SM.getIdentifierForBuffer(bufferId);
22562262
auto offset = SM.getLocOffsetInBuffer(startLoc, bufferId);
2257-
allConsts.emplace_back(file, kind, offset, length, Value);
2263+
allConsts.emplace_back(file, kind, offset, length, Value, ReferencedD);
2264+
}
2265+
2266+
void record(Expr *E, Expr *ValueProvider, StringRef ReferecedD = "") {
2267+
std::string content;
2268+
llvm::raw_string_ostream os(content);
2269+
ValueProvider->printConstExprValue(&os);
2270+
assert(!content.empty());
2271+
auto buffered = SCtx.buffer(content);
2272+
switch(ValueProvider->getKind()) {
2273+
#define CASE(X) case ExprKind::X: record(E, ConstKind::X, buffered, ReferecedD); break;
2274+
CASE(StringLiteral)
2275+
CASE(IntegerLiteral)
2276+
CASE(FloatLiteral)
2277+
CASE(BooleanLiteral)
2278+
CASE(Dictionary)
2279+
CASE(Array)
2280+
#undef CASE
2281+
default:
2282+
return;
2283+
}
2284+
}
2285+
2286+
StringRef getDeclName(Decl *D) {
2287+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
2288+
std::string content;
2289+
llvm::raw_string_ostream os(content);
2290+
VD->getName().print(os);
2291+
return SCtx.buffer(content);
2292+
}
2293+
return StringRef();
22582294
}
22592295

2296+
bool handleSimpleReference(Expr *E) {
2297+
assert(E);
2298+
Decl *ReferencedDecl = nullptr;
2299+
if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
2300+
ReferencedDecl = MRE->getDecl().getDecl();
2301+
} else if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
2302+
ReferencedDecl = DRE->getDecl();
2303+
} else {
2304+
return false;
2305+
}
2306+
assert(ReferencedDecl);
2307+
if (auto *VAR = dyn_cast<VarDecl>(ReferencedDecl)) {
2308+
if (!VAR->getAttrs().hasAttribute<CompileTimeConstAttr>()) {
2309+
return false;
2310+
}
2311+
if (auto *PD = VAR->getParentPatternBinding()) {
2312+
if (auto *init = PD->getInit(PD->getPatternEntryIndexForVarDecl(VAR))) {
2313+
record(E, init, getDeclName(ReferencedDecl));
2314+
return true;
2315+
}
2316+
}
2317+
}
2318+
return false;
2319+
}
22602320
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
22612321
if (E->isSemanticallyConstExpr()) {
2262-
if (auto *SL = dyn_cast<StringLiteralExpr>(E)) {
2263-
record(SL, ConstKind::String, SL->getValue());
2264-
}
2322+
record(E, E);
2323+
return { false, E };
2324+
}
2325+
if (handleSimpleReference(E)) {
2326+
return { false, E };
22652327
}
22662328
return { true, E };
22672329
}
@@ -2279,14 +2341,20 @@ template <> struct swift::json::ObjectTraits<ConstExprInfo> {
22792341
StringRef kind;
22802342
switch(info.kind) {
22812343
#define CASE(X) case ConstKind::X: kind = #X; break;
2282-
CASE(String)
2283-
CASE(Int)
2344+
CASE(StringLiteral)
2345+
CASE(IntegerLiteral)
2346+
CASE(FloatLiteral)
2347+
CASE(BooleanLiteral)
2348+
CASE(Dictionary)
2349+
CASE(Array)
22842350
#undef CASE
22852351
}
22862352
out.mapRequired("kind", kind);
22872353
out.mapRequired("offset", info.offset);
22882354
out.mapRequired("length", info.length);
22892355
out.mapRequired("value", info.value);
2356+
if (!info.referencedD.empty())
2357+
out.mapRequired("decl", info.referencedD);
22902358
}
22912359
};
22922360

lib/AST/Expr.cpp

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -198,42 +198,83 @@ Expr *Expr::getSemanticsProvidingExpr() {
198198
return this;
199199
}
200200

201-
bool Expr::isSemanticallyConstExpr() const {
202-
auto E = getSemanticsProvidingExpr();
203-
if (!E) {
204-
return false;
201+
bool Expr::printConstExprValue(llvm::raw_ostream *OS) const {
202+
auto print = [&](StringRef text) {
203+
if (OS) {
204+
*OS << text;
205+
}
206+
};
207+
auto *E = getSemanticsProvidingExpr();
208+
assert(E);
209+
switch(getKind()) {
210+
case ExprKind::BooleanLiteral: {
211+
auto isTrue = cast<BooleanLiteralExpr>(E)->getValue();
212+
print(isTrue ? "true" : "false");
213+
return true;
205214
}
206-
switch(E->getKind()) {
207215
case ExprKind::IntegerLiteral:
208-
case ExprKind::NilLiteral:
209-
case ExprKind::BooleanLiteral:
210-
case ExprKind::FloatLiteral:
211-
case ExprKind::StringLiteral:
212-
case ExprKind::KeyPath:
216+
case ExprKind::FloatLiteral: {
217+
auto digits = cast<NumberLiteralExpr>(E)->getDigitsText();
218+
assert(!digits.empty());
219+
print(digits);
213220
return true;
221+
}
222+
case ExprKind::NilLiteral: {
223+
print("nil");
224+
return true;
225+
}
226+
case ExprKind::StringLiteral: {
227+
auto *LE = cast<StringLiteralExpr>(E);
228+
print("\"");
229+
print(LE->getValue());
230+
print("\"");
231+
return true;
232+
}
233+
case ExprKind::KeyPath: {
234+
// FIXME: print keypath
235+
print("\\.<NOT_IMPLEMENTED>");
236+
return true;
237+
}
214238
case ExprKind::Array:
215239
case ExprKind::Dictionary: {
240+
print("[");
216241
auto *CE = cast<CollectionExpr>(E);
217-
for (auto *EL: CE->getElements()) {
218-
if (!EL->isSemanticallyConstExpr())
242+
for (unsigned N = CE->getNumElements(), I = 0; I != N; I ++) {
243+
auto Ele = CE->getElement(I);
244+
auto needComma = I + 1 != N;
245+
if (!Ele->printConstExprValue(OS)) {
219246
return false;
247+
}
248+
if (needComma)
249+
print(", ");
220250
}
251+
print("]");
221252
return true;
222253
}
223254
case ExprKind::Tuple: {
255+
print("(");
224256
auto *TE = cast<TupleExpr>(E);
225-
for (auto *EL: TE->getElements()) {
226-
if (!EL->isSemanticallyConstExpr()) {
257+
for (unsigned N = TE->getNumElements(), I = 0; I != N; I ++) {
258+
auto Ele = TE->getElement(I);
259+
auto needComma = I + 1 != N;
260+
if (!Ele->printConstExprValue(OS)) {
227261
return false;
228262
}
263+
if (needComma)
264+
print(", ");
229265
}
266+
print(")");
230267
return true;
231268
}
232269
default:
233270
return false;
234271
}
235272
}
236273

274+
bool Expr::isSemanticallyConstExpr() const {
275+
return printConstExprValue(nullptr);
276+
}
277+
237278
Expr *Expr::getValueProvidingExpr() {
238279
Expr *E = getSemanticsProvidingExpr();
239280

lib/AST/SearchPathOptions.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,24 @@ void ModuleSearchPathLookup::addFilesInPathToLookupTable(
1919
llvm::vfs::FileSystem *FS, StringRef SearchPath, ModuleSearchPathKind Kind,
2020
bool IsSystem, unsigned SearchPathIndex) {
2121
std::error_code Error;
22-
assert(llvm::all_of(LookupTable, [&](const auto &LookupTableEntry) {
23-
return llvm::none_of(LookupTableEntry.second, [&](const ModuleSearchPath &ExistingSearchPath) -> bool {
24-
return ExistingSearchPath.Kind == Kind && ExistingSearchPath.Index == SearchPathIndex;
22+
auto entryAlreadyExists = [this](ModuleSearchPathKind Kind,
23+
unsigned SearchPathIndex) -> bool {
24+
return llvm::any_of(LookupTable, [&](const auto &LookupTableEntry) {
25+
return llvm::any_of(
26+
LookupTableEntry.second, [&](ModuleSearchPathPtr ExistingSearchPath) {
27+
return ExistingSearchPath->getKind() == Kind &&
28+
ExistingSearchPath->getIndex() == SearchPathIndex;
29+
});
2530
});
26-
}) && "Search path with this kind and index already exists");
31+
};
32+
assert(!entryAlreadyExists(Kind, SearchPathIndex) &&
33+
"Search path with this kind and index already exists");
34+
ModuleSearchPathPtr TableEntry =
35+
new ModuleSearchPath(SearchPath, Kind, IsSystem, SearchPathIndex);
2736
for (auto Dir = FS->dir_begin(SearchPath, Error);
2837
!Error && Dir != llvm::vfs::directory_iterator(); Dir.increment(Error)) {
2938
StringRef Filename = llvm::sys::path::filename(Dir->path());
30-
LookupTable[Filename].push_back(
31-
{SearchPath, Kind, IsSystem, SearchPathIndex});
39+
LookupTable[Filename].push_back(TableEntry);
3240
}
3341
}
3442

@@ -92,8 +100,9 @@ ModuleSearchPathLookup::searchPathsContainingFile(
92100

93101
for (auto &Filename : Filenames) {
94102
for (auto &Entry : LookupTable[Filename]) {
95-
if (ResultIds.insert(std::make_pair(Entry.Kind, Entry.Index)).second) {
96-
Result.push_back(&Entry);
103+
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
104+
.second) {
105+
Result.push_back(Entry.get());
97106
}
98107
}
99108
}

0 commit comments

Comments
 (0)