forked from OSchip/llvm-project
Consistently use smart pointers for stmt and expr nodes in parser local variables.
llvm-svn: 60761
This commit is contained in:
parent
08628db9d2
commit
17f2c7d251
|
@ -19,49 +19,118 @@
|
||||||
|
|
||||||
namespace clang
|
namespace clang
|
||||||
{
|
{
|
||||||
/// RAII guard for freeing StmtTys and ExprTys on early exit in the parser.
|
|
||||||
/// Instantiated for statements and expressions (Action::DeleteStmt and
|
|
||||||
/// Action::DeleteExpr).
|
|
||||||
template <void (Action::*Destroyer)(void*)>
|
template <void (Action::*Destroyer)(void*)>
|
||||||
class ASTGuard {
|
class ASTOwner;
|
||||||
|
|
||||||
|
typedef ASTOwner<&Action::DeleteStmt> StmtOwner;
|
||||||
|
typedef ASTOwner<&Action::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 (Action::*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 (Action::*Destroyer)(void*)>
|
||||||
|
class ASTOwner {
|
||||||
|
typedef typename ResultOfOwner<ASTOwner>::type Result;
|
||||||
|
|
||||||
Action &Actions;
|
Action &Actions;
|
||||||
void *Node;
|
void *Node;
|
||||||
|
bool Invalid;
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (Node)
|
if (Node)
|
||||||
(Actions.*Destroyer)(Node);
|
(Actions.*Destroyer)(Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTGuard(const ASTGuard&); // DO NOT IMPLEMENT
|
ASTOwner(const ASTOwner&); // DO NOT IMPLEMENT
|
||||||
// Reference member prevents copy assignment.
|
// Reference member prevents copy assignment.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ASTGuard(Action &actions) : Actions(actions), Node(0) {}
|
explicit ASTOwner(Action &actions, bool invalid = false)
|
||||||
ASTGuard(Action &actions, void *node)
|
: Actions(actions), Node(0), Invalid(invalid) {}
|
||||||
: Actions(actions), Node(node) {}
|
ASTOwner(Action &actions, void *node)
|
||||||
template <unsigned N>
|
: Actions(actions), Node(node), Invalid(false) {}
|
||||||
ASTGuard(Action &actions, const Action::ActionResult<N> &res)
|
ASTOwner(Action &actions, const Result &res)
|
||||||
: Actions(actions), Node(res.Val) {}
|
: Actions(actions), Node(res.Val), Invalid(res.isInvalid) {}
|
||||||
~ASTGuard() { destroy(); }
|
/// Move constructor
|
||||||
|
ASTOwner(ASTMove<Destroyer> mover)
|
||||||
void reset(void *element) {
|
: 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();
|
destroy();
|
||||||
Node = element;
|
Node = mover->take();
|
||||||
|
Invalid = mover->Invalid;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
template <unsigned N>
|
/// Convenience, for better syntax. reset() is so ugly. Just remember that
|
||||||
void reset(const Action::ActionResult<N> &res) {
|
/// this takes ownership.
|
||||||
reset(res.Val);
|
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 *take() {
|
||||||
void *Temp = Node;
|
void *Temp = Node;
|
||||||
Node = 0;
|
Node = 0;
|
||||||
return Temp;
|
return Temp;
|
||||||
}
|
}
|
||||||
void *get() const { return Node; }
|
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; }
|
||||||
|
|
||||||
typedef ASTGuard<&Action::DeleteStmt> StmtGuard;
|
ASTMove<Destroyer> move() {
|
||||||
typedef ASTGuard<&Action::DeleteExpr> ExprGuard;
|
return ASTMove<Destroyer>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
|
/// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
|
||||||
/// automatically freeing them on destruction unless it's been disowned.
|
/// automatically freeing them on destruction unless it's been disowned.
|
||||||
|
|
|
@ -126,13 +126,13 @@ AttributeList *Parser::ParseAttributes() {
|
||||||
|
|
||||||
// now parse the non-empty comma separated list of expressions
|
// now parse the non-empty comma separated list of expressions
|
||||||
while (1) {
|
while (1) {
|
||||||
ExprResult ArgExpr = ParseAssignmentExpression();
|
ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
|
||||||
if (ArgExpr.isInvalid) {
|
if (ArgExpr.isInvalid()) {
|
||||||
ArgExprsOk = false;
|
ArgExprsOk = false;
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
ArgExprs.push_back(ArgExpr.Val);
|
ArgExprs.push_back(ArgExpr.move());
|
||||||
}
|
}
|
||||||
if (Tok.isNot(tok::comma))
|
if (Tok.isNot(tok::comma))
|
||||||
break;
|
break;
|
||||||
|
@ -158,13 +158,13 @@ AttributeList *Parser::ParseAttributes() {
|
||||||
|
|
||||||
// now parse the list of expressions
|
// now parse the list of expressions
|
||||||
while (1) {
|
while (1) {
|
||||||
ExprResult ArgExpr = ParseAssignmentExpression();
|
ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
|
||||||
if (ArgExpr.isInvalid) {
|
if (ArgExpr.isInvalid()) {
|
||||||
ArgExprsOk = false;
|
ArgExprsOk = false;
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
ArgExprs.push_back(ArgExpr.Val);
|
ArgExprs.push_back(ArgExpr.move());
|
||||||
}
|
}
|
||||||
if (Tok.isNot(tok::comma))
|
if (Tok.isNot(tok::comma))
|
||||||
break;
|
break;
|
||||||
|
@ -270,13 +270,13 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||||
while (1) {
|
while (1) {
|
||||||
// If a simple-asm-expr is present, parse it.
|
// If a simple-asm-expr is present, parse it.
|
||||||
if (Tok.is(tok::kw_asm)) {
|
if (Tok.is(tok::kw_asm)) {
|
||||||
ExprResult AsmLabel = ParseSimpleAsm();
|
ExprOwner AsmLabel(Actions, ParseSimpleAsm());
|
||||||
if (AsmLabel.isInvalid) {
|
if (AsmLabel.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
D.setAsmLabel(AsmLabel.Val);
|
D.setAsmLabel(AsmLabel.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
|
@ -285,16 +285,16 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||||
|
|
||||||
// Inform the current actions module that we just parsed this declarator.
|
// Inform the current actions module that we just parsed this declarator.
|
||||||
LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
|
LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
|
||||||
|
|
||||||
// Parse declarator '=' initializer.
|
// Parse declarator '=' initializer.
|
||||||
if (Tok.is(tok::equal)) {
|
if (Tok.is(tok::equal)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ExprResult Init = ParseInitializer();
|
ExprOwner Init(Actions, ParseInitializer());
|
||||||
if (Init.isInvalid) {
|
if (Init.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
|
Actions.AddInitializerToDecl(LastDeclInGroup, Init.move());
|
||||||
} else if (Tok.is(tok::l_paren)) {
|
} else if (Tok.is(tok::l_paren)) {
|
||||||
// Parse C++ direct initializer: '(' expression-list ')'
|
// Parse C++ direct initializer: '(' expression-list ')'
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
|
@ -842,11 +842,11 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
|
|
||||||
if (Tok.is(tok::colon)) {
|
if (Tok.is(tok::colon)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ExprResult Res = ParseConstantExpression();
|
ExprOwner Res(Actions, ParseConstantExpression());
|
||||||
if (Res.isInvalid)
|
if (Res.isInvalid())
|
||||||
SkipUntil(tok::semi, true, true);
|
SkipUntil(tok::semi, true, true);
|
||||||
else
|
else
|
||||||
DeclaratorInfo.BitfieldSize = Res.Val;
|
DeclaratorInfo.BitfieldSize = Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, parse them.
|
// If attributes exist after the declarator, parse them.
|
||||||
|
@ -1074,21 +1074,20 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
|
||||||
SourceLocation IdentLoc = ConsumeToken();
|
SourceLocation IdentLoc = ConsumeToken();
|
||||||
|
|
||||||
SourceLocation EqualLoc;
|
SourceLocation EqualLoc;
|
||||||
ExprTy *AssignedVal = 0;
|
ExprOwner AssignedVal(Actions);
|
||||||
if (Tok.is(tok::equal)) {
|
if (Tok.is(tok::equal)) {
|
||||||
EqualLoc = ConsumeToken();
|
EqualLoc = ConsumeToken();
|
||||||
ExprResult Res = ParseConstantExpression();
|
AssignedVal = ParseConstantExpression();
|
||||||
if (Res.isInvalid)
|
if (AssignedVal.isInvalid())
|
||||||
SkipUntil(tok::comma, tok::r_brace, true, true);
|
SkipUntil(tok::comma, tok::r_brace, true, true);
|
||||||
else
|
|
||||||
AssignedVal = Res.Val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install the enumerator constant into EnumDecl.
|
// Install the enumerator constant into EnumDecl.
|
||||||
DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
|
DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
|
||||||
LastEnumConstDecl,
|
LastEnumConstDecl,
|
||||||
IdentLoc, Ident,
|
IdentLoc, Ident,
|
||||||
EqualLoc, AssignedVal);
|
EqualLoc,
|
||||||
|
AssignedVal.move());
|
||||||
EnumConstantDecls.push_back(EnumConstDecl);
|
EnumConstantDecls.push_back(EnumConstDecl);
|
||||||
LastEnumConstDecl = EnumConstDecl;
|
LastEnumConstDecl = EnumConstDecl;
|
||||||
|
|
||||||
|
@ -1797,12 +1796,13 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// Parse the default argument
|
// Parse the default argument
|
||||||
ExprResult DefArgResult = ParseAssignmentExpression();
|
ExprOwner DefArgResult(Actions, ParseAssignmentExpression());
|
||||||
if (DefArgResult.isInvalid) {
|
if (DefArgResult.isInvalid()) {
|
||||||
SkipUntil(tok::comma, tok::r_paren, true, true);
|
SkipUntil(tok::comma, tok::r_paren, true, true);
|
||||||
} else {
|
} else {
|
||||||
// Inform the actions module about the default argument
|
// Inform the actions module about the default argument
|
||||||
Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
|
Actions.ActOnParamDefaultArgument(Param, EqualLoc,
|
||||||
|
DefArgResult.move());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,7 +1934,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
|
|
||||||
// Handle "direct-declarator [ type-qual-list[opt] * ]".
|
// Handle "direct-declarator [ type-qual-list[opt] * ]".
|
||||||
bool isStar = false;
|
bool isStar = false;
|
||||||
ExprResult NumElements(false);
|
ExprOwner NumElements(Actions);
|
||||||
|
|
||||||
// Handle the case where we have '[*]' as the array size. However, a leading
|
// 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
|
// star could be the start of an expression, for example 'X[*p + 4]'. Verify
|
||||||
|
@ -1953,7 +1953,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there was an error parsing the assignment-expression, recover.
|
// If there was an error parsing the assignment-expression, recover.
|
||||||
if (NumElements.isInvalid) {
|
if (NumElements.isInvalid()) {
|
||||||
// If the expression was invalid, skip it.
|
// If the expression was invalid, skip it.
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return;
|
return;
|
||||||
|
@ -1973,7 +1973,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
// Remember that we parsed a pointer type, and remember the type-quals.
|
// Remember that we parsed a pointer type, and remember the type-quals.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
|
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
|
||||||
StaticLoc.isValid(), isStar,
|
StaticLoc.isValid(), isStar,
|
||||||
NumElements.Val, StartLoc));
|
NumElements.move(), StartLoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [GNU] typeof-specifier:
|
/// [GNU] typeof-specifier:
|
||||||
|
@ -1992,14 +1992,14 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
|
ExprOwner Result(Actions, ParseCastExpression(true/*isUnaryExpression*/));
|
||||||
if (Result.isInvalid)
|
if (Result.isInvalid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char *PrevSpec = 0;
|
const char *PrevSpec = 0;
|
||||||
// Check for duplicate type specifiers.
|
// Check for duplicate type specifiers.
|
||||||
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
|
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
|
||||||
Result.Val))
|
Result.move()))
|
||||||
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||||
|
|
||||||
// FIXME: Not accurate, the range gets one token more than it should.
|
// FIXME: Not accurate, the range gets one token more than it should.
|
||||||
|
@ -2024,10 +2024,9 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
||||||
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
|
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
|
||||||
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||||
} else { // we have an expression.
|
} else { // we have an expression.
|
||||||
ExprResult Result = ParseExpression();
|
ExprOwner Result(Actions, ParseExpression());
|
||||||
ExprGuard ResultGuard(Actions, Result);
|
|
||||||
|
if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
|
||||||
if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
|
|
||||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2035,7 +2034,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
||||||
const char *PrevSpec = 0;
|
const char *PrevSpec = 0;
|
||||||
// Check for duplicate type specifiers (e.g. "int typeof(int)").
|
// Check for duplicate type specifiers (e.g. "int typeof(int)").
|
||||||
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
|
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
|
||||||
ResultGuard.take()))
|
Result.move()))
|
||||||
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||||
}
|
}
|
||||||
DS.SetRangeEnd(RParenLoc);
|
DS.SetRangeEnd(RParenLoc);
|
||||||
|
|
|
@ -489,8 +489,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
// member-declarator-list ',' member-declarator
|
// member-declarator-list ',' member-declarator
|
||||||
|
|
||||||
DeclTy *LastDeclInGroup = 0;
|
DeclTy *LastDeclInGroup = 0;
|
||||||
ExprTy *BitfieldSize = 0;
|
ExprOwner BitfieldSize(Actions);
|
||||||
ExprTy *Init = 0;
|
ExprOwner Init(Actions);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
@ -501,11 +501,9 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
|
|
||||||
if (Tok.is(tok::colon)) {
|
if (Tok.is(tok::colon)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ExprResult Res = ParseConstantExpression();
|
BitfieldSize = ParseConstantExpression();
|
||||||
if (Res.isInvalid)
|
if (BitfieldSize.isInvalid())
|
||||||
SkipUntil(tok::comma, true, true);
|
SkipUntil(tok::comma, true, true);
|
||||||
else
|
|
||||||
BitfieldSize = Res.Val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pure-specifier:
|
// pure-specifier:
|
||||||
|
@ -516,11 +514,9 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
|
|
||||||
if (Tok.is(tok::equal)) {
|
if (Tok.is(tok::equal)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ExprResult Res = ParseInitializer();
|
Init = ParseInitializer();
|
||||||
if (Res.isInvalid)
|
if (Init.isInvalid())
|
||||||
SkipUntil(tok::comma, true, true);
|
SkipUntil(tok::comma, true, true);
|
||||||
else
|
|
||||||
Init = Res.Val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, parse them.
|
// If attributes exist after the declarator, parse them.
|
||||||
|
@ -533,7 +529,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
// See Sema::ActOnCXXMemberDeclarator for details.
|
// See Sema::ActOnCXXMemberDeclarator for details.
|
||||||
LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
|
LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
|
||||||
DeclaratorInfo,
|
DeclaratorInfo,
|
||||||
BitfieldSize, Init,
|
BitfieldSize.move(),
|
||||||
|
Init.move(),
|
||||||
LastDeclInGroup);
|
LastDeclInGroup);
|
||||||
|
|
||||||
// If we don't have a comma, it is either the end of the list (a ';')
|
// If we don't have a comma, it is either the end of the list (a ';')
|
||||||
|
@ -546,7 +543,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
|
|
||||||
// Parse the next declarator.
|
// Parse the next declarator.
|
||||||
DeclaratorInfo.clear();
|
DeclaratorInfo.clear();
|
||||||
BitfieldSize = Init = 0;
|
BitfieldSize.reset();
|
||||||
|
Init.reset();
|
||||||
|
|
||||||
// Attributes are only allowed on the second declarator.
|
// Attributes are only allowed on the second declarator.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute))
|
||||||
|
|
|
@ -173,10 +173,10 @@ Parser::ExprResult Parser::ParseExpression() {
|
||||||
if (Tok.is(tok::kw_throw))
|
if (Tok.is(tok::kw_throw))
|
||||||
return ParseThrowExpression();
|
return ParseThrowExpression();
|
||||||
|
|
||||||
ExprResult LHS = ParseCastExpression(false);
|
ExprOwner LHS(Actions, ParseCastExpression(false));
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid()) return LHS.move();
|
||||||
|
|
||||||
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
|
return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This routine is called when the '@' is seen and consumed.
|
/// This routine is called when the '@' is seen and consumed.
|
||||||
|
@ -185,10 +185,10 @@ Parser::ExprResult Parser::ParseExpression() {
|
||||||
/// for example, @encode-expression.
|
/// for example, @encode-expression.
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
|
Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
|
||||||
ExprResult LHS = ParseObjCAtExpression(AtLoc);
|
ExprOwner LHS(Actions, ParseObjCAtExpression(AtLoc));
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid()) return LHS.move();
|
||||||
|
|
||||||
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
|
return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
|
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
|
||||||
|
@ -197,10 +197,10 @@ Parser::ExprResult Parser::ParseAssignmentExpression() {
|
||||||
if (Tok.is(tok::kw_throw))
|
if (Tok.is(tok::kw_throw))
|
||||||
return ParseThrowExpression();
|
return ParseThrowExpression();
|
||||||
|
|
||||||
ExprResult LHS = ParseCastExpression(false);
|
ExprOwner LHS(Actions, ParseCastExpression(false));
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid()) return LHS.move();
|
||||||
|
|
||||||
return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
|
return ParseRHSOfBinaryExpression(LHS.move(), prec::Assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
|
/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
|
||||||
|
@ -216,46 +216,44 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
|
||||||
SourceLocation NameLoc,
|
SourceLocation NameLoc,
|
||||||
IdentifierInfo *ReceiverName,
|
IdentifierInfo *ReceiverName,
|
||||||
ExprTy *ReceiverExpr) {
|
ExprTy *ReceiverExpr) {
|
||||||
ExprResult R = ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
|
ExprOwner R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
|
||||||
ReceiverExpr);
|
ReceiverName,
|
||||||
if (R.isInvalid) return R;
|
ReceiverExpr));
|
||||||
R = ParsePostfixExpressionSuffix(R);
|
if (R.isInvalid()) return R.move();
|
||||||
if (R.isInvalid) return R;
|
R = ParsePostfixExpressionSuffix(R.move());
|
||||||
return ParseRHSOfBinaryExpression(R, 2);
|
if (R.isInvalid()) return R.move();
|
||||||
|
return ParseRHSOfBinaryExpression(R.move(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Parser::ExprResult Parser::ParseConstantExpression() {
|
Parser::ExprResult Parser::ParseConstantExpression() {
|
||||||
ExprResult LHS = ParseCastExpression(false);
|
ExprOwner LHS(Actions, ParseCastExpression(false));
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid()) return LHS.move();
|
||||||
|
|
||||||
return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
|
return ParseRHSOfBinaryExpression(LHS.move(), prec::Conditional);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
|
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
|
||||||
/// LHS and has a precedence of at least MinPrec.
|
/// LHS and has a precedence of at least MinPrec.
|
||||||
Parser::ExprResult
|
Parser::ExprResult
|
||||||
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
|
Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
|
||||||
unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
|
unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
|
||||||
SourceLocation ColonLoc;
|
SourceLocation ColonLoc;
|
||||||
|
|
||||||
ExprGuard LHSGuard(Actions, LHS);
|
ExprOwner LHS(Actions, LHSArg);
|
||||||
while (1) {
|
while (1) {
|
||||||
// If this token has a lower precedence than we are allowed to parse (e.g.
|
// 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),
|
// because we are called recursively, or because the token is not a binop),
|
||||||
// then we are done!
|
// then we are done!
|
||||||
if (NextTokPrec < MinPrec) {
|
if (NextTokPrec < MinPrec)
|
||||||
LHSGuard.take();
|
return LHS.move();
|
||||||
return LHS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consume the operator, saving the operator token for error reporting.
|
// Consume the operator, saving the operator token for error reporting.
|
||||||
Token OpToken = Tok;
|
Token OpToken = Tok;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// Special case handling for the ternary operator.
|
// Special case handling for the ternary operator.
|
||||||
ExprResult TernaryMiddle(true);
|
ExprOwner TernaryMiddle(Actions, true);
|
||||||
ExprGuard MiddleGuard(Actions);
|
|
||||||
if (NextTokPrec == prec::Conditional) {
|
if (NextTokPrec == prec::Conditional) {
|
||||||
if (Tok.isNot(tok::colon)) {
|
if (Tok.isNot(tok::colon)) {
|
||||||
// Handle this production specially:
|
// Handle this production specially:
|
||||||
|
@ -263,17 +261,15 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
|
||||||
// In particular, the RHS of the '?' is 'expression', not
|
// In particular, the RHS of the '?' is 'expression', not
|
||||||
// 'logical-OR-expression' as we might expect.
|
// 'logical-OR-expression' as we might expect.
|
||||||
TernaryMiddle = ParseExpression();
|
TernaryMiddle = ParseExpression();
|
||||||
if (TernaryMiddle.isInvalid) {
|
if (TernaryMiddle.isInvalid())
|
||||||
return TernaryMiddle;
|
return TernaryMiddle.move();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Special case handling of "X ? Y : Z" where Y is empty:
|
// Special case handling of "X ? Y : Z" where Y is empty:
|
||||||
// logical-OR-expression '?' ':' conditional-expression [GNU]
|
// logical-OR-expression '?' ':' conditional-expression [GNU]
|
||||||
TernaryMiddle = ExprResult(false);
|
TernaryMiddle.reset();
|
||||||
Diag(Tok, diag::ext_gnu_conditional_expr);
|
Diag(Tok, diag::ext_gnu_conditional_expr);
|
||||||
}
|
}
|
||||||
MiddleGuard.reset(TernaryMiddle);
|
|
||||||
|
|
||||||
if (Tok.isNot(tok::colon)) {
|
if (Tok.isNot(tok::colon)) {
|
||||||
Diag(Tok, diag::err_expected_colon);
|
Diag(Tok, diag::err_expected_colon);
|
||||||
Diag(OpToken, diag::note_matching) << "?";
|
Diag(OpToken, diag::note_matching) << "?";
|
||||||
|
@ -285,11 +281,9 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse another leaf here for the RHS of the operator.
|
// Parse another leaf here for the RHS of the operator.
|
||||||
ExprResult RHS = ParseCastExpression(false);
|
ExprOwner RHS(Actions, ParseCastExpression(false));
|
||||||
if (RHS.isInvalid) {
|
if (RHS.isInvalid())
|
||||||
return RHS;
|
return RHS.move();
|
||||||
}
|
|
||||||
ExprGuard RHSGuard(Actions, RHS);
|
|
||||||
|
|
||||||
// Remember the precedence of this operator and get the precedence of the
|
// Remember the precedence of this operator and get the precedence of the
|
||||||
// operator immediately to the right of the RHS.
|
// operator immediately to the right of the RHS.
|
||||||
|
@ -309,31 +303,24 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
|
||||||
// is okay, to bind exactly as tightly. For example, compile A=B=C=D as
|
// is okay, to bind exactly as tightly. For example, compile A=B=C=D as
|
||||||
// A=(B=(C=D)), where each paren is a level of recursion here.
|
// A=(B=(C=D)), where each paren is a level of recursion here.
|
||||||
// The function takes ownership of the RHS.
|
// The function takes ownership of the RHS.
|
||||||
RHSGuard.take();
|
RHS = ParseRHSOfBinaryExpression(RHS.move(), ThisPrec + !isRightAssoc);
|
||||||
RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
|
if (RHS.isInvalid())
|
||||||
if (RHS.isInvalid) {
|
return RHS.move();
|
||||||
return RHS;
|
|
||||||
}
|
|
||||||
RHSGuard.reset(RHS);
|
|
||||||
|
|
||||||
NextTokPrec = getBinOpPrecedence(Tok.getKind());
|
NextTokPrec = getBinOpPrecedence(Tok.getKind());
|
||||||
}
|
}
|
||||||
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
|
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
|
||||||
|
|
||||||
if (!LHS.isInvalid) {
|
if (!LHS.isInvalid()) {
|
||||||
// Combine the LHS and RHS into the LHS (e.g. build AST).
|
// Combine the LHS and RHS into the LHS (e.g. build AST).
|
||||||
LHSGuard.take();
|
if (TernaryMiddle.isInvalid())
|
||||||
MiddleGuard.take();
|
|
||||||
RHSGuard.take();
|
|
||||||
if (TernaryMiddle.isInvalid)
|
|
||||||
LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
|
LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
|
||||||
OpToken.getKind(), LHS.Val, RHS.Val);
|
OpToken.getKind(), LHS.move(), RHS.move());
|
||||||
else
|
else
|
||||||
LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
|
LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
|
||||||
LHS.Val, TernaryMiddle.Val, RHS.Val);
|
LHS.move(), TernaryMiddle.move(),
|
||||||
LHSGuard.reset(LHS);
|
RHS.move());
|
||||||
}
|
}
|
||||||
// If we had an invalid LHS, Middle and RHS will be freed by the guards here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +420,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
TryAnnotateTypeOrScopeToken();
|
TryAnnotateTypeOrScopeToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Res;
|
ExprOwner Res(Actions);
|
||||||
tok::TokenKind SavedKind = Tok.getKind();
|
tok::TokenKind SavedKind = Tok.getKind();
|
||||||
|
|
||||||
// This handles all of cast-expression, unary-expression, postfix-expression,
|
// This handles all of cast-expression, unary-expression, postfix-expression,
|
||||||
|
@ -456,7 +443,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
SourceLocation LParenLoc = Tok.getLocation();
|
SourceLocation LParenLoc = Tok.getLocation();
|
||||||
SourceLocation RParenLoc;
|
SourceLocation RParenLoc;
|
||||||
Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
|
Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
|
||||||
if (Res.isInvalid) return Res;
|
if (Res.isInvalid()) return Res.move();
|
||||||
|
|
||||||
switch (ParenExprType) {
|
switch (ParenExprType) {
|
||||||
case SimpleExpr: break; // Nothing else to do.
|
case SimpleExpr: break; // Nothing else to do.
|
||||||
|
@ -470,15 +457,15 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
// the cast-expression that follows it next.
|
// the cast-expression that follows it next.
|
||||||
// TODO: For cast expression with CastTy.
|
// TODO: For cast expression with CastTy.
|
||||||
Res = ParseCastExpression(false);
|
Res = ParseCastExpression(false);
|
||||||
if (!Res.isInvalid)
|
if (!Res.isInvalid())
|
||||||
Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
|
Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.move());
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// primary-expression
|
// primary-expression
|
||||||
case tok::numeric_constant:
|
case tok::numeric_constant:
|
||||||
// constant: integer-constant
|
// constant: integer-constant
|
||||||
|
@ -488,7 +475,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
|
|
||||||
case tok::kw_true:
|
case tok::kw_true:
|
||||||
case tok::kw_false:
|
case tok::kw_false:
|
||||||
|
@ -506,26 +493,26 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
SourceLocation L = ConsumeToken();
|
SourceLocation L = ConsumeToken();
|
||||||
Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
|
Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
}
|
}
|
||||||
case tok::char_constant: // constant: character-constant
|
case tok::char_constant: // constant: character-constant
|
||||||
Res = Actions.ActOnCharacterConstant(Tok);
|
Res = Actions.ActOnCharacterConstant(Tok);
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
|
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
|
||||||
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
|
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
|
||||||
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
|
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
|
||||||
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
|
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
case tok::string_literal: // primary-expression: string-literal
|
case tok::string_literal: // primary-expression: string-literal
|
||||||
case tok::wide_string_literal:
|
case tok::wide_string_literal:
|
||||||
Res = ParseStringLiteralExpression();
|
Res = ParseStringLiteralExpression();
|
||||||
if (Res.isInvalid) return Res;
|
if (Res.isInvalid()) return Res.move();
|
||||||
// This can be followed by postfix-expr pieces (e.g. "foo"[1]).
|
// This can be followed by postfix-expr pieces (e.g. "foo"[1]).
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
case tok::kw___builtin_va_arg:
|
case tok::kw___builtin_va_arg:
|
||||||
case tok::kw___builtin_offsetof:
|
case tok::kw___builtin_offsetof:
|
||||||
case tok::kw___builtin_choose_expr:
|
case tok::kw___builtin_choose_expr:
|
||||||
|
@ -539,9 +526,9 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
case tok::minusminus: { // unary-expression: '--' unary-expression
|
case tok::minusminus: { // unary-expression: '--' unary-expression
|
||||||
SourceLocation SavedLoc = ConsumeToken();
|
SourceLocation SavedLoc = ConsumeToken();
|
||||||
Res = ParseCastExpression(true);
|
Res = ParseCastExpression(true);
|
||||||
if (!Res.isInvalid)
|
if (!Res.isInvalid())
|
||||||
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
|
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
case tok::amp: // unary-expression: '&' cast-expression
|
case tok::amp: // unary-expression: '&' cast-expression
|
||||||
case tok::star: // unary-expression: '*' cast-expression
|
case tok::star: // unary-expression: '*' cast-expression
|
||||||
|
@ -553,19 +540,19 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
|
case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
|
||||||
SourceLocation SavedLoc = ConsumeToken();
|
SourceLocation SavedLoc = ConsumeToken();
|
||||||
Res = ParseCastExpression(false);
|
Res = ParseCastExpression(false);
|
||||||
if (!Res.isInvalid)
|
if (!Res.isInvalid())
|
||||||
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
|
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
|
case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
|
||||||
// __extension__ silences extension warnings in the subexpression.
|
// __extension__ silences extension warnings in the subexpression.
|
||||||
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
||||||
SourceLocation SavedLoc = ConsumeToken();
|
SourceLocation SavedLoc = ConsumeToken();
|
||||||
Res = ParseCastExpression(false);
|
Res = ParseCastExpression(false);
|
||||||
if (!Res.isInvalid)
|
if (!Res.isInvalid())
|
||||||
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
|
Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
|
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
|
||||||
// unary-expression: 'sizeof' '(' type-name ')'
|
// unary-expression: 'sizeof' '(' type-name ')'
|
||||||
|
@ -585,7 +572,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
|
Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
|
||||||
Tok.getIdentifierInfo());
|
Tok.getIdentifierInfo());
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
case tok::kw_const_cast:
|
case tok::kw_const_cast:
|
||||||
case tok::kw_dynamic_cast:
|
case tok::kw_dynamic_cast:
|
||||||
|
@ -593,15 +580,15 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
case tok::kw_static_cast:
|
case tok::kw_static_cast:
|
||||||
Res = ParseCXXCasts();
|
Res = ParseCXXCasts();
|
||||||
// These can be followed by postfix-expr pieces.
|
// These can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
case tok::kw_typeid:
|
case tok::kw_typeid:
|
||||||
Res = ParseCXXTypeid();
|
Res = ParseCXXTypeid();
|
||||||
// This can be followed by postfix-expr pieces.
|
// This can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
case tok::kw_this:
|
case tok::kw_this:
|
||||||
Res = ParseCXXThis();
|
Res = ParseCXXThis();
|
||||||
// This can be followed by postfix-expr pieces.
|
// This can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
|
|
||||||
case tok::kw_char:
|
case tok::kw_char:
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
|
@ -629,14 +616,14 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
|
|
||||||
Res = ParseCXXTypeConstructExpression(DS);
|
Res = ParseCXXTypeConstructExpression(DS);
|
||||||
// This can be followed by postfix-expr pieces.
|
// This can be followed by postfix-expr pieces.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
|
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
|
||||||
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
|
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
|
||||||
// template-id
|
// template-id
|
||||||
Res = ParseCXXIdExpression();
|
Res = ParseCXXIdExpression();
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
|
|
||||||
case tok::coloncolon: // [C++] new-expression or [C++] delete-expression
|
case tok::coloncolon: // [C++] new-expression or [C++] delete-expression
|
||||||
// If the next token is neither 'new' nor 'delete', the :: would have been
|
// If the next token is neither 'new' nor 'delete', the :: would have been
|
||||||
|
@ -694,35 +681,32 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
/// argument-expression
|
/// argument-expression
|
||||||
/// argument-expression-list ',' assignment-expression
|
/// argument-expression-list ',' assignment-expression
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHSArg) {
|
||||||
ExprGuard LHSGuard(Actions, LHS);
|
ExprOwner LHS(Actions, LHSArg);
|
||||||
// Now that the primary-expression piece of the postfix-expression has been
|
// Now that the primary-expression piece of the postfix-expression has been
|
||||||
// parsed, see if there are any postfix-expression pieces here.
|
// parsed, see if there are any postfix-expression pieces here.
|
||||||
SourceLocation Loc;
|
SourceLocation Loc;
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
default: // Not a postfix-expression suffix.
|
default: // Not a postfix-expression suffix.
|
||||||
LHSGuard.take();
|
return LHS.move();
|
||||||
return LHS;
|
|
||||||
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
|
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
|
||||||
Loc = ConsumeBracket();
|
Loc = ConsumeBracket();
|
||||||
ExprResult Idx = ParseExpression();
|
ExprOwner Idx(Actions, ParseExpression());
|
||||||
ExprGuard IdxGuard(Actions, Idx);
|
|
||||||
|
|
||||||
SourceLocation RLoc = Tok.getLocation();
|
SourceLocation RLoc = Tok.getLocation();
|
||||||
|
|
||||||
if (!LHS.isInvalid && !Idx.isInvalid && Tok.is(tok::r_square)) {
|
if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
|
||||||
LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHSGuard.take(), Loc,
|
LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHS.move(), Loc,
|
||||||
IdxGuard.take(), RLoc);
|
Idx.move(), RLoc);
|
||||||
LHSGuard.reset(LHS);
|
} else
|
||||||
} else
|
|
||||||
LHS = ExprResult(true);
|
LHS = ExprResult(true);
|
||||||
|
|
||||||
// Match the ']'.
|
// Match the ']'.
|
||||||
MatchRHSPunctuation(tok::r_square, Loc);
|
MatchRHSPunctuation(tok::r_square, Loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')'
|
case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')'
|
||||||
ExprVector ArgExprs(Actions);
|
ExprVector ArgExprs(Actions);
|
||||||
CommaLocsTy CommaLocs;
|
CommaLocsTy CommaLocs;
|
||||||
|
@ -737,14 +721,13 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
if (!LHS.isInvalid && Tok.is(tok::r_paren)) {
|
if (!LHS.isInvalid() && Tok.is(tok::r_paren)) {
|
||||||
assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
|
assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
|
||||||
"Unexpected number of commas!");
|
"Unexpected number of commas!");
|
||||||
LHS = Actions.ActOnCallExpr(CurScope, LHSGuard.take(), Loc,
|
LHS = Actions.ActOnCallExpr(CurScope, LHS.move(), Loc,
|
||||||
ArgExprs.take(),
|
ArgExprs.take(),
|
||||||
ArgExprs.size(), &CommaLocs[0],
|
ArgExprs.size(), &CommaLocs[0],
|
||||||
Tok.getLocation());
|
Tok.getLocation());
|
||||||
LHSGuard.reset(LHS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchRHSPunctuation(tok::r_paren, Loc);
|
MatchRHSPunctuation(tok::r_paren, Loc);
|
||||||
|
@ -760,21 +743,19 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LHS.isInvalid) {
|
if (!LHS.isInvalid()) {
|
||||||
LHS = Actions.ActOnMemberReferenceExpr(LHSGuard.take(), OpLoc, OpKind,
|
LHS = Actions.ActOnMemberReferenceExpr(LHS.move(), OpLoc, OpKind,
|
||||||
Tok.getLocation(),
|
Tok.getLocation(),
|
||||||
*Tok.getIdentifierInfo());
|
*Tok.getIdentifierInfo());
|
||||||
LHSGuard.reset(LHS);
|
|
||||||
}
|
}
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tok::plusplus: // postfix-expression: postfix-expression '++'
|
case tok::plusplus: // postfix-expression: postfix-expression '++'
|
||||||
case tok::minusminus: // postfix-expression: postfix-expression '--'
|
case tok::minusminus: // postfix-expression: postfix-expression '--'
|
||||||
if (!LHS.isInvalid) {
|
if (!LHS.isInvalid()) {
|
||||||
LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
|
LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
|
||||||
Tok.getKind(), LHSGuard.take());
|
Tok.getKind(), LHS.move());
|
||||||
LHSGuard.reset(LHS);
|
|
||||||
}
|
}
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
break;
|
break;
|
||||||
|
@ -798,7 +779,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// If the operand doesn't start with an '(', it must be an expression.
|
// If the operand doesn't start with an '(', it must be an expression.
|
||||||
ExprResult Operand;
|
ExprOwner Operand(Actions);
|
||||||
if (Tok.isNot(tok::l_paren)) {
|
if (Tok.isNot(tok::l_paren)) {
|
||||||
Operand = ParseCastExpression(true);
|
Operand = ParseCastExpression(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -822,16 +803,16 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
|
||||||
// If this is a parenthesized expression, it is the start of a
|
// If this is a parenthesized expression, it is the start of a
|
||||||
// unary-expression, but doesn't include any postfix pieces. Parse these
|
// unary-expression, but doesn't include any postfix pieces. Parse these
|
||||||
// now if present.
|
// now if present.
|
||||||
Operand = ParsePostfixExpressionSuffix(Operand);
|
Operand = ParsePostfixExpressionSuffix(Operand.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get here, the operand to the sizeof/alignof was an expresion.
|
// If we get here, the operand to the sizeof/alignof was an expresion.
|
||||||
if (!Operand.isInvalid)
|
if (!Operand.isInvalid())
|
||||||
Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
|
Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
|
||||||
OpTok.is(tok::kw_sizeof),
|
OpTok.is(tok::kw_sizeof),
|
||||||
/*isType=*/false, Operand.Val,
|
/*isType=*/false, Operand.move(),
|
||||||
SourceRange());
|
SourceRange());
|
||||||
return Operand;
|
return Operand.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseBuiltinPrimaryExpression
|
/// ParseBuiltinPrimaryExpression
|
||||||
|
@ -850,7 +831,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
|
||||||
/// [GNU] offsetof-member-designator '[' expression ']'
|
/// [GNU] offsetof-member-designator '[' expression ']'
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
ExprResult Res(false);
|
ExprOwner Res(Actions);
|
||||||
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
|
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
|
||||||
|
|
||||||
tok::TokenKind T = Tok.getKind();
|
tok::TokenKind T = Tok.getKind();
|
||||||
|
@ -868,9 +849,8 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
switch (T) {
|
switch (T) {
|
||||||
default: assert(0 && "Not a builtin primary expression!");
|
default: assert(0 && "Not a builtin primary expression!");
|
||||||
case tok::kw___builtin_va_arg: {
|
case tok::kw___builtin_va_arg: {
|
||||||
ExprResult Expr = ParseAssignmentExpression();
|
ExprOwner Expr(Actions, ParseAssignmentExpression());
|
||||||
ExprGuard ExprGuard(Actions, Expr);
|
if (Expr.isInvalid()) {
|
||||||
if (Expr.isInvalid) {
|
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
}
|
}
|
||||||
|
@ -879,12 +859,12 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
|
|
||||||
TypeTy *Ty = ParseTypeName();
|
TypeTy *Ty = ParseTypeName();
|
||||||
|
|
||||||
if (Tok.isNot(tok::r_paren)) {
|
if (Tok.isNot(tok::r_paren)) {
|
||||||
Diag(Tok, diag::err_expected_rparen);
|
Diag(Tok, diag::err_expected_rparen);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
}
|
}
|
||||||
Res = Actions.ActOnVAArg(StartLoc, ExprGuard.take(), Ty, ConsumeParen());
|
Res = Actions.ActOnVAArg(StartLoc, Expr.move(), Ty, ConsumeParen());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tok::kw___builtin_offsetof: {
|
case tok::kw___builtin_offsetof: {
|
||||||
|
@ -931,11 +911,11 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
Comps.back().isBrackets = true;
|
Comps.back().isBrackets = true;
|
||||||
Comps.back().LocStart = ConsumeBracket();
|
Comps.back().LocStart = ConsumeBracket();
|
||||||
Res = ParseExpression();
|
Res = ParseExpression();
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
Comps.back().U.E = Res.Val;
|
Comps.back().U.E = Res.move();
|
||||||
|
|
||||||
Comps.back().LocEnd =
|
Comps.back().LocEnd =
|
||||||
MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
|
MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
|
||||||
|
@ -951,36 +931,33 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tok::kw___builtin_choose_expr: {
|
case tok::kw___builtin_choose_expr: {
|
||||||
ExprResult Cond = ParseAssignmentExpression();
|
ExprOwner Cond(Actions, ParseAssignmentExpression());
|
||||||
ExprGuard CondGuard(Actions, Cond);
|
if (Cond.isInvalid()) {
|
||||||
if (Cond.isInvalid) {
|
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return Cond;
|
return Cond.move();
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
|
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
|
|
||||||
ExprResult Expr1 = ParseAssignmentExpression();
|
ExprOwner Expr1(Actions, ParseAssignmentExpression());
|
||||||
ExprGuard Guard1(Actions, Expr1);
|
if (Expr1.isInvalid()) {
|
||||||
if (Expr1.isInvalid) {
|
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return Expr1;
|
return Expr1.move();
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
|
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
|
|
||||||
ExprResult Expr2 = ParseAssignmentExpression();
|
ExprOwner Expr2(Actions, ParseAssignmentExpression());
|
||||||
ExprGuard Guard2(Actions, Expr2);
|
if (Expr2.isInvalid()) {
|
||||||
if (Expr2.isInvalid) {
|
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return Expr2;
|
return Expr2.move();
|
||||||
}
|
}
|
||||||
if (Tok.isNot(tok::r_paren)) {
|
if (Tok.isNot(tok::r_paren)) {
|
||||||
Diag(Tok, diag::err_expected_rparen);
|
Diag(Tok, diag::err_expected_rparen);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
}
|
}
|
||||||
Res = Actions.ActOnChooseExpr(StartLoc, CondGuard.take(), Guard1.take(),
|
Res = Actions.ActOnChooseExpr(StartLoc, Cond.move(), Expr1.move(),
|
||||||
Guard2.take(), ConsumeParen());
|
Expr2.move(), ConsumeParen());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tok::kw___builtin_overload: {
|
case tok::kw___builtin_overload: {
|
||||||
|
@ -991,13 +968,13 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
// comma. If there is no comma, break and attempt to match r-paren.
|
// comma. If there is no comma, break and attempt to match r-paren.
|
||||||
if (Tok.isNot(tok::r_paren)) {
|
if (Tok.isNot(tok::r_paren)) {
|
||||||
while (1) {
|
while (1) {
|
||||||
ExprResult ArgExpr = ParseAssignmentExpression();
|
ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
|
||||||
if (ArgExpr.isInvalid) {
|
if (ArgExpr.isInvalid()) {
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
} else
|
} else
|
||||||
ArgExprs.push_back(ArgExpr.Val);
|
ArgExprs.push_back(ArgExpr.move());
|
||||||
|
|
||||||
if (Tok.isNot(tok::comma))
|
if (Tok.isNot(tok::comma))
|
||||||
break;
|
break;
|
||||||
// Move to the next argument, remember where the comma was.
|
// Move to the next argument, remember where the comma was.
|
||||||
|
@ -1033,7 +1010,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||||
|
|
||||||
// These can be followed by postfix-expr pieces because they are
|
// These can be followed by postfix-expr pieces because they are
|
||||||
// primary-expressions.
|
// primary-expressions.
|
||||||
return ParsePostfixExpressionSuffix(Res);
|
return ParsePostfixExpressionSuffix(Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseParenExpression - This parses the unit that starts with a '(' token,
|
/// ParseParenExpression - This parses the unit that starts with a '(' token,
|
||||||
|
@ -1054,18 +1031,19 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
|
||||||
SourceLocation &RParenLoc) {
|
SourceLocation &RParenLoc) {
|
||||||
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
|
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
|
||||||
SourceLocation OpenLoc = ConsumeParen();
|
SourceLocation OpenLoc = ConsumeParen();
|
||||||
ExprResult Result(true);
|
ExprOwner Result(Actions, true);
|
||||||
CastTy = 0;
|
CastTy = 0;
|
||||||
|
|
||||||
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
||||||
Diag(Tok, diag::ext_gnu_statement_expr);
|
Diag(Tok, diag::ext_gnu_statement_expr);
|
||||||
Parser::StmtResult Stmt = ParseCompoundStatement(true);
|
StmtOwner Stmt(Actions, ParseCompoundStatement(true));
|
||||||
ExprType = CompoundStmt;
|
ExprType = CompoundStmt;
|
||||||
|
|
||||||
// If the substmt parsed correctly, build the AST node.
|
// If the substmt parsed correctly, build the AST node.
|
||||||
if (!Stmt.isInvalid && Tok.is(tok::r_paren))
|
if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
|
||||||
Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation());
|
Result = Actions.ActOnStmtExpr(
|
||||||
|
OpenLoc, Stmt.move(), Tok.getLocation());
|
||||||
|
|
||||||
} else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
|
} else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
|
||||||
// Otherwise, this is a compound literal expression or cast expression.
|
// Otherwise, this is a compound literal expression or cast expression.
|
||||||
TypeTy *Ty = ParseTypeName();
|
TypeTy *Ty = ParseTypeName();
|
||||||
|
@ -1081,8 +1059,9 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
|
||||||
Diag(OpenLoc, diag::ext_c99_compound_literal);
|
Diag(OpenLoc, diag::ext_c99_compound_literal);
|
||||||
Result = ParseInitializer();
|
Result = ParseInitializer();
|
||||||
ExprType = CompoundLiteral;
|
ExprType = CompoundLiteral;
|
||||||
if (!Result.isInvalid)
|
if (!Result.isInvalid())
|
||||||
return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
|
return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc,
|
||||||
|
Result.take());
|
||||||
} else if (ExprType == CastExpr) {
|
} else if (ExprType == CastExpr) {
|
||||||
// Note that this doesn't parse the subsequence cast-expression, it just
|
// Note that this doesn't parse the subsequence cast-expression, it just
|
||||||
// returns the parsed type to the callee.
|
// returns the parsed type to the callee.
|
||||||
|
@ -1093,16 +1072,17 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
|
||||||
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
|
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result.move();
|
||||||
} else {
|
} else {
|
||||||
Result = ParseExpression();
|
Result = ParseExpression();
|
||||||
ExprType = SimpleExpr;
|
ExprType = SimpleExpr;
|
||||||
if (!Result.isInvalid && Tok.is(tok::r_paren))
|
if (!Result.isInvalid() && Tok.is(tok::r_paren))
|
||||||
Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.Val);
|
Result = Actions.ActOnParenExpr(
|
||||||
|
OpenLoc, Tok.getLocation(), Result.take());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
if (Result.isInvalid)
|
if (Result.isInvalid())
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
else {
|
else {
|
||||||
if (Tok.is(tok::r_paren))
|
if (Tok.is(tok::r_paren))
|
||||||
|
@ -1111,7 +1091,7 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
|
||||||
MatchRHSPunctuation(tok::r_paren, OpenLoc);
|
MatchRHSPunctuation(tok::r_paren, OpenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseStringLiteralExpression - This handles the various token types that
|
/// ParseStringLiteralExpression - This handles the various token types that
|
||||||
|
@ -1148,11 +1128,11 @@ Parser::ExprResult Parser::ParseStringLiteralExpression() {
|
||||||
///
|
///
|
||||||
bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
|
bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
|
||||||
while (1) {
|
while (1) {
|
||||||
ExprResult Expr = ParseAssignmentExpression();
|
ExprOwner Expr(Actions, ParseAssignmentExpression());
|
||||||
if (Expr.isInvalid)
|
if (Expr.isInvalid())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Exprs.push_back(Expr.Val);
|
Exprs.push_back(Expr.move());
|
||||||
|
|
||||||
if (Tok.isNot(tok::comma))
|
if (Tok.isNot(tok::comma))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1209,16 +1189,16 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockArguments(ParamInfo);
|
Actions.ActOnBlockArguments(ParamInfo);
|
||||||
|
|
||||||
ExprResult Result = true;
|
ExprOwner Result(Actions, true);
|
||||||
if (Tok.is(tok::l_brace)) {
|
if (Tok.is(tok::l_brace)) {
|
||||||
StmtResult Stmt = ParseCompoundStatementBody();
|
StmtOwner Stmt(Actions, ParseCompoundStatementBody());
|
||||||
if (!Stmt.isInvalid) {
|
if (!Stmt.isInvalid()) {
|
||||||
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope);
|
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.move(), CurScope);
|
||||||
} else {
|
} else {
|
||||||
Actions.ActOnBlockError(CaretLoc, CurScope);
|
Actions.ActOnBlockError(CaretLoc, CurScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExitScope();
|
ExitScope();
|
||||||
return Result;
|
return Result.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,14 +221,14 @@ Parser::ExprResult Parser::ParseCXXCasts() {
|
||||||
if (Tok.isNot(tok::l_paren))
|
if (Tok.isNot(tok::l_paren))
|
||||||
return Diag(Tok, diag::err_expected_lparen_after) << CastName;
|
return Diag(Tok, diag::err_expected_lparen_after) << CastName;
|
||||||
|
|
||||||
ExprResult Result = ParseSimpleParenExpression(RParenLoc);
|
ExprOwner Result(Actions, ParseSimpleParenExpression(RParenLoc));
|
||||||
|
|
||||||
if (!Result.isInvalid)
|
if (!Result.isInvalid())
|
||||||
Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
|
Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
|
||||||
LAngleBracketLoc, CastTy, RAngleBracketLoc,
|
LAngleBracketLoc, CastTy, RAngleBracketLoc,
|
||||||
LParenLoc, Result.Val, RParenLoc);
|
LParenLoc, Result.move(), RParenLoc);
|
||||||
|
|
||||||
return Result;
|
return Result.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCXXTypeid - This handles the C++ typeid expression.
|
/// ParseCXXTypeid - This handles the C++ typeid expression.
|
||||||
|
@ -249,7 +249,7 @@ Parser::ExprResult Parser::ParseCXXTypeid() {
|
||||||
"typeid"))
|
"typeid"))
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
|
|
||||||
Parser::ExprResult Result;
|
ExprOwner Result(Actions);
|
||||||
|
|
||||||
if (isTypeIdInParens()) {
|
if (isTypeIdInParens()) {
|
||||||
TypeTy *Ty = ParseTypeName();
|
TypeTy *Ty = ParseTypeName();
|
||||||
|
@ -266,17 +266,17 @@ Parser::ExprResult Parser::ParseCXXTypeid() {
|
||||||
Result = ParseExpression();
|
Result = ParseExpression();
|
||||||
|
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
if (Result.isInvalid)
|
if (Result.isInvalid())
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
else {
|
else {
|
||||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
|
|
||||||
Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
|
Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
|
||||||
Result.Val, RParenLoc);
|
Result.move(), RParenLoc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
|
/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
|
||||||
|
@ -310,9 +310,9 @@ Parser::ExprResult Parser::ParseThrowExpression() {
|
||||||
return Actions.ActOnCXXThrow(ThrowLoc);
|
return Actions.ActOnCXXThrow(ThrowLoc);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ExprResult Expr = ParseAssignmentExpression();
|
ExprOwner Expr(Actions, ParseAssignmentExpression());
|
||||||
if (Expr.isInvalid) return Expr;
|
if (Expr.isInvalid()) return Expr.move();
|
||||||
return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val);
|
return Actions.ActOnCXXThrow(ThrowLoc, Expr.move());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,12 +388,12 @@ Parser::ExprResult Parser::ParseCXXCondition() {
|
||||||
|
|
||||||
// simple-asm-expr[opt]
|
// simple-asm-expr[opt]
|
||||||
if (Tok.is(tok::kw_asm)) {
|
if (Tok.is(tok::kw_asm)) {
|
||||||
ExprResult AsmLabel = ParseSimpleAsm();
|
ExprOwner AsmLabel(Actions, ParseSimpleAsm());
|
||||||
if (AsmLabel.isInvalid) {
|
if (AsmLabel.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
DeclaratorInfo.setAsmLabel(AsmLabel.Val);
|
DeclaratorInfo.setAsmLabel(AsmLabel.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
|
@ -404,13 +404,13 @@ Parser::ExprResult Parser::ParseCXXCondition() {
|
||||||
if (Tok.isNot(tok::equal))
|
if (Tok.isNot(tok::equal))
|
||||||
return Diag(Tok, diag::err_expected_equal_after_declarator);
|
return Diag(Tok, diag::err_expected_equal_after_declarator);
|
||||||
SourceLocation EqualLoc = ConsumeToken();
|
SourceLocation EqualLoc = ConsumeToken();
|
||||||
ExprResult AssignExpr = ParseAssignmentExpression();
|
ExprOwner AssignExpr(Actions, ParseAssignmentExpression());
|
||||||
if (AssignExpr.isInvalid)
|
if (AssignExpr.isInvalid())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
|
return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
|
||||||
DeclaratorInfo,
|
DeclaratorInfo,
|
||||||
EqualLoc, AssignExpr.Val);
|
EqualLoc, AssignExpr.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
|
/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
|
||||||
|
@ -776,8 +776,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D)
|
||||||
bool first = true;
|
bool first = true;
|
||||||
while (Tok.is(tok::l_square)) {
|
while (Tok.is(tok::l_square)) {
|
||||||
SourceLocation LLoc = ConsumeBracket();
|
SourceLocation LLoc = ConsumeBracket();
|
||||||
ExprResult Size = first ? ParseExpression() : ParseConstantExpression();
|
ExprOwner Size(Actions, first ? ParseExpression()
|
||||||
if (Size.isInvalid) {
|
: ParseConstantExpression());
|
||||||
|
if (Size.isInvalid()) {
|
||||||
// Recover
|
// Recover
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return;
|
return;
|
||||||
|
@ -785,7 +786,7 @@ void Parser::ParseDirectNewDeclarator(Declarator &D)
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
|
||||||
Size.Val, LLoc));
|
Size.move(), LLoc));
|
||||||
|
|
||||||
if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid())
|
if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid())
|
||||||
return;
|
return;
|
||||||
|
@ -850,9 +851,9 @@ Parser::ExprResult Parser::ParseCXXDeleteExpression()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Operand = ParseCastExpression(false);
|
ExprOwner Operand(Actions, ParseCastExpression(false));
|
||||||
if (Operand.isInvalid)
|
if (Operand.isInvalid())
|
||||||
return Operand;
|
return Operand.move();
|
||||||
|
|
||||||
return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.Val);
|
return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.move());
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,10 +143,10 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
|
||||||
// Note that we parse this as an assignment expression, not a constant
|
// Note that we parse this as an assignment expression, not a constant
|
||||||
// expression (allowing *=, =, etc) to handle the objc case. Sema needs
|
// expression (allowing *=, =, etc) to handle the objc case. Sema needs
|
||||||
// to validate that the expression is a constant.
|
// to validate that the expression is a constant.
|
||||||
ExprResult Idx = ParseAssignmentExpression();
|
ExprOwner Idx(Actions, ParseAssignmentExpression());
|
||||||
if (Idx.isInvalid) {
|
if (Idx.isInvalid()) {
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return Idx;
|
return Idx.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an expression, we could either have a designator (if the next
|
// Given an expression, we could either have a designator (if the next
|
||||||
|
@ -170,7 +170,7 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
|
||||||
|
|
||||||
return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
|
return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
0, Idx.Val);
|
0, Idx.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create designation if we haven't already.
|
// Create designation if we haven't already.
|
||||||
|
@ -179,21 +179,20 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
|
||||||
|
|
||||||
// If this is a normal array designator, remember it.
|
// If this is a normal array designator, remember it.
|
||||||
if (Tok.isNot(tok::ellipsis)) {
|
if (Tok.isNot(tok::ellipsis)) {
|
||||||
Desig->AddDesignator(Designator::getArray(Idx.Val));
|
Desig->AddDesignator(Designator::getArray(Idx.move()));
|
||||||
} else {
|
} else {
|
||||||
// Handle the gnu array range extension.
|
// Handle the gnu array range extension.
|
||||||
Diag(Tok, diag::ext_gnu_array_range);
|
Diag(Tok, diag::ext_gnu_array_range);
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
ExprResult RHS = ParseConstantExpression();
|
ExprOwner RHS(Actions, ParseConstantExpression());
|
||||||
if (RHS.isInvalid) {
|
if (RHS.isInvalid()) {
|
||||||
Actions.DeleteExpr(Idx.Val);
|
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return RHS;
|
return RHS.move();
|
||||||
}
|
}
|
||||||
Desig->AddDesignator(Designator::getArrayRange(Idx.Val, RHS.Val));
|
Desig->AddDesignator(Designator::getArrayRange(Idx.move(), RHS.move()));
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchRHSPunctuation(tok::r_square, StartLoc);
|
MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +263,7 @@ Parser::ExprResult Parser::ParseBraceInitializer() {
|
||||||
|
|
||||||
// If we know that this cannot be a designation, just parse the nested
|
// If we know that this cannot be a designation, just parse the nested
|
||||||
// initializer directly.
|
// initializer directly.
|
||||||
ExprResult SubElt;
|
ExprOwner SubElt(Actions);
|
||||||
if (!MayBeDesignationStart(Tok.getKind(), PP))
|
if (!MayBeDesignationStart(Tok.getKind(), PP))
|
||||||
SubElt = ParseInitializer();
|
SubElt = ParseInitializer();
|
||||||
else {
|
else {
|
||||||
|
@ -275,13 +274,13 @@ Parser::ExprResult Parser::ParseBraceInitializer() {
|
||||||
// designator, make sure to remove the designator from
|
// designator, make sure to remove the designator from
|
||||||
// InitExprDesignations, otherwise we'll end up with a designator with no
|
// InitExprDesignations, otherwise we'll end up with a designator with no
|
||||||
// making initializer.
|
// making initializer.
|
||||||
if (SubElt.isInvalid)
|
if (SubElt.isInvalid())
|
||||||
InitExprDesignations.EraseDesignation(InitExprs.size());
|
InitExprDesignations.EraseDesignation(InitExprs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we couldn't parse the subelement, bail out.
|
// If we couldn't parse the subelement, bail out.
|
||||||
if (!SubElt.isInvalid) {
|
if (!SubElt.isInvalid()) {
|
||||||
InitExprs.push_back(SubElt.Val);
|
InitExprs.push_back(SubElt.move());
|
||||||
} else {
|
} else {
|
||||||
InitExprsOk = false;
|
InitExprsOk = false;
|
||||||
|
|
||||||
|
@ -298,7 +297,7 @@ Parser::ExprResult Parser::ParseBraceInitializer() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have a comma continued list, we're done.
|
// If we don't have a comma continued list, we're done.
|
||||||
if (Tok.isNot(tok::comma)) break;
|
if (Tok.isNot(tok::comma)) break;
|
||||||
|
|
||||||
|
|
|
@ -1175,17 +1175,17 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
|
||||||
/// throw expression[opt];
|
/// throw expression[opt];
|
||||||
///
|
///
|
||||||
Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
|
Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
|
||||||
ExprResult Res;
|
ExprOwner Res(Actions);
|
||||||
ConsumeToken(); // consume throw
|
ConsumeToken(); // consume throw
|
||||||
if (Tok.isNot(tok::semi)) {
|
if (Tok.isNot(tok::semi)) {
|
||||||
Res = ParseExpression();
|
Res = ParseExpression();
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConsumeToken(); // consume ';'
|
ConsumeToken(); // consume ';'
|
||||||
return Actions.ActOnObjCAtThrowStmt(atLoc, Res.Val);
|
return Actions.ActOnObjCAtThrowStmt(atLoc, Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// objc-synchronized-statement:
|
/// objc-synchronized-statement:
|
||||||
|
@ -1198,9 +1198,8 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ConsumeParen(); // '('
|
ConsumeParen(); // '('
|
||||||
ExprResult Res = ParseExpression();
|
ExprOwner Res(Actions, ParseExpression());
|
||||||
ExprGuard ResGuard(Actions, Res);
|
if (Res.isInvalid()) {
|
||||||
if (Res.isInvalid) {
|
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1217,13 +1216,13 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
|
||||||
// statements can always hold declarations.
|
// statements can always hold declarations.
|
||||||
EnterScope(Scope::DeclScope);
|
EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
StmtResult SynchBody = ParseCompoundStatementBody();
|
StmtOwner SynchBody(Actions, ParseCompoundStatementBody());
|
||||||
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
if (SynchBody.isInvalid)
|
if (SynchBody.isInvalid())
|
||||||
SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
return Actions.ActOnObjCAtSynchronizedStmt(atLoc, ResGuard.take(),
|
return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.move(),
|
||||||
SynchBody.Val);
|
SynchBody.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// objc-try-catch-statement:
|
/// objc-try-catch-statement:
|
||||||
|
@ -1245,15 +1244,13 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
Diag(Tok, diag::err_expected_lbrace);
|
Diag(Tok, diag::err_expected_lbrace);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
StmtResult CatchStmts;
|
StmtOwner CatchStmts(Actions);
|
||||||
StmtResult FinallyStmt;
|
StmtOwner FinallyStmt(Actions);
|
||||||
EnterScope(Scope::DeclScope);
|
EnterScope(Scope::DeclScope);
|
||||||
StmtResult TryBody = ParseCompoundStatementBody();
|
StmtOwner TryBody(Actions, ParseCompoundStatementBody());
|
||||||
ExitScope();
|
ExitScope();
|
||||||
if (TryBody.isInvalid)
|
if (TryBody.isInvalid())
|
||||||
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
|
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
ExprGuard TryGuard(Actions, TryBody);
|
|
||||||
ExprGuard CatchGuard(Actions), FinallyGuard(Actions);
|
|
||||||
|
|
||||||
while (Tok.is(tok::at)) {
|
while (Tok.is(tok::at)) {
|
||||||
// At this point, we need to lookahead to determine if this @ is the start
|
// At this point, we need to lookahead to determine if this @ is the start
|
||||||
|
@ -1263,10 +1260,10 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
|
if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
|
||||||
!AfterAt.isObjCAtKeyword(tok::objc_finally))
|
!AfterAt.isObjCAtKeyword(tok::objc_finally))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SourceLocation AtCatchFinallyLoc = ConsumeToken();
|
SourceLocation AtCatchFinallyLoc = ConsumeToken();
|
||||||
if (Tok.isObjCAtKeyword(tok::objc_catch)) {
|
if (Tok.isObjCAtKeyword(tok::objc_catch)) {
|
||||||
StmtTy *FirstPart = 0;
|
StmtOwner FirstPart(Actions);
|
||||||
ConsumeToken(); // consume catch
|
ConsumeToken(); // consume catch
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
|
@ -1281,26 +1278,24 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
if (DeclaratorInfo.getIdentifier()) {
|
if (DeclaratorInfo.getIdentifier()) {
|
||||||
DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
|
DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
|
||||||
DeclaratorInfo, 0);
|
DeclaratorInfo, 0);
|
||||||
StmtResult stmtResult =
|
FirstPart =
|
||||||
Actions.ActOnDeclStmt(aBlockVarDecl,
|
Actions.ActOnDeclStmt(aBlockVarDecl,
|
||||||
DS.getSourceRange().getBegin(),
|
DS.getSourceRange().getBegin(),
|
||||||
DeclaratorInfo.getSourceRange().getEnd());
|
DeclaratorInfo.getSourceRange().getEnd());
|
||||||
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
ConsumeToken(); // consume '...'
|
ConsumeToken(); // consume '...'
|
||||||
SourceLocation RParenLoc = ConsumeParen();
|
SourceLocation RParenLoc = ConsumeParen();
|
||||||
|
|
||||||
StmtResult CatchBody(true);
|
StmtOwner CatchBody(Actions, true);
|
||||||
if (Tok.is(tok::l_brace))
|
if (Tok.is(tok::l_brace))
|
||||||
CatchBody = ParseCompoundStatementBody();
|
CatchBody = ParseCompoundStatementBody();
|
||||||
else
|
else
|
||||||
Diag(Tok, diag::err_expected_lbrace);
|
Diag(Tok, diag::err_expected_lbrace);
|
||||||
if (CatchBody.isInvalid)
|
if (CatchBody.isInvalid())
|
||||||
CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc,
|
CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
|
||||||
FirstPart, CatchBody.Val, CatchGuard.take());
|
RParenLoc, FirstPart.move(), CatchBody.move(), CatchStmts.move());
|
||||||
CatchGuard.reset(CatchStmts);
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
} else {
|
} else {
|
||||||
Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
|
Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
|
||||||
|
@ -1313,17 +1308,16 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
ConsumeToken(); // consume finally
|
ConsumeToken(); // consume finally
|
||||||
EnterScope(Scope::DeclScope);
|
EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
|
|
||||||
StmtResult FinallyBody(true);
|
StmtOwner FinallyBody(Actions, true);
|
||||||
if (Tok.is(tok::l_brace))
|
if (Tok.is(tok::l_brace))
|
||||||
FinallyBody = ParseCompoundStatementBody();
|
FinallyBody = ParseCompoundStatementBody();
|
||||||
else
|
else
|
||||||
Diag(Tok, diag::err_expected_lbrace);
|
Diag(Tok, diag::err_expected_lbrace);
|
||||||
if (FinallyBody.isInvalid)
|
if (FinallyBody.isInvalid())
|
||||||
FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
|
FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
|
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
|
||||||
FinallyBody.Val);
|
FinallyBody.move());
|
||||||
FinallyGuard.reset(FinallyStmt);
|
|
||||||
catch_or_finally_seen = true;
|
catch_or_finally_seen = true;
|
||||||
ExitScope();
|
ExitScope();
|
||||||
break;
|
break;
|
||||||
|
@ -1333,8 +1327,8 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
Diag(atLoc, diag::err_missing_catch_finally);
|
Diag(atLoc, diag::err_missing_catch_finally);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return Actions.ActOnObjCAtTryStmt(atLoc, TryGuard.take(), CatchGuard.take(),
|
return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.move(), CatchStmts.move(),
|
||||||
FinallyGuard.take());
|
FinallyStmt.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
|
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
|
||||||
|
@ -1365,17 +1359,17 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
|
||||||
// specified Declarator for the method.
|
// specified Declarator for the method.
|
||||||
Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl);
|
Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl);
|
||||||
|
|
||||||
StmtResult FnBody = ParseCompoundStatementBody();
|
StmtOwner FnBody(Actions, ParseCompoundStatementBody());
|
||||||
|
|
||||||
// If the function body could not be parsed, make a bogus compoundstmt.
|
// If the function body could not be parsed, make a bogus compoundstmt.
|
||||||
if (FnBody.isInvalid)
|
if (FnBody.isInvalid())
|
||||||
FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
|
FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
|
||||||
|
|
||||||
// Leave the function body scope.
|
// Leave the function body scope.
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
// TODO: Pass argument information.
|
// TODO: Pass argument information.
|
||||||
Actions.ActOnFinishFunctionBody(MDecl, FnBody.Val);
|
Actions.ActOnFinishFunctionBody(MDecl, FnBody.move());
|
||||||
return MDecl;
|
return MDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1386,8 +1380,8 @@ Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
|
||||||
return ParseObjCThrowStmt(AtLoc);
|
return ParseObjCThrowStmt(AtLoc);
|
||||||
else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
|
else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
|
||||||
return ParseObjCSynchronizedStmt(AtLoc);
|
return ParseObjCSynchronizedStmt(AtLoc);
|
||||||
ExprResult Res = ParseExpressionWithLeadingAt(AtLoc);
|
ExprOwner Res(Actions, ParseExpressionWithLeadingAt(AtLoc));
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
// If the expression is invalid, skip ahead to the next semicolon. Not
|
// If the expression is invalid, skip ahead to the next semicolon. Not
|
||||||
// doing this opens us up to the possibility of infinite loops if
|
// doing this opens us up to the possibility of infinite loops if
|
||||||
// ParseExpression does not consume any tokens.
|
// ParseExpression does not consume any tokens.
|
||||||
|
@ -1396,7 +1390,7 @@ Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
|
||||||
}
|
}
|
||||||
// Otherwise, eat the semicolon.
|
// Otherwise, eat the semicolon.
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
||||||
return Actions.ActOnExprStmt(Res.Val);
|
return Actions.ActOnExprStmt(Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||||
|
@ -1439,13 +1433,14 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
|
||||||
return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0);
|
return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Res = ParseExpression();
|
ExprOwner Res(Actions, ParseExpression());
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, Res.Val);
|
return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
|
||||||
|
0, Res.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
|
/// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
|
||||||
|
@ -1497,17 +1492,17 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
|
|
||||||
ConsumeToken(); // Eat the ':'.
|
ConsumeToken(); // Eat the ':'.
|
||||||
/// Parse the expression after ':'
|
/// Parse the expression after ':'
|
||||||
ExprResult Res = ParseAssignmentExpression();
|
ExprOwner Res(Actions, ParseAssignmentExpression());
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
// We must manually skip to a ']', otherwise the expression skipper will
|
// 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
|
// stop at the ']' when it skips to the ';'. We want it to skip beyond
|
||||||
// the enclosing expression.
|
// the enclosing expression.
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a valid expression.
|
// We have a valid expression.
|
||||||
KeyExprs.push_back(Res.Val);
|
KeyExprs.push_back(Res.move());
|
||||||
|
|
||||||
// Check for another keyword selector.
|
// Check for another keyword selector.
|
||||||
selIdent = ParseObjCSelector(Loc);
|
selIdent = ParseObjCSelector(Loc);
|
||||||
|
@ -1519,17 +1514,17 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
while (Tok.is(tok::comma)) {
|
while (Tok.is(tok::comma)) {
|
||||||
ConsumeToken(); // Eat the ','.
|
ConsumeToken(); // Eat the ','.
|
||||||
/// Parse the expression after ','
|
/// Parse the expression after ','
|
||||||
ExprResult Res = ParseAssignmentExpression();
|
ExprOwner Res(Actions, ParseAssignmentExpression());
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
// We must manually skip to a ']', otherwise the expression skipper will
|
// 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
|
// stop at the ']' when it skips to the ';'. We want it to skip beyond
|
||||||
// the enclosing expression.
|
// the enclosing expression.
|
||||||
SkipUntil(tok::r_square);
|
SkipUntil(tok::r_square);
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a valid expression.
|
// We have a valid expression.
|
||||||
KeyExprs.push_back(Res.Val);
|
KeyExprs.push_back(Res.move());
|
||||||
}
|
}
|
||||||
} else if (!selIdent) {
|
} else if (!selIdent) {
|
||||||
Diag(Tok, diag::err_expected_ident); // missing selector name.
|
Diag(Tok, diag::err_expected_ident); // missing selector name.
|
||||||
|
@ -1568,8 +1563,8 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
|
Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
|
||||||
ExprResult Res = ParseStringLiteralExpression();
|
ExprOwner Res(Actions, ParseStringLiteralExpression());
|
||||||
if (Res.isInvalid) return Res;
|
if (Res.isInvalid()) return Res.move();
|
||||||
|
|
||||||
// @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
|
// @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
|
||||||
// expressions. At this point, we know that the only valid thing that starts
|
// expressions. At this point, we know that the only valid thing that starts
|
||||||
|
@ -1577,21 +1572,21 @@ Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
|
||||||
llvm::SmallVector<SourceLocation, 4> AtLocs;
|
llvm::SmallVector<SourceLocation, 4> AtLocs;
|
||||||
ExprVector AtStrings(Actions);
|
ExprVector AtStrings(Actions);
|
||||||
AtLocs.push_back(AtLoc);
|
AtLocs.push_back(AtLoc);
|
||||||
AtStrings.push_back(Res.Val);
|
AtStrings.push_back(Res.move());
|
||||||
|
|
||||||
while (Tok.is(tok::at)) {
|
while (Tok.is(tok::at)) {
|
||||||
AtLocs.push_back(ConsumeToken()); // eat the @.
|
AtLocs.push_back(ConsumeToken()); // eat the @.
|
||||||
|
|
||||||
ExprResult Lit(true); // Invalid unless there is a string literal.
|
ExprOwner Lit(Actions, true); // Invalid unless there is a string literal.
|
||||||
if (isTokenStringLiteral())
|
if (isTokenStringLiteral())
|
||||||
Lit = ParseStringLiteralExpression();
|
Lit = ParseStringLiteralExpression();
|
||||||
else
|
else
|
||||||
Diag(Tok, diag::err_objc_concat_string);
|
Diag(Tok, diag::err_objc_concat_string);
|
||||||
|
|
||||||
if (Lit.isInvalid)
|
|
||||||
return Lit;
|
|
||||||
|
|
||||||
AtStrings.push_back(Lit.Val);
|
if (Lit.isInvalid())
|
||||||
|
return Lit.move();
|
||||||
|
|
||||||
|
AtStrings.push_back(Lit.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
|
return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
|
||||||
|
|
|
@ -35,15 +35,13 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
||||||
|
|
||||||
Action::PragmaPackKind Kind = Action::PPK_Default;
|
Action::PragmaPackKind Kind = Action::PPK_Default;
|
||||||
IdentifierInfo *Name = 0;
|
IdentifierInfo *Name = 0;
|
||||||
Action::ExprResult Alignment;
|
ExprOwner Alignment(Actions);
|
||||||
ExprGuard AlignmentGuard(Actions);
|
|
||||||
SourceLocation LParenLoc = Tok.getLocation();
|
SourceLocation LParenLoc = Tok.getLocation();
|
||||||
PP.Lex(Tok);
|
PP.Lex(Tok);
|
||||||
if (Tok.is(tok::numeric_constant)) {
|
if (Tok.is(tok::numeric_constant)) {
|
||||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||||
if (Alignment.isInvalid)
|
if (Alignment.isInvalid())
|
||||||
return;
|
return;
|
||||||
AlignmentGuard.reset(Alignment);
|
|
||||||
|
|
||||||
PP.Lex(Tok);
|
PP.Lex(Tok);
|
||||||
} else if (Tok.is(tok::identifier)) {
|
} else if (Tok.is(tok::identifier)) {
|
||||||
|
@ -67,9 +65,8 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
||||||
|
|
||||||
if (Tok.is(tok::numeric_constant)) {
|
if (Tok.is(tok::numeric_constant)) {
|
||||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||||
if (Alignment.isInvalid)
|
if (Alignment.isInvalid())
|
||||||
return;
|
return;
|
||||||
AlignmentGuard.reset(Alignment);
|
|
||||||
|
|
||||||
PP.Lex(Tok);
|
PP.Lex(Tok);
|
||||||
} else if (Tok.is(tok::identifier)) {
|
} else if (Tok.is(tok::identifier)) {
|
||||||
|
@ -85,9 +82,8 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||||
if (Alignment.isInvalid)
|
if (Alignment.isInvalid())
|
||||||
return;
|
return;
|
||||||
AlignmentGuard.reset(Alignment);
|
|
||||||
|
|
||||||
PP.Lex(Tok);
|
PP.Lex(Tok);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +93,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.isNot(tok::r_paren)) {
|
if (Tok.isNot(tok::r_paren)) {
|
||||||
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
|
||||||
|
@ -105,7 +101,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation RParenLoc = Tok.getLocation();
|
SourceLocation RParenLoc = Tok.getLocation();
|
||||||
Actions.ActOnPragmaPack(Kind, Name, AlignmentGuard.take(), PackLoc,
|
Actions.ActOnPragmaPack(Kind, Name, Alignment.move(), PackLoc,
|
||||||
LParenLoc, RParenLoc);
|
LParenLoc, RParenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,8 @@ using namespace clang;
|
||||||
///
|
///
|
||||||
Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||||
const char *SemiError = 0;
|
const char *SemiError = 0;
|
||||||
Parser::StmtResult Res;
|
StmtOwner Res(Actions);
|
||||||
|
|
||||||
// Cases in this switch statement should fall through if the parser expects
|
// 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),
|
// the token to end in a semicolon (in which case SemiError should be set),
|
||||||
// or they directly 'return;' if not.
|
// or they directly 'return;' if not.
|
||||||
|
@ -98,16 +98,16 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||||
default:
|
default:
|
||||||
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
|
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
|
||||||
SourceLocation DeclStart = Tok.getLocation();
|
SourceLocation DeclStart = Tok.getLocation();
|
||||||
DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
|
DeclTy *Decl = ParseDeclaration(Declarator::BlockContext);
|
||||||
// FIXME: Pass in the right location for the end of the declstmt.
|
// FIXME: Pass in the right location for the end of the declstmt.
|
||||||
return Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
|
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
|
||||||
} else if (Tok.is(tok::r_brace)) {
|
} else if (Tok.is(tok::r_brace)) {
|
||||||
Diag(Tok, diag::err_expected_statement);
|
Diag(Tok, diag::err_expected_statement);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// expression[opt] ';'
|
// expression[opt] ';'
|
||||||
ExprResult Res = ParseExpression();
|
ExprOwner Expr(Actions, ParseExpression());
|
||||||
if (Res.isInvalid) {
|
if (Expr.isInvalid()) {
|
||||||
// If the expression is invalid, skip ahead to the next semicolon. Not
|
// If the expression is invalid, skip ahead to the next semicolon. Not
|
||||||
// doing this opens us up to the possibility of infinite loops if
|
// doing this opens us up to the possibility of infinite loops if
|
||||||
// ParseExpression does not consume any tokens.
|
// ParseExpression does not consume any tokens.
|
||||||
|
@ -116,7 +116,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||||
}
|
}
|
||||||
// Otherwise, eat the semicolon.
|
// Otherwise, eat the semicolon.
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
||||||
return Actions.ActOnExprStmt(Res.Val);
|
return Actions.ActOnExprStmt(Expr.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_case: // C99 6.8.1: labeled-statement
|
case tok::kw_case: // C99 6.8.1: labeled-statement
|
||||||
|
@ -163,7 +163,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||||
case tok::kw_asm:
|
case tok::kw_asm:
|
||||||
bool msAsm = false;
|
bool msAsm = false;
|
||||||
Res = ParseAsmStatement(msAsm);
|
Res = ParseAsmStatement(msAsm);
|
||||||
if (msAsm) return Res;
|
if (msAsm) return Res.move();
|
||||||
SemiError = "asm statement";
|
SemiError = "asm statement";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -171,12 +171,12 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||||
// If we reached this code, the statement must end in a semicolon.
|
// If we reached this code, the statement must end in a semicolon.
|
||||||
if (Tok.is(tok::semi)) {
|
if (Tok.is(tok::semi)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
} else if (!Res.isInvalid) {
|
} else if (!Res.isInvalid()) {
|
||||||
Diag(Tok, diag::err_expected_semi_after) << SemiError;
|
Diag(Tok, diag::err_expected_semi_after) << SemiError;
|
||||||
// Skip until we see a } or ;, but don't eat it.
|
// Skip until we see a } or ;, but don't eat it.
|
||||||
SkipUntil(tok::r_brace, true, true);
|
SkipUntil(tok::r_brace, true, true);
|
||||||
}
|
}
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseLabeledStatement - We have an identifier and a ':' after it.
|
/// ParseLabeledStatement - We have an identifier and a ':' after it.
|
||||||
|
@ -203,15 +203,15 @@ Parser::StmtResult Parser::ParseLabeledStatement() {
|
||||||
// TODO: save these somewhere.
|
// TODO: save these somewhere.
|
||||||
AttrList = ParseAttributes();
|
AttrList = ParseAttributes();
|
||||||
|
|
||||||
StmtResult SubStmt = ParseStatement();
|
StmtOwner SubStmt(Actions, ParseStatement());
|
||||||
|
|
||||||
// Broken substmt shouldn't prevent the label from being added to the AST.
|
// Broken substmt shouldn't prevent the label from being added to the AST.
|
||||||
if (SubStmt.isInvalid)
|
if (SubStmt.isInvalid())
|
||||||
SubStmt = Actions.ActOnNullStmt(ColonLoc);
|
SubStmt = Actions.ActOnNullStmt(ColonLoc);
|
||||||
|
|
||||||
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
|
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
|
||||||
IdentTok.getIdentifierInfo(),
|
IdentTok.getIdentifierInfo(),
|
||||||
ColonLoc, SubStmt.Val);
|
ColonLoc, SubStmt.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCaseStatement
|
/// ParseCaseStatement
|
||||||
|
@ -225,29 +225,26 @@ Parser::StmtResult Parser::ParseCaseStatement() {
|
||||||
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
|
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
|
||||||
SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'.
|
SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'.
|
||||||
|
|
||||||
ExprResult LHS = ParseConstantExpression();
|
ExprOwner LHS(Actions, ParseConstantExpression());
|
||||||
if (LHS.isInvalid) {
|
if (LHS.isInvalid()) {
|
||||||
SkipUntil(tok::colon);
|
SkipUntil(tok::colon);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ExprGuard LHSGuard(Actions, LHS);
|
|
||||||
|
|
||||||
// GNU case range extension.
|
// GNU case range extension.
|
||||||
SourceLocation DotDotDotLoc;
|
SourceLocation DotDotDotLoc;
|
||||||
ExprTy *RHSVal = 0;
|
ExprOwner RHS(Actions);
|
||||||
if (Tok.is(tok::ellipsis)) {
|
if (Tok.is(tok::ellipsis)) {
|
||||||
Diag(Tok, diag::ext_gnu_case_range);
|
Diag(Tok, diag::ext_gnu_case_range);
|
||||||
DotDotDotLoc = ConsumeToken();
|
DotDotDotLoc = ConsumeToken();
|
||||||
|
|
||||||
ExprResult RHS = ParseConstantExpression();
|
RHS = ParseConstantExpression();
|
||||||
if (RHS.isInvalid) {
|
if (RHS.isInvalid()) {
|
||||||
SkipUntil(tok::colon);
|
SkipUntil(tok::colon);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
RHSVal = RHS.Val;
|
|
||||||
}
|
}
|
||||||
ExprGuard RHSGuard(Actions, RHSVal);
|
|
||||||
|
|
||||||
if (Tok.isNot(tok::colon)) {
|
if (Tok.isNot(tok::colon)) {
|
||||||
Diag(Tok, diag::err_expected_colon_after) << "'case'";
|
Diag(Tok, diag::err_expected_colon_after) << "'case'";
|
||||||
SkipUntil(tok::colon);
|
SkipUntil(tok::colon);
|
||||||
|
@ -262,14 +259,14 @@ Parser::StmtResult Parser::ParseCaseStatement() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StmtResult SubStmt = ParseStatement();
|
StmtOwner SubStmt(Actions, ParseStatement());
|
||||||
|
|
||||||
// Broken substmt shouldn't prevent the case from being added to the AST.
|
// Broken substmt shouldn't prevent the case from being added to the AST.
|
||||||
if (SubStmt.isInvalid)
|
if (SubStmt.isInvalid())
|
||||||
SubStmt = Actions.ActOnNullStmt(ColonLoc);
|
SubStmt = Actions.ActOnNullStmt(ColonLoc);
|
||||||
|
|
||||||
return Actions.ActOnCaseStmt(CaseLoc, LHSGuard.take(), DotDotDotLoc,
|
return Actions.ActOnCaseStmt(CaseLoc, LHS.move(), DotDotDotLoc,
|
||||||
RHSGuard.take(), ColonLoc, SubStmt.Val);
|
RHS.move(), ColonLoc, SubStmt.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseDefaultStatement
|
/// ParseDefaultStatement
|
||||||
|
@ -295,11 +292,12 @@ Parser::StmtResult Parser::ParseDefaultStatement() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StmtResult SubStmt = ParseStatement();
|
StmtOwner SubStmt(Actions, ParseStatement());
|
||||||
if (SubStmt.isInvalid)
|
if (SubStmt.isInvalid())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope);
|
return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
|
||||||
|
SubStmt.move(), CurScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,10 +336,10 @@ Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
|
||||||
EnterScope(Scope::DeclScope);
|
EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
// Parse the statements in the body.
|
// Parse the statements in the body.
|
||||||
StmtResult Body = ParseCompoundStatementBody(isStmtExpr);
|
StmtOwner Body(Actions, ParseCompoundStatementBody(isStmtExpr));
|
||||||
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
return Body;
|
return Body.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,7 +356,7 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||||
typedef StmtVector StmtsTy;
|
typedef StmtVector StmtsTy;
|
||||||
StmtsTy Stmts(Actions);
|
StmtsTy Stmts(Actions);
|
||||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||||
StmtResult R;
|
StmtOwner R(Actions);
|
||||||
if (Tok.isNot(tok::kw___extension__)) {
|
if (Tok.isNot(tok::kw___extension__)) {
|
||||||
R = ParseStatementOrDeclaration(false);
|
R = ParseStatementOrDeclaration(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -382,28 +380,28 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||||
} else {
|
} else {
|
||||||
// Otherwise this was a unary __extension__ marker. Parse the
|
// Otherwise this was a unary __extension__ marker. Parse the
|
||||||
// subexpression and add the __extension__ unary op.
|
// subexpression and add the __extension__ unary op.
|
||||||
ExprResult Res = ParseCastExpression(false);
|
ExprOwner Res(Actions, ParseCastExpression(false));
|
||||||
|
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the __extension__ node to the AST.
|
// Add the __extension__ node to the AST.
|
||||||
Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
|
Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
|
||||||
Res.Val);
|
Res.move());
|
||||||
if (Res.isInvalid)
|
if (Res.isInvalid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Eat the semicolon at the end of stmt and convert the expr into a
|
// Eat the semicolon at the end of stmt and convert the expr into a
|
||||||
// statement.
|
// statement.
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
||||||
R = Actions.ActOnExprStmt(Res.Val);
|
R = Actions.ActOnExprStmt(Res.move());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!R.isInvalid && R.Val)
|
if (R.isUsable())
|
||||||
Stmts.push_back(R.Val);
|
Stmts.push_back(R.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We broke out of the while loop because we found a '}' or EOF.
|
// We broke out of the while loop because we found a '}' or EOF.
|
||||||
|
@ -452,7 +450,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
EnterScope(Scope::DeclScope | Scope::ControlScope);
|
EnterScope(Scope::DeclScope | Scope::ControlScope);
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
ExprResult CondExp;
|
ExprOwner CondExp(Actions);
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
CondExp = ParseCXXCondition();
|
CondExp = ParseCXXCondition();
|
||||||
|
@ -460,9 +458,8 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
} else {
|
} else {
|
||||||
CondExp = ParseSimpleParenExpression();
|
CondExp = ParseSimpleParenExpression();
|
||||||
}
|
}
|
||||||
ExprGuard CondGuard(Actions, CondExp);
|
|
||||||
|
|
||||||
if (CondExp.isInvalid) {
|
if (CondExp.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
if (C99orCXX)
|
if (C99orCXX)
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
@ -492,7 +489,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
|
|
||||||
// Read the 'then' stmt.
|
// Read the 'then' stmt.
|
||||||
SourceLocation ThenStmtLoc = Tok.getLocation();
|
SourceLocation ThenStmtLoc = Tok.getLocation();
|
||||||
StmtResult ThenStmt = ParseStatement();
|
StmtOwner ThenStmt(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the 'if' scope if needed.
|
// Pop the 'if' scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
if (NeedsInnerScope) ExitScope();
|
||||||
|
@ -500,8 +497,8 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
// If it has an else, parse it.
|
// If it has an else, parse it.
|
||||||
SourceLocation ElseLoc;
|
SourceLocation ElseLoc;
|
||||||
SourceLocation ElseStmtLoc;
|
SourceLocation ElseStmtLoc;
|
||||||
StmtResult ElseStmt(false);
|
StmtOwner ElseStmt(Actions);
|
||||||
|
|
||||||
if (Tok.is(tok::kw_else)) {
|
if (Tok.is(tok::kw_else)) {
|
||||||
ElseLoc = ConsumeToken();
|
ElseLoc = ConsumeToken();
|
||||||
|
|
||||||
|
@ -516,7 +513,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
//
|
//
|
||||||
NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
ElseStmtLoc = Tok.getLocation();
|
ElseStmtLoc = Tok.getLocation();
|
||||||
ElseStmt = ParseStatement();
|
ElseStmt = ParseStatement();
|
||||||
|
|
||||||
|
@ -530,21 +527,21 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
// If the then or else stmt is invalid and the other is valid (and present),
|
// If the then or else stmt is invalid and the other is valid (and present),
|
||||||
// make turn the invalid one into a null stmt to avoid dropping the other
|
// make turn the invalid one into a null stmt to avoid dropping the other
|
||||||
// part. If both are invalid, return error.
|
// part. If both are invalid, return error.
|
||||||
if ((ThenStmt.isInvalid && ElseStmt.isInvalid) ||
|
if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
|
||||||
(ThenStmt.isInvalid && ElseStmt.Val == 0) ||
|
(ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
|
||||||
(ThenStmt.Val == 0 && ElseStmt.isInvalid)) {
|
(ThenStmt.get() == 0 && ElseStmt.isInvalid())) {
|
||||||
// Both invalid, or one is invalid and other is non-present: return error.
|
// Both invalid, or one is invalid and other is non-present: return error.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now if either are invalid, replace with a ';'.
|
// Now if either are invalid, replace with a ';'.
|
||||||
if (ThenStmt.isInvalid)
|
if (ThenStmt.isInvalid())
|
||||||
ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
|
ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
|
||||||
if (ElseStmt.isInvalid)
|
if (ElseStmt.isInvalid())
|
||||||
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
|
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
|
||||||
|
|
||||||
return Actions.ActOnIfStmt(IfLoc, CondGuard.take(), ThenStmt.Val,
|
return Actions.ActOnIfStmt(IfLoc, CondExp.move(), ThenStmt.move(),
|
||||||
ElseLoc, ElseStmt.Val);
|
ElseLoc, ElseStmt.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseSwitchStatement
|
/// ParseSwitchStatement
|
||||||
|
@ -581,7 +578,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
EnterScope(Scope::BreakScope);
|
EnterScope(Scope::BreakScope);
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
ExprResult Cond;
|
ExprOwner Cond(Actions);
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
Cond = ParseCXXCondition();
|
Cond = ParseCXXCondition();
|
||||||
|
@ -590,13 +587,13 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
Cond = ParseSimpleParenExpression();
|
Cond = ParseSimpleParenExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cond.isInvalid) {
|
if (Cond.isInvalid()) {
|
||||||
ExitScope();
|
ExitScope();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StmtResult Switch = Actions.ActOnStartOfSwitchStmt(Cond.Val);
|
StmtOwner Switch(Actions, Actions.ActOnStartOfSwitchStmt(Cond.move()));
|
||||||
|
|
||||||
// C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
|
// 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
|
// there is no compound stmt. C90 does not have this clause. We only do this
|
||||||
// if the body isn't a compound statement to avoid push/pop in common cases.
|
// if the body isn't a compound statement to avoid push/pop in common cases.
|
||||||
|
@ -612,19 +609,19 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
StmtResult Body = ParseStatement();
|
StmtOwner Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
if (NeedsInnerScope) ExitScope();
|
||||||
|
|
||||||
if (Body.isInvalid) {
|
if (Body.isInvalid()) {
|
||||||
Body = Actions.ActOnNullStmt(Tok.getLocation());
|
Body = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
// FIXME: Remove the case statement list from the Switch statement.
|
// FIXME: Remove the case statement list from the Switch statement.
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.Val, Body.Val);
|
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.move(), Body.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseWhileStatement
|
/// ParseWhileStatement
|
||||||
|
@ -663,7 +660,7 @@ Parser::StmtResult Parser::ParseWhileStatement() {
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
ExprResult Cond;
|
ExprOwner Cond(Actions);
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
Cond = ParseCXXCondition();
|
Cond = ParseCXXCondition();
|
||||||
|
@ -671,8 +668,7 @@ Parser::StmtResult Parser::ParseWhileStatement() {
|
||||||
} else {
|
} else {
|
||||||
Cond = ParseSimpleParenExpression();
|
Cond = ParseSimpleParenExpression();
|
||||||
}
|
}
|
||||||
ExprGuard CondGuard(Actions, Cond);
|
|
||||||
|
|
||||||
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
||||||
// there is no compound stmt. C90 does not have this clause. We only do this
|
// there is no compound stmt. C90 does not have this clause. We only do this
|
||||||
// if the body isn't a compound statement to avoid push/pop in common cases.
|
// if the body isn't a compound statement to avoid push/pop in common cases.
|
||||||
|
@ -688,17 +684,16 @@ Parser::StmtResult Parser::ParseWhileStatement() {
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
StmtResult Body = ParseStatement();
|
StmtOwner Body(Actions, ParseStatement());
|
||||||
StmtGuard BodyGuard(Actions, Body);
|
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
if (NeedsInnerScope) ExitScope();
|
||||||
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
if (Cond.isInvalid || Body.isInvalid) return true;
|
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
||||||
|
|
||||||
return Actions.ActOnWhileStmt(WhileLoc, CondGuard.take(), BodyGuard.take());
|
return Actions.ActOnWhileStmt(WhileLoc, Cond.move(), Body.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseDoStatement
|
/// ParseDoStatement
|
||||||
|
@ -729,15 +724,14 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
StmtResult Body = ParseStatement();
|
StmtOwner Body(Actions, ParseStatement());
|
||||||
StmtGuard BodyGuard(Actions, Body);
|
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
if (NeedsInnerScope) ExitScope();
|
||||||
|
|
||||||
if (Tok.isNot(tok::kw_while)) {
|
if (Tok.isNot(tok::kw_while)) {
|
||||||
ExitScope();
|
ExitScope();
|
||||||
if (!Body.isInvalid) {
|
if (!Body.isInvalid()) {
|
||||||
Diag(Tok, diag::err_expected_while);
|
Diag(Tok, diag::err_expected_while);
|
||||||
Diag(DoLoc, diag::note_matching) << "do";
|
Diag(DoLoc, diag::note_matching) << "do";
|
||||||
SkipUntil(tok::semi, false, true);
|
SkipUntil(tok::semi, false, true);
|
||||||
|
@ -754,15 +748,13 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
ExprResult Cond = ParseSimpleParenExpression();
|
ExprOwner Cond(Actions, ParseSimpleParenExpression());
|
||||||
ExprGuard CondGuard(Actions, Cond);
|
|
||||||
|
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
if (Cond.isInvalid || Body.isInvalid) return true;
|
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
||||||
|
|
||||||
return Actions.ActOnDoStmt(DoLoc, BodyGuard.take(),
|
return Actions.ActOnDoStmt(DoLoc, Body.move(), WhileLoc, Cond.move());
|
||||||
WhileLoc, CondGuard.take());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseForStatement
|
/// ParseForStatement
|
||||||
|
@ -812,15 +804,12 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
||||||
|
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
ExprResult Value;
|
ExprOwner Value(Actions);
|
||||||
|
|
||||||
StmtTy *FirstPart = 0;
|
|
||||||
ExprTy *SecondPart = 0;
|
|
||||||
StmtTy *ThirdPart = 0;
|
|
||||||
bool ForEach = false;
|
bool ForEach = false;
|
||||||
StmtGuard FirstGuard(Actions), ThirdGuard(Actions);
|
StmtOwner FirstPart(Actions), ThirdPart(Actions);
|
||||||
ExprGuard SecondGuard(Actions);
|
ExprOwner SecondPart(Actions);
|
||||||
|
|
||||||
// Parse the first part of the for specifier.
|
// Parse the first part of the for specifier.
|
||||||
if (Tok.is(tok::semi)) { // for (;
|
if (Tok.is(tok::semi)) { // for (;
|
||||||
// no first part, eat the ';'.
|
// no first part, eat the ';'.
|
||||||
|
@ -833,80 +822,62 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||||
SourceLocation DeclStart = Tok.getLocation();
|
SourceLocation DeclStart = Tok.getLocation();
|
||||||
DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
|
DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
|
||||||
// FIXME: Pass in the right location for the end of the declstmt.
|
// FIXME: Pass in the right location for the end of the declstmt.
|
||||||
StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
|
FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
|
||||||
DeclStart);
|
DeclStart);
|
||||||
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
|
|
||||||
if ((ForEach = isTokIdentifier_in())) {
|
if ((ForEach = isTokIdentifier_in())) {
|
||||||
ConsumeToken(); // consume 'in'
|
ConsumeToken(); // consume 'in'
|
||||||
Value = ParseExpression();
|
SecondPart = ParseExpression();
|
||||||
if (!Value.isInvalid)
|
|
||||||
SecondPart = Value.Val;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value = ParseExpression();
|
Value = ParseExpression();
|
||||||
|
|
||||||
// Turn the expression into a stmt.
|
// Turn the expression into a stmt.
|
||||||
if (!Value.isInvalid) {
|
if (!Value.isInvalid())
|
||||||
StmtResult R = Actions.ActOnExprStmt(Value.Val);
|
FirstPart = Actions.ActOnExprStmt(Value.move());
|
||||||
if (!R.isInvalid)
|
|
||||||
FirstPart = R.Val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tok.is(tok::semi)) {
|
if (Tok.is(tok::semi)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
}
|
}
|
||||||
else if ((ForEach = isTokIdentifier_in())) {
|
else if ((ForEach = isTokIdentifier_in())) {
|
||||||
ConsumeToken(); // consume 'in'
|
ConsumeToken(); // consume 'in'
|
||||||
Value = ParseExpression();
|
SecondPart = ParseExpression();
|
||||||
if (!Value.isInvalid)
|
|
||||||
SecondPart = Value.Val;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
|
if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FirstGuard.reset(FirstPart);
|
|
||||||
SecondGuard.reset(SecondPart);
|
|
||||||
if (!ForEach) {
|
if (!ForEach) {
|
||||||
assert(!SecondGuard.get() && "Shouldn't have a second expression yet.");
|
assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
|
||||||
// Parse the second part of the for specifier.
|
// Parse the second part of the for specifier.
|
||||||
if (Tok.is(tok::semi)) { // for (...;;
|
if (Tok.is(tok::semi)) { // for (...;;
|
||||||
// no second part.
|
// no second part.
|
||||||
Value = ExprResult();
|
|
||||||
} else {
|
} else {
|
||||||
Value = getLang().CPlusPlus ? ParseCXXCondition()
|
SecondPart = getLang().CPlusPlus ? ParseCXXCondition()
|
||||||
: ParseExpression();
|
: ParseExpression();
|
||||||
if (!Value.isInvalid)
|
|
||||||
SecondPart = Value.Val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::semi)) {
|
if (Tok.is(tok::semi)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
} else {
|
} else {
|
||||||
if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
|
if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the third part of the for specifier.
|
// Parse the third part of the for specifier.
|
||||||
if (Tok.is(tok::r_paren)) { // for (...;...;)
|
if (Tok.is(tok::r_paren)) { // for (...;...;)
|
||||||
// no third part.
|
// no third part.
|
||||||
Value = ExprResult();
|
|
||||||
} else {
|
} else {
|
||||||
Value = ParseExpression();
|
Value = ParseExpression();
|
||||||
if (!Value.isInvalid) {
|
if (!Value.isInvalid()) {
|
||||||
// Turn the expression into a stmt.
|
// Turn the expression into a stmt.
|
||||||
StmtResult R = Actions.ActOnExprStmt(Value.Val);
|
ThirdPart = Actions.ActOnExprStmt(Value.move());
|
||||||
if (!R.isInvalid)
|
|
||||||
ThirdPart = R.Val;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SecondGuard.reset(SecondPart);
|
|
||||||
ThirdGuard.reset(ThirdPart);
|
|
||||||
}
|
}
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
|
|
||||||
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
||||||
// there is no compound stmt. C90 does not have this clause. We only do this
|
// there is no compound stmt. C90 does not have this clause. We only do this
|
||||||
// if the body isn't a compound statement to avoid push/pop in common cases.
|
// if the body isn't a compound statement to avoid push/pop in common cases.
|
||||||
|
@ -920,29 +891,28 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
StmtResult Body = ParseStatement();
|
StmtOwner Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
if (NeedsInnerScope) ExitScope();
|
||||||
|
|
||||||
// Leave the for-scope.
|
// Leave the for-scope.
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
if (Body.isInvalid)
|
if (Body.isInvalid())
|
||||||
return Body;
|
return true;
|
||||||
|
|
||||||
// Release all the guards.
|
|
||||||
FirstGuard.take();
|
|
||||||
SecondGuard.take();
|
|
||||||
ThirdGuard.take();
|
|
||||||
if (!ForEach)
|
if (!ForEach)
|
||||||
return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart,
|
return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.move(),
|
||||||
SecondPart, ThirdPart, RParenLoc, Body.Val);
|
SecondPart.move(), ThirdPart.move(), RParenLoc,
|
||||||
|
Body.move());
|
||||||
else
|
else
|
||||||
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart,
|
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
|
||||||
SecondPart, RParenLoc, Body.Val);
|
FirstPart.move(),
|
||||||
|
SecondPart.move(),
|
||||||
|
RParenLoc, Body.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseGotoStatement
|
/// ParseGotoStatement
|
||||||
|
@ -956,7 +926,7 @@ Parser::StmtResult Parser::ParseGotoStatement() {
|
||||||
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
|
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
|
||||||
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
|
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
|
||||||
|
|
||||||
StmtResult Res;
|
StmtOwner Res(Actions);
|
||||||
if (Tok.is(tok::identifier)) {
|
if (Tok.is(tok::identifier)) {
|
||||||
Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
|
Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
|
||||||
Tok.getIdentifierInfo());
|
Tok.getIdentifierInfo());
|
||||||
|
@ -965,18 +935,18 @@ Parser::StmtResult Parser::ParseGotoStatement() {
|
||||||
// GNU indirect goto extension.
|
// GNU indirect goto extension.
|
||||||
Diag(Tok, diag::ext_gnu_indirect_goto);
|
Diag(Tok, diag::ext_gnu_indirect_goto);
|
||||||
SourceLocation StarLoc = ConsumeToken();
|
SourceLocation StarLoc = ConsumeToken();
|
||||||
ExprResult R = ParseExpression();
|
ExprOwner R(Actions, ParseExpression());
|
||||||
if (R.isInvalid) { // Skip to the semicolon, but don't consume it.
|
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
|
||||||
SkipUntil(tok::semi, false, true);
|
SkipUntil(tok::semi, false, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.Val);
|
Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.move());
|
||||||
} else {
|
} else {
|
||||||
Diag(Tok, diag::err_expected_ident);
|
Diag(Tok, diag::err_expected_ident);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseContinueStatement
|
/// ParseContinueStatement
|
||||||
|
@ -1008,15 +978,15 @@ Parser::StmtResult Parser::ParseReturnStatement() {
|
||||||
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
|
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
|
||||||
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
|
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
|
||||||
|
|
||||||
ExprResult R(0);
|
ExprOwner R(Actions);
|
||||||
if (Tok.isNot(tok::semi)) {
|
if (Tok.isNot(tok::semi)) {
|
||||||
R = ParseExpression();
|
R = ParseExpression();
|
||||||
if (R.isInvalid) { // Skip to the semicolon, but don't consume it.
|
if (R.isInvalid()) { // Skip to the semicolon, but don't consume it.
|
||||||
SkipUntil(tok::semi, false, true);
|
SkipUntil(tok::semi, false, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Actions.ActOnReturnStmt(ReturnLoc, R.Val);
|
return Actions.ActOnReturnStmt(ReturnLoc, R.move());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
|
/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
|
||||||
|
@ -1098,11 +1068,10 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
|
||||||
}
|
}
|
||||||
Loc = ConsumeParen();
|
Loc = ConsumeParen();
|
||||||
|
|
||||||
ExprResult AsmString = ParseAsmStringLiteral();
|
ExprOwner AsmString(Actions, ParseAsmStringLiteral());
|
||||||
if (AsmString.isInvalid)
|
if (AsmString.isInvalid())
|
||||||
return true;
|
return true;
|
||||||
ExprGuard AsmGuard(Actions, AsmString);
|
|
||||||
|
|
||||||
llvm::SmallVector<std::string, 4> Names;
|
llvm::SmallVector<std::string, 4> Names;
|
||||||
ExprVector Constraints(Actions);
|
ExprVector Constraints(Actions);
|
||||||
ExprVector Exprs(Actions);
|
ExprVector Exprs(Actions);
|
||||||
|
@ -1139,12 +1108,12 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
|
||||||
|
|
||||||
// Parse the asm-string list for clobbers.
|
// Parse the asm-string list for clobbers.
|
||||||
while (1) {
|
while (1) {
|
||||||
ExprResult Clobber = ParseAsmStringLiteral();
|
ExprOwner Clobber(Actions, ParseAsmStringLiteral());
|
||||||
|
|
||||||
if (Clobber.isInvalid)
|
if (Clobber.isInvalid())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Clobbers.push_back(Clobber.Val);
|
Clobbers.push_back(Clobber.move());
|
||||||
|
|
||||||
if (Tok.isNot(tok::comma)) break;
|
if (Tok.isNot(tok::comma)) break;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
@ -1157,7 +1126,7 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
|
||||||
return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
|
return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
|
||||||
NumOutputs, NumInputs,
|
NumOutputs, NumInputs,
|
||||||
&Names[0], Constraints.take(),
|
&Names[0], Constraints.take(),
|
||||||
Exprs.take(), AsmGuard.take(),
|
Exprs.take(), AsmString.move(),
|
||||||
Clobbers.size(), Clobbers.take(),
|
Clobbers.size(), Clobbers.take(),
|
||||||
RParenLoc);
|
RParenLoc);
|
||||||
}
|
}
|
||||||
|
@ -1203,13 +1172,13 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
|
||||||
MatchRHSPunctuation(tok::r_square, Loc);
|
MatchRHSPunctuation(tok::r_square, Loc);
|
||||||
} else
|
} else
|
||||||
Names.push_back(std::string());
|
Names.push_back(std::string());
|
||||||
|
|
||||||
ExprResult Constraint = ParseAsmStringLiteral();
|
ExprOwner Constraint(Actions, ParseAsmStringLiteral());
|
||||||
if (Constraint.isInvalid) {
|
if (Constraint.isInvalid()) {
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Constraints.push_back(Constraint.Val);
|
Constraints.push_back(Constraint.move());
|
||||||
|
|
||||||
if (Tok.isNot(tok::l_paren)) {
|
if (Tok.isNot(tok::l_paren)) {
|
||||||
Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
|
Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
|
||||||
|
@ -1218,12 +1187,12 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the parenthesized expression.
|
// Read the parenthesized expression.
|
||||||
ExprResult Res = ParseSimpleParenExpression();
|
ExprOwner Res(Actions, ParseSimpleParenExpression());
|
||||||
if (Res.isInvalid) {
|
if (Res.isInvalid()) {
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Exprs.push_back(Res.Val);
|
Exprs.push_back(Res.move());
|
||||||
// Eat the comma and continue parsing if it exists.
|
// Eat the comma and continue parsing if it exists.
|
||||||
if (Tok.isNot(tok::comma)) return false;
|
if (Tok.isNot(tok::comma)) return false;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
@ -1237,14 +1206,14 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
|
||||||
// Do not enter a scope for the brace, as the arguments are in the same scope
|
// 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
|
// (the function body) as the body itself. Instead, just read the statement
|
||||||
// list and put it into a CompoundStmt for safe keeping.
|
// list and put it into a CompoundStmt for safe keeping.
|
||||||
StmtResult FnBody = ParseCompoundStatementBody();
|
StmtOwner FnBody(Actions, ParseCompoundStatementBody());
|
||||||
|
|
||||||
// If the function body could not be parsed, make a bogus compoundstmt.
|
// If the function body could not be parsed, make a bogus compoundstmt.
|
||||||
if (FnBody.isInvalid)
|
if (FnBody.isInvalid())
|
||||||
FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
|
FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
|
||||||
|
|
||||||
// Leave the function body scope.
|
// Leave the function body scope.
|
||||||
ExitScope();
|
ExitScope();
|
||||||
|
|
||||||
return Actions.ActOnFinishFunctionBody(Decl, FnBody.Val);
|
return Actions.ActOnFinishFunctionBody(Decl, FnBody.move());
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "clang/Basic/Diagnostic.h"
|
#include "clang/Basic/Diagnostic.h"
|
||||||
#include "clang/Parse/DeclSpec.h"
|
#include "clang/Parse/DeclSpec.h"
|
||||||
#include "clang/Parse/Scope.h"
|
#include "clang/Parse/Scope.h"
|
||||||
|
#include "AstGuard.h"
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
|
@ -231,11 +232,11 @@ Parser::DeclTy* Parser::ParseTemplateTemplateParameter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the a default value, if given.
|
// Get the a default value, if given.
|
||||||
ExprResult defaultExpr;
|
ExprOwner DefaultExpr(Actions);
|
||||||
if(Tok.is(tok::equal)) {
|
if(Tok.is(tok::equal)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
defaultExpr = ParseCXXIdExpression();
|
DefaultExpr = ParseCXXIdExpression();
|
||||||
if(defaultExpr.isInvalid) {
|
if(DefaultExpr.isInvalid()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "clang/Parse/Scope.h"
|
#include "clang/Parse/Scope.h"
|
||||||
#include "ExtensionRAIIObject.h"
|
#include "ExtensionRAIIObject.h"
|
||||||
#include "ParsePragma.h"
|
#include "ParsePragma.h"
|
||||||
|
#include "AstGuard.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
Parser::Parser(Preprocessor &pp, Action &actions)
|
Parser::Parser(Preprocessor &pp, Action &actions)
|
||||||
|
@ -333,13 +334,13 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
||||||
return ParseExternalDeclaration();
|
return ParseExternalDeclaration();
|
||||||
}
|
}
|
||||||
case tok::kw_asm: {
|
case tok::kw_asm: {
|
||||||
ExprResult Result = ParseSimpleAsm();
|
ExprOwner Result(Actions, ParseSimpleAsm());
|
||||||
|
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
||||||
"top-level asm block");
|
"top-level asm block");
|
||||||
|
|
||||||
if (!Result.isInvalid)
|
if (!Result.isInvalid())
|
||||||
return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.Val);
|
return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.move());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case tok::at:
|
case tok::at:
|
||||||
|
@ -669,12 +670,12 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Res = ParseStringLiteralExpression();
|
ExprOwner Res(Actions, ParseStringLiteralExpression());
|
||||||
if (Res.isInvalid) return true;
|
if (Res.isInvalid()) return true;
|
||||||
|
|
||||||
// TODO: Diagnose: wide string literal in 'asm'
|
// TODO: Diagnose: wide string literal in 'asm'
|
||||||
|
|
||||||
return Res;
|
return Res.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseSimpleAsm
|
/// ParseSimpleAsm
|
||||||
|
@ -693,14 +694,14 @@ Parser::ExprResult Parser::ParseSimpleAsm() {
|
||||||
|
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
|
|
||||||
ExprResult Result = ParseAsmStringLiteral();
|
ExprOwner Result(Actions, ParseAsmStringLiteral());
|
||||||
|
|
||||||
if (Result.isInvalid)
|
if (Result.isInvalid())
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren);
|
||||||
else
|
else
|
||||||
MatchRHSPunctuation(tok::r_paren, Loc);
|
MatchRHSPunctuation(tok::r_paren, Loc);
|
||||||
|
|
||||||
return Result;
|
return Result.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TryAnnotateTypeOrScopeToken - If the current token position is on a
|
/// TryAnnotateTypeOrScopeToken - If the current token position is on a
|
||||||
|
|
Loading…
Reference in New Issue