diff options
author | lh123 <1585086582@qq.com> | 2020-06-25 20:04:18 +0800 |
---|---|---|
committer | lh123 <1585086582@qq.com> | 2020-07-01 12:51:25 +0800 |
commit | 83fae3f762699655a4329fe3cf6fd3e2a2617559 (patch) | |
tree | dcdfb1153d7f331095aeabb42356f1ae080bdde0 /clang/lib/Parse/ParseDecl.cpp | |
parent | ca134e4c525babf0c414c78fb53d648fbee364d8 (diff) | |
download | llvm-83fae3f762699655a4329fe3cf6fd3e2a2617559.zip llvm-83fae3f762699655a4329fe3cf6fd3e2a2617559.tar.gz llvm-83fae3f762699655a4329fe3cf6fd3e2a2617559.tar.bz2 |
[CodeComplete] Add code completion after function equals
Summary:
Provide `default` and `delete` completion after the function equals.
Reviewers: kadircet, sammccall
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82548
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 80 |
1 files changed, 43 insertions, 37 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f336af6..c87d240 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1898,46 +1898,52 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, } // Check to see if we have a function *definition* which must have a body. - if (D.isFunctionDeclarator() && - // Look at the next token to make sure that this isn't a function - // declaration. We have to check this because __attribute__ might be the - // start of a function definition in GCC-extended K&R C. - !isDeclarationAfterDeclarator()) { - - // Function definitions are only allowed at file scope and in C++ classes. - // The C++ inline method definition case is handled elsewhere, so we only - // need to handle the file scope definition case. - if (Context == DeclaratorContext::FileContext) { - if (isStartOfFunctionDefinition(D)) { - if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { - Diag(Tok, diag::err_function_declared_typedef); - - // Recover by treating the 'typedef' as spurious. - DS.ClearStorageClassSpecs(); - } + if (D.isFunctionDeclarator()) { + if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) { + Actions.CodeCompleteAfterFunctionEquals(D); + cutOffParsing(); + return nullptr; + } + // Look at the next token to make sure that this isn't a function + // declaration. We have to check this because __attribute__ might be the + // start of a function definition in GCC-extended K&R C. + if (!isDeclarationAfterDeclarator()) { + + // Function definitions are only allowed at file scope and in C++ classes. + // The C++ inline method definition case is handled elsewhere, so we only + // need to handle the file scope definition case. + if (Context == DeclaratorContext::FileContext) { + if (isStartOfFunctionDefinition(D)) { + if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { + Diag(Tok, diag::err_function_declared_typedef); + + // Recover by treating the 'typedef' as spurious. + DS.ClearStorageClassSpecs(); + } - Decl *TheDecl = - ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); - return Actions.ConvertDeclToDeclGroup(TheDecl); - } + Decl *TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(), + &LateParsedAttrs); + return Actions.ConvertDeclToDeclGroup(TheDecl); + } - if (isDeclarationSpecifier()) { - // If there is an invalid declaration specifier right after the - // function prototype, then we must be in a missing semicolon case - // where this isn't actually a body. Just fall through into the code - // that handles it as a prototype, and let the top-level code handle - // the erroneous declspec where it would otherwise expect a comma or - // semicolon. + if (isDeclarationSpecifier()) { + // If there is an invalid declaration specifier right after the + // function prototype, then we must be in a missing semicolon case + // where this isn't actually a body. Just fall through into the code + // that handles it as a prototype, and let the top-level code handle + // the erroneous declspec where it would otherwise expect a comma or + // semicolon. + } else { + Diag(Tok, diag::err_expected_fn_body); + SkipUntil(tok::semi); + return nullptr; + } } else { - Diag(Tok, diag::err_expected_fn_body); - SkipUntil(tok::semi); - return nullptr; - } - } else { - if (Tok.is(tok::l_brace)) { - Diag(Tok, diag::err_function_definition_not_allowed); - SkipMalformedDecl(); - return nullptr; + if (Tok.is(tok::l_brace)) { + Diag(Tok, diag::err_function_definition_not_allowed); + SkipMalformedDecl(); + return nullptr; + } } } } |