diff options
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 249 |
1 files changed, 160 insertions, 89 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c64b97d01b9a..45e1c3e465ce 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ScopedPrinter.h" using namespace clang; @@ -609,7 +610,6 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) { case tok::kw___ptr64: case tok::kw___w64: case tok::kw___ptr32: - case tok::kw___unaligned: case tok::kw___sptr: case tok::kw___uptr: { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); @@ -670,7 +670,7 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) { } } -void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) { +void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) { // Treat these like attributes while (Tok.is(tok::kw___kernel)) { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); @@ -720,7 +720,7 @@ static bool VersionNumberSeparator(const char Separator) { /// simple-integer ',' simple-integer /// simple-integer ',' simple-integer ',' simple-integer VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { - Range = Tok.getLocation(); + Range = SourceRange(Tok.getLocation(), Tok.getEndLoc()); if (!Tok.is(tok::numeric_constant)) { Diag(Tok, diag::err_expected_version); @@ -833,11 +833,15 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// \brief Parse the contents of the "availability" attribute. /// /// availability-attribute: -/// 'availability' '(' platform ',' version-arg-list, opt-message')' +/// 'availability' '(' platform ',' opt-strict version-arg-list, +/// opt-replacement, opt-message')' /// /// platform: /// identifier /// +/// opt-strict: +/// 'strict' ',' +/// /// version-arg-list: /// version-arg /// version-arg ',' version-arg-list @@ -847,6 +851,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// 'deprecated' '=' version /// 'obsoleted' = version /// 'unavailable' +/// opt-replacement: +/// 'replacement' '=' <string> /// opt-message: /// 'message' '=' <string> void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, @@ -858,7 +864,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, AttributeList::Syntax Syntax) { enum { Introduced, Deprecated, Obsoleted, Unknown }; AvailabilityChange Changes[Unknown]; - ExprResult MessageExpr; + ExprResult MessageExpr, ReplacementExpr; // Opening '('. BalancedDelimiterTracker T(*this, tok::l_paren); @@ -867,13 +873,20 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } - // Parse the platform name, + // Parse the platform name. if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_availability_expected_platform); SkipUntil(tok::r_paren, StopAtSemi); 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"); // Parse the ',' following the platform name. if (ExpectAndConsume(tok::comma)) { @@ -889,10 +902,13 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); Ident_unavailable = PP.getIdentifierInfo("unavailable"); Ident_message = PP.getIdentifierInfo("message"); + Ident_strict = PP.getIdentifierInfo("strict"); + Ident_replacement = PP.getIdentifierInfo("replacement"); } - // Parse the set of introductions/deprecations/removals. - SourceLocation UnavailableLoc; + // Parse the optional "strict", the optional "replacement" and the set of + // introductions/deprecations/removals. + SourceLocation UnavailableLoc, StrictLoc; do { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_availability_expected_change); @@ -902,6 +918,15 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, IdentifierInfo *Keyword = Tok.getIdentifierInfo(); SourceLocation KeywordLoc = ConsumeToken(); + if (Keyword == Ident_strict) { + if (StrictLoc.isValid()) { + Diag(KeywordLoc, diag::err_availability_redundant) + << Keyword << SourceRange(StrictLoc); + } + StrictLoc = KeywordLoc; + continue; + } + if (Keyword == Ident_unavailable) { if (UnavailableLoc.isValid()) { Diag(KeywordLoc, diag::err_availability_redundant) @@ -917,14 +942,17 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } ConsumeToken(); - if (Keyword == Ident_message) { + if (Keyword == Ident_message || Keyword == Ident_replacement) { if (Tok.isNot(tok::string_literal)) { Diag(Tok, diag::err_expected_string_literal) << /*Source='availability attribute'*/2; SkipUntil(tok::r_paren, StopAtSemi); return; } - MessageExpr = ParseStringLiteralExpression(); + if (Keyword == Ident_message) + MessageExpr = ParseStringLiteralExpression(); + else + ReplacementExpr = ParseStringLiteralExpression(); // Also reject wide string literals. if (StringLiteral *MessageStringLiteral = cast_or_null<StringLiteral>(MessageExpr.get())) { @@ -936,7 +964,10 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } } - break; + if (Keyword == Ident_message) + break; + else + continue; } // Special handling of 'NA' only when applied to introduced or @@ -1023,7 +1054,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Changes[Deprecated], Changes[Obsoleted], UnavailableLoc, MessageExpr.get(), - Syntax); + Syntax, StrictLoc, ReplacementExpr.get()); } /// \brief Parse the contents of the "objc_bridge_related" attribute. @@ -1187,7 +1218,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, // Append the current token at the end of the new token stream so that it // doesn't get lost. LA.Toks.push_back(Tok); - PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false); + PP.EnterTokenStream(LA.Toks, true); // Consume the previously pushed token. ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); @@ -1402,8 +1433,8 @@ void Parser::handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs, while (AL) { AttributeList *Next = AL->getNext(); - // We only consider attributes using the appropriate '__declspec' spelling, - // this behavior doesn't extend to any other spellings. + // We only consider attributes using the appropriate '__declspec' spelling. + // This behavior doesn't extend to any other spellings. if (AL->getKind() == AttributeList::AT_Aligned && AL->isDeclspecAttribute()) { // Stitch the attribute into the tag's attribute list. @@ -1522,7 +1553,7 @@ Parser::ParseSimpleDeclaration(unsigned Context, // may get this far before the problem becomes obvious. if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext)) - return DeclGroupPtrTy(); + return nullptr; // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" // declaration-specifiers init-declarator-list[opt] ';' @@ -1530,9 +1561,14 @@ Parser::ParseSimpleDeclaration(unsigned Context, ProhibitAttributes(Attrs); DeclEnd = Tok.getLocation(); if (RequireSemi) ConsumeToken(); + RecordDecl *AnonRecord = nullptr; Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, - DS); + DS, AnonRecord); DS.complete(TheDecl); + if (AnonRecord) { + Decl* decls[] = {AnonRecord, TheDecl}; + return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false); + } return Actions.ConvertDeclToDeclGroup(TheDecl); } @@ -1701,7 +1737,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, // Bail out if the first declarator didn't seem well-formed. if (!D.hasName() && !D.mayOmitIdentifier()) { SkipMalformedDecl(); - return DeclGroupPtrTy(); + return nullptr; } // Save late-parsed attributes for now; they need to be parsed in the @@ -1766,19 +1802,19 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, } else { Diag(Tok, diag::err_expected_fn_body); SkipUntil(tok::semi); - return DeclGroupPtrTy(); + return nullptr; } } else { if (Tok.is(tok::l_brace)) { Diag(Tok, diag::err_function_definition_not_allowed); SkipMalformedDecl(); - return DeclGroupPtrTy(); + return nullptr; } } } if (ParseAsmAttributesAfterDeclarator(D)) - return DeclGroupPtrTy(); + return nullptr; // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we // must parse and analyze the for-range-initializer before the declaration is @@ -1975,7 +2011,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( TemplateParameterLists FakedParamLists; FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, - LAngleLoc)); + LAngleLoc, nullptr)); ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D); @@ -2039,7 +2075,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( if (Init.isInvalid()) { SmallVector<tok::TokenKind, 2> StopTokens; StopTokens.push_back(tok::comma); - if (D.getContext() == Declarator::ForContext) + if (D.getContext() == Declarator::ForContext || + D.getContext() == Declarator::InitStmtContext) StopTokens.push_back(tok::r_paren); SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch); Actions.ActOnInitializerError(ThisDecl); @@ -2250,6 +2287,24 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, return false; } + if (getLangOpts().CPlusPlus && (!SS || SS->isEmpty()) && + getLangOpts().MSVCCompat) { + // Lookup of an unqualified type name has failed in MSVC compatibility mode. + // Give Sema a chance to recover if we are in a template with dependent base + // classes. + if (ParsedType T = Actions.ActOnMSVCUnknownTypeName( + *Tok.getIdentifierInfo(), Tok.getLocation(), + DSC == DSC_template_type_arg)) { + const char *PrevSpec; + unsigned DiagID; + DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, + Actions.getASTContext().getPrintingPolicy()); + DS.SetRangeEnd(Tok.getLocation()); + ConsumeToken(); + return false; + } + } + // Otherwise, if we don't consume this token, we are going to emit an // error anyway. Try to recover from various common problems. Check // to see if this was a reference to a tag name without a tag specified. @@ -2632,7 +2687,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, bool AttrsLastTime = false; ParsedAttributesWithRange attrs(AttrFactory); // We use Sema's policy to get bool macros right. - const PrintingPolicy &Policy = Actions.getPrintingPolicy(); + PrintingPolicy Policy = Actions.getPrintingPolicy(); while (1) { bool isInvalid = false; bool isStorageClass = false; @@ -2835,12 +2890,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, << Next.getIdentifierInfo() << 1 /* type */; } - ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), - Next.getLocation(), - getCurScope(), &SS, - false, false, ParsedType(), - /*IsCtorOrDtorName=*/false, - /*NonTrivialSourceInfo=*/true); + ParsedType TypeRep = + Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(), + getCurScope(), &SS, false, false, nullptr, + /*IsCtorOrDtorName=*/false, + /*NonTrivialSourceInfo=*/true); // If the referenced identifier is not a type, then this declspec is // erroneous: We already checked about that it has no type specifier, and @@ -2958,16 +3012,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope()); - // MSVC: If we weren't able to parse a default template argument, and it's - // just a simple identifier, create a DependentNameType. This will allow - // us to defer the name lookup to template instantiation time, as long we - // forge a NestedNameSpecifier for the current context. - if (!TypeRep && DSContext == DSC_template_type_arg && - getLangOpts().MSVCCompat && getCurScope()->isTemplateParamScope()) { - TypeRep = Actions.ActOnDelayedDefaultTemplateArg( - *Tok.getIdentifierInfo(), Tok.getLocation()); - } - // If this is not a typedef name, don't parse it as part of the declspec, // it must be an implicit int or an error. if (!TypeRep) { @@ -3059,6 +3103,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, break; } + case tok::kw___unaligned: + isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID, + getLangOpts()); + break; + case tok::kw___sptr: case tok::kw___uptr: case tok::kw___ptr64: @@ -3069,7 +3118,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw___fastcall: case tok::kw___thiscall: case tok::kw___vectorcall: - case tok::kw___unaligned: ParseMicrosoftTypeAttributes(DS.getAttributes()); continue; @@ -3080,7 +3128,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // OpenCL single token adornments. case tok::kw___kernel: - ParseOpenCLAttributes(DS.getAttributes()); + ParseOpenCLKernelAttributes(DS.getAttributes()); continue; // Nullability type specifiers. @@ -3278,6 +3326,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw___float128: + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw_wchar_t: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy); @@ -3335,6 +3387,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); break; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + case tok::kw_##ImgType##_t: \ + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, \ + DiagID, Policy); \ + break; +#include "clang/Basic/OpenCLImageTypes.def" case tok::kw___unknown_anytype: isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, PrevSpec, DiagID, Policy); @@ -3403,6 +3461,22 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, ParseDecltypeSpecifier(DS); continue; + case tok::annot_pragma_pack: + HandlePragmaPack(); + continue; + + case tok::annot_pragma_ms_pragma: + HandlePragmaMSPragma(); + continue; + + case tok::annot_pragma_ms_vtordisp: + HandlePragmaMSVtorDisp(); + continue; + + case tok::annot_pragma_ms_pointers_to_members: + HandlePragmaMSPointersToMembers(); + continue; + case tok::kw___underlying_type: ParseUnderlyingTypeSpecifier(DS); continue; @@ -3473,9 +3547,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DiagID == diag::ext_duplicate_declspec) Diag(Tok, DiagID) << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); - else if (DiagID == diag::err_opencl_unknown_type_specifier) - Diag(Tok, DiagID) << PrevSpec << isStorageClass; - else + else if (DiagID == diag::err_opencl_unknown_type_specifier) { + const int OpenCLVer = getLangOpts().OpenCLVersion; + std::string VerSpec = llvm::to_string(OpenCLVer / 100) + + std::string (".") + + llvm::to_string((OpenCLVer % 100) / 10); + Diag(Tok, DiagID) << VerSpec << PrevSpec << isStorageClass; + } else Diag(Tok, DiagID) << PrevSpec; } @@ -3521,8 +3599,10 @@ void Parser::ParseStructDeclaration( // If there are no declarators, this is a free-standing declaration // specifier. Let the actions module cope with it. if (Tok.is(tok::semi)) { + RecordDecl *AnonRecord = nullptr; Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, - DS); + DS, AnonRecord); + assert(!AnonRecord && "Did not expect anonymous struct or union here"); DS.complete(TheDecl); return; } @@ -3625,12 +3705,12 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, if (Tok.is(tok::annot_pragma_openmp)) { // Result can be ignored, because it must be always empty. - auto Res = ParseOpenMPDeclarativeDirective(); - assert(!Res); - // Silence possible warnings. - (void)Res; + AccessSpecifier AS = AS_none; + ParsedAttributesWithRange Attrs(AttrFactory); + (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs); continue; } + if (!Tok.is(tok::at)) { auto CFieldCallback = [&](ParsingFieldDeclarator &FD) { // Install the declarator into the current TagDecl. @@ -3693,8 +3773,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, T.getOpenLocation(), T.getCloseLocation(), attrs.getList()); StructScope.Exit(); - Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, - T.getCloseLocation()); + Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange()); } /// ParseEnumSpecifier @@ -3788,7 +3867,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType); CXXScopeSpec Spec; - if (ParseOptionalCXXScopeSpecifier(Spec, ParsedType(), + if (ParseOptionalCXXScopeSpecifier(Spec, nullptr, /*EnteringContext=*/true)) return; @@ -4189,7 +4268,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { ParsedAttributes attrs(AttrFactory); MaybeParseGNUAttributes(attrs); - Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(), + Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls, getCurScope(), attrs.getList()); @@ -4203,8 +4282,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { } EnumScope.Exit(); - Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, - T.getCloseLocation()); + Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, T.getRange()); // The next token must be valid after an enum definition. If not, a ';' // was probably forgotten. @@ -4219,27 +4297,6 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { } } -/// isTypeSpecifierQualifier - Return true if the current token could be the -/// start of a type-qualifier-list. -bool Parser::isTypeQualifier() const { - switch (Tok.getKind()) { - default: return false; - // type-qualifier - case tok::kw_const: - case tok::kw_volatile: - case tok::kw_restrict: - case tok::kw___private: - case tok::kw___local: - case tok::kw___global: - case tok::kw___constant: - case tok::kw___generic: - case tok::kw___read_only: - case tok::kw___read_write: - case tok::kw___write_only: - return true; - } -} - /// isKnownToBeTypeSpecifier - Return true if we know that the specified token /// is definitely a type-specifier. Return false if it isn't part of a type /// specifier or if we're not sure. @@ -4264,12 +4321,15 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/Basic/OpenCLImageTypes.def" // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -4336,12 +4396,15 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/Basic/OpenCLImageTypes.def" // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -4488,6 +4551,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw___float128: case tok::kw_bool: case tok::kw__Bool: case tok::kw__Decimal32: @@ -4578,6 +4642,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw___read_only: case tok::kw___read_write: case tok::kw___write_only: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/Basic/OpenCLImageTypes.def" return true; } @@ -4588,7 +4654,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified) { // Parse the C++ scope specifier. CXXScopeSpec SS; - if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), + if (ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/true)) { TPA.Revert(); return false; @@ -4770,6 +4836,10 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs, ParseOpenCLQualifiers(DS.getAttributes()); break; + case tok::kw___unaligned: + isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID, + getLangOpts()); + break; case tok::kw___uptr: // GNU libc headers in C mode use '__uptr' as an identifer which conflicts // with the MS modifier keyword. @@ -4787,7 +4857,6 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs, case tok::kw___fastcall: case tok::kw___thiscall: case tok::kw___vectorcall: - case tok::kw___unaligned: if (AttrReqs & AR_DeclspecAttributesParsed) { ParseMicrosoftTypeAttributes(DS.getAttributes()); continue; @@ -4925,14 +4994,14 @@ void Parser::ParseDeclaratorInternal(Declarator &D, // Member pointers get special handling, since there's no place for the // scope spec in the generic path below. if (getLangOpts().CPlusPlus && - (Tok.is(tok::coloncolon) || + (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) || (Tok.is(tok::identifier) && (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) || Tok.is(tok::annot_cxxscope))) { bool EnteringContext = D.getContext() == Declarator::FileContext || D.getContext() == Declarator::MemberContext; CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext); + ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext); if (SS.isNotEmpty()) { if (Tok.isNot(tok::star)) { @@ -4969,7 +5038,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D, tok::TokenKind Kind = Tok.getKind(); if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclerator(D)) { - DeclSpec &DS = D.getMutableDeclSpec(); + DeclSpec DS(AttrFactory); + ParseTypeQualifierListOpt(DS); D.AddTypeInfo( DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()), @@ -5009,7 +5079,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D, DS.getConstSpecLoc(), DS.getVolatileSpecLoc(), DS.getRestrictSpecLoc(), - DS.getAtomicSpecLoc()), + DS.getAtomicSpecLoc(), + DS.getUnalignedSpecLoc()), DS.getAttributes(), SourceLocation()); else @@ -5147,7 +5218,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (D.getCXXScopeSpec().isEmpty()) { bool EnteringContext = D.getContext() == Declarator::FileContext || D.getContext() == Declarator::MemberContext; - ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), + ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), nullptr, EnteringContext); } @@ -5208,11 +5279,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) { bool HadScope = D.getCXXScopeSpec().isValid(); if (ParseUnqualifiedId(D.getCXXScopeSpec(), /*EnteringContext=*/true, - /*AllowDestructorName=*/true, - AllowConstructorName, - ParsedType(), - TemplateKWLoc, - D.getName()) || + /*AllowDestructorName=*/true, AllowConstructorName, + nullptr, TemplateKWLoc, D.getName()) || // Once we're past the identifier, if the scope was bad, mark the // whole declarator bad. D.getCXXScopeSpec().isInvalid()) { @@ -6013,6 +6081,9 @@ void Parser::ParseBracketDeclarator(Declarator &D) { T.getCloseLocation()), attrs, T.getCloseLocation()); return; + } else if (Tok.getKind() == tok::code_completion) { + Actions.CodeCompleteBracketDeclarator(getCurScope()); + return cutOffParsing(); } // If valid, this location is the position where we read the 'static' keyword. |