forked from OSchip/llvm-project
Refactor the common code of 'ParseTypeofSpecifier' and 'ParseSizeofAlignofExpression' into a new
'ParseExprAfterTypeofSizeofAlignof' method. llvm-svn: 72256
This commit is contained in:
parent
f5cc7ac4d5
commit
7bd98440b3
|
@ -158,6 +158,8 @@ public:
|
|||
OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
|
||||
OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
|
||||
|
||||
OwningExprResult ExprEmpty() { return OwningExprResult(Actions, false); }
|
||||
|
||||
// Parsing methods.
|
||||
|
||||
/// ParseTranslationUnit - All in one method that initializes parses, and
|
||||
|
@ -663,6 +665,11 @@ private:
|
|||
OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
|
||||
OwningExprResult ParseSizeofAlignofExpression();
|
||||
OwningExprResult ParseBuiltinPrimaryExpression();
|
||||
|
||||
OwningExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
|
||||
bool &isCastExpr,
|
||||
TypeTy *&CastTy,
|
||||
SourceRange &CastRange);
|
||||
|
||||
static const unsigned ExprListSize = 12;
|
||||
typedef llvm::SmallVector<ExprTy*, ExprListSize> ExprListTy;
|
||||
|
|
|
@ -2648,51 +2648,35 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
|||
///
|
||||
void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
||||
assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
|
||||
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
|
||||
Token OpTok = Tok;
|
||||
SourceLocation StartLoc = ConsumeToken();
|
||||
|
||||
// If the operand doesn't start with an '(', it must be an expression.
|
||||
OwningExprResult Operand(Actions);
|
||||
if (Tok.isNot(tok::l_paren)) {
|
||||
if (!getLang().CPlusPlus) {
|
||||
Diag(Tok, diag::err_expected_lparen_after_id) << BuiltinII;
|
||||
return;
|
||||
}
|
||||
Operand = ParseCastExpression(true/*isUnaryExpression*/);
|
||||
bool isCastExpr;
|
||||
TypeTy *CastTy;
|
||||
SourceRange CastRange;
|
||||
OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
|
||||
isCastExpr,
|
||||
CastTy,
|
||||
CastRange);
|
||||
|
||||
if (CastRange.getEnd().isInvalid())
|
||||
// FIXME: Not accurate, the range gets one token more than it should.
|
||||
DS.SetRangeEnd(Tok.getLocation());
|
||||
|
||||
} else {
|
||||
// If it starts with a '(', we know that it is either a parenthesized
|
||||
// type-name, or it is a unary-expression that starts with a compound
|
||||
// literal, or starts with a primary-expression that is a parenthesized
|
||||
// expression.
|
||||
ParenParseOption ExprType = CastExpr;
|
||||
TypeTy *CastTy;
|
||||
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
|
||||
Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
|
||||
DS.SetRangeEnd(RParenLoc);
|
||||
|
||||
// If ParseParenExpression parsed a '(typename)' sequence only, then this is
|
||||
// typeof a type. Otherwise, it is typeof an expression.
|
||||
if (ExprType == CastExpr) {
|
||||
if (!CastTy) {
|
||||
DS.SetTypeSpecError();
|
||||
return;
|
||||
}
|
||||
|
||||
const char *PrevSpec = 0;
|
||||
// Check for duplicate type specifiers (e.g. "int typeof(int)").
|
||||
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
|
||||
CastTy))
|
||||
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||
else
|
||||
DS.SetRangeEnd(CastRange.getEnd());
|
||||
|
||||
if (isCastExpr) {
|
||||
if (!CastTy) {
|
||||
DS.SetTypeSpecError();
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a parenthesized expression, it is the start of a
|
||||
// unary-expression, but doesn't include any postfix pieces. Parse these
|
||||
// now if present.
|
||||
Operand = ParsePostfixExpressionSuffix(move(Operand));
|
||||
const char *PrevSpec = 0;
|
||||
// Check for duplicate type specifiers (e.g. "int typeof(int)").
|
||||
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
|
||||
CastTy))
|
||||
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, the operand to the typeof was an expresion.
|
||||
|
|
|
@ -913,6 +913,72 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
|
|||
}
|
||||
}
|
||||
|
||||
/// ParseExprAfterTypeofSizeofAlignof - We parsed a typeof/sizeof/alignof and
|
||||
/// we are at the start of an expression or a parenthesized type-id.
|
||||
/// OpTok is the operand token (typeof/sizeof/alignof). Returns the expression
|
||||
/// (isCastExpr == false) or the type (isCastExpr == true).
|
||||
///
|
||||
/// unary-expression: [C99 6.5.3]
|
||||
/// 'sizeof' unary-expression
|
||||
/// 'sizeof' '(' type-name ')'
|
||||
/// [GNU] '__alignof' unary-expression
|
||||
/// [GNU] '__alignof' '(' type-name ')'
|
||||
/// [C++0x] 'alignof' '(' type-id ')'
|
||||
///
|
||||
/// [GNU] typeof-specifier:
|
||||
/// typeof ( expressions )
|
||||
/// typeof ( type-name )
|
||||
/// [GNU/C++] typeof unary-expression
|
||||
///
|
||||
Parser::OwningExprResult
|
||||
Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
|
||||
bool &isCastExpr,
|
||||
TypeTy *&CastTy,
|
||||
SourceRange &CastRange) {
|
||||
|
||||
assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) ||
|
||||
OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) &&
|
||||
"Not a typeof/sizeof/alignof expression!");
|
||||
|
||||
OwningExprResult Operand(Actions);
|
||||
|
||||
// If the operand doesn't start with an '(', it must be an expression.
|
||||
if (Tok.isNot(tok::l_paren)) {
|
||||
isCastExpr = false;
|
||||
if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) {
|
||||
Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
|
||||
return ExprError();
|
||||
}
|
||||
Operand = ParseCastExpression(true/*isUnaryExpression*/);
|
||||
|
||||
} else {
|
||||
// If it starts with a '(', we know that it is either a parenthesized
|
||||
// type-name, or it is a unary-expression that starts with a compound
|
||||
// literal, or starts with a primary-expression that is a parenthesized
|
||||
// expression.
|
||||
ParenParseOption ExprType = CastExpr;
|
||||
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
|
||||
Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
|
||||
CastRange = SourceRange(LParenLoc, RParenLoc);
|
||||
|
||||
// If ParseParenExpression parsed a '(typename)' sequence only, then this is
|
||||
// a type.
|
||||
if (ExprType == CastExpr) {
|
||||
isCastExpr = true;
|
||||
return ExprEmpty();
|
||||
}
|
||||
|
||||
// If this is a parenthesized expression, it is the start of a
|
||||
// unary-expression, but doesn't include any postfix pieces. Parse these
|
||||
// now if present.
|
||||
Operand = ParsePostfixExpressionSuffix(move(Operand));
|
||||
}
|
||||
|
||||
// If we get here, the operand to the typeof/sizeof/alignof was an expresion.
|
||||
isCastExpr = false;
|
||||
return move(Operand);
|
||||
}
|
||||
|
||||
|
||||
/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
|
||||
/// unary-expression: [C99 6.5.3]
|
||||
|
@ -928,40 +994,26 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
|
|||
Token OpTok = Tok;
|
||||
ConsumeToken();
|
||||
|
||||
// If the operand doesn't start with an '(', it must be an expression.
|
||||
OwningExprResult Operand(Actions);
|
||||
if (Tok.isNot(tok::l_paren)) {
|
||||
Operand = ParseCastExpression(true);
|
||||
} else {
|
||||
// If it starts with a '(', we know that it is either a parenthesized
|
||||
// type-name, or it is a unary-expression that starts with a compound
|
||||
// literal, or starts with a primary-expression that is a parenthesized
|
||||
// expression.
|
||||
ParenParseOption ExprType = CastExpr;
|
||||
TypeTy *CastTy;
|
||||
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
|
||||
Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
|
||||
bool isCastExpr;
|
||||
TypeTy *CastTy;
|
||||
SourceRange CastRange;
|
||||
OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
|
||||
isCastExpr,
|
||||
CastTy,
|
||||
CastRange);
|
||||
|
||||
// If ParseParenExpression parsed a '(typename)' sequence only, the this is
|
||||
// sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression.
|
||||
if (ExprType == CastExpr)
|
||||
return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
|
||||
OpTok.is(tok::kw_sizeof),
|
||||
/*isType=*/true, CastTy,
|
||||
SourceRange(LParenLoc, RParenLoc));
|
||||
|
||||
// If this is a parenthesized expression, it is the start of a
|
||||
// unary-expression, but doesn't include any postfix pieces. Parse these
|
||||
// now if present.
|
||||
Operand = ParsePostfixExpressionSuffix(move(Operand));
|
||||
}
|
||||
if (isCastExpr)
|
||||
return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
|
||||
OpTok.is(tok::kw_sizeof),
|
||||
/*isType=*/true, CastTy,
|
||||
CastRange);
|
||||
|
||||
// If we get here, the operand to the sizeof/alignof was an expresion.
|
||||
if (!Operand.isInvalid())
|
||||
Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
|
||||
OpTok.is(tok::kw_sizeof),
|
||||
/*isType=*/false,
|
||||
Operand.release(), SourceRange());
|
||||
Operand.release(), CastRange);
|
||||
return move(Operand);
|
||||
}
|
||||
|
||||
|
@ -1177,6 +1229,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType,
|
|||
Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation());
|
||||
|
||||
} else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
|
||||
|
||||
// Otherwise, this is a compound literal expression or cast expression.
|
||||
TypeResult Ty = ParseTypeName();
|
||||
|
||||
|
|
Loading…
Reference in New Issue