forked from OSchip/llvm-project
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:
parent
956d96ce34
commit
da6c89de48
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue