Introduce a new parser annotation token for primary expressions. When

ClassifyName() builds a primary expression, generate one of these
annotation tokens rather than jumping into the parser.

llvm-svn: 130297
This commit is contained in:
Douglas Gregor 2011-04-27 06:18:01 +00:00
parent 956d96ce34
commit da6c89de48
4 changed files with 42 additions and 30 deletions

View File

@ -483,6 +483,7 @@ ANNOTATION(typename) // annotation for a C typedef name, a C++ (possibly
ANNOTATION(template_id) // annotation for a C++ template-id that names a ANNOTATION(template_id) // annotation for a C++ template-id that names a
// function template specialization (not a type), // function template specialization (not a type),
// e.g., "std::swap<int>" // e.g., "std::swap<int>"
ANNOTATION(primary_expr) // annotation for a primary expression
// Annotation for #pragma unused(...) // Annotation for #pragma unused(...)
// For each argument inside the parentheses the pragma handler will produce // For each argument inside the parentheses the pragma handler will produce

View File

@ -392,6 +392,24 @@ private:
static void setTypeAnnotation(Token &Tok, ParsedType T) { static void setTypeAnnotation(Token &Tok, ParsedType T) {
Tok.setAnnotationValue(T.getAsOpaquePtr()); Tok.setAnnotationValue(T.getAsOpaquePtr());
} }
/// \brief Read an already-translated primary expression out of an annotation
/// token.
static ExprResult getExprAnnotation(Token &Tok) {
if (Tok.getAnnotationValue())
return ExprResult((Expr *)Tok.getAnnotationValue());
return ExprResult(true);
}
/// \brief Set the primary expression corresponding to the given annotation
/// token.
static void setExprAnnotation(Token &Tok, ExprResult ER) {
if (ER.isInvalid())
Tok.setAnnotationValue(0);
else
Tok.setAnnotationValue(ER.get());
}
/// TryAnnotateTypeOrScopeToken - If the current token position is on a /// TryAnnotateTypeOrScopeToken - If the current token position is on a
/// typename (possibly qualified in C++) or a C++ scope specifier not followed /// typename (possibly qualified in C++) or a C++ scope specifier not followed
@ -1049,10 +1067,10 @@ private:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// C99 6.5: Expressions. // C99 6.5: Expressions.
ExprResult ParseExpression(ExprResult Primary = ExprResult()); ExprResult ParseExpression();
ExprResult ParseConstantExpression(); ExprResult ParseConstantExpression();
// Expr that doesn't include commas. // Expr that doesn't include commas.
ExprResult ParseAssignmentExpression(ExprResult Primary = ExprResult()); ExprResult ParseAssignmentExpression();
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
@ -1258,7 +1276,7 @@ private:
} }
StmtResult ParseStatementOrDeclaration(StmtVector& Stmts, StmtResult ParseStatementOrDeclaration(StmtVector& Stmts,
bool OnlyStatement = false); bool OnlyStatement = false);
StmtResult ParseExprStatement(ParsedAttributes &Attrs, ExprResult Primary); StmtResult ParseExprStatement(ParsedAttributes &Attrs);
StmtResult ParseLabeledStatement(ParsedAttributes &Attr); StmtResult ParseLabeledStatement(ParsedAttributes &Attr);
StmtResult ParseCaseStatement(ParsedAttributes &Attr, StmtResult ParseCaseStatement(ParsedAttributes &Attr,
bool MissingCase = false, bool MissingCase = false,

View File

@ -174,11 +174,8 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
/// expression: [C99 6.5.17] /// expression: [C99 6.5.17]
/// assignment-expression ...[opt] /// assignment-expression ...[opt]
/// expression ',' assignment-expression ...[opt] /// expression ',' assignment-expression ...[opt]
/// ExprResult Parser::ParseExpression() {
/// \param Primary if non-empty, an already-parsed expression that will be used ExprResult LHS(ParseAssignmentExpression());
/// as the first primary expression.
ExprResult Parser::ParseExpression(ExprResult Primary) {
ExprResult LHS(ParseAssignmentExpression(Primary));
return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
} }
@ -214,27 +211,16 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
} }
/// ParseAssignmentExpression - Parse an expr that doesn't include commas. /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
/// ExprResult Parser::ParseAssignmentExpression() {
/// \param Primary if non-empty, an already-parsed expression that will be used
/// as the first primary expression.
ExprResult Parser::ParseAssignmentExpression(ExprResult Primary) {
if (Tok.is(tok::code_completion)) { if (Tok.is(tok::code_completion)) {
if (Primary.isUsable()) Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
Actions.CodeCompletePostfixExpression(getCurScope(), Primary);
else
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
ConsumeCodeCompletionToken(); ConsumeCodeCompletionToken();
} }
if (!Primary.isUsable() && Tok.is(tok::kw_throw)) if (Tok.is(tok::kw_throw))
return ParseThrowExpression(); return ParseThrowExpression();
ExprResult LHS; ExprResult LHS = ParseCastExpression(false, false, ParsedType());
if (Primary.get() || Primary.isInvalid())
LHS = ParsePostfixExpressionSuffix(Primary);
else
LHS = ParseCastExpression(false, false, ParsedType());
return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment); return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
} }
@ -628,6 +614,12 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw_nullptr: case tok::kw_nullptr:
return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
case tok::annot_primary_expr:
assert(Res.get() == 0 && "Stray primary-expression annotation?");
Res = getExprAnnotation(Tok);
ConsumeToken();
break;
case tok::identifier: { // primary-expression: identifier case tok::identifier: { // primary-expression: identifier
// unqualified-id: identifier // unqualified-id: identifier
// constant: enumeration-constant // constant: enumeration-constant

View File

@ -146,13 +146,15 @@ Retry:
Tok.setKind(tok::annot_typename); Tok.setKind(tok::annot_typename);
setTypeAnnotation(Tok, Classification.getType()); setTypeAnnotation(Tok, Classification.getType());
Tok.setAnnotationEndLoc(NameLoc); Tok.setAnnotationEndLoc(NameLoc);
Tok.setLocation(NameLoc);
PP.AnnotateCachedTokens(Tok); PP.AnnotateCachedTokens(Tok);
break; break;
case Sema::NC_Expression: case Sema::NC_Expression:
ConsumeToken(); // the identifier Tok.setKind(tok::annot_primary_expr);
return ParseExprStatement(attrs, Classification.getExpression()); setExprAnnotation(Tok, Classification.getExpression());
Tok.setAnnotationEndLoc(NameLoc);
PP.AnnotateCachedTokens(Tok);
break;
case Sema::NC_TypeTemplate: case Sema::NC_TypeTemplate:
case Sema::NC_FunctionTemplate: { case Sema::NC_FunctionTemplate: {
@ -210,7 +212,7 @@ Retry:
return StmtError(); return StmtError();
} }
return ParseExprStatement(attrs, ExprResult()); return ParseExprStatement(attrs);
} }
case tok::kw_case: // C99 6.8.1: labeled-statement case tok::kw_case: // C99 6.8.1: labeled-statement
@ -288,14 +290,13 @@ Retry:
} }
/// \brief Parse an expression statement. /// \brief Parse an expression statement.
StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs, StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) {
ExprResult Primary) {
// If a case keyword is missing, this is where it should be inserted. // If a case keyword is missing, this is where it should be inserted.
Token OldToken = Tok; Token OldToken = Tok;
// FIXME: Use the attributes // FIXME: Use the attributes
// expression[opt] ';' // expression[opt] ';'
ExprResult Expr(ParseExpression(Primary)); ExprResult Expr(ParseExpression());
if (Expr.isInvalid()) { if (Expr.isInvalid()) {
// If the expression is invalid, skip ahead to the next semicolon or '}'. // If the expression is invalid, skip ahead to the next semicolon or '}'.
// Not doing this opens us up to the possibility of infinite loops if // Not doing this opens us up to the possibility of infinite loops if