// Lex.
class Preprocessor;
class Token;
- // Basic.
- class DiagnosticBuilder;
/// Action - As the parser reads the input file and recognizes the productions
/// of the grammar, it invokes methods on this class to turn the parsed input
namespace clang
{
+ // Basic
class DiagnosticBuilder;
/// ActionBase - A small part split from Action because of the horrible
}
public:
+ typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
+
// For convenience and compatibility.
ASTOwningResult(bool invalid = false)
: Actions(0), Node(0), Invalid(invalid) {}
: Actions(&actions), Node(0), Invalid(invalid) {}
ASTOwningResult(ActionBase &actions, void *node)
: Actions(&actions), Node(node), Invalid(false) {}
+ ASTOwningResult(ActionBase &actions, const DumbResult &res)
+ : Actions(&actions), Node(res.Val), Invalid(res.isInvalid) {}
/// Move from another owning result
ASTOwningResult(ASTResultMover<Destroyer> mover)
: Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {}
}
/// Assignment from an ActionResult. Takes ownership - beware!
- ASTOwningResult & operator =(
- const ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> &res) {
+ ASTOwningResult & operator =(const DumbResult &res) {
assert((!res.Val || Actions) &&
"Cannot assign from ActionResult when there's no Action");
Node = res.Val;
return Moved.take();
}
+ template <ASTDestroyer Destroyer> inline
+ ASTResultMover<Destroyer>::operator
+ ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID>()
+ {
+ if(Moved.isInvalid())
+ return true;
+ return Moved.take();
+ }
+
template <ASTDestroyer Destroyer> inline
ASTPtrMover<Destroyer>::operator void*() {
return Moved.take();
typedef Action::MemInitTy MemInitTy;
typedef Action::CXXScopeTy CXXScopeTy;
+ typedef Action::ExprResult ExprResult;
+ typedef Action::StmtResult StmtResult;
+ typedef Action::BaseResult BaseResult;
+ typedef Action::MemInitResult MemInitResult;
+
+ typedef Action::OwningExprResult OwningExprResult;
+ typedef Action::OwningStmtResult OwningStmtResult;
+
// Parsing methods.
/// ParseTranslationUnit - All in one method that initializes parses, and
//===--------------------------------------------------------------------===//
// Diagnostic Emission and Error recovery.
-
+
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
-
+
/// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is true). Because we cannot guarantee that the
/// token will ever occur, this skips to the next token, or to some likely
}
bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
bool StopAtSemi = true, bool DontConsume = false);
-
- typedef Action::ExprResult ExprResult;
- typedef Action::StmtResult StmtResult;
- typedef Action::BaseResult BaseResult;
- typedef Action::MemInitResult MemInitResult;
//===--------------------------------------------------------------------===//
// Lexing and parsing of C++ inline methods.
namespace clang
{
- template <void (ActionBase::*Destroyer)(void*)>
- class ASTOwner;
-
- typedef ASTOwner<&ActionBase::DeleteStmt> StmtOwner;
- typedef ASTOwner<&ActionBase::DeleteExpr> ExprOwner;
-
- /// Some trickery to switch between an ActionResult and an ASTOwner
- template <typename Owner> struct ResultOfOwner;
- template <> struct ResultOfOwner<StmtOwner> {
- typedef Action::StmtResult type;
- };
- template <> struct ResultOfOwner<ExprOwner> {
- typedef Action::ExprResult type;
- };
-
- /// Move emulation helper for ASTOwner. Implicitly convertible to ActionResult
- /// and void*, which means ASTOwner::move() can be used universally.
- template <void (ActionBase::*Destroyer)(void*)>
- class ASTMove {
- ASTOwner<Destroyer> &Moved;
-
- public:
- explicit ASTMove(ASTOwner<Destroyer> &moved) : Moved(moved) {}
- ASTOwner<Destroyer> * operator ->() {
- return &Moved;
- }
-
- /// Allow moving from ASTOwner to ActionResult
- operator typename ResultOfOwner< ASTOwner<Destroyer> >::type() {
- if (Moved.isInvalid())
- return true;
- return Moved.take();
- }
-
- /// Allow moving from ASTOwner to void*
- operator void*() {
- if (Moved.isInvalid())
- return 0;
- return Moved.take();
- }
- };
-
- /// RAII owning pointer for StmtTys and ExprTys. Simple move emulation.
- template <void (ActionBase::*Destroyer)(void*)>
- class ASTOwner {
- typedef typename ResultOfOwner<ASTOwner>::type Result;
-
- Action &Actions;
- void *Node;
- bool Invalid;
-
- void destroy() {
- if (Node)
- (Actions.*Destroyer)(Node);
- }
-
- ASTOwner(const ASTOwner&); // DO NOT IMPLEMENT
- // Reference member prevents copy assignment.
-
- public:
- explicit ASTOwner(Action &actions, bool invalid = false)
- : Actions(actions), Node(0), Invalid(invalid) {}
- ASTOwner(Action &actions, void *node)
- : Actions(actions), Node(node), Invalid(false) {}
- ASTOwner(Action &actions, const Result &res)
- : Actions(actions), Node(res.Val), Invalid(res.isInvalid) {}
- /// Move constructor
- ASTOwner(ASTMove<Destroyer> mover)
- : Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {}
- /// Move assignment
- ASTOwner & operator =(ASTMove<Destroyer> mover) {
- assert(&Actions == &mover->Actions &&
- "AST Owners from different actions.");
- destroy();
- Node = mover->take();
- Invalid = mover->Invalid;
- return *this;
- }
- /// Convenience, for better syntax. reset() is so ugly. Just remember that
- /// this takes ownership.
- ASTOwner & operator =(const Result &res) {
- reset(res);
- return *this;
- }
-
- void reset(void *node = 0) {
- destroy();
- Node = node;
- Invalid = false;
- }
- void reset(const Result &res) {
- destroy();
- Node = res.Val;
- Invalid = res.isInvalid;
- }
- /// Take ownership from this pointer and return the node. Calling move() is
- /// better.
- void *take() {
- void *Temp = Node;
- Node = 0;
- return Temp;
- }
- void *get() const { return Node; }
- bool isInvalid() const { return Invalid; }
- /// Does this point to a usable AST node? To be usable, the node must be
- /// valid and non-null.
- bool isUsable() const { return !Invalid && Node; }
-
- ASTMove<Destroyer> move() {
- return ASTMove<Destroyer>(*this);
- }
- };
-
/// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
/// automatically freeing them on destruction unless it's been disowned.
/// Instantiated for statements and expressions (Action::DeleteStmt and
// now parse the non-empty comma separated list of expressions
while (1) {
- ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+ OwningExprResult ArgExpr(Actions, ParseAssignmentExpression());
if (ArgExpr.isInvalid()) {
ArgExprsOk = false;
SkipUntil(tok::r_paren);
// now parse the list of expressions
while (1) {
- ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+ OwningExprResult ArgExpr(Actions, ParseAssignmentExpression());
if (ArgExpr.isInvalid()) {
ArgExprsOk = false;
SkipUntil(tok::r_paren);
while (1) {
// If a simple-asm-expr is present, parse it.
if (Tok.is(tok::kw_asm)) {
- ExprOwner AsmLabel(Actions, ParseSimpleAsm());
+ OwningExprResult AsmLabel(Actions, ParseSimpleAsm());
if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi);
return 0;
// Parse declarator '=' initializer.
if (Tok.is(tok::equal)) {
ConsumeToken();
- ExprOwner Init(Actions, ParseInitializer());
+ OwningExprResult Init(Actions, ParseInitializer());
if (Init.isInvalid()) {
SkipUntil(tok::semi);
return 0;
if (Tok.is(tok::colon)) {
ConsumeToken();
- ExprOwner Res(Actions, ParseConstantExpression());
+ OwningExprResult Res(Actions, ParseConstantExpression());
if (Res.isInvalid())
SkipUntil(tok::semi, true, true);
else
SourceLocation IdentLoc = ConsumeToken();
SourceLocation EqualLoc;
- ExprOwner AssignedVal(Actions);
+ OwningExprResult AssignedVal(Actions);
if (Tok.is(tok::equal)) {
EqualLoc = ConsumeToken();
AssignedVal = ParseConstantExpression();
ConsumeToken();
// Parse the default argument
- ExprOwner DefArgResult(Actions, ParseAssignmentExpression());
+ OwningExprResult DefArgResult(Actions, ParseAssignmentExpression());
if (DefArgResult.isInvalid()) {
SkipUntil(tok::comma, tok::r_paren, true, true);
} else {
// Handle "direct-declarator [ type-qual-list[opt] * ]".
bool isStar = false;
- ExprOwner NumElements(Actions);
+ OwningExprResult NumElements(Actions);
// Handle the case where we have '[*]' as the array size. However, a leading
// star could be the start of an expression, for example 'X[*p + 4]'. Verify
return;
}
- ExprOwner Result(Actions, ParseCastExpression(true/*isUnaryExpression*/));
+ OwningExprResult Result(Actions,
+ ParseCastExpression(true/*isUnaryExpression*/));
if (Result.isInvalid())
return;
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
} else { // we have an expression.
- ExprOwner Result(Actions, ParseExpression());
+ OwningExprResult Result(Actions, ParseExpression());
if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
MatchRHSPunctuation(tok::r_paren, LParenLoc);
// member-declarator-list ',' member-declarator
DeclTy *LastDeclInGroup = 0;
- ExprOwner BitfieldSize(Actions);
- ExprOwner Init(Actions);
+ OwningExprResult BitfieldSize(Actions);
+ OwningExprResult Init(Actions);
while (1) {
// Parse the next declarator.
DeclaratorInfo.clear();
- BitfieldSize.reset();
- Init.reset();
+ BitfieldSize = 0;
+ Init = 0;
// Attributes are only allowed on the second declarator.
if (Tok.is(tok::kw___attribute))
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprOwner LHS(Actions, ParseCastExpression(false));
+ OwningExprResult LHS(Actions, ParseCastExpression(false));
if (LHS.isInvalid()) return LHS.move();
return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
/// for example, @encode-expression.
///
Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
- ExprOwner LHS(Actions, ParseObjCAtExpression(AtLoc));
+ OwningExprResult LHS(Actions, ParseObjCAtExpression(AtLoc));
if (LHS.isInvalid()) return LHS.move();
return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprOwner LHS(Actions, ParseCastExpression(false));
+ OwningExprResult LHS(Actions, ParseCastExpression(false));
if (LHS.isInvalid()) return LHS.move();
return ParseRHSOfBinaryExpression(LHS.move(), prec::Assignment);
SourceLocation NameLoc,
IdentifierInfo *ReceiverName,
ExprTy *ReceiverExpr) {
- ExprOwner R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
- ReceiverName,
- ReceiverExpr));
+ OwningExprResult R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
+ ReceiverName,
+ ReceiverExpr));
if (R.isInvalid()) return R.move();
R = ParsePostfixExpressionSuffix(R.move());
if (R.isInvalid()) return R.move();
Parser::ExprResult Parser::ParseConstantExpression() {
- ExprOwner LHS(Actions, ParseCastExpression(false));
+ OwningExprResult LHS(Actions, ParseCastExpression(false));
if (LHS.isInvalid()) return LHS.move();
return ParseRHSOfBinaryExpression(LHS.move(), prec::Conditional);
unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
SourceLocation ColonLoc;
- ExprOwner LHS(Actions, LHSArg);
+ OwningExprResult LHS(Actions, LHSArg);
while (1) {
// If this token has a lower precedence than we are allowed to parse (e.g.
// because we are called recursively, or because the token is not a binop),
ConsumeToken();
// Special case handling for the ternary operator.
- ExprOwner TernaryMiddle(Actions, true);
+ OwningExprResult TernaryMiddle(Actions, true);
if (NextTokPrec == prec::Conditional) {
if (Tok.isNot(tok::colon)) {
// Handle this production specially:
} else {
// Special case handling of "X ? Y : Z" where Y is empty:
// logical-OR-expression '?' ':' conditional-expression [GNU]
- TernaryMiddle.reset();
+ TernaryMiddle = 0;
Diag(Tok, diag::ext_gnu_conditional_expr);
}
}
// Parse another leaf here for the RHS of the operator.
- ExprOwner RHS(Actions, ParseCastExpression(false));
+ OwningExprResult RHS(Actions, ParseCastExpression(false));
if (RHS.isInvalid())
return RHS.move();
TryAnnotateTypeOrScopeToken();
}
- ExprOwner Res(Actions);
+ OwningExprResult Res(Actions);
tok::TokenKind SavedKind = Tok.getKind();
// This handles all of cast-expression, unary-expression, postfix-expression,
/// argument-expression-list ',' assignment-expression
///
Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHSArg) {
- ExprOwner LHS(Actions, LHSArg);
+ OwningExprResult LHS(Actions, LHSArg);
// Now that the primary-expression piece of the postfix-expression has been
// parsed, see if there are any postfix-expression pieces here.
SourceLocation Loc;
return LHS.move();
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
Loc = ConsumeBracket();
- ExprOwner Idx(Actions, ParseExpression());
+ OwningExprResult Idx(Actions, ParseExpression());
SourceLocation RLoc = Tok.getLocation();
ConsumeToken();
// If the operand doesn't start with an '(', it must be an expression.
- ExprOwner Operand(Actions);
+ OwningExprResult Operand(Actions);
if (Tok.isNot(tok::l_paren)) {
Operand = ParseCastExpression(true);
} else {
/// [GNU] offsetof-member-designator '[' expression ']'
///
Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
- ExprOwner Res(Actions);
+ OwningExprResult Res(Actions);
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
tok::TokenKind T = Tok.getKind();
switch (T) {
default: assert(0 && "Not a builtin primary expression!");
case tok::kw___builtin_va_arg: {
- ExprOwner Expr(Actions, ParseAssignmentExpression());
+ OwningExprResult Expr(Actions, ParseAssignmentExpression());
if (Expr.isInvalid()) {
SkipUntil(tok::r_paren);
return ExprResult(true);
break;
}
case tok::kw___builtin_choose_expr: {
- ExprOwner Cond(Actions, ParseAssignmentExpression());
+ OwningExprResult Cond(Actions, ParseAssignmentExpression());
if (Cond.isInvalid()) {
SkipUntil(tok::r_paren);
return Cond.move();
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprResult(true);
- ExprOwner Expr1(Actions, ParseAssignmentExpression());
+ OwningExprResult Expr1(Actions, ParseAssignmentExpression());
if (Expr1.isInvalid()) {
SkipUntil(tok::r_paren);
return Expr1.move();
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprResult(true);
- ExprOwner Expr2(Actions, ParseAssignmentExpression());
+ OwningExprResult Expr2(Actions, ParseAssignmentExpression());
if (Expr2.isInvalid()) {
SkipUntil(tok::r_paren);
return Expr2.move();
// comma. If there is no comma, break and attempt to match r-paren.
if (Tok.isNot(tok::r_paren)) {
while (1) {
- ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+ OwningExprResult ArgExpr(Actions, ParseAssignmentExpression());
if (ArgExpr.isInvalid()) {
SkipUntil(tok::r_paren);
return ExprResult(true);
SourceLocation &RParenLoc) {
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
SourceLocation OpenLoc = ConsumeParen();
- ExprOwner Result(Actions, true);
+ OwningExprResult Result(Actions, true);
CastTy = 0;
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
Diag(Tok, diag::ext_gnu_statement_expr);
- StmtOwner Stmt(Actions, ParseCompoundStatement(true));
+ OwningStmtResult Stmt(Actions, ParseCompoundStatement(true));
ExprType = CompoundStmt;
// If the substmt parsed correctly, build the AST node.
ExprType = CompoundLiteral;
if (!Result.isInvalid())
return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc,
- Result.take());
+ Result.move());
} else if (ExprType == CastExpr) {
// Note that this doesn't parse the subsequence cast-expression, it just
// returns the parsed type to the callee.
ExprType = SimpleExpr;
if (!Result.isInvalid() && Tok.is(tok::r_paren))
Result = Actions.ActOnParenExpr(
- OpenLoc, Tok.getLocation(), Result.take());
+ OpenLoc, Tok.getLocation(), Result.move());
}
// Match the ')'.
///
bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
while (1) {
- ExprOwner Expr(Actions, ParseAssignmentExpression());
+ OwningExprResult Expr(Actions, ParseAssignmentExpression());
if (Expr.isInvalid())
return true;
// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(ParamInfo);
- ExprOwner Result(Actions, true);
+ OwningExprResult Result(Actions, true);
if (Tok.is(tok::l_brace)) {
- StmtOwner Stmt(Actions, ParseCompoundStatementBody());
+ OwningStmtResult Stmt(Actions, ParseCompoundStatementBody());
if (!Stmt.isInvalid()) {
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.move(), CurScope);
} else {
if (Tok.isNot(tok::l_paren))
return Diag(Tok, diag::err_expected_lparen_after) << CastName;
- ExprOwner Result(Actions, ParseSimpleParenExpression(RParenLoc));
+ OwningExprResult Result(Actions, ParseSimpleParenExpression(RParenLoc));
if (!Result.isInvalid())
Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
"typeid"))
return ExprResult(true);
- ExprOwner Result(Actions);
+ OwningExprResult Result(Actions);
if (isTypeIdInParens()) {
TypeTy *Ty = ParseTypeName();
return Actions.ActOnCXXThrow(ThrowLoc);
default:
- ExprOwner Expr(Actions, ParseAssignmentExpression());
+ OwningExprResult Expr(Actions, ParseAssignmentExpression());
if (Expr.isInvalid()) return Expr.move();
return Actions.ActOnCXXThrow(ThrowLoc, Expr.move());
}
// simple-asm-expr[opt]
if (Tok.is(tok::kw_asm)) {
- ExprOwner AsmLabel(Actions, ParseSimpleAsm());
+ OwningExprResult AsmLabel(Actions, ParseSimpleAsm());
if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi);
return true;
if (Tok.isNot(tok::equal))
return Diag(Tok, diag::err_expected_equal_after_declarator);
SourceLocation EqualLoc = ConsumeToken();
- ExprOwner AssignExpr(Actions, ParseAssignmentExpression());
+ OwningExprResult AssignExpr(Actions, ParseAssignmentExpression());
if (AssignExpr.isInvalid())
return true;
bool first = true;
while (Tok.is(tok::l_square)) {
SourceLocation LLoc = ConsumeBracket();
- ExprOwner Size(Actions, first ? ParseExpression()
- : ParseConstantExpression());
+ OwningExprResult Size(Actions, first ? ParseExpression()
+ : ParseConstantExpression());
if (Size.isInvalid()) {
// Recover
SkipUntil(tok::r_square);
return true;
}
- ExprOwner Operand(Actions, ParseCastExpression(false));
+ OwningExprResult Operand(Actions, ParseCastExpression(false));
if (Operand.isInvalid())
return Operand.move();
// Note that we parse this as an assignment expression, not a constant
// expression (allowing *=, =, etc) to handle the objc case. Sema needs
// to validate that the expression is a constant.
- ExprOwner Idx(Actions, ParseAssignmentExpression());
+ OwningExprResult Idx(Actions, ParseAssignmentExpression());
if (Idx.isInvalid()) {
SkipUntil(tok::r_square);
return Idx.move();
Diag(Tok, diag::ext_gnu_array_range);
ConsumeToken();
- ExprOwner RHS(Actions, ParseConstantExpression());
+ OwningExprResult RHS(Actions, ParseConstantExpression());
if (RHS.isInvalid()) {
SkipUntil(tok::r_square);
return RHS.move();
// If we know that this cannot be a designation, just parse the nested
// initializer directly.
- ExprOwner SubElt(Actions);
+ OwningExprResult SubElt(Actions);
if (!MayBeDesignationStart(Tok.getKind(), PP))
SubElt = ParseInitializer();
else {
/// throw expression[opt];
///
Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
- ExprOwner Res(Actions);
+ OwningExprResult Res(Actions);
ConsumeToken(); // consume throw
if (Tok.isNot(tok::semi)) {
Res = ParseExpression();
return true;
}
ConsumeParen(); // '('
- ExprOwner Res(Actions, ParseExpression());
+ OwningExprResult Res(Actions, ParseExpression());
if (Res.isInvalid()) {
SkipUntil(tok::semi);
return true;
// statements can always hold declarations.
EnterScope(Scope::DeclScope);
- StmtOwner SynchBody(Actions, ParseCompoundStatementBody());
+ OwningStmtResult SynchBody(Actions, ParseCompoundStatementBody());
ExitScope();
if (SynchBody.isInvalid())
Diag(Tok, diag::err_expected_lbrace);
return true;
}
- StmtOwner CatchStmts(Actions);
- StmtOwner FinallyStmt(Actions);
+ OwningStmtResult CatchStmts(Actions);
+ OwningStmtResult FinallyStmt(Actions);
EnterScope(Scope::DeclScope);
- StmtOwner TryBody(Actions, ParseCompoundStatementBody());
+ OwningStmtResult TryBody(Actions, ParseCompoundStatementBody());
ExitScope();
if (TryBody.isInvalid())
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
SourceLocation AtCatchFinallyLoc = ConsumeToken();
if (Tok.isObjCAtKeyword(tok::objc_catch)) {
- StmtOwner FirstPart(Actions);
+ OwningStmtResult FirstPart(Actions);
ConsumeToken(); // consume catch
if (Tok.is(tok::l_paren)) {
ConsumeParen();
ConsumeToken(); // consume '...'
SourceLocation RParenLoc = ConsumeParen();
- StmtOwner CatchBody(Actions, true);
+ OwningStmtResult CatchBody(Actions, true);
if (Tok.is(tok::l_brace))
CatchBody = ParseCompoundStatementBody();
else
EnterScope(Scope::DeclScope);
- StmtOwner FinallyBody(Actions, true);
+ OwningStmtResult FinallyBody(Actions, true);
if (Tok.is(tok::l_brace))
FinallyBody = ParseCompoundStatementBody();
else
// specified Declarator for the method.
Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl);
- StmtOwner FnBody(Actions, ParseCompoundStatementBody());
+ OwningStmtResult FnBody(Actions, ParseCompoundStatementBody());
// If the function body could not be parsed, make a bogus compoundstmt.
if (FnBody.isInvalid())
return ParseObjCThrowStmt(AtLoc);
else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
return ParseObjCSynchronizedStmt(AtLoc);
- ExprOwner Res(Actions, ParseExpressionWithLeadingAt(AtLoc));
+ OwningExprResult Res(Actions, ParseExpressionWithLeadingAt(AtLoc));
if (Res.isInvalid()) {
// If the expression is invalid, skip ahead to the next semicolon. Not
// doing this opens us up to the possibility of infinite loops if
return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0);
}
- ExprOwner Res(Actions, ParseExpression());
+ OwningExprResult Res(Actions, ParseExpression());
if (Res.isInvalid()) {
SkipUntil(tok::r_square);
return Res.move();
ConsumeToken(); // Eat the ':'.
/// Parse the expression after ':'
- ExprOwner Res(Actions, ParseAssignmentExpression());
+ OwningExprResult Res(Actions, ParseAssignmentExpression());
if (Res.isInvalid()) {
// We must manually skip to a ']', otherwise the expression skipper will
// stop at the ']' when it skips to the ';'. We want it to skip beyond
while (Tok.is(tok::comma)) {
ConsumeToken(); // Eat the ','.
/// Parse the expression after ','
- ExprOwner Res(Actions, ParseAssignmentExpression());
+ OwningExprResult Res(Actions, ParseAssignmentExpression());
if (Res.isInvalid()) {
// We must manually skip to a ']', otherwise the expression skipper will
// stop at the ']' when it skips to the ';'. We want it to skip beyond
}
Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
- ExprOwner Res(Actions, ParseStringLiteralExpression());
+ OwningExprResult Res(Actions, ParseStringLiteralExpression());
if (Res.isInvalid()) return Res.move();
// @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
while (Tok.is(tok::at)) {
AtLocs.push_back(ConsumeToken()); // eat the @.
- ExprOwner Lit(Actions, true); // Invalid unless there is a string literal.
+ // Invalid unless there is a string literal.
+ OwningExprResult Lit(Actions, true);
if (isTokenStringLiteral())
Lit = ParseStringLiteralExpression();
else
//===----------------------------------------------------------------------===//
#include "ParsePragma.h"
-#include "AstGuard.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Action.h"
Action::PragmaPackKind Kind = Action::PPK_Default;
IdentifierInfo *Name = 0;
- ExprOwner Alignment(Actions);
+ Action::OwningExprResult Alignment(Actions);
SourceLocation LParenLoc = Tok.getLocation();
PP.Lex(Tok);
if (Tok.is(tok::numeric_constant)) {
///
Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
const char *SemiError = 0;
- StmtOwner Res(Actions);
+ OwningStmtResult Res(Actions);
// Cases in this switch statement should fall through if the parser expects
// the token to end in a semicolon (in which case SemiError should be set),
return true;
} else {
// expression[opt] ';'
- ExprOwner Expr(Actions, ParseExpression());
+ OwningExprResult Expr(Actions, ParseExpression());
if (Expr.isInvalid()) {
// If the expression is invalid, skip ahead to the next semicolon. Not
// doing this opens us up to the possibility of infinite loops if
// TODO: save these somewhere.
AttrList = ParseAttributes();
- StmtOwner SubStmt(Actions, ParseStatement());
+ OwningStmtResult SubStmt(Actions, ParseStatement());
// Broken substmt shouldn't prevent the label from being added to the AST.
if (SubStmt.isInvalid())
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'.
- ExprOwner LHS(Actions, ParseConstantExpression());
+ OwningExprResult LHS(Actions, ParseConstantExpression());
if (LHS.isInvalid()) {
SkipUntil(tok::colon);
return true;
// GNU case range extension.
SourceLocation DotDotDotLoc;
- ExprOwner RHS(Actions);
+ OwningExprResult RHS(Actions);
if (Tok.is(tok::ellipsis)) {
Diag(Tok, diag::ext_gnu_case_range);
DotDotDotLoc = ConsumeToken();
return true;
}
- StmtOwner SubStmt(Actions, ParseStatement());
+ OwningStmtResult SubStmt(Actions, ParseStatement());
// Broken substmt shouldn't prevent the case from being added to the AST.
if (SubStmt.isInvalid())
return true;
}
- StmtOwner SubStmt(Actions, ParseStatement());
+ OwningStmtResult SubStmt(Actions, ParseStatement());
if (SubStmt.isInvalid())
return true;
EnterScope(Scope::DeclScope);
// Parse the statements in the body.
- StmtOwner Body(Actions, ParseCompoundStatementBody(isStmtExpr));
+ OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr));
ExitScope();
return Body.move();
typedef StmtVector StmtsTy;
StmtsTy Stmts(Actions);
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- StmtOwner R(Actions);
+ OwningStmtResult R(Actions);
if (Tok.isNot(tok::kw___extension__)) {
R = ParseStatementOrDeclaration(false);
} else {
} else {
// Otherwise this was a unary __extension__ marker. Parse the
// subexpression and add the __extension__ unary op.
- ExprOwner Res(Actions, ParseCastExpression(false));
+ OwningExprResult Res(Actions, ParseCastExpression(false));
if (Res.isInvalid()) {
SkipUntil(tok::semi);
EnterScope(Scope::DeclScope | Scope::ControlScope);
// Parse the condition.
- ExprOwner CondExp(Actions);
+ OwningExprResult CondExp(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
CondExp = ParseCXXCondition();
// Read the 'then' stmt.
SourceLocation ThenStmtLoc = Tok.getLocation();
- StmtOwner ThenStmt(Actions, ParseStatement());
+ OwningStmtResult ThenStmt(Actions, ParseStatement());
// Pop the 'if' scope if needed.
if (NeedsInnerScope) ExitScope();
// If it has an else, parse it.
SourceLocation ElseLoc;
SourceLocation ElseStmtLoc;
- StmtOwner ElseStmt(Actions);
+ OwningStmtResult ElseStmt(Actions);
if (Tok.is(tok::kw_else)) {
ElseLoc = ConsumeToken();
EnterScope(Scope::BreakScope);
// Parse the condition.
- ExprOwner Cond(Actions);
+ OwningExprResult Cond(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
Cond = ParseCXXCondition();
return true;
}
- StmtOwner Switch(Actions, Actions.ActOnStartOfSwitchStmt(Cond.move()));
+ OwningStmtResult Switch(Actions, Actions.ActOnStartOfSwitchStmt(Cond.move()));
// C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the body statement.
- StmtOwner Body(Actions, ParseStatement());
+ OwningStmtResult Body(Actions, ParseStatement());
// Pop the body scope if needed.
if (NeedsInnerScope) ExitScope();
EnterScope(Scope::BreakScope | Scope::ContinueScope);
// Parse the condition.
- ExprOwner Cond(Actions);
+ OwningExprResult Cond(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
Cond = ParseCXXCondition();
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the body statement.
- StmtOwner Body(Actions, ParseStatement());
+ OwningStmtResult Body(Actions, ParseStatement());
// Pop the body scope if needed.
if (NeedsInnerScope) ExitScope();
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the body statement.
- StmtOwner Body(Actions, ParseStatement());
+ OwningStmtResult Body(Actions, ParseStatement());
// Pop the body scope if needed.
if (NeedsInnerScope) ExitScope();
}
// Parse the condition.
- ExprOwner Cond(Actions, ParseSimpleParenExpression());
+ OwningExprResult Cond(Actions, ParseSimpleParenExpression());
ExitScope();
EnterScope(Scope::BreakScope | Scope::ContinueScope);
SourceLocation LParenLoc = ConsumeParen();
- ExprOwner Value(Actions);
+ OwningExprResult Value(Actions);
bool ForEach = false;
- StmtOwner FirstPart(Actions), ThirdPart(Actions);
- ExprOwner SecondPart(Actions);
+ OwningStmtResult FirstPart(Actions), ThirdPart(Actions);
+ OwningExprResult SecondPart(Actions);
// Parse the first part of the for specifier.
if (Tok.is(tok::semi)) { // for (;
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the body statement.
- StmtOwner Body(Actions, ParseStatement());
+ OwningStmtResult Body(Actions, ParseStatement());
// Pop the body scope if needed.
if (NeedsInnerScope) ExitScope();
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
- StmtOwner Res(Actions);
+ OwningStmtResult Res(Actions);
if (Tok.is(tok::identifier)) {
Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
Tok.getIdentifierInfo());
// GNU indirect goto extension.
Diag(Tok, diag::ext_gnu_indirect_goto);
SourceLocation StarLoc = ConsumeToken();
- ExprOwner R(Actions, ParseExpression());
+ OwningExprResult R(Actions, ParseExpression());
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
SkipUntil(tok::semi, false, true);
return true;
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
- ExprOwner R(Actions);
+ OwningExprResult R(Actions);
if (Tok.isNot(tok::semi)) {
R = ParseExpression();
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
}
Loc = ConsumeParen();
- ExprOwner AsmString(Actions, ParseAsmStringLiteral());
+ OwningExprResult AsmString(Actions, ParseAsmStringLiteral());
if (AsmString.isInvalid())
return true;
// Parse the asm-string list for clobbers.
while (1) {
- ExprOwner Clobber(Actions, ParseAsmStringLiteral());
+ OwningExprResult Clobber(Actions, ParseAsmStringLiteral());
if (Clobber.isInvalid())
break;
} else
Names.push_back(std::string());
- ExprOwner Constraint(Actions, ParseAsmStringLiteral());
+ OwningExprResult Constraint(Actions, ParseAsmStringLiteral());
if (Constraint.isInvalid()) {
SkipUntil(tok::r_paren);
return true;
}
// Read the parenthesized expression.
- ExprOwner Res(Actions, ParseSimpleParenExpression());
+ OwningExprResult Res(Actions, ParseSimpleParenExpression());
if (Res.isInvalid()) {
SkipUntil(tok::r_paren);
return true;
// Do not enter a scope for the brace, as the arguments are in the same scope
// (the function body) as the body itself. Instead, just read the statement
// list and put it into a CompoundStmt for safe keeping.
- StmtOwner FnBody(Actions, ParseCompoundStatementBody());
+ OwningStmtResult FnBody(Actions, ParseCompoundStatementBody());
// If the function body could not be parsed, make a bogus compoundstmt.
if (FnBody.isInvalid())
#include "clang/Basic/Diagnostic.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
-#include "AstGuard.h"
using namespace clang;
}
// Get the a default value, if given.
- ExprOwner DefaultExpr(Actions);
+ OwningExprResult DefaultExpr(Actions);
if(Tok.is(tok::equal)) {
ConsumeToken();
DefaultExpr = ParseCXXIdExpression();
#include "clang/Parse/Scope.h"
#include "ExtensionRAIIObject.h"
#include "ParsePragma.h"
-#include "AstGuard.h"
using namespace clang;
Parser::Parser(Preprocessor &pp, Action &actions)
return ParseExternalDeclaration();
}
case tok::kw_asm: {
- ExprOwner Result(Actions, ParseSimpleAsm());
+ OwningExprResult Result(Actions, ParseSimpleAsm());
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
"top-level asm block");
return true;
}
- ExprOwner Res(Actions, ParseStringLiteralExpression());
+ OwningExprResult Res(Actions, ParseStringLiteralExpression());
if (Res.isInvalid()) return true;
// TODO: Diagnose: wide string literal in 'asm'
ConsumeParen();
- ExprOwner Result(Actions, ParseAsmStringLiteral());
+ OwningExprResult Result(Actions, ParseAsmStringLiteral());
if (Result.isInvalid())
SkipUntil(tok::r_paren);