summaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp160
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);
}
}