diff options
author | Ilya Biryukov <ibiryukov@google.com> | 2019-01-31 20:20:32 +0000 |
---|---|---|
committer | Ilya Biryukov <ibiryukov@google.com> | 2019-01-31 20:20:32 +0000 |
commit | 4f9543b4d6152a5ee574246a645c7a3ec1db2c4f (patch) | |
tree | 30f0dd5daaa87f4663c6637e9b22140357937b59 /clang/lib/Parse/ParseExpr.cpp | |
parent | 240a90a57e3f313914dfb08c881fe7b079137c84 (diff) | |
download | bcm5719-llvm-4f9543b4d6152a5ee574246a645c7a3ec1db2c4f.tar.gz bcm5719-llvm-4f9543b4d6152a5ee574246a645c7a3ec1db2c4f.zip |
[CodeComplete] Propagate preferred types through parser in more cases
Preferred types are used by code completion for ranking. This commit
considerably increases the number of points in code where those types
are propagated.
In order to avoid complicating signatures of Parser's methods, a
preferred type is kept as a member variable in the parser and updated
during parsing.
Differential revision: https://reviews.llvm.org/D56723
llvm-svn: 352788
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index d3787b9760d..1146afd134c 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -158,7 +158,8 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { /// Parse an expr that doesn't include (top-level) commas. ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); + Actions.CodeCompleteExpression(getCurScope(), + PreferredType.get(Tok.getLocation())); cutOffParsing(); return ExprError(); } @@ -271,7 +272,10 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { getLangOpts().CPlusPlus11); SourceLocation ColonLoc; + auto SavedType = PreferredType; while (1) { + // Every iteration may rely on a preferred type for the whole expression. + PreferredType = SavedType; // 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), // then we are done! @@ -392,15 +396,8 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { } } - // Code completion for the right-hand side of a binary expression goes - // through a special hook that takes the left-hand side into account. - if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteBinaryRHS(getCurScope(), LHS.get(), - OpToken.getKind()); - cutOffParsing(); - return ExprError(); - } - + PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(), + OpToken.getKind()); // Parse another leaf here for the RHS of the operator. // ParseCastExpression works here because all RHS expressions in C have it // as a prefix, at least. However, in C++, an assignment-expression could @@ -763,6 +760,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isVectorLiteral) { ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); + auto SavedType = PreferredType; NotCastExpr = false; // This handles all of cast-expression, unary-expression, postfix-expression, @@ -1114,6 +1112,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // -- cast-expression Token SavedTok = Tok; ConsumeToken(); + + PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(), + SavedTok.getLocation()); // One special case is implicitly handled here: if the preceding tokens are // an ambiguous cast expression, such as "(T())++", then we recurse to // determine whether the '++' is prefix or postfix. @@ -1135,6 +1136,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::amp: { // unary-expression: '&' cast-expression // Special treatment because of member pointers SourceLocation SavedLoc = ConsumeToken(); + PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); Res = ParseCastExpression(false, true); if (!Res.isInvalid()) Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); @@ -1149,6 +1151,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___real: // unary-expression: '__real' cast-expression [GNU] case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU] SourceLocation SavedLoc = ConsumeToken(); + PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc); Res = ParseCastExpression(false); if (!Res.isInvalid()) Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); @@ -1423,7 +1426,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, Res = ParseBlockLiteralExpression(); break; case tok::code_completion: { - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); + Actions.CodeCompleteExpression(getCurScope(), + PreferredType.get(Tok.getLocation())); cutOffParsing(); return ExprError(); } @@ -1458,6 +1462,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // that the address of the function is being taken, which is illegal in CL. // These can be followed by postfix-expr pieces. + PreferredType = SavedType; Res = ParsePostfixExpressionSuffix(Res); if (getLangOpts().OpenCL) if (Expr *PostfixExpr = Res.get()) { @@ -1497,13 +1502,17 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Now that the primary-expression piece of the postfix-expression has been // parsed, see if there are any postfix-expression pieces here. SourceLocation Loc; + auto SavedType = PreferredType; while (1) { + // Each iteration relies on preferred type for the whole expression. + PreferredType = SavedType; switch (Tok.getKind()) { case tok::code_completion: if (InMessageExpression) return LHS; - Actions.CodeCompletePostfixExpression(getCurScope(), LHS); + Actions.CodeCompletePostfixExpression( + getCurScope(), LHS, PreferredType.get(Tok.getLocation())); cutOffParsing(); return ExprError(); @@ -1545,6 +1554,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { Loc = T.getOpenLocation(); ExprResult Idx, Length; SourceLocation ColonLoc; + PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); Idx = ParseBraceInitializer(); @@ -1726,6 +1736,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { bool MayBePseudoDestructor = false; Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; + PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS); + if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { Expr *Base = OrigLHS; const Type* BaseType = Base->getType().getTypePtrOrNull(); @@ -1772,7 +1784,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Code completion for a member access expression. Actions.CodeCompleteMemberReferenceExpr( getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, - Base && ExprStatementTokLoc == Base->getBeginLoc()); + Base && ExprStatementTokLoc == Base->getBeginLoc(), + PreferredType.get(Tok.getLocation())); cutOffParsing(); return ExprError(); @@ -2326,14 +2339,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, return ExprError(); SourceLocation OpenLoc = T.getOpenLocation(); + PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc); + ExprResult Result(true); bool isAmbiguousTypeId; CastTy = nullptr; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), - ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression - : Sema::PCC_Expression); + Actions.CodeCompleteExpression( + getCurScope(), PreferredType.get(Tok.getLocation()), + /*IsParenthesized=*/ExprType >= CompoundLiteral); cutOffParsing(); return ExprError(); } @@ -2414,6 +2429,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, T.consumeClose(); ColonProtection.restore(); RParenLoc = T.getCloseLocation(); + + PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get()); ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); if (Ty.isInvalid() || SubExpr.isInvalid()) @@ -2544,6 +2561,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, return ExprError(); } + PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get()); // Parse the cast-expression that follows it next. // TODO: For cast expression with CastTy. Result = ParseCastExpression(/*isUnaryExpression=*/false, @@ -2845,7 +2863,8 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, if (Completer) Completer(); else - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); + Actions.CodeCompleteExpression(getCurScope(), + PreferredType.get(Tok.getLocation())); cutOffParsing(); return true; } |