diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -888,7 +888,9 @@ /// \param IncludeBriefComments Whether to include brief documentation within /// the set of code completions returned. /// - /// \param Act A SyntaxOnlyAction performs actions on the syntax. + /// \param Act If supplied, this argument is used to parse the input file, + /// allowing customized parsing by overriding SyntaxOnlyAction lifecycle + /// methods. /// /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and /// OwnedBuffers parameters are all disgusting hacks. They will go away. diff --git a/clang/include/clang/Interpreter/InterpreterCodeCompletion.h b/clang/include/clang/Interpreter/InterpreterCodeCompletion.h --- a/clang/include/clang/Interpreter/InterpreterCodeCompletion.h +++ b/clang/include/clang/Interpreter/InterpreterCodeCompletion.h @@ -12,6 +12,7 @@ #ifndef LLVM_CLANG_INTERPRETER_CODE_COMPLETION_H #define LLVM_CLANG_INTERPRETER_CODE_COMPLETION_H +#include #include namespace llvm { @@ -26,7 +27,7 @@ unsigned Line, unsigned Col, const CompilerInstance *ParentCI, std::vector &CCResults); -std::vector -ConvertToCodeCompleteStrings(const std::vector &Results); +std::vector +convertToCodeCompleteStrings(const std::vector &Results); } // namespace clang #endif diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -339,7 +339,7 @@ CCC_ObjCClassForwardDecl, /// Code completion at a top level in a REPL session. - CCC_ReplTopLevel, + CCC_TopLevelOrExpression, }; using VisitedContextSet = llvm::SmallPtrSet; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13452,7 +13452,7 @@ /// specifiers within a function, method, or block. PCC_LocalDeclarationSpecifiers, /// Code completion occurs at top-level in a REPL session - PCC_TopLevelStmtDecl, + PCC_TopLevelOrExpression, }; void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -2007,7 +2007,7 @@ case CodeCompletionContext::CCC_SymbolOrNewName: case CodeCompletionContext::CCC_ParenthesizedExpression: case CodeCompletionContext::CCC_ObjCInterfaceName: - case CodeCompletionContext::CCC_ReplTopLevel: + case CodeCompletionContext::CCC_TopLevelOrExpression: break; case CodeCompletionContext::CCC_EnumTag: diff --git a/clang/lib/Interpreter/InterpreterCodeCompletion.cpp b/clang/lib/Interpreter/InterpreterCodeCompletion.cpp --- a/clang/lib/Interpreter/InterpreterCodeCompletion.cpp +++ b/clang/lib/Interpreter/InterpreterCodeCompletion.cpp @@ -69,23 +69,23 @@ Results.push_back(Result); } break; - default: - break; case CodeCompletionResult::RK_Keyword: Results.push_back(Result); break; + default: + break; } } }; -std::vector ConvertToCodeCompleteStrings( +std::vector convertToCodeCompleteStrings( const std::vector &Results) { - std::vector CompletionStrings; + std::vector CompletionStrings; for (auto Res : Results) { switch (Res.Kind) { case clang::CodeCompletionResult::RK_Declaration: if (auto *ID = Res.Declaration->getIdentifier()) { - CompletionStrings.push_back(ID->getName()); + CompletionStrings.push_back(ID->getName().str()); } break; case clang::CodeCompletionResult::RK_Keyword: diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -6645,18 +6645,6 @@ while (true) { if (Tok.is(tok::l_paren)) { - if (PP.isIncrementalProcessingEnabled() && - NextToken().is(tok::code_completion)) { - // In clang-repl, code completion for input like `void foo(` should - // not trigger a parsing error. So we make the declarator malformed and - // exits the loop. - ConsumeParen(); - cutOffParsing(); - D.SetIdentifier(nullptr, Tok.getLocation()); - D.setInvalidType(true); - break; - } - bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration(); // Enter function-declaration scope, limiting any declarators to the // function prototype scope, including parameter declarators. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -928,7 +928,7 @@ if (CurParsedObjCImpl) { PCC = Sema::PCC_ObjCImplementation; } else if (PP.isIncrementalProcessingEnabled()) { - PCC = Sema::PCC_TopLevelStmtDecl; + PCC = Sema::PCC_TopLevelOrExpression; } else { PCC = Sema::PCC_Namespace; }; diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -51,7 +51,7 @@ case CCC_ParenthesizedExpression: case CCC_Symbol: case CCC_SymbolOrNewName: - case CCC_ReplTopLevel: + case CCC_TopLevelOrExpression: return true; case CCC_TopLevel: @@ -170,7 +170,7 @@ return "Recovery"; case CCKind::CCC_ObjCClassForwardDecl: return "ObjCClassForwardDecl"; - case CCKind::CCC_ReplTopLevel: + case CCKind::CCC_TopLevelOrExpression: return "ReplTopLevel"; } llvm_unreachable("Invalid CodeCompletionContext::Kind!"); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -225,7 +225,7 @@ case CodeCompletionContext::CCC_ObjCMessageReceiver: case CodeCompletionContext::CCC_ParenthesizedExpression: case CodeCompletionContext::CCC_Statement: - case CodeCompletionContext::CCC_ReplTopLevel: + case CodeCompletionContext::CCC_TopLevelOrExpression: case CodeCompletionContext::CCC_Recovery: if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) if (Method->isInstanceMethod()) @@ -1851,7 +1851,7 @@ case Sema::PCC_ObjCInstanceVariableList: case Sema::PCC_Expression: case Sema::PCC_Statement: - case Sema::PCC_TopLevelStmtDecl: + case Sema::PCC_TopLevelOrExpression: case Sema::PCC_ForInit: case Sema::PCC_Condition: case Sema::PCC_RecoveryInFunction: @@ -1909,7 +1909,7 @@ case Sema::PCC_Type: case Sema::PCC_ParenthesizedExpression: case Sema::PCC_LocalDeclarationSpecifiers: - case Sema::PCC_TopLevelStmtDecl: + case Sema::PCC_TopLevelOrExpression: return true; case Sema::PCC_Expression: @@ -2222,7 +2222,7 @@ break; case Sema::PCC_RecoveryInFunction: - case Sema::PCC_TopLevelStmtDecl: + case Sema::PCC_TopLevelOrExpression: case Sema::PCC_Statement: { if (SemaRef.getLangOpts().CPlusPlus11) AddUsingAliasResult(Builder, Results); @@ -4212,8 +4212,8 @@ case Sema::PCC_LocalDeclarationSpecifiers: return CodeCompletionContext::CCC_Type; - case Sema::PCC_TopLevelStmtDecl: - return CodeCompletionContext::CCC_ReplTopLevel; + case Sema::PCC_TopLevelOrExpression: + return CodeCompletionContext::CCC_TopLevelOrExpression; } llvm_unreachable("Invalid ParserCompletionContext!"); @@ -4354,7 +4354,7 @@ break; case PCC_Statement: - case PCC_TopLevelStmtDecl: + case PCC_TopLevelOrExpression: case PCC_ParenthesizedExpression: case PCC_Expression: case PCC_ForInit: @@ -4392,7 +4392,7 @@ case PCC_ParenthesizedExpression: case PCC_Expression: case PCC_Statement: - case PCC_TopLevelStmtDecl: + case PCC_TopLevelOrExpression: case PCC_RecoveryInFunction: if (S->getFnParent()) AddPrettyFunctionResults(getLangOpts(), Results); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -129,13 +129,14 @@ s = Buffer.substr(space_pos + 1); } - for (auto c : ConvertToCodeCompleteStrings(Results)) { - if (c.startswith(s)) + for (auto c : convertToCodeCompleteStrings(Results)) { + if (c.find(s) == 0) Comps.push_back( - llvm::LineEditor::Completion(c.substr(s.size()).str(), c.str())); + llvm::LineEditor::Completion(c.substr(s.size()), c)); } return Comps; } + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -543,7 +543,7 @@ case CodeCompletionContext::CCC_PreprocessorExpression: case CodeCompletionContext::CCC_PreprocessorDirective: case CodeCompletionContext::CCC_Attribute: - case CodeCompletionContext::CCC_ReplTopLevel: + case CodeCompletionContext::CCC_TopLevelOrExpression: case CodeCompletionContext::CCC_TypeQualifiers: { //Only Clang results should be accepted, so we'll set all of the other //context bits to 0 (i.e. the empty set) diff --git a/clang/unittests/Interpreter/CodeCompletionTest.cpp b/clang/unittests/Interpreter/CodeCompletionTest.cpp --- a/clang/unittests/Interpreter/CodeCompletionTest.cpp +++ b/clang/unittests/Interpreter/CodeCompletionTest.cpp @@ -42,9 +42,9 @@ Prefix, 1, Prefix.size(), MainInterp.getCompilerInstance(), Results); std::vector Comps; - for (auto c : ConvertToCodeCompleteStrings(Results)) { - if (c.startswith(Prefix)) - Comps.push_back(c.substr(Prefix.size()).str()); + for (auto c : convertToCodeCompleteStrings(Results)) { + if (c.find(Prefix) == 0) + Comps.push_back(c.substr(Prefix.size())); } return Comps;