diff options
Diffstat (limited to 'clang/include/clang')
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 6 | ||||
| -rw-r--r-- | clang/include/clang/AST/Stmt.h | 35 | ||||
| -rw-r--r-- | clang/include/clang/Basic/StmtNodes.td | 10 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Parser.h | 68 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 3 |
5 files changed, 80 insertions, 42 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 4fec8efd2dc..95804173c8f 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -105,13 +105,13 @@ struct SubobjectAdjustment { /// This represents one expression. Note that Expr's are subclasses of Stmt. /// This allows an expression to be transparently used any place a Stmt is /// required. -class Expr : public Stmt { +class Expr : public ValueStmt { QualType TR; protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : Stmt(SC) + : ValueStmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; @@ -124,7 +124,7 @@ protected: } /// Construct an empty expression. - explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } + explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { } public: QualType getType() const { return TR; } diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index b892d852060..e63354c2631 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1584,21 +1584,44 @@ Stmt *SwitchCase::getSubStmt() { llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!"); } +/// Represents a statement that could possibly have a value and type. This +/// covers expression-statements, as well as labels and attributed statements. +/// +/// Value statements have a special meaning when they are the last non-null +/// statement in a GNU statement expression, where they determine the value +/// of the statement expression. +class ValueStmt : public Stmt { +protected: + using Stmt::Stmt; + +public: + const Expr *getExprStmt() const; + Expr *getExprStmt() { + const ValueStmt *ConstThis = this; + return const_cast<Expr*>(ConstThis->getExprStmt()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() >= firstValueStmtConstant && + T->getStmtClass() <= lastValueStmtConstant; + } +}; + /// LabelStmt - Represents a label, which has a substatement. For example: /// foo: return; -class LabelStmt : public Stmt { +class LabelStmt : public ValueStmt { LabelDecl *TheDecl; Stmt *SubStmt; public: /// Build a label statement. LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) - : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { + : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { setIdentLoc(IL); } /// Build an empty label statement. - explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {} + explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {} SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; } void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; } @@ -1627,7 +1650,7 @@ public: /// Represents an attribute applied to a statement. For example: /// [[omp::for(...)]] for (...) { ... } class AttributedStmt final - : public Stmt, + : public ValueStmt, private llvm::TrailingObjects<AttributedStmt, const Attr *> { friend class ASTStmtReader; friend TrailingObjects; @@ -1636,14 +1659,14 @@ class AttributedStmt final AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs, Stmt *SubStmt) - : Stmt(AttributedStmtClass), SubStmt(SubStmt) { + : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) { AttributedStmtBits.NumAttrs = Attrs.size(); AttributedStmtBits.AttrLoc = Loc; std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr()); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) - : Stmt(AttributedStmtClass, Empty) { + : ValueStmt(AttributedStmtClass, Empty) { AttributedStmtBits.NumAttrs = NumAttrs; AttributedStmtBits.AttrLoc = SourceLocation{}; std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr); diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 9054fb11a6f..2dbbee7bbfc 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -11,8 +11,6 @@ class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> { // Statements def NullStmt : Stmt; def CompoundStmt : Stmt; -def LabelStmt : Stmt; -def AttributedStmt : Stmt; def IfStmt : Stmt; def SwitchStmt : Stmt; def WhileStmt : Stmt; @@ -29,6 +27,12 @@ def CaseStmt : DStmt<SwitchCase>; def DefaultStmt : DStmt<SwitchCase>; def CapturedStmt : Stmt; +// Statements that might produce a value (for example, as the last non-null +// statement in a GNU statement-expression). +def ValueStmt : Stmt<1>; +def LabelStmt : DStmt<ValueStmt>; +def AttributedStmt : DStmt<ValueStmt>; + // Asm statements def AsmStmt : Stmt<1>; def GCCAsmStmt : DStmt<AsmStmt>; @@ -53,7 +57,7 @@ def CoroutineBodyStmt : Stmt; def CoreturnStmt : Stmt; // Expressions -def Expr : Stmt<1>; +def Expr : DStmt<ValueStmt, 1>; def PredefinedExpr : DStmt<Expr>; def DeclRefExpr : DStmt<Expr>; def IntegerLiteral : DStmt<Expr>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index f5c70e71b8a..db0217324b6 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -363,10 +363,28 @@ class Parser : public CodeCompletionHandler { /// just a regular sub-expression. SourceLocation ExprStatementTokLoc; - /// Tests whether an expression value is discarded based on token lookahead. - /// It will return true if the lexer is currently processing the }) - /// terminating a GNU statement expression and false otherwise. - bool isExprValueDiscarded(); + /// Flags describing a context in which we're parsing a statement. + enum class ParsedStmtContext { + /// This context permits declarations in language modes where declarations + /// are not statements. + AllowDeclarationsInC = 0x1, + /// This context permits standalone OpenMP directives. + AllowStandaloneOpenMPDirectives = 0x2, + /// This context is at the top level of a GNU statement expression. + InStmtExpr = 0x4, + + /// The context of a regular substatement. + SubStmt = 0, + /// The context of a compound-statement. + Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives, + + LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr) + }; + + /// Act on an expression statement that might be the last statement in a + /// GNU statement expression. Checks whether we are actually at the end of + /// a statement expression and builds a suitable expression statement. + StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx); public: Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); @@ -1873,29 +1891,24 @@ private: /// A SmallVector of types. typedef SmallVector<ParsedType, 12> TypeVector; - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr, - bool AllowOpenMPStandalone = false); - enum AllowedConstructsKind { - /// Allow any declarations, statements, OpenMP directives. - ACK_Any, - /// Allow only statements and non-standalone OpenMP directives. - ACK_StatementsOpenMPNonStandalone, - /// Allow statements and all executable OpenMP directives - ACK_StatementsOpenMPAnyExecutable - }; StmtResult - ParseStatementOrDeclaration(StmtVector &Stmts, AllowedConstructsKind Allowed, - SourceLocation *TrailingElseLoc = nullptr); + ParseStatement(SourceLocation *TrailingElseLoc = nullptr, + ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt); + StmtResult ParseStatementOrDeclaration( + StmtVector &Stmts, ParsedStmtContext StmtCtx, + SourceLocation *TrailingElseLoc = nullptr); StmtResult ParseStatementOrDeclarationAfterAttributes( StmtVector &Stmts, - AllowedConstructsKind Allowed, + ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs); - StmtResult ParseExprStatement(); - StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs); - StmtResult ParseCaseStatement(bool MissingCase = false, + StmtResult ParseExprStatement(ParsedStmtContext StmtCtx); + StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs, + ParsedStmtContext StmtCtx); + StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx, + bool MissingCase = false, ExprResult Expr = ExprResult()); - StmtResult ParseDefaultStatement(); + StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx); StmtResult ParseCompoundStatement(bool isStmtExpr = false); StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags); @@ -1918,7 +1931,7 @@ private: StmtResult ParseAsmStatement(bool &msAsm); StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); StmtResult ParsePragmaLoopHint(StmtVector &Stmts, - AllowedConstructsKind Allowed, + ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs); @@ -1984,7 +1997,8 @@ private: //===--------------------------------------------------------------------===// // Objective-C Statements - StmtResult ParseObjCAtStatement(SourceLocation atLoc); + StmtResult ParseObjCAtStatement(SourceLocation atLoc, + ParsedStmtContext StmtCtx); StmtResult ParseObjCTryStmt(SourceLocation atLoc); StmtResult ParseObjCThrowStmt(SourceLocation atLoc); StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc); @@ -2824,13 +2838,9 @@ private: bool AllowScopeSpecifier); /// Parses declarative or executable directive. /// - /// \param Allowed ACK_Any, if any directives are allowed, - /// ACK_StatementsOpenMPAnyExecutable - if any executable directives are - /// allowed, ACK_StatementsOpenMPNonStandalone - if only non-standalone - /// executable directives are allowed. - /// + /// \param StmtCtx The context in which we're parsing the directive. StmtResult - ParseOpenMPDeclarativeOrExecutableDirective(AllowedConstructsKind Allowed); + ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx); /// Parses clause of kind \a CKind for directive of a kind \a Kind. /// /// \param DKind Kind of current directive. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 0c2479a0207..10eff5333fe 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1403,7 +1403,6 @@ public: void PopCompoundScope(); sema::CompoundScopeInfo &getCurCompoundScope() const; - bool isCurCompoundStmtAStmtExpr() const; bool hasAnyUnrecoverableErrorsInThisFunction() const; @@ -4533,6 +4532,8 @@ public: void ActOnStartStmtExpr(); ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc); // "({..})" + // Handle the final expression in a statement expression. + ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); // __builtin_offsetof(type, identifier(.identifier|[expr])*) |

