Skip to content

Commit 72beb9d

Browse files
committed
Extract common code into StmtTransformer
1 parent a060eb5 commit 72beb9d

25 files changed

+844
-848
lines changed

include/swift/AST/AST.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/AST/ParameterList.h"
2828
#include "swift/AST/Pattern.h"
2929
#include "swift/AST/Stmt.h"
30+
#include "swift/AST/StmtTransformer.h"
3031
#include "swift/AST/Types.h"
3132
#include "swift/AST/TypeRepr.h"
3233

include/swift/AST/Decl.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,8 +1929,12 @@ struct IfConfigDeclClause {
19291929

19301930
ArrayRef<Decl*> Members;
19311931

1932-
IfConfigDeclClause(SourceLoc Loc, Expr *Cond, ArrayRef<Decl*> Members)
1933-
: Loc(Loc), Cond(Cond), Members(Members) {
1932+
/// True if this is the active clause of the #if block.
1933+
bool isActive;
1934+
1935+
IfConfigDeclClause(SourceLoc Loc, Expr *Cond, ArrayRef<Decl*> Members,
1936+
bool isActive)
1937+
: Loc(Loc), Cond(Cond), Members(Members), isActive(isActive) {
19341938
}
19351939
};
19361940

@@ -1955,7 +1959,20 @@ class IfConfigDecl : public Decl {
19551959

19561960
ArrayRef<IfConfigDeclClause> getClauses() const { return Clauses; }
19571961

1958-
bool isResolved() { return HasBeenResolved; }
1962+
/// Return the active clause, or null if there is no active one.
1963+
const IfConfigDeclClause *getActiveClause() const {
1964+
for (auto &Clause : Clauses)
1965+
if (Clause.isActive) return &Clause;
1966+
return nullptr;
1967+
}
1968+
1969+
const ArrayRef<Decl*> getActiveMembers() const {
1970+
if (auto *Clause = getActiveClause())
1971+
return Clause->Members;
1972+
return {};
1973+
}
1974+
1975+
bool isResolved() const { return HasBeenResolved; }
19591976
void setResolved() { HasBeenResolved = true; }
19601977

19611978
SourceLoc getEndLoc() const { return EndLoc; }

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,8 @@ ERROR(unsupported_conditional_compilation_binary_expression,none,
13341334
ERROR(unsupported_conditional_compilation_unary_expression,none,
13351335
"expected unary '!' expression", ())
13361336
ERROR(unsupported_platform_condition_expression,none,
1337-
"unexpected platform condition (expected 'os', 'arch', or 'swift')",
1337+
"unexpected platform condition "
1338+
"(expected 'canImport', 'os', 'arch', or 'swift')",
13381339
())
13391340
ERROR(platform_condition_expected_one_argument,none,
13401341
"expected only one argument to platform condition",

include/swift/AST/Module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,13 +831,13 @@ class SourceFile final : public FileUnit {
831831
std::vector<Decl*> Decls;
832832

833833
/// The list of local type declarations in the source file.
834-
SmallPtrSet<TypeDecl *, 4> LocalTypeDecls;
834+
SmallPtrSet<TypeDecl *, 2> LocalTypeDecls;
835835

836836
/// A set of special declaration attributes which require the
837837
/// Foundation module to be imported to work. If the foundation
838838
/// module is still not imported by the time type checking is
839839
/// complete, we diagnose.
840-
std::map<DeclAttrKind, const DeclAttribute *> AttrsRequiringFoundation;
840+
SmallPtrSet<const DeclAttribute *, 4> AttrsRequiringFoundation;
841841

842842
/// A mapping from Objective-C selectors to the methods that have
843843
/// those selectors.

include/swift/AST/Stmt.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -668,30 +668,27 @@ struct IfConfigStmtClause {
668668
/// Elements inside the clause
669669
ArrayRef<ASTNode> Elements;
670670

671-
/// Whether or not name binding has resolved this statement.
672-
bool HasBeenResolved = false;
671+
/// True if this is the active clause of the #if block.
672+
bool isActive;
673673

674674
IfConfigStmtClause(SourceLoc Loc, Expr *Cond,
675-
ArrayRef<ASTNode> Elements)
676-
: Loc(Loc), Cond(Cond), Elements(Elements) {
675+
ArrayRef<ASTNode> Elements, bool isActive)
676+
: Loc(Loc), Cond(Cond), Elements(Elements), isActive(isActive) {
677677
}
678-
679-
public:
680-
bool isResolved() const { return HasBeenResolved; }
681-
void setResolved() { HasBeenResolved = true; }
682678
};
683679

684680
/// IfConfigStmt - This class models the statement-side representation of
685681
/// #if/#else/#endif blocks.
686682
class IfConfigStmt : public Stmt {
687683
/// An array of clauses controlling each of the #if/#elseif/#else conditions.
688684
/// The array is ASTContext allocated.
689-
MutableArrayRef<IfConfigStmtClause> Clauses;
685+
ArrayRef<IfConfigStmtClause> Clauses;
690686
SourceLoc EndLoc;
691687
bool HadMissingEnd;
688+
bool HasBeenResolved = false;
692689

693690
public:
694-
IfConfigStmt(MutableArrayRef<IfConfigStmtClause> Clauses, SourceLoc EndLoc,
691+
IfConfigStmt(ArrayRef<IfConfigStmtClause> Clauses, SourceLoc EndLoc,
695692
bool HadMissingEnd)
696693
: Stmt(StmtKind::IfConfig, /*implicit=*/false),
697694
Clauses(Clauses), EndLoc(EndLoc), HadMissingEnd(HadMissingEnd) {}
@@ -703,7 +700,17 @@ class IfConfigStmt : public Stmt {
703700

704701
bool hadMissingEnd() const { return HadMissingEnd; }
705702

706-
const MutableArrayRef<IfConfigStmtClause> &getClauses() const { return Clauses; }
703+
bool isResolved() { return HasBeenResolved; }
704+
void setResolved() { HasBeenResolved = true; }
705+
706+
const ArrayRef<IfConfigStmtClause> &getClauses() const { return Clauses; }
707+
708+
ArrayRef<ASTNode> getActiveClauseElements() const {
709+
for (auto &Clause : Clauses)
710+
if (Clause.isActive)
711+
return Clause.Elements;
712+
return ArrayRef<ASTNode>();
713+
}
707714

708715
// Implement isa/cast/dyncast/etc.
709716
static bool classof(const Stmt *S) {

include/swift/AST/StmtTransformer.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===--- Stmt.h - Swift Language Statement ASTs -----------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the StmtTransformer class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_STMTTRANSFORMER_H
18+
#define SWIFT_AST_STMTTRANSFORMER_H
19+
20+
#include "swift/AST/ASTWalker.h"
21+
#include "swift/AST/Stmt.h"
22+
#include "swift/AST/Expr.h"
23+
24+
#include <forward_list>
25+
26+
namespace swift {
27+
class StmtTransformer {
28+
protected:
29+
class ClosureFinder : public ASTWalker {
30+
StmtTransformer &StmtTrans;
31+
public:
32+
ClosureFinder(StmtTransformer &CCR) : StmtTrans(CCR) { }
33+
virtual std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) {
34+
if (isa<BraceStmt>(S)) {
35+
// To respect nesting, don't walk into brace statements.
36+
return { false, S };
37+
} else {
38+
return { true, S };
39+
}
40+
}
41+
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) {
42+
if (ClosureExpr *CE = dyn_cast<ClosureExpr>(E)) {
43+
BraceStmt *B = CE->getBody();
44+
if (B) {
45+
BraceStmt *NB = StmtTrans.transformBraceStmt(B, false);
46+
CE->setBody(NB, CE->hasSingleExpressionBody());
47+
}
48+
}
49+
return { true, E };
50+
}
51+
};
52+
ClosureFinder CF;
53+
54+
public:
55+
StmtTransformer() : CF(*this) {}
56+
virtual ~StmtTransformer() {}
57+
58+
const ASTWalker &getClosureFinder() const {
59+
return CF;
60+
}
61+
62+
virtual Stmt *transformStmt(Stmt *S);
63+
virtual BraceStmt *transformBraceStmt(BraceStmt *BS, bool TopLevel);
64+
#define STMT(CLASS, PARENT) \
65+
virtual CLASS##Stmt *transform##CLASS##Stmt(CLASS##Stmt *S);
66+
#include "swift/AST/StmtNodes.def"
67+
};
68+
};
69+
70+
#endif /* SWIFT_AST_STMTTRANSFORMER_H */

include/swift/Parse/Parser.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ namespace swift {
6161
TopLevelLibrary,
6262
/// The body of the clause of an #if/#else/#endif block
6363
ConditionalBlock,
64+
/// The body of the clause of an #if/#else/#endif block that was statically
65+
/// determined to be inactive.
66+
StaticallyInactiveConditionalBlock,
6467
};
6568

6669

@@ -615,9 +618,10 @@ class Parser {
615618
BraceItemListKind::Brace,
616619
BraceItemListKind ConditionalBlockKind =
617620
BraceItemListKind::Brace);
618-
ParserResult<BraceStmt> parseBraceItemList(Diag<> ID, bool inConfig = false);
621+
ParserResult<BraceStmt> parseBraceItemList(Diag<> ID);
619622

620-
void parseIfConfigClauseElements(BraceItemListKind Kind,
623+
void parseIfConfigClauseElements(bool isInactive,
624+
BraceItemListKind Kind,
621625
SmallVectorImpl<ASTNode> &Elements);
622626

623627
void parseTopLevelCodeDeclDelayed();
@@ -644,7 +648,6 @@ class Parser {
644648
PD_InStruct = 1 << 9,
645649
PD_InEnum = 1 << 10,
646650
PD_InLoop = 1 << 11,
647-
PD_InIfConfig = 1 << 12,
648651
};
649652

650653
/// Options that control the parsing of declarations.
@@ -693,7 +696,7 @@ class Parser {
693696
/// 'isLine = true' indicates parsing #line instead of #sourcelocation
694697
ParserStatus parseLineDirective(bool isLine = false);
695698

696-
void setLocalDiscriminator(ParseDeclOptions Flags, ValueDecl *D);
699+
void setLocalDiscriminator(ValueDecl *D);
697700

698701
/// Parse the optional attributes before a declaration.
699702
bool parseDeclAttributeList(DeclAttributes &Attributes,
@@ -1227,9 +1230,14 @@ class Parser {
12271230
ParserResult<Stmt> parseStmtSwitch(LabeledStmtInfo LabelInfo);
12281231
ParserResult<CaseStmt> parseStmtCase();
12291232

1230-
/// Classify the condition of an #if directive.
1231-
ConditionalCompilationExprKind
1232-
classifyConditionalCompilationExpr(Expr *condition);
1233+
/// Classify the condition of an #if directive according to whether it can
1234+
/// be evaluated statically. If evaluation is not possible, the result is
1235+
/// 'None'.
1236+
static Optional<bool>
1237+
classifyConditionalCompilationExpr(Expr *condition,
1238+
ASTContext &context,
1239+
DiagnosticEngine &diags,
1240+
bool fullCheck = false);
12331241

12341242
//===--------------------------------------------------------------------===//
12351243
// Generics Parsing

include/swift/Parse/ParserResult.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,6 @@ template <typename T> ParserResult<T>::ParserResult(ParserStatus Status) {
217217
setHasCodeCompletion();
218218
}
219219

220-
enum class ConditionalCompilationExprKind {
221-
Unknown,
222-
Error,
223-
OS,
224-
Arch,
225-
LanguageVersion,
226-
CompilerVersion,
227-
Binary,
228-
Paren,
229-
DeclRef,
230-
Boolean,
231-
Integer
232-
};
233-
234220
} // namespace swift
235221

236222
#endif // LLVM_SWIFT_PARSER_PARSER_RESULT_H

include/swift/Parse/Scope.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class ScopeInfo {
5454
/// scope.
5555
void addToScope(ValueDecl *D, Parser &TheParser);
5656

57+
bool isStaticallyInactiveConfigBlock() const;
58+
5759
SavedScope saveCurrentScope();
5860
};
5961

@@ -89,6 +91,7 @@ class SavedScope {
8991
ScopeInfo::ScopedHTDetachedScopeTy HTDetachedScope;
9092
unsigned Depth;
9193
ScopeKind Kind;
94+
bool IsStaticallyInactiveConfigBlock;
9295

9396
SavedScope() = delete;
9497
SavedScope(const SavedScope &) = delete;
@@ -100,8 +103,9 @@ class SavedScope {
100103
~SavedScope() = default;
101104

102105
SavedScope(ScopeInfo::ScopedHTDetachedScopeTy &&HTDetachedScope,
103-
unsigned Depth, ScopeKind Kind)
104-
: HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind) {}
106+
unsigned Depth, ScopeKind Kind, bool IsStaticallyInactiveConfigBlock)
107+
: HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind),
108+
IsStaticallyInactiveConfigBlock(IsStaticallyInactiveConfigBlock) {}
105109
};
106110

107111
/// Scope - This class represents lexical scopes. These objects are created
@@ -121,11 +125,13 @@ class Scope {
121125
unsigned PrevResolvableDepth;
122126
unsigned Depth;
123127
ScopeKind Kind;
128+
bool IsStaticallyInactiveConfigBlock;
124129

125130
/// \brief Save this scope so that it can be re-entered later. Transfers the
126131
/// ownership of the scope frame to returned object.
127132
SavedScope saveScope() {
128-
return SavedScope(HTScope.detach(), Depth, Kind);
133+
return SavedScope(HTScope.detach(), Depth, Kind,
134+
IsStaticallyInactiveConfigBlock);
129135
}
130136

131137
unsigned getDepth() const {
@@ -136,7 +142,7 @@ class Scope {
136142

137143
public:
138144
/// \brief Create a lexical scope of the specified kind.
139-
Scope(Parser *P, ScopeKind SC);
145+
Scope(Parser *P, ScopeKind SC, bool IsStaticallyInactiveConfigBlock = false);
140146

141147
/// \brief Re-enter the specified scope, transferring the ownership of the
142148
/// scope frame to the new object.
@@ -169,6 +175,17 @@ inline ValueDecl *ScopeInfo::lookupValueName(DeclName Name) {
169175
return Res.second;
170176
}
171177

178+
inline bool ScopeInfo::isStaticallyInactiveConfigBlock() const {
179+
auto scope = CurScope;
180+
while (scope) {
181+
if (scope->IsStaticallyInactiveConfigBlock) {
182+
return true;
183+
}
184+
scope = scope->PrevScope;
185+
}
186+
return false;
187+
}
188+
172189
inline SavedScope ScopeInfo::saveCurrentScope() {
173190
return CurScope->saveScope();
174191
}

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,18 +1877,11 @@ void ASTContext::diagnoseAttrsRequiringFoundation(SourceFile &SF) {
18771877
if (ImportsFoundationModule)
18781878
return;
18791879

1880-
for (auto &Attr : SF.AttrsRequiringFoundation) {
1881-
// If we've already diagnosed this attribute, keep going.
1882-
if (!Attr.second)
1883-
continue;
1884-
1885-
Diags.diagnose(Attr.second->getLocation(),
1880+
for (auto Attr : SF.AttrsRequiringFoundation) {
1881+
Diags.diagnose(Attr->getLocation(),
18861882
diag::attr_used_without_required_module,
1887-
Attr.second, Id_Foundation)
1888-
.highlight(Attr.second->getRangeWithAt());
1889-
1890-
// Don't diagnose this again.
1891-
Attr.second = nullptr;
1883+
Attr, Id_Foundation)
1884+
.highlight(Attr->getRangeWithAt());
18921885
}
18931886
}
18941887

lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_swift_library(swiftAST STATIC
3939
RawComment.cpp
4040
SILLayout.cpp
4141
Stmt.cpp
42+
StmtTransformer.cpp
4243
SourceEntityWalker.cpp
4344
Substitution.cpp
4445
SubstitutionMap.cpp

0 commit comments

Comments
 (0)