Skip to content

Simplify Condition Resolution #6547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion include/swift/AST/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "swift/AST/ParameterList.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/StmtTransformer.h"
#include "swift/AST/Types.h"
#include "swift/AST/TypeRepr.h"

Expand Down
14 changes: 2 additions & 12 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,12 +587,8 @@ class alignas(1 << DeclAlignInBits) Decl {

/// Whether this decl is missing its closing '#endif'.
unsigned HadMissingEnd : 1;

/// Whether this condition has been resolved either statically by Parse or
/// later by Condition Resolution.
unsigned HasBeenResolved : 1;
};
enum { NumIfConfigDeclBits = NumDeclBits + 2 };
enum { NumIfConfigDeclBits = NumDeclBits + 1 };
static_assert(NumIfConfigDeclBits <= 32, "fits in an unsigned");

protected:
Expand Down Expand Up @@ -1935,8 +1931,7 @@ struct IfConfigDeclClause {

IfConfigDeclClause(SourceLoc Loc, Expr *Cond, ArrayRef<Decl*> Members,
bool isActive)
: Loc(Loc), Cond(Cond), Members(Members), isActive(isActive) {
}
: Loc(Loc), Cond(Cond), Members(Members), isActive(isActive) {}
};


Expand All @@ -1949,15 +1944,13 @@ class IfConfigDecl : public Decl {
/// The array is ASTContext allocated.
ArrayRef<IfConfigDeclClause> Clauses;
SourceLoc EndLoc;

public:

IfConfigDecl(DeclContext *Parent, ArrayRef<IfConfigDeclClause> Clauses,
SourceLoc EndLoc, bool HadMissingEnd)
: Decl(DeclKind::IfConfig, Parent), Clauses(Clauses), EndLoc(EndLoc)
{
IfConfigDeclBits.HadMissingEnd = HadMissingEnd;
IfConfigDeclBits.HasBeenResolved = false;
}

ArrayRef<IfConfigDeclClause> getClauses() const { return Clauses; }
Expand All @@ -1974,9 +1967,6 @@ class IfConfigDecl : public Decl {
return Clause->Members;
return {};
}

bool isResolved() const { return IfConfigDeclBits.HasBeenResolved; }
void setResolved() { IfConfigDeclBits.HasBeenResolved = true; }

SourceLoc getEndLoc() const { return EndLoc; }
SourceLoc getLoc() const { return Clauses[0].Loc; }
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,7 @@ ERROR(unsupported_conditional_compilation_unary_expression,none,
"expected unary '!' expression", ())
ERROR(unsupported_platform_condition_expression,none,
"unexpected platform condition "
"(expected 'canImport', 'os', 'arch', or 'swift')",
"(expected 'os', 'arch', or 'swift')",
())
ERROR(platform_condition_expected_one_argument,none,
"expected only one argument to platform condition",
Expand Down
4 changes: 0 additions & 4 deletions include/swift/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ class IfConfigStmt : public Stmt {
ArrayRef<IfConfigStmtClause> Clauses;
SourceLoc EndLoc;
bool HadMissingEnd;
bool HasBeenResolved = false;

public:
IfConfigStmt(ArrayRef<IfConfigStmtClause> Clauses, SourceLoc EndLoc,
Expand All @@ -699,9 +698,6 @@ class IfConfigStmt : public Stmt {
SourceLoc getEndLoc() const { return EndLoc; }

bool hadMissingEnd() const { return HadMissingEnd; }

bool isResolved() { return HasBeenResolved; }
void setResolved() { HasBeenResolved = true; }

const ArrayRef<IfConfigStmtClause> &getClauses() const { return Clauses; }

Expand Down
70 changes: 0 additions & 70 deletions include/swift/AST/StmtTransformer.h

This file was deleted.

23 changes: 9 additions & 14 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,10 @@ namespace swift {
TopLevelCode,
/// The top-level of a file, when in parse-as-library mode.
TopLevelLibrary,
/// The body of the clause of an #if/#else/#endif block
ConditionalBlock,
/// The body of the clause of an #if/#else/#endif block that was statically
/// determined to be inactive.
StaticallyInactiveConditionalBlock,
/// The body of the inactive clause of an #if/#else/#endif block
InactiveConditionalBlock,
/// The body of the active clause of an #if/#else/#endif block
ActiveConditionalBlock,
};


Expand Down Expand Up @@ -620,10 +619,6 @@ class Parser {
BraceItemListKind::Brace);
ParserResult<BraceStmt> parseBraceItemList(Diag<> ID);

void parseIfConfigClauseElements(bool isInactive,
BraceItemListKind Kind,
SmallVectorImpl<ASTNode> &Elements);

void parseTopLevelCodeDeclDelayed();

//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -1231,13 +1226,13 @@ class Parser {
ParserResult<CaseStmt> parseStmtCase();

/// Classify the condition of an #if directive according to whether it can
/// be evaluated statically. If evaluation is not possible, the result is
/// 'None'.
static Optional<bool>
/// be evaluated statically. The first member of the pair indicates whether
/// parsing of the condition body should occur, the second contains the result
/// of evaluating the conditional expression.
static ConditionalCompilationExprState
classifyConditionalCompilationExpr(Expr *condition,
ASTContext &context,
DiagnosticEngine &diags,
bool fullCheck = false);
DiagnosticEngine &diags);

//===--------------------------------------------------------------------===//
// Generics Parsing
Expand Down
69 changes: 69 additions & 0 deletions include/swift/Parse/ParserResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,75 @@ template <typename T> ParserResult<T>::ParserResult(ParserStatus Status) {
setHasCodeCompletion();
}

enum class ConditionalCompilationExprKind {
Unknown,
Error,
OS,
Arch,
LanguageVersion,
CompilerVersion,
Binary,
Paren,
DeclRef,
Boolean,
Integer,
Import,
};

class ConditionalCompilationExprState {

uint8_t ConditionActive : 1;
uint8_t Kind : 7;
public:
ConditionalCompilationExprState() : ConditionActive(false) {
setKind(ConditionalCompilationExprKind::Unknown);
}

ConditionalCompilationExprState(bool ConditionActive,
ConditionalCompilationExprKind Kind)
: ConditionActive(ConditionActive) {
setKind(Kind);
}

bool isConditionActive() const {
return ConditionActive;
}

void setConditionActive(bool A) {
ConditionActive = A;
}

ConditionalCompilationExprKind getKind() const {
return static_cast<ConditionalCompilationExprKind>(Kind);
}

void setKind(ConditionalCompilationExprKind K) {
Kind = static_cast<uint8_t>(K);
assert(getKind() == K);
}

bool shouldParse() const {
if (getKind() == ConditionalCompilationExprKind::Error)
return true;
return ConditionActive ||
(getKind() != ConditionalCompilationExprKind::CompilerVersion &&
getKind() != ConditionalCompilationExprKind::LanguageVersion);
}

static ConditionalCompilationExprState error() {
return {false, ConditionalCompilationExprKind::Error};
}
};

ConditionalCompilationExprState
operator&&(const ConditionalCompilationExprState lhs,
const ConditionalCompilationExprState rhs);
ConditionalCompilationExprState
operator||(const ConditionalCompilationExprState lhs,
const ConditionalCompilationExprState rhs);
ConditionalCompilationExprState
operator!(const ConditionalCompilationExprState Result);

} // namespace swift

#endif // LLVM_SWIFT_PARSER_PARSER_RESULT_H
Expand Down
28 changes: 11 additions & 17 deletions include/swift/Parse/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class ScopeInfo {
/// scope.
void addToScope(ValueDecl *D, Parser &TheParser);

bool isStaticallyInactiveConfigBlock() const;
bool isInactiveConfigBlock() const;

SavedScope saveCurrentScope();
};
Expand Down Expand Up @@ -91,7 +91,7 @@ class SavedScope {
ScopeInfo::ScopedHTDetachedScopeTy HTDetachedScope;
unsigned Depth;
ScopeKind Kind;
bool IsStaticallyInactiveConfigBlock;
bool IsInactiveConfigBlock;

SavedScope() = delete;
SavedScope(const SavedScope &) = delete;
Expand All @@ -103,9 +103,9 @@ class SavedScope {
~SavedScope() = default;

SavedScope(ScopeInfo::ScopedHTDetachedScopeTy &&HTDetachedScope,
unsigned Depth, ScopeKind Kind, bool IsStaticallyInactiveConfigBlock)
unsigned Depth, ScopeKind Kind, bool isInactiveConfigBlock)
: HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind),
IsStaticallyInactiveConfigBlock(IsStaticallyInactiveConfigBlock) {}
IsInactiveConfigBlock(isInactiveConfigBlock) {}
};

/// Scope - This class represents lexical scopes. These objects are created
Expand All @@ -125,13 +125,12 @@ class Scope {
unsigned PrevResolvableDepth;
unsigned Depth;
ScopeKind Kind;
bool IsStaticallyInactiveConfigBlock;
bool IsInactiveConfigBlock;

/// \brief Save this scope so that it can be re-entered later. Transfers the
/// ownership of the scope frame to returned object.
SavedScope saveScope() {
return SavedScope(HTScope.detach(), Depth, Kind,
IsStaticallyInactiveConfigBlock);
return SavedScope(HTScope.detach(), Depth, Kind, IsInactiveConfigBlock);
}

unsigned getDepth() const {
Expand All @@ -142,7 +141,7 @@ class Scope {

public:
/// \brief Create a lexical scope of the specified kind.
Scope(Parser *P, ScopeKind SC, bool IsStaticallyInactiveConfigBlock = false);
Scope(Parser *P, ScopeKind SC, bool isInactiveConfigBlock = false);

/// \brief Re-enter the specified scope, transferring the ownership of the
/// scope frame to the new object.
Expand Down Expand Up @@ -175,15 +174,10 @@ inline ValueDecl *ScopeInfo::lookupValueName(DeclName Name) {
return Res.second;
}

inline bool ScopeInfo::isStaticallyInactiveConfigBlock() const {
auto scope = CurScope;
while (scope) {
if (scope->IsStaticallyInactiveConfigBlock) {
return true;
}
scope = scope->PrevScope;
}
return false;
inline bool ScopeInfo::isInactiveConfigBlock() const {
if (!CurScope)
return false;
return CurScope->IsInactiveConfigBlock;
}

inline SavedScope ScopeInfo::saveCurrentScope() {
Expand Down
9 changes: 0 additions & 9 deletions include/swift/Subsystems.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,6 @@ namespace swift {
bool TokenizeInterpolatedString = true,
ArrayRef<Token> SplitTokens = ArrayRef<Token>());

/// Once parsing is complete, this walks the AST to resolve condition clauses
/// and other top-level validation.
void performConditionResolution(SourceFile &SF);

/// \brief Finish condition resolution for the bodies of function nodes that
/// were delayed during the first parsing pass.
void performDelayedConditionResolution(Decl *D, SourceFile &BSF,
SmallVectorImpl<Decl *> &ExtraTLCDs);

/// Once parsing is complete, this walks the AST to resolve imports, record
/// operators, and do other top-level validation.
///
Expand Down
1 change: 0 additions & 1 deletion lib/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ add_swift_library(swiftAST STATIC
RawComment.cpp
SILLayout.cpp
Stmt.cpp
StmtTransformer.cpp
SourceEntityWalker.cpp
Substitution.cpp
SubstitutionMap.cpp
Expand Down
Loading