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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130297 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 1abdeb4..eefa9c0 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -483,6 +483,7 @@
ANNOTATION(template_id) // annotation for a C++ template-id that names a
// function template specialization (not a type),
// e.g., "std::swap<int>"
+ANNOTATION(primary_expr) // annotation for a primary expression
// Annotation for #pragma unused(...)
// For each argument inside the parentheses the pragma handler will produce
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 9932bbb..4308977 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -392,6 +392,24 @@
static void setTypeAnnotation(Token &Tok, ParsedType T) {
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
/// typename (possibly qualified in C++) or a C++ scope specifier not followed
@@ -1049,10 +1067,10 @@
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
- ExprResult ParseExpression(ExprResult Primary = ExprResult());
+ ExprResult ParseExpression();
ExprResult ParseConstantExpression();
// Expr that doesn't include commas.
- ExprResult ParseAssignmentExpression(ExprResult Primary = ExprResult());
+ ExprResult ParseAssignmentExpression();
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
@@ -1258,7 +1276,7 @@
}
StmtResult ParseStatementOrDeclaration(StmtVector& Stmts,
bool OnlyStatement = false);
- StmtResult ParseExprStatement(ParsedAttributes &Attrs, ExprResult Primary);
+ StmtResult ParseExprStatement(ParsedAttributes &Attrs);
StmtResult ParseLabeledStatement(ParsedAttributes &Attr);
StmtResult ParseCaseStatement(ParsedAttributes &Attr,
bool MissingCase = false,
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 12761e8..c990c52 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -174,11 +174,8 @@
/// expression: [C99 6.5.17]
/// assignment-expression ...[opt]
/// expression ',' assignment-expression ...[opt]
-///
-/// \param Primary if non-empty, an already-parsed expression that will be used
-/// as the first primary expression.
-ExprResult Parser::ParseExpression(ExprResult Primary) {
- ExprResult LHS(ParseAssignmentExpression(Primary));
+ExprResult Parser::ParseExpression() {
+ ExprResult LHS(ParseAssignmentExpression());
return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
}
@@ -214,27 +211,16 @@
}
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
-///
-/// \param Primary if non-empty, an already-parsed expression that will be used
-/// as the first primary expression.
-ExprResult Parser::ParseAssignmentExpression(ExprResult Primary) {
+ExprResult Parser::ParseAssignmentExpression() {
if (Tok.is(tok::code_completion)) {
- if (Primary.isUsable())
- Actions.CodeCompletePostfixExpression(getCurScope(), Primary);
- else
- Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+ Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
ConsumeCodeCompletionToken();
}
- if (!Primary.isUsable() && Tok.is(tok::kw_throw))
+ if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprResult LHS;
- if (Primary.get() || Primary.isInvalid())
- LHS = ParsePostfixExpressionSuffix(Primary);
- else
- LHS = ParseCastExpression(false, false, ParsedType());
-
+ ExprResult LHS = ParseCastExpression(false, false, ParsedType());
return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
}
@@ -628,6 +614,12 @@
case tok::kw_nullptr:
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
// unqualified-id: identifier
// constant: enumeration-constant
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 2ab2fcc..07cef55 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -146,13 +146,15 @@
Tok.setKind(tok::annot_typename);
setTypeAnnotation(Tok, Classification.getType());
Tok.setAnnotationEndLoc(NameLoc);
- Tok.setLocation(NameLoc);
PP.AnnotateCachedTokens(Tok);
break;
case Sema::NC_Expression:
- ConsumeToken(); // the identifier
- return ParseExprStatement(attrs, Classification.getExpression());
+ Tok.setKind(tok::annot_primary_expr);
+ setExprAnnotation(Tok, Classification.getExpression());
+ Tok.setAnnotationEndLoc(NameLoc);
+ PP.AnnotateCachedTokens(Tok);
+ break;
case Sema::NC_TypeTemplate:
case Sema::NC_FunctionTemplate: {
@@ -210,7 +212,7 @@
return StmtError();
}
- return ParseExprStatement(attrs, ExprResult());
+ return ParseExprStatement(attrs);
}
case tok::kw_case: // C99 6.8.1: labeled-statement
@@ -288,14 +290,13 @@
}
/// \brief Parse an expression statement.
-StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs,
- ExprResult Primary) {
+StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) {
// If a case keyword is missing, this is where it should be inserted.
Token OldToken = Tok;
// FIXME: Use the attributes
// expression[opt] ';'
- ExprResult Expr(ParseExpression(Primary));
+ ExprResult Expr(ParseExpression());
if (Expr.isInvalid()) {
// 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