diff options
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 160 |
1 files changed, 101 insertions, 59 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a4610698c46d..9fe4309ca124 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -912,13 +912,18 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } IdentifierLoc *Platform = ParseIdentifierLoc(); - // Canonicalize platform name from "macosx" to "macos". - if (Platform->Ident && Platform->Ident->getName() == "macosx") - Platform->Ident = PP.getIdentifierInfo("macos"); - // Canonicalize platform name from "macosx_app_extension" to - // "macos_app_extension". - if (Platform->Ident && Platform->Ident->getName() == "macosx_app_extension") - Platform->Ident = PP.getIdentifierInfo("macos_app_extension"); + if (const IdentifierInfo *const Ident = Platform->Ident) { + // Canonicalize platform name from "macosx" to "macos". + if (Ident->getName() == "macosx") + Platform->Ident = PP.getIdentifierInfo("macos"); + // Canonicalize platform name from "macosx_app_extension" to + // "macos_app_extension". + else if (Ident->getName() == "macosx_app_extension") + Platform->Ident = PP.getIdentifierInfo("macos_app_extension"); + else + Platform->Ident = PP.getIdentifierInfo( + AvailabilityAttr::canonicalizePlatformName(Ident->getName())); + } // Parse the ',' following the platform name. if (ExpectAndConsume(tok::comma)) { @@ -1388,7 +1393,9 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, // If the Decl is on a function, add function parameters to the scope. bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); + ParseScope FnScope( + this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, + HasFunScope); if (HasFunScope) Actions.ActOnReenterFunctionContext(Actions.CurScope, D); @@ -1555,7 +1562,7 @@ void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, unsigned DiagID) { for (AttributeList *Attr = Attrs.getList(); Attr; Attr = Attr->getNext()) { - if (!Attr->isCXX11Attribute()) + if (!Attr->isCXX11Attribute() && !Attr->isC2xAttribute()) continue; if (Attr->getKind() == AttributeList::UnknownAttribute) Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored) @@ -2124,6 +2131,37 @@ Decl *Parser::ParseDeclarationAfterDeclarator( Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) { + // RAII type used to track whether we're inside an initializer. + struct InitializerScopeRAII { + Parser &P; + Declarator &D; + Decl *ThisDecl; + + InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl) + : P(P), D(D), ThisDecl(ThisDecl) { + if (ThisDecl && P.getLangOpts().CPlusPlus) { + Scope *S = nullptr; + if (D.getCXXScopeSpec().isSet()) { + P.EnterScope(0); + S = P.getCurScope(); + } + P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl); + } + } + ~InitializerScopeRAII() { pop(); } + void pop() { + if (ThisDecl && P.getLangOpts().CPlusPlus) { + Scope *S = nullptr; + if (D.getCXXScopeSpec().isSet()) + S = P.getCurScope(); + P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl); + if (S) + P.ExitScope(); + } + ThisDecl = nullptr; + } + }; + // Inform the current actions module that we just parsed this declarator. Decl *ThisDecl = nullptr; switch (TemplateInfo.Kind) { @@ -2201,10 +2239,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( else Diag(ConsumeToken(), diag::err_default_special_members); } else { - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); - } + InitializerScopeRAII InitScope(*this, D, ThisDecl); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); @@ -2227,10 +2262,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( FRI->RangeExpr = Init; } - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); if (Init.isInvalid()) { SmallVector<tok::TokenKind, 2> StopTokens; @@ -2252,23 +2284,27 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( ExprVector Exprs; CommaLocsTy CommaLocs; - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); + InitializerScopeRAII InitScope(*this, D, ThisDecl); + + llvm::function_ref<void()> ExprListCompleter; + auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl); + auto ConstructorCompleter = [&, ThisVarDecl] { + Actions.CodeCompleteConstructor( + getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(), + ThisDecl->getLocation(), Exprs); + }; + if (ThisVarDecl) { + // ParseExpressionList can sometimes succeed even when ThisDecl is not + // VarDecl. This is an error and it is reported in a call to + // Actions.ActOnInitializerError(). However, we call + // CodeCompleteConstructor only on VarDecls, falling back to default + // completer in other cases. + ExprListCompleter = ConstructorCompleter; } - if (ParseExpressionList(Exprs, CommaLocs, [&] { - Actions.CodeCompleteConstructor(getCurScope(), - cast<VarDecl>(ThisDecl)->getType()->getCanonicalTypeInternal(), - ThisDecl->getLocation(), Exprs); - })) { + if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) { Actions.ActOnInitializerError(ThisDecl); SkipUntil(tok::r_paren, StopAtSemi); - - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } } else { // Match the ')'. T.consumeClose(); @@ -2276,10 +2312,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && "Unexpected number of commas!"); - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), T.getCloseLocation(), @@ -2292,17 +2325,11 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( // Parse C++0x braced-init-list. Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); - if (D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); - } + InitializerScopeRAII InitScope(*this, D, ThisDecl); ExprResult Init(ParseBraceInitializer()); - if (D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); if (Init.isInvalid()) { Actions.ActOnInitializerError(ThisDecl); @@ -2898,7 +2925,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::l_square: case tok::kw_alignas: - if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier()) + if (!standardAttributesAllowed() || !isCXX11AttributeSpecifier()) goto DoneWithDeclSpec; ProhibitAttributes(attrs); @@ -3201,7 +3228,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // Likewise, if this is a context where the identifier could be a template // name, check whether this is a deduction guide declaration. - if (getLangOpts().CPlusPlus1z && + if (getLangOpts().CPlusPlus17 && (DSContext == DSC_class || DSContext == DSC_top_level) && Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(), Tok.getLocation()) && @@ -3437,11 +3464,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID); break; - // concept - case tok::kw_concept: - isInvalid = DS.SetConceptSpec(Loc, PrevSpec, DiagID); - break; - // type-specifier case tok::kw_short: isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, @@ -3503,6 +3525,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw__Float16: + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw___float128: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); @@ -3747,7 +3773,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, /// semicolon. /// /// struct-declaration: -/// specifier-qualifier-list struct-declarator-list +/// [C2x] attributes-specifier-seq[opt] +/// specifier-qualifier-list struct-declarator-list /// [GNU] __extension__ struct-declaration /// [GNU] specifier-qualifier-list /// struct-declarator-list: @@ -3771,6 +3798,11 @@ void Parser::ParseStructDeclaration( return ParseStructDeclaration(DS, FieldsCallback); } + // Parse leading attributes. + ParsedAttributesWithRange Attrs(AttrFactory); + MaybeParseCXX11Attributes(Attrs); + DS.takeAttributesFrom(Attrs); + // Parse the common specifier-qualifiers-list piece. ParseSpecifierQualifierList(DS); @@ -4381,9 +4413,11 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { ParsedAttributesWithRange attrs(AttrFactory); MaybeParseGNUAttributes(attrs); ProhibitAttributes(attrs); // GNU-style attributes are prohibited. - if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { - if (!getLangOpts().CPlusPlus1z) - Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute) + if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { + if (getLangOpts().CPlusPlus) + Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 + ? diag::warn_cxx14_compat_ns_enum_attribute + : diag::ext_ns_enum_attribute) << 1 /*enumerator*/; ParseCXX11Attributes(attrs); } @@ -4506,6 +4540,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: @@ -4581,6 +4616,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: @@ -4737,6 +4773,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: @@ -4783,9 +4820,6 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::annot_decltype: case tok::kw_constexpr: - // C++ Concepts TS - concept - case tok::kw_concept: - // C11 _Atomic case tok::kw__Atomic: return true; @@ -4990,7 +5024,7 @@ void Parser::ParseTypeQualifierListOpt( DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed, bool IdentifierRequired, Optional<llvm::function_ref<void()>> CodeCompletionHandler) { - if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) && + if (standardAttributesAllowed() && (AttrReqs & AR_CXX11AttributesParsed) && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrs(AttrFactory); ParseCXX11Attributes(attrs); @@ -5927,7 +5961,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, SmallVector<SourceRange, 2> DynamicExceptionRanges; ExprResult NoexceptExpr; CachedTokens *ExceptionSpecTokens = nullptr; - ParsedAttributes FnAttrs(AttrFactory); + ParsedAttributesWithRange FnAttrs(AttrFactory); TypeResult TrailingReturnType; /* LocalEndLoc is the end location for the local FunctionTypeLoc. @@ -5948,6 +5982,11 @@ void Parser::ParseFunctionDeclarator(Declarator &D, RParenLoc = Tracker.getCloseLocation(); LocalEndLoc = RParenLoc; EndLoc = RParenLoc; + + // If there are attributes following the identifier list, parse them and + // prohibit them. + MaybeParseCXX11Attributes(FnAttrs); + ProhibitAttributes(FnAttrs); } else { if (Tok.isNot(tok::r_paren)) ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, @@ -5955,7 +5994,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D, else if (RequiresArg) Diag(Tok, diag::err_argument_required_after_attribute); - HasProto = ParamInfo.size() || getLangOpts().CPlusPlus; + HasProto = ParamInfo.size() || getLangOpts().CPlusPlus + || getLangOpts().OpenCL; // If we have the closing ')', eat it. Tracker.consumeClose(); @@ -6053,6 +6093,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D, TrailingReturnType = ParseTrailingReturnType(Range); EndLoc = Range.getEnd(); } + } else if (standardAttributesAllowed()) { + MaybeParseCXX11Attributes(FnAttrs); } } |