/// Described the kind of function definition (if any) provided for
/// a function.
-enum FunctionDefinitionKind {
- FDK_Declaration,
- FDK_Definition,
- FDK_Defaulted,
- FDK_Deleted
+enum class FunctionDefinitionKind {
+ Declaration,
+ Definition,
+ Defaulted,
+ Deleted
};
enum class DeclaratorContext {
Declarator(const DeclSpec &ds, DeclaratorContext C)
: DS(ds), Range(ds.getSourceRange()), Context(C),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
- GroupingParens(false), FunctionDefinition(FDK_Declaration),
+ GroupingParens(false), FunctionDefinition(static_cast<unsigned>(
+ FunctionDefinitionKind::Declaration)),
Redeclaration(false), Extension(false), ObjCIvar(false),
ObjCWeakProperty(false), InlineStorageUsed(false),
Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; }
void setFunctionDefinitionKind(FunctionDefinitionKind Val) {
- FunctionDefinition = Val;
+ FunctionDefinition = static_cast<unsigned>(Val);
}
bool isFunctionDefinition() const {
- return getFunctionDefinitionKind() != FDK_Declaration;
+ return getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration;
}
FunctionDefinitionKind getFunctionDefinitionKind() const {
// or if we are about to parse function member template then consume
// the tokens and store them for parsing at the end of the translation unit.
if (getLangOpts().DelayedTemplateParsing &&
- D.getFunctionDefinitionKind() == FDK_Definition &&
+ D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition &&
!D.getDeclSpec().hasConstexprSpecifier() &&
!(FnD && FnD->getAsFunction() &&
FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&
SourceLocation StartLoc,
SourceLocation EndLoc) {
// make sure we have a token we can turn into an annotation token
- if (PP.isBacktrackEnabled())
+ if (PP.isBacktrackEnabled()) {
PP.RevertCachedTokens(1);
+ if (DS.getTypeSpecType() == TST_error) {
+ // We encountered an error in parsing 'decltype(...)' so lets annotate all
+ // the tokens in the backtracking cache - that we likely had to skip over
+ // to get to a token that allows us to resume parsing, such as a
+ // semi-colon.
+ EndLoc = PP.getLastCachedTokenLocation();
+ }
+ }
else
PP.EnterToken(Tok, /*IsReinject*/true);
if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction())
TryConsumePureSpecifier(/*AllowDefinition*/ true);
- FunctionDefinitionKind DefinitionKind = FDK_Declaration;
+ FunctionDefinitionKind DefinitionKind = FunctionDefinitionKind::Declaration;
// function-definition:
//
// In C++11, a non-function declarator followed by an open brace is a
// braced-init-list for an in-class member initialization, not an
// erroneous function definition.
if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {
- DefinitionKind = FDK_Definition;
+ DefinitionKind = FunctionDefinitionKind::Definition;
} else if (DeclaratorInfo.isFunctionDeclarator()) {
if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
- DefinitionKind = FDK_Definition;
+ DefinitionKind = FunctionDefinitionKind::Definition;
} else if (Tok.is(tok::equal)) {
const Token &KW = NextToken();
if (KW.is(tok::kw_default))
- DefinitionKind = FDK_Defaulted;
+ DefinitionKind = FunctionDefinitionKind::Defaulted;
else if (KW.is(tok::kw_delete))
- DefinitionKind = FDK_Deleted;
+ DefinitionKind = FunctionDefinitionKind::Deleted;
else if (KW.is(tok::code_completion)) {
Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo);
cutOffParsing();
// C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
// to a friend declaration, that declaration shall be a definition.
if (DeclaratorInfo.isFunctionDeclarator() &&
- DefinitionKind == FDK_Declaration && DS.isFriendSpecified()) {
+ DefinitionKind == FunctionDefinitionKind::Declaration &&
+ DS.isFriendSpecified()) {
// Diagnose attributes that appear before decl specifier:
// [[]] friend int foo();
ProhibitAttributes(FnAttrs);
}
- if (DefinitionKind != FDK_Declaration) {
+ if (DefinitionKind != FunctionDefinitionKind::Declaration) {
if (!DeclaratorInfo.isFunctionDeclarator()) {
Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
ConsumeBrace();
// Parse the block-declarator.
Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteral);
- DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition);
+ DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
ParseDeclarator(DeclaratorInfo);
MaybeParseGNUAttributes(DeclaratorInfo);
// Parse the return type if present.
DeclSpec DS(AttrFactory);
Declarator ParamInfo(DS, DeclaratorContext::BlockLiteral);
- ParamInfo.setFunctionDefinitionKind(FDK_Definition);
+ ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
// FIXME: Since the return type isn't actually parsed, it can't be used to
// fill ParamInfo with an initial valid range, so do it manually.
ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
Scope::CompoundStmtScope);
Scope *ParentScope = getCurScope()->getParent();
- D.setFunctionDefinitionKind(FDK_Definition);
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
Decl *DP = Actions.HandleDeclarator(ParentScope, D,
TemplateParameterLists);
D.complete(DP);
Scope::CompoundStmtScope);
Scope *ParentScope = getCurScope()->getParent();
- D.setFunctionDefinitionKind(FDK_Definition);
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
MultiTemplateParamsArg());
D.complete(FuncDecl);
}
Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
- D.setFunctionDefinitionKind(FDK_Declaration);
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
Decl *Dcl = HandleDeclarator(S, D, MultiTemplateParamsArg());
if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer() &&
// If a function is defined as defaulted or deleted, mark it as such now.
// We'll do the relevant checks on defaulted / deleted functions later.
switch (D.getFunctionDefinitionKind()) {
- case FDK_Declaration:
- case FDK_Definition:
- break;
+ case FunctionDefinitionKind::Declaration:
+ case FunctionDefinitionKind::Definition:
+ break;
- case FDK_Defaulted:
- NewFD->setDefaulted();
- break;
+ case FunctionDefinitionKind::Defaulted:
+ NewFD->setDefaulted();
+ break;
- case FDK_Deleted:
- NewFD->setDeletedAsWritten();
- break;
+ case FunctionDefinitionKind::Deleted:
+ NewFD->setDeletedAsWritten();
+ break;
}
if (isa<CXXMethodDecl>(NewFD) && DC == CurContext &&
// because Sema::ActOnStartOfFunctionDef has not been called yet.
if (const auto *NBA = NewFD->getAttr<NoBuiltinAttr>())
switch (D.getFunctionDefinitionKind()) {
- case FDK_Defaulted:
- case FDK_Deleted:
+ case FunctionDefinitionKind::Defaulted:
+ case FunctionDefinitionKind::Deleted:
Diag(NBA->getLocation(),
diag::err_attribute_no_builtin_on_defaulted_deleted_function)
<< NBA->getSpelling();
break;
- case FDK_Declaration:
+ case FunctionDefinitionKind::Declaration:
Diag(NBA->getLocation(), diag::err_attribute_no_builtin_on_non_definition)
<< NBA->getSpelling();
break;
- case FDK_Definition:
+ case FunctionDefinitionKind::Definition:
break;
}
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
ParentScope, D, TemplateParameterLists, Bases);
- D.setFunctionDefinitionKind(FDK_Definition);
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
// If no base was found we create a declaration that we use as base.
if (Bases.empty() && UseImplicitBase) {
- D.setFunctionDefinitionKind(FDK_Declaration);
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
BaseD->setImplicit(true);
if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
// Only warn if this declarator is declaring a function at block scope, and
// doesn't have a storage class (such as 'extern') specified.
if (!D.isFunctionDeclarator() ||
- D.getFunctionDefinitionKind() != FDK_Declaration ||
+ D.getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration ||
!S.CurContext->isFunctionOrMethod() ||
- D.getDeclSpec().getStorageClassSpec()
- != DeclSpec::SCS_unspecified)
+ D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_unspecified)
return;
// Inside a condition, a direct initializer is not permitted. We allow one to
!(S.getLangOpts().CPlusPlus &&
(T->isDependentType() || T->isRecordType()))) {
if (T->isVoidType() && !S.getLangOpts().CPlusPlus &&
- D.getFunctionDefinitionKind() == FDK_Definition) {
+ D.getFunctionDefinitionKind() ==
+ FunctionDefinitionKind::Definition) {
// [6.9.1/3] qualified void return is invalid on a C
// function definition. Apparently ok on declarations and
// in C++ though (!)
// The empty list in a function declarator that is not part of a definition
// of that function specifies that no information about the number or types
// of the parameters is supplied.
- if (!LangOpts.CPlusPlus && D.getFunctionDefinitionKind() == FDK_Declaration) {
+ if (!LangOpts.CPlusPlus &&
+ D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) {
bool IsBlock = false;
for (const DeclaratorChunk &DeclType : D.type_objects()) {
switch (DeclType.Kind) {