aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorlh123 <1585086582@qq.com>2020-06-25 20:04:18 +0800
committerlh123 <1585086582@qq.com>2020-07-01 12:51:25 +0800
commit83fae3f762699655a4329fe3cf6fd3e2a2617559 (patch)
treedcdfb1153d7f331095aeabb42356f1ae080bdde0 /clang/lib/Parse/ParseDecl.cpp
parentca134e4c525babf0c414c78fb53d648fbee364d8 (diff)
downloadllvm-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.cpp80
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;
+ }
}
}
}