Skip to content

[AST] Eliminate IfConfigStmt #9413

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
merged 5 commits into from
Jun 16, 2017
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
18 changes: 9 additions & 9 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace swift {
class GenericEnvironment;
class ArchetypeType;
class ASTContext;
struct ASTNode;
class ASTPrinter;
class ASTWalker;
class ConstructorDecl;
Expand Down Expand Up @@ -2023,34 +2024,33 @@ class SerializedTopLevelCodeDeclContext : public SerializedLocalDeclContext {
}
};

/// IfConfigDecl - This class represents the declaration-side representation of
/// #if/#else/#endif blocks. Active and inactive block members are stored
/// separately, with the intention being that active members will be handed
/// back to the enclosing declaration.
/// IfConfigDecl - This class represents #if/#else/#endif blocks.
/// Active and inactive block members are stored separately, with the intention
/// being that active members will be handed back to the enclosing context.
class IfConfigDecl : public Decl {
/// An array of clauses controlling each of the #if/#elseif/#else conditions.
/// The array is ASTContext allocated.
ArrayRef<IfConfigClause<Decl *>> Clauses;
ArrayRef<IfConfigClause> Clauses;
SourceLoc EndLoc;
public:

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

ArrayRef<IfConfigClause<Decl *>> getClauses() const { return Clauses; }
ArrayRef<IfConfigClause> getClauses() const { return Clauses; }

/// Return the active clause, or null if there is no active one.
const IfConfigClause<Decl *> *getActiveClause() const {
const IfConfigClause *getActiveClause() const {
for (auto &Clause : Clauses)
if (Clause.isActive) return &Clause;
return nullptr;
}

const ArrayRef<Decl*> getActiveMembers() const {
const ArrayRef<ASTNode> getActiveClauseElements() const {
if (auto *Clause = getActiveClause())
return Clause->Elements;
return {};
Expand Down
8 changes: 4 additions & 4 deletions include/swift/AST/IfConfigClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
namespace swift {
class Expr;
class SourceLoc;
struct ASTNode;

/// This represents one part of a #if block. If the condition field is
/// non-null, then this represents a #if or a #elseif, otherwise it represents
/// an #else block.
template <typename ElemTy>
struct IfConfigClause {
/// The location of the #if, #elseif, or #else keyword.
SourceLoc Loc;
Expand All @@ -36,13 +36,13 @@ struct IfConfigClause {
Expr *Cond;

/// Elements inside the clause
ArrayRef<ElemTy> Elements;
ArrayRef<ASTNode> Elements;

/// True if this is the active clause of the #if block.
bool isActive;

IfConfigClause<ElemTy>(SourceLoc Loc, Expr *Cond,
ArrayRef<ElemTy> Elements, bool isActive)
IfConfigClause(SourceLoc Loc, Expr *Cond,
ArrayRef<ASTNode> Elements, bool isActive)
: Loc(Loc), Cond(Cond), Elements(Elements), isActive(isActive) {
}
};
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ struct PrintOptions {
/// Print all decls that have at least this level of access.
Accessibility AccessibilityFilter = Accessibility::Private;

/// Print IfConfigDecls and IfConfigStmts.
/// Print IfConfigDecls.
bool PrintIfConfig = true;

/// Whether we are printing for sil.
Expand Down
40 changes: 0 additions & 40 deletions include/swift/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,46 +655,6 @@ class GuardStmt : public LabeledConditionalStmt {
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Guard; }
};

/// IfConfigStmt - This class models the statement-side representation of
/// #if/#else/#endif blocks.
class IfConfigStmt : public Stmt {
/// An array of clauses controlling each of the #if/#elseif/#else conditions.
/// The array is ASTContext allocated.
ArrayRef<IfConfigClause<ASTNode>> Clauses;
SourceLoc EndLoc;
bool HadMissingEnd;

public:
IfConfigStmt(ArrayRef<IfConfigClause<ASTNode>> Clauses, SourceLoc EndLoc,
bool HadMissingEnd)
: Stmt(StmtKind::IfConfig, /*implicit=*/false),
Clauses(Clauses), EndLoc(EndLoc), HadMissingEnd(HadMissingEnd) {}

SourceLoc getIfLoc() const { return Clauses[0].Loc; }

SourceLoc getStartLoc() const { return getIfLoc(); }
SourceLoc getEndLoc() const { return EndLoc; }

bool hadMissingEnd() const { return HadMissingEnd; }

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

ArrayRef<ASTNode> getActiveClauseElements() const {
for (auto &Clause : Clauses)
if (Clause.isActive)
return Clause.Elements;
return ArrayRef<ASTNode>();
}

// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *S) {
return S->getKind() == StmtKind::IfConfig;
}
};


/// WhileStmt - while statement. After type-checking, the condition is of
/// type Builtin.Int1.
class WhileStmt : public LabeledConditionalStmt {
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/StmtNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ STMT(Catch, Stmt)
STMT(Break, Stmt)
STMT(Continue, Stmt)
STMT(Fallthrough, Stmt)
STMT(IfConfig, Stmt)
STMT(Fail, Stmt)
STMT(Throw, Stmt)

Expand Down
8 changes: 5 additions & 3 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,11 @@ class Parser {
ParserResult<TypeDecl> parseDeclAssociatedType(ParseDeclOptions Flags,
DeclAttributes &Attributes);

ParserResult<IfConfigDecl> parseDeclIfConfig(ParseDeclOptions Flags);
/// Parse a #if ... #endif directive.
/// Delegate callback function to parse elements in the blocks.
ParserResult<IfConfigDecl> parseIfConfig(
llvm::function_ref<void(SmallVectorImpl<ASTNode> &, bool)> parseElements);

/// Parse a #line/#sourceLocation directive.
/// 'isLine = true' indicates parsing #line instead of #sourcelocation
ParserStatus parseLineDirective(bool isLine = false);
Expand Down Expand Up @@ -1277,8 +1281,6 @@ class Parser {
ParserResult<PoundAvailableInfo> parseStmtConditionPoundAvailable();
ParserResult<Stmt> parseStmtIf(LabeledStmtInfo LabelInfo);
ParserResult<Stmt> parseStmtGuard();
ParserResult<Stmt> parseStmtIfConfig(BraceItemListKind Kind
= BraceItemListKind::Brace);
ParserResult<Stmt> parseStmtWhile(LabeledStmtInfo LabelInfo);
ParserResult<Stmt> parseStmtRepeat(LabeledStmtInfo LabelInfo);
ParserResult<Stmt> parseStmtDo(LabeledStmtInfo LabelInfo);
Expand Down
73 changes: 26 additions & 47 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1030,33 +1030,41 @@ namespace {
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void printASTNodes(const ArrayRef<ASTNode> &Elements, StringRef Name) {
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << "(";
PrintWithColorRAII(OS, ASTNodeColor) << Name;
for (auto Elt : Elements) {
OS << '\n';
if (auto *SubExpr = Elt.dyn_cast<Expr*>())
printRec(SubExpr);
else if (auto *SubStmt = Elt.dyn_cast<Stmt*>())
printRec(SubStmt);
else
printRec(Elt.get<Decl*>());
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitIfConfigDecl(IfConfigDecl *ICD) {
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
OS << "#if_decl\n";
printCommon(ICD, "if_config_decl");
Indent += 2;
for (auto &Clause : ICD->getClauses()) {
OS << '\n';
OS.indent(Indent);
PrintWithColorRAII(OS, StmtColor) << (Clause.Cond ? "#if:" : "#else:");
if (Clause.isActive)
PrintWithColorRAII(OS, DeclModifierColor) << " active";
if (Clause.Cond) {
PrintWithColorRAII(OS, ParenthesisColor) << '(';
OS << "#if:";
if (Clause.isActive) OS << " active";
OS << "\n";
printRec(Clause.Cond);
} else {
OS << '\n';
PrintWithColorRAII(OS, ParenthesisColor) << '(';
OS << "#else:";
if (Clause.isActive) OS << " active";
OS << "\n";
}

for (auto D : Clause.Elements) {
OS << '\n';
printRec(D);
}

PrintWithColorRAII(OS, ParenthesisColor) << ')';
OS << '\n';
Indent += 2;
printASTNodes(Clause.Elements, "elements");
Indent -= 2;
}

Indent -= 2;
Expand Down Expand Up @@ -1416,35 +1424,6 @@ class PrintStmt : public StmtVisitor<PrintStmt> {
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitIfConfigStmt(IfConfigStmt *S) {
printCommon(S, "#if_stmt");
Indent += 2;
for (auto &Clause : S->getClauses()) {
OS << '\n';
OS.indent(Indent);
if (Clause.Cond) {
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, StmtColor) << "#if:";
if (Clause.isActive)
PrintWithColorRAII(OS, DeclModifierColor) << " active";
OS << '\n';
printRec(Clause.Cond);
} else {
PrintWithColorRAII(OS, StmtColor) << "#else";
if (Clause.isActive)
PrintWithColorRAII(OS, DeclModifierColor) << " active";
}

OS << '\n';
Indent += 2;
printASTNodes(Clause.Elements, "elements");
Indent -= 2;
}

Indent -= 2;
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitDoStmt(DoStmt *S) {
printCommon(S, "do_stmt") << '\n';
printRec(S->getBody());
Expand Down
37 changes: 15 additions & 22 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2360,7 +2360,21 @@ void PrintAST::visitTopLevelCodeDecl(TopLevelCodeDecl *decl) {
}

void PrintAST::visitIfConfigDecl(IfConfigDecl *ICD) {
// FIXME: Pretty print #if decls
if (!Options.PrintIfConfig)
return;

for (auto &Clause : ICD->getClauses()) {
if (&Clause == &*ICD->getClauses().begin())
Printer << tok::pound_if << " /* condition */"; // FIXME: print condition
else if (Clause.Cond)
Printer << tok::pound_elseif << " /* condition */"; // FIXME: print condition
else
Printer << tok::pound_else;
printASTNodes(Clause.Elements);
Printer.printNewline();
indent();
}
Printer << tok::pound_endif;
}

void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
Expand Down Expand Up @@ -3267,27 +3281,6 @@ void PrintAST::visitGuardStmt(GuardStmt *stmt) {
visit(stmt->getBody());
}

void PrintAST::visitIfConfigStmt(IfConfigStmt *stmt) {
if (!Options.PrintIfConfig)
return;

for (auto &Clause : stmt->getClauses()) {
if (&Clause == &*stmt->getClauses().begin())
Printer << tok::pound_if << " "; // FIXME: print condition
else if (Clause.Cond)
Printer << tok::pound_elseif << ""; // FIXME: print condition
else
Printer << tok::pound_else;
Printer.printNewline();
if (printASTNodes(Clause.Elements)) {
Printer.printNewline();
indent();
}
}
Printer.printNewline();
Printer << tok::pound_endif;
}

void PrintAST::visitWhileStmt(WhileStmt *stmt) {
Printer << tok::kw_while << " ";
// FIXME: print condition
Expand Down
22 changes: 1 addition & 21 deletions lib/AST/ASTScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,6 @@ static bool hasAccessors(AbstractStorageDecl *asd) {
llvm_unreachable("Unhandled ContinuationKind in switch.");
}

/// Determine whether this is a top-level code declaration that isn't just
/// wrapping an #if.
static bool isRealTopLevelCodeDecl(Decl *decl) {
auto topLevelCode = dyn_cast<TopLevelCodeDecl>(decl);
if (!topLevelCode) return false;

// Drop top-level statements containing just an IfConfigStmt.
// FIXME: The modeling of IfConfig is weird.
auto braceStmt = topLevelCode->getBody();
auto elements = braceStmt->getElements();
if (elements.size() == 1 &&
elements[0].is<Stmt *>() &&
isa<IfConfigStmt>(elements[0].get<Stmt *>()))
return false;

return true;
}

void ASTScope::expand() const {
assert(!isExpanded() && "Already expanded the children of this node");
ASTContext &ctx = getASTContext();
Expand Down Expand Up @@ -313,7 +295,7 @@ void ASTScope::expand() const {

// If the declaration is a top-level code declaration, turn the source
// file into a continuation. We're done.
if (isRealTopLevelCodeDecl(decl)) {
if (isa<TopLevelCodeDecl>(decl)) {
addActiveContinuation(this);
break;
}
Expand Down Expand Up @@ -950,7 +932,6 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
}

case DeclKind::TopLevelCode:
if (!isRealTopLevelCodeDecl(decl)) return nullptr;
return new (ctx) ASTScope(parent, cast<TopLevelCodeDecl>(decl));

case DeclKind::Protocol:
Expand Down Expand Up @@ -1153,7 +1134,6 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Stmt *stmt) {
case StmtKind::Break:
case StmtKind::Continue:
case StmtKind::Fallthrough:
case StmtKind::IfConfig:
case StmtKind::Fail:
case StmtKind::Throw:
// Nothing to do for these statements.
Expand Down
Loading