Kick out the proof-of-concept ASTOwner and replace it with ASTOwningResult

llvm-svn: 60791
This commit is contained in:
Sebastian Redl 2008-12-09 20:22:58 +00:00
parent 93041ba483
commit c13f26873f
14 changed files with 133 additions and 233 deletions

View File

@ -35,8 +35,6 @@ namespace clang {
// 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

View File

@ -16,6 +16,7 @@
namespace clang
{
// Basic
class DiagnosticBuilder;
/// ActionBase - A small part split from Action because of the horrible
@ -154,6 +155,8 @@ namespace clang
}
public:
typedef ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> DumbResult;
// For convenience and compatibility.
ASTOwningResult(bool invalid = false)
: Actions(0), Node(0), Invalid(invalid) {}
@ -164,6 +167,8 @@ namespace clang
: 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) {}
@ -192,8 +197,7 @@ namespace clang
}
/// 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;
@ -333,6 +337,15 @@ namespace clang
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();

View File

@ -79,6 +79,14 @@ public:
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
@ -305,10 +313,10 @@ private:
//===--------------------------------------------------------------------===//
// 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
@ -328,11 +336,6 @@ private:
}
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.

View File

@ -19,119 +19,6 @@
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

View File

@ -126,7 +126,7 @@ AttributeList *Parser::ParseAttributes() {
// 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);
@ -158,7 +158,7 @@ AttributeList *Parser::ParseAttributes() {
// 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);
@ -270,7 +270,7 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
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;
@ -289,7 +289,7 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
// 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;
@ -842,7 +842,7 @@ ParseStructDeclaration(DeclSpec &DS,
if (Tok.is(tok::colon)) {
ConsumeToken();
ExprOwner Res(Actions, ParseConstantExpression());
OwningExprResult Res(Actions, ParseConstantExpression());
if (Res.isInvalid())
SkipUntil(tok::semi, true, true);
else
@ -1074,7 +1074,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
SourceLocation IdentLoc = ConsumeToken();
SourceLocation EqualLoc;
ExprOwner AssignedVal(Actions);
OwningExprResult AssignedVal(Actions);
if (Tok.is(tok::equal)) {
EqualLoc = ConsumeToken();
AssignedVal = ParseConstantExpression();
@ -1796,7 +1796,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
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 {
@ -1934,7 +1934,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
// 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
@ -1992,7 +1992,8 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
return;
}
ExprOwner Result(Actions, ParseCastExpression(true/*isUnaryExpression*/));
OwningExprResult Result(Actions,
ParseCastExpression(true/*isUnaryExpression*/));
if (Result.isInvalid())
return;
@ -2024,7 +2025,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
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);

View File

@ -489,8 +489,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// member-declarator-list ',' member-declarator
DeclTy *LastDeclInGroup = 0;
ExprOwner BitfieldSize(Actions);
ExprOwner Init(Actions);
OwningExprResult BitfieldSize(Actions);
OwningExprResult Init(Actions);
while (1) {
@ -543,8 +543,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// 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))

View File

@ -173,7 +173,7 @@ Parser::ExprResult Parser::ParseExpression() {
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);
@ -185,7 +185,7 @@ Parser::ExprResult Parser::ParseExpression() {
/// 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);
@ -197,7 +197,7 @@ Parser::ExprResult Parser::ParseAssignmentExpression() {
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);
@ -216,9 +216,9 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
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();
@ -227,7 +227,7 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
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);
@ -240,7 +240,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
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),
@ -253,7 +253,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
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:
@ -266,7 +266,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
} 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);
}
@ -281,7 +281,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
}
// 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();
@ -420,7 +420,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
TryAnnotateTypeOrScopeToken();
}
ExprOwner Res(Actions);
OwningExprResult Res(Actions);
tok::TokenKind SavedKind = Tok.getKind();
// This handles all of cast-expression, unary-expression, postfix-expression,
@ -682,7 +682,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
/// 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;
@ -692,7 +692,7 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHSArg) {
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();
@ -779,7 +779,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
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 {
@ -831,7 +831,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
/// [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();
@ -849,7 +849,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
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);
@ -931,7 +931,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
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();
@ -939,7 +939,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
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();
@ -947,7 +947,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
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();
@ -968,7 +968,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
// 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);
@ -1031,12 +1031,12 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
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.
@ -1061,7 +1061,7 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
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.
@ -1078,7 +1078,7 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
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 ')'.
@ -1128,7 +1128,7 @@ Parser::ExprResult Parser::ParseStringLiteralExpression() {
///
bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
while (1) {
ExprOwner Expr(Actions, ParseAssignmentExpression());
OwningExprResult Expr(Actions, ParseAssignmentExpression());
if (Expr.isInvalid())
return true;
@ -1189,9 +1189,9 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
// 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 {

View File

@ -221,7 +221,7 @@ Parser::ExprResult Parser::ParseCXXCasts() {
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,
@ -249,7 +249,7 @@ Parser::ExprResult Parser::ParseCXXTypeid() {
"typeid"))
return ExprResult(true);
ExprOwner Result(Actions);
OwningExprResult Result(Actions);
if (isTypeIdInParens()) {
TypeTy *Ty = ParseTypeName();
@ -310,7 +310,7 @@ Parser::ExprResult Parser::ParseThrowExpression() {
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());
}
@ -388,7 +388,7 @@ Parser::ExprResult Parser::ParseCXXCondition() {
// 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;
@ -404,7 +404,7 @@ Parser::ExprResult Parser::ParseCXXCondition() {
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;
@ -776,8 +776,8 @@ void Parser::ParseDirectNewDeclarator(Declarator &D)
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);
@ -851,7 +851,7 @@ Parser::ExprResult Parser::ParseCXXDeleteExpression()
return true;
}
ExprOwner Operand(Actions, ParseCastExpression(false));
OwningExprResult Operand(Actions, ParseCastExpression(false));
if (Operand.isInvalid())
return Operand.move();

View File

@ -143,7 +143,7 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
// 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();
@ -185,7 +185,7 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
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();
@ -263,7 +263,7 @@ Parser::ExprResult Parser::ParseBraceInitializer() {
// 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 {

View File

@ -1175,7 +1175,7 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
/// 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();
@ -1198,7 +1198,7 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
return true;
}
ConsumeParen(); // '('
ExprOwner Res(Actions, ParseExpression());
OwningExprResult Res(Actions, ParseExpression());
if (Res.isInvalid()) {
SkipUntil(tok::semi);
return true;
@ -1216,7 +1216,7 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
// statements can always hold declarations.
EnterScope(Scope::DeclScope);
StmtOwner SynchBody(Actions, ParseCompoundStatementBody());
OwningStmtResult SynchBody(Actions, ParseCompoundStatementBody());
ExitScope();
if (SynchBody.isInvalid())
@ -1244,10 +1244,10 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
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());
@ -1263,7 +1263,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
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();
@ -1287,7 +1287,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
ConsumeToken(); // consume '...'
SourceLocation RParenLoc = ConsumeParen();
StmtOwner CatchBody(Actions, true);
OwningStmtResult CatchBody(Actions, true);
if (Tok.is(tok::l_brace))
CatchBody = ParseCompoundStatementBody();
else
@ -1309,7 +1309,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
EnterScope(Scope::DeclScope);
StmtOwner FinallyBody(Actions, true);
OwningStmtResult FinallyBody(Actions, true);
if (Tok.is(tok::l_brace))
FinallyBody = ParseCompoundStatementBody();
else
@ -1359,7 +1359,7 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
// 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())
@ -1380,7 +1380,7 @@ Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
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
@ -1433,7 +1433,7 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0);
}
ExprOwner Res(Actions, ParseExpression());
OwningExprResult Res(Actions, ParseExpression());
if (Res.isInvalid()) {
SkipUntil(tok::r_square);
return Res.move();
@ -1492,7 +1492,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
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
@ -1514,7 +1514,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
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
@ -1563,7 +1563,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
}
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
@ -1577,7 +1577,8 @@ Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
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

View File

@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "ParsePragma.h"
#include "AstGuard.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Action.h"
@ -35,7 +34,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
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)) {

View File

@ -74,7 +74,7 @@ using namespace clang;
///
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),
@ -106,7 +106,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
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
@ -203,7 +203,7 @@ Parser::StmtResult Parser::ParseLabeledStatement() {
// 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())
@ -225,7 +225,7 @@ Parser::StmtResult Parser::ParseCaseStatement() {
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;
@ -233,7 +233,7 @@ Parser::StmtResult Parser::ParseCaseStatement() {
// 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();
@ -259,7 +259,7 @@ Parser::StmtResult Parser::ParseCaseStatement() {
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())
@ -292,7 +292,7 @@ Parser::StmtResult Parser::ParseDefaultStatement() {
return true;
}
StmtOwner SubStmt(Actions, ParseStatement());
OwningStmtResult SubStmt(Actions, ParseStatement());
if (SubStmt.isInvalid())
return true;
@ -336,7 +336,7 @@ Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
EnterScope(Scope::DeclScope);
// Parse the statements in the body.
StmtOwner Body(Actions, ParseCompoundStatementBody(isStmtExpr));
OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr));
ExitScope();
return Body.move();
@ -356,7 +356,7 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
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 {
@ -380,7 +380,7 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
} 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);
@ -450,7 +450,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
EnterScope(Scope::DeclScope | Scope::ControlScope);
// Parse the condition.
ExprOwner CondExp(Actions);
OwningExprResult CondExp(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
CondExp = ParseCXXCondition();
@ -489,7 +489,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
// 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();
@ -497,7 +497,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
// 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();
@ -578,7 +578,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
EnterScope(Scope::BreakScope);
// Parse the condition.
ExprOwner Cond(Actions);
OwningExprResult Cond(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
Cond = ParseCXXCondition();
@ -592,7 +592,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
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
@ -609,7 +609,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
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();
@ -660,7 +660,7 @@ Parser::StmtResult Parser::ParseWhileStatement() {
EnterScope(Scope::BreakScope | Scope::ContinueScope);
// Parse the condition.
ExprOwner Cond(Actions);
OwningExprResult Cond(Actions);
if (getLang().CPlusPlus) {
SourceLocation LParenLoc = ConsumeParen();
Cond = ParseCXXCondition();
@ -684,7 +684,7 @@ Parser::StmtResult Parser::ParseWhileStatement() {
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();
@ -724,7 +724,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
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();
@ -748,7 +748,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
}
// Parse the condition.
ExprOwner Cond(Actions, ParseSimpleParenExpression());
OwningExprResult Cond(Actions, ParseSimpleParenExpression());
ExitScope();
@ -804,11 +804,11 @@ Parser::StmtResult Parser::ParseForStatement() {
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 (;
@ -893,7 +893,7 @@ Parser::StmtResult Parser::ParseForStatement() {
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();
@ -926,7 +926,7 @@ Parser::StmtResult Parser::ParseGotoStatement() {
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());
@ -935,7 +935,7 @@ Parser::StmtResult Parser::ParseGotoStatement() {
// 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;
@ -978,7 +978,7 @@ Parser::StmtResult Parser::ParseReturnStatement() {
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.
@ -1068,7 +1068,7 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
}
Loc = ConsumeParen();
ExprOwner AsmString(Actions, ParseAsmStringLiteral());
OwningExprResult AsmString(Actions, ParseAsmStringLiteral());
if (AsmString.isInvalid())
return true;
@ -1108,7 +1108,7 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
// Parse the asm-string list for clobbers.
while (1) {
ExprOwner Clobber(Actions, ParseAsmStringLiteral());
OwningExprResult Clobber(Actions, ParseAsmStringLiteral());
if (Clobber.isInvalid())
break;
@ -1173,7 +1173,7 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
} else
Names.push_back(std::string());
ExprOwner Constraint(Actions, ParseAsmStringLiteral());
OwningExprResult Constraint(Actions, ParseAsmStringLiteral());
if (Constraint.isInvalid()) {
SkipUntil(tok::r_paren);
return true;
@ -1187,7 +1187,7 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
}
// Read the parenthesized expression.
ExprOwner Res(Actions, ParseSimpleParenExpression());
OwningExprResult Res(Actions, ParseSimpleParenExpression());
if (Res.isInvalid()) {
SkipUntil(tok::r_paren);
return true;
@ -1206,7 +1206,7 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
// 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())

View File

@ -15,7 +15,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
#include "AstGuard.h"
using namespace clang;
@ -232,7 +231,7 @@ Parser::DeclTy* Parser::ParseTemplateTemplateParameter() {
}
// Get the a default value, if given.
ExprOwner DefaultExpr(Actions);
OwningExprResult DefaultExpr(Actions);
if(Tok.is(tok::equal)) {
ConsumeToken();
DefaultExpr = ParseCXXIdExpression();

View File

@ -17,7 +17,6 @@
#include "clang/Parse/Scope.h"
#include "ExtensionRAIIObject.h"
#include "ParsePragma.h"
#include "AstGuard.h"
using namespace clang;
Parser::Parser(Preprocessor &pp, Action &actions)
@ -337,7 +336,7 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
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");
@ -673,7 +672,7 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() {
return true;
}
ExprOwner Res(Actions, ParseStringLiteralExpression());
OwningExprResult Res(Actions, ParseStringLiteralExpression());
if (Res.isInvalid()) return true;
// TODO: Diagnose: wide string literal in 'asm'
@ -697,7 +696,7 @@ Parser::ExprResult Parser::ParseSimpleAsm() {
ConsumeParen();
ExprOwner Result(Actions, ParseAsmStringLiteral());
OwningExprResult Result(Actions, ParseAsmStringLiteral());
if (Result.isInvalid())
SkipUntil(tok::r_paren);