diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 203 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 145 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 50 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 105 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 99 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 58 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 22 |
10 files changed, 294 insertions, 424 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 77f2dccfede..27d48be0e3e 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -22,12 +22,10 @@ using namespace clang; /// ParseCXXInlineMethodDef - We parsed and verified that the specified /// Declarator is a well formed C++ inline method definition. Now lex its body /// and store its tokens for parsing after the C++ class is complete. -NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, - AttributeList *AccessAttrs, - ParsingDeclarator &D, - const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS, - SourceLocation PureSpecLoc) { +NamedDecl *Parser::ParseCXXInlineMethodDef( + AccessSpecifier AS, ParsedAttributes &AccessAttrs, ParsingDeclarator &D, + const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers &VS, + SourceLocation PureSpecLoc) { assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) && "Current token not a '{', ':', '=', or 'try'!"); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c580d1777db..4b6b2b3336d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -53,7 +53,7 @@ TypeResult Parser::ParseTypeName(SourceRange *Range, // Parse the common declaration-specifiers piece. DeclSpec DS(AttrFactory); if (Attrs) - DS.addAttributes(Attrs->getList()); + DS.addAttributes(*Attrs); ParseSpecifierQualifierList(DS, AS, DSC); if (OwnedType) *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr; @@ -422,7 +422,7 @@ unsigned Parser::ParseClangAttributeArgs( ScopeName, ScopeLoc, Syntax); break; } - return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0; + return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0; } bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, @@ -560,8 +560,7 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, // If this attribute's args were parsed, and it was expected to have // arguments but none were provided, emit a diagnostic. - const AttributeList *Attr = Attrs.getList(); - if (Attr && Attr->getMaxArgs() && !NumArgs) { + if (!Attrs.empty() && Attrs.begin()->getMaxArgs() && !NumArgs) { Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName; return false; } @@ -1437,9 +1436,8 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); } - const AttributeList *AL = Attrs.getList(); - if (OnDefinition && AL && !AL->isCXX11Attribute() && - AL->isKnownToGCC()) + if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && + Attrs.begin()->isKnownToGCC()) Diag(Tok, diag::warn_attribute_on_function_definition) << &LA.AttrName; @@ -1570,29 +1568,27 @@ void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, << FixItHint::CreateRemoval(AttrRange); } -void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs, - const SourceLocation CorrectLocation) { +void Parser::DiagnoseProhibitedAttributes( + const SourceRange &Range, const SourceLocation CorrectLocation) { if (CorrectLocation.isValid()) { - CharSourceRange AttrRange(attrs.Range, true); + CharSourceRange AttrRange(Range, true); Diag(CorrectLocation, diag::err_attributes_misplaced) << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) << FixItHint::CreateRemoval(AttrRange); } else - Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << attrs.Range; + Diag(Range.getBegin(), diag::err_attributes_not_allowed) << Range; } void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, unsigned DiagID) { - for (AttributeList *Attr = Attrs.getList(); Attr; Attr = Attr->getNext()) { - if (!Attr->isCXX11Attribute() && !Attr->isC2xAttribute()) + for (const AttributeList &AL : Attrs) { + if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) continue; - if (Attr->getKind() == AttributeList::UnknownAttribute) - Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored) - << Attr->getName(); + if (AL.getKind() == AttributeList::UnknownAttribute) + Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName(); else { - Diag(Attr->getLoc(), DiagID) - << Attr->getName(); - Attr->setInvalid(); + Diag(AL.getLoc(), DiagID) << AL.getName(); + AL.setInvalid(); } } } @@ -1610,47 +1606,19 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs, if (TUK == Sema::TUK_Reference) return; - ParsedAttributes &PA = DS.getAttributes(); - AttributeList *AL = PA.getList(); - AttributeList *Prev = nullptr; - AttributeList *TypeAttrHead = nullptr; - AttributeList *TypeAttrTail = nullptr; - while (AL) { - AttributeList *Next = AL->getNext(); - - if ((AL->getKind() == AttributeList::AT_Aligned && - AL->isDeclspecAttribute()) || - AL->isMicrosoftAttribute()) { - // Stitch the attribute into the tag's attribute list. - if (TypeAttrTail) - TypeAttrTail->setNext(AL); - else - TypeAttrHead = AL; - TypeAttrTail = AL; - TypeAttrTail->setNext(nullptr); - - // Remove the attribute from the variable's attribute list. - if (Prev) { - // Set the last variable attribute's next attribute to be the attribute - // after the current one. - Prev->setNext(Next); - } else { - // Removing the head of the list requires us to reset the head to the - // next attribute. - PA.set(Next); - } - } else { - Prev = AL; - } + llvm::SmallVector<AttributeList *, 1> ToBeMoved; - AL = Next; + for (AttributeList &AL : DS.getAttributes()) { + if ((AL.getKind() == AttributeList::AT_Aligned && + AL.isDeclspecAttribute()) || + AL.isMicrosoftAttribute()) + ToBeMoved.push_back(&AL); } - // Find end of type attributes Attrs and add NewTypeAttributes in the same - // order they were in originally. (Remember, in AttributeList things earlier - // in source order are later in the list, since new attributes are added to - // the front of the list.) - Attrs.addAllAtEnd(TypeAttrHead); + for (AttributeList *AL : ToBeMoved) { + DS.getAttributes().remove(AL); + Attrs.addAtEnd(AL); + } } /// ParseDeclaration - Parse a full 'declaration', which consists of @@ -1682,7 +1650,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, case tok::kw_template: case tok::kw_export: ProhibitAttributes(attrs); - SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); + SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd, attrs); break; case tok::kw_inline: // Could be the start of an inline namespace. Allowed as an ext in C++03. @@ -4075,10 +4043,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, // If attributes exist after struct contents, parse them. MaybeParseGNUAttributes(attrs); - Actions.ActOnFields(getCurScope(), - RecordLoc, TagDecl, FieldDecls, - T.getOpenLocation(), T.getCloseLocation(), - attrs.getList()); + Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls, + T.getOpenLocation(), T.getCloseLocation(), attrs); StructScope.Exit(); Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange()); } @@ -4389,8 +4355,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, unsigned DiagID; Decl *TagDecl = Actions.ActOnTag( getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc, - attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned, - IsDependent, ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType, + attrs, AS, DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, + ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType, DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, @@ -4531,8 +4497,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { // Install the enumerator constant into EnumDecl. Decl *EnumConstDecl = Actions.ActOnEnumConstant( - getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, - attrs.getList(), EqualLoc, AssignedVal.get()); + getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs, + EqualLoc, AssignedVal.get()); EnumAvailabilityDiags.back().done(); EnumConstantDecls.push_back(EnumConstDecl); @@ -4584,10 +4550,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { ParsedAttributes attrs(AttrFactory); MaybeParseGNUAttributes(attrs); - Actions.ActOnEnumBody(StartLoc, T.getRange(), - EnumDecl, EnumConstantDecls, - getCurScope(), - attrs.getList()); + Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls, + getCurScope(), attrs); // Now handle enum constant availability diagnostics. assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size()); @@ -5382,10 +5346,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D, // Sema will have to catch (syntactically invalid) pointers into global // scope. It has to catch pointers into namespace scope anyway. - D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), - DS.getLocEnd()), - DS.getAttributes(), - /* Don't replace range end. */SourceLocation()); + D.AddTypeInfo(DeclaratorChunk::getMemberPointer( + SS, DS.getTypeQualifiers(), DS.getLocEnd()), + std::move(DS.getAttributes()), + /* Don't replace range end. */ SourceLocation()); return; } } @@ -5398,7 +5362,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, D.AddTypeInfo( DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()), - DS.getAttributes(), SourceLocation()); + std::move(DS.getAttributes()), SourceLocation()); } // Not a pointer, C++ reference, or block. @@ -5430,20 +5394,16 @@ void Parser::ParseDeclaratorInternal(Declarator &D, ParseDeclaratorInternal(D, DirectDeclParser); if (Kind == tok::star) // Remember that we parsed a pointer type, and remember the type-quals. - D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, - DS.getConstSpecLoc(), - DS.getVolatileSpecLoc(), - DS.getRestrictSpecLoc(), - DS.getAtomicSpecLoc(), - DS.getUnalignedSpecLoc()), - DS.getAttributes(), - SourceLocation()); + D.AddTypeInfo(DeclaratorChunk::getPointer( + DS.getTypeQualifiers(), Loc, DS.getConstSpecLoc(), + DS.getVolatileSpecLoc(), DS.getRestrictSpecLoc(), + DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()), + std::move(DS.getAttributes()), SourceLocation()); else // Remember that we parsed a Block type, and remember the type-quals. - D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), - Loc), - DS.getAttributes(), - SourceLocation()); + D.AddTypeInfo( + DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), Loc), + std::move(DS.getAttributes()), SourceLocation()); } else { // Is a reference DeclSpec DS(AttrFactory); @@ -5498,8 +5458,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, // Remember that we parsed a reference type. D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, Kind == tok::amp), - DS.getAttributes(), - SourceLocation()); + std::move(DS.getAttributes()), SourceLocation()); } } @@ -6007,9 +5966,9 @@ void Parser::ParseParenDeclarator(Declarator &D) { ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); // Match the ')'. T.consumeClose(); - D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(), - T.getCloseLocation()), - attrs, T.getCloseLocation()); + D.AddTypeInfo( + DeclaratorChunk::getParen(T.getOpenLocation(), T.getCloseLocation()), + std::move(attrs), T.getCloseLocation()); D.setGroupingParens(hadGroupingParens); @@ -6239,28 +6198,19 @@ void Parser::ParseFunctionDeclarator(Declarator &D, } // Remember that we parsed a function type, and remember the attributes. - D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, - IsAmbiguous, - LParenLoc, - ParamInfo.data(), ParamInfo.size(), - EllipsisLoc, RParenLoc, - DS.getTypeQualifiers(), - RefQualifierIsLValueRef, - RefQualifierLoc, ConstQualifierLoc, - VolatileQualifierLoc, - RestrictQualifierLoc, - /*MutableLoc=*/SourceLocation(), - ESpecType, ESpecRange, - DynamicExceptions.data(), - DynamicExceptionRanges.data(), - DynamicExceptions.size(), - NoexceptExpr.isUsable() ? - NoexceptExpr.get() : nullptr, - ExceptionSpecTokens, - DeclsInPrototype, - StartLoc, LocalEndLoc, D, - TrailingReturnType), - FnAttrs, EndLoc); + D.AddTypeInfo(DeclaratorChunk::getFunction( + HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(), + ParamInfo.size(), EllipsisLoc, RParenLoc, + DS.getTypeQualifiers(), RefQualifierIsLValueRef, + RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc, + RestrictQualifierLoc, + /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange, + DynamicExceptions.data(), DynamicExceptionRanges.data(), + DynamicExceptions.size(), + NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, + ExceptionSpecTokens, DeclsInPrototype, StartLoc, + LocalEndLoc, D, TrailingReturnType), + std::move(FnAttrs), EndLoc); } /// ParseRefQualifier - Parses a member function ref-qualifier. Returns @@ -6582,7 +6532,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, nullptr, T.getOpenLocation(), T.getCloseLocation()), - attrs, T.getCloseLocation()); + std::move(attrs), T.getCloseLocation()); return; } else if (Tok.getKind() == tok::numeric_constant && GetLookAheadToken(1).is(tok::r_square)) { @@ -6595,11 +6545,10 @@ void Parser::ParseBracketDeclarator(Declarator &D) { MaybeParseCXX11Attributes(attrs); // Remember that we parsed a array type, and remember its features. - D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, - ExprRes.get(), + D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, ExprRes.get(), T.getOpenLocation(), T.getCloseLocation()), - attrs, T.getCloseLocation()); + std::move(attrs), T.getCloseLocation()); return; } else if (Tok.getKind() == tok::code_completion) { Actions.CodeCompleteBracketDeclarator(getCurScope()); @@ -6672,12 +6621,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) { MaybeParseCXX11Attributes(DS.getAttributes()); // Remember that we parsed a array type, and remember its features. - D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), - StaticLoc.isValid(), isStar, - NumElements.get(), - T.getOpenLocation(), - T.getCloseLocation()), - DS.getAttributes(), T.getCloseLocation()); + D.AddTypeInfo( + DeclaratorChunk::getArray(DS.getTypeQualifiers(), StaticLoc.isValid(), + isStar, NumElements.get(), T.getOpenLocation(), + T.getCloseLocation()), + std::move(DS.getAttributes()), T.getCloseLocation()); } /// Diagnose brackets before an identifier. @@ -6729,18 +6677,15 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) { if (NeedParens) { // Create a DeclaratorChunk for the inserted parens. - ParsedAttributes attrs(AttrFactory); SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd()); - D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), attrs, + D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), SourceLocation()); } // Adding back the bracket info to the end of the Declarator. for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) { const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i); - ParsedAttributes attrs(AttrFactory); - attrs.set(Chunk.Common.AttrList); - D.AddTypeInfo(Chunk, attrs, SourceLocation()); + D.AddTypeInfo(Chunk, SourceLocation()); } // The missing identifier would have been diagnosed in ParseDirectDeclarator. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index a969a0f8497..166f7a8d233 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -183,10 +183,9 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context, ParseScope NamespaceScope(this, Scope::DeclScope); UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; - Decl *NamespcDecl = - Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc, - IdentLoc, Ident, T.getOpenLocation(), - attrs.getList(), ImplicitUsingDirectiveDecl); + Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( + getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, + T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, NamespaceLoc, "parsing namespace"); @@ -233,11 +232,10 @@ void Parser::ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc, // desugaring it here. ParseScope NamespaceScope(this, Scope::DeclScope); UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; - Decl *NamespcDecl = - Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(), - NamespaceLoc[index], IdentLoc[index], - Ident[index], Tracker.getOpenLocation(), - attrs.getList(), ImplicitUsingDirectiveDecl); + Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( + getCurScope(), SourceLocation(), NamespaceLoc[index], IdentLoc[index], + Ident[index], Tracker.getOpenLocation(), attrs, + ImplicitUsingDirectiveDecl); assert(!ImplicitUsingDirectiveDecl && "nested namespace definition cannot define anonymous namespace"); @@ -543,7 +541,7 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context, SkipUntil(tok::semi); return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, - IdentLoc, NamespcName, attrs.getList()); + IdentLoc, NamespcName, attrs); } /// Parse a using-declarator (or the identifier in a C++11 alias-declaration). @@ -711,7 +709,7 @@ Parser::ParseUsingDeclaration(DeclaratorContext Context, Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc, D.TypenameLoc, D.SS, D.Name, - D.EllipsisLoc, Attrs.getList()); + D.EllipsisLoc, Attrs); if (UD) DeclsInGroup.push_back(UD); } @@ -813,8 +811,8 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator( TemplateParams ? TemplateParams->data() : nullptr, TemplateParams ? TemplateParams->size() : 0); return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, - UsingLoc, D.Name, Attrs.getList(), - TypeAlias, DeclFromDeclSpec); + UsingLoc, D.Name, Attrs, TypeAlias, + DeclFromDeclSpec); } /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. @@ -1752,24 +1750,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // This is an explicit instantiation of a class template. ProhibitAttributes(attrs); - TagOrTempResult - = Actions.ActOnExplicitInstantiation(getCurScope(), - TemplateInfo.ExternLoc, - TemplateInfo.TemplateLoc, - TagType, - StartLoc, - SS, - TemplateId->Template, - TemplateId->TemplateNameLoc, - TemplateId->LAngleLoc, - TemplateArgsPtr, - TemplateId->RAngleLoc, - attrs.getList()); - - // Friend template-ids are treated as references unless - // they have template headers, in which case they're ill-formed - // (FIXME: "template <class T> friend class A<T>::B<int>;"). - // We diagnose this error in ActOnClassTemplateSpecialization. + TagOrTempResult = Actions.ActOnExplicitInstantiation( + getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, + TagType, StartLoc, SS, TemplateId->Template, + TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, + TemplateId->RAngleLoc, attrs); + + // Friend template-ids are treated as references unless + // they have template headers, in which case they're ill-formed + // (FIXME: "template <class T> friend class A<T>::B<int>;"). + // We diagnose this error in ActOnClassTemplateSpecialization. } else if (TUK == Sema::TUK_Reference || (TUK == Sema::TUK_Friend && TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { @@ -1825,7 +1815,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Build the class template specialization. TagOrTempResult = Actions.ActOnClassTemplateSpecialization( getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(), - *TemplateId, attrs.getList(), + *TemplateId, attrs, MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, TemplateParams ? TemplateParams->size() : 0), @@ -1840,24 +1830,18 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // ProhibitAttributes(attrs); - TagOrTempResult - = Actions.ActOnExplicitInstantiation(getCurScope(), - TemplateInfo.ExternLoc, - TemplateInfo.TemplateLoc, - TagType, StartLoc, SS, Name, - NameLoc, attrs.getList()); + TagOrTempResult = Actions.ActOnExplicitInstantiation( + getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, + TagType, StartLoc, SS, Name, NameLoc, attrs); } else if (TUK == Sema::TUK_Friend && TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { ProhibitAttributes(attrs); - TagOrTempResult = - Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(), - TagType, StartLoc, SS, - Name, NameLoc, attrs.getList(), - MultiTemplateParamsArg( - TemplateParams? &(*TemplateParams)[0] - : nullptr, - TemplateParams? TemplateParams->size() : 0)); + TagOrTempResult = Actions.ActOnTemplatedFriendTag( + getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name, + NameLoc, attrs, + MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, + TemplateParams ? TemplateParams->size() : 0)); } else { if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) ProhibitAttributes(attrs); @@ -1885,9 +1869,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Declaration or definition of a class type TagOrTempResult = Actions.ActOnTag( - getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, - attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned, - IsDependent, SourceLocation(), false, clang::TypeResult(), + getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS, + DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, + SourceLocation(), false, clang::TypeResult(), DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, @@ -1929,7 +1913,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (!TagOrTempResult.isInvalid()) // Delayed processing of attributes. - Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList()); + Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs); const char *PrevSpec = nullptr; unsigned DiagID; @@ -2300,12 +2284,10 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer( if (!VS.isUnset()) { // If we saw any GNU-style attributes that are known to GCC followed by a // virt-specifier, issue a GCC-compat warning. - const AttributeList *Attr = DeclaratorInfo.getAttributes(); - while (Attr) { - if (Attr->isKnownToGCC() && !Attr->isCXX11Attribute()) - Diag(Attr->getLoc(), diag::warn_gcc_attribute_location); - Attr = Attr->getNext(); - } + for (const AttributeList &AL : DeclaratorInfo.getAttributes()) + if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) + Diag(AL.getLoc(), diag::warn_gcc_attribute_location); + MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS); } } @@ -2424,7 +2406,7 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq( /// Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, - AttributeList *AccessAttrs, + ParsedAttributes &AccessAttrs, const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) { if (Tok.is(tok::at)) { @@ -2492,7 +2474,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration( getCurScope(), AS, /*UsingLoc*/ SourceLocation(), /*TypenameLoc*/ SourceLocation(), SS, Name, - /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr))); + /*EllipsisLoc*/ SourceLocation(), + /*AttrList*/ ParsedAttributesView()))); } } @@ -2512,7 +2495,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, SourceLocation DeclEnd; return DeclGroupPtrTy::make( DeclGroupRef(ParseTemplateDeclarationOrSpecialization( - DeclaratorContext::MemberContext, DeclEnd, AS, AccessAttrs))); + DeclaratorContext::MemberContext, DeclEnd, AccessAttrs, AS))); } // Handle: member-declaration ::= '__extension__' member-declaration @@ -2525,12 +2508,12 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } ParsedAttributesWithRange attrs(AttrFactory); - ParsedAttributesWithRange FnAttrs(AttrFactory); + ParsedAttributesViewWithRange FnAttrs; // Optional C++11 attribute-specifier MaybeParseCXX11Attributes(attrs); // We need to keep these attributes for future diagnostic // before they are taken over by declaration specifier. - FnAttrs.addAll(attrs.getList()); + FnAttrs.addAll(attrs.begin(), attrs.end()); FnAttrs.Range = attrs.Range; MaybeParseMicrosoftAttributes(attrs); @@ -2777,7 +2760,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // initialize it. ThisDecl = VT->getTemplatedDecl(); - if (ThisDecl && AccessAttrs) + if (ThisDecl) Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs); } @@ -3014,7 +2997,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas( switch (Tok.getKind()) { case tok::kw___if_exists: case tok::kw___if_not_exists: - ParseMicrosoftIfExistsClassDeclaration(TagType, AS); + ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS); return nullptr; case tok::semi: @@ -3080,8 +3063,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas( Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected); } - if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, - AccessAttrs.getList())) { + if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) { // found another attribute than only annotations AccessAttrs.clear(); } @@ -3094,7 +3076,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas( TagDecl); default: - return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList()); + return ParseCXXClassMemberDeclaration(AS, AccessAttrs); } } @@ -3282,9 +3264,8 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (TagDecl) Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, - T.getOpenLocation(), - T.getCloseLocation(), - attrs.getList()); + T.getOpenLocation(), + T.getCloseLocation(), attrs); // C++11 [class.mem]p2: // Within the class member-specification, the class is regarded as complete @@ -3893,25 +3874,26 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName, ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Syntax); - const AttributeList *Attr = Attrs.getList(); - if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { + if (!Attrs.empty() && + IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { + AttributeList &Attr = *Attrs.begin(); // If the attribute is a standard or built-in attribute and we are // parsing an argument list, we need to determine whether this attribute // was allowed to have an argument list (such as [[deprecated]]), and how // many arguments were parsed (so we can diagnose on [[deprecated()]]). - if (Attr->getMaxArgs() && !NumArgs) { + if (Attr.getMaxArgs() && !NumArgs) { // The attribute was allowed to have arguments, but none were provided // even though the attribute parsed successfully. This is an error. Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName; - Attr->setInvalid(true); - } else if (!Attr->getMaxArgs()) { + Attr.setInvalid(true); + } else if (!Attr.getMaxArgs()) { // The attribute parsed successfully, but was not allowed to have any // arguments. It doesn't matter whether any were provided -- the // presence of the argument list (even if empty) is diagnosed. Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments) << AttrName << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc)); - Attr->setInvalid(true); + Attr.setInvalid(true); } } return true; @@ -4221,8 +4203,9 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, } while (Tok.is(tok::l_square)); } -void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, - AccessSpecifier& CurAS) { +void Parser::ParseMicrosoftIfExistsClassDeclaration( + DeclSpec::TST TagType, ParsedAttributes &AccessAttrs, + AccessSpecifier &CurAS) { IfExistsCondition Result; if (ParseMicrosoftIfExistsCondition(Result)) return; @@ -4252,7 +4235,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { // __if_exists, __if_not_exists can nest. if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) { - ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); + ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, + AccessAttrs, CurAS); continue; } @@ -4269,7 +4253,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, SourceLocation ASLoc = Tok.getLocation(); ConsumeToken(); if (Tok.is(tok::colon)) - Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); + Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(), + ParsedAttributesView{}); else Diag(Tok, diag::err_expected) << tok::colon; ConsumeToken(); @@ -4277,7 +4262,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, } // Parse all the comma separated declarators. - ParseCXXClassMemberDeclaration(CurAS, nullptr); + ParseCXXClassMemberDeclaration(CurAS, AccessAttrs); } Braces.consumeClose(); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 619fd222fd3..d96dc5b3628 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2948,33 +2948,31 @@ ExprResult Parser::ParseBlockLiteralExpression() { ParseBlockId(CaretLoc); } else { // Otherwise, pretend we saw (void). - ParsedAttributes attrs(AttrFactory); SourceLocation NoLoc; - ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true, - /*IsAmbiguous=*/false, - /*RParenLoc=*/NoLoc, - /*ArgInfo=*/nullptr, - /*NumArgs=*/0, - /*EllipsisLoc=*/NoLoc, - /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, - /*RefQualifierIsLvalueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, - /*MutableLoc=*/NoLoc, - EST_None, - /*ESpecRange=*/SourceRange(), - /*Exceptions=*/nullptr, - /*ExceptionRanges=*/nullptr, - /*NumExceptions=*/0, - /*NoexceptExpr=*/nullptr, - /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, - CaretLoc, CaretLoc, - ParamInfo), - attrs, CaretLoc); + ParamInfo.AddTypeInfo( + DeclaratorChunk::getFunction(/*HasProto=*/true, + /*IsAmbiguous=*/false, + /*RParenLoc=*/NoLoc, + /*ArgInfo=*/nullptr, + /*NumArgs=*/0, + /*EllipsisLoc=*/NoLoc, + /*RParenLoc=*/NoLoc, + /*TypeQuals=*/0, + /*RefQualifierIsLvalueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + /*RestrictQualifierLoc=*/NoLoc, + /*MutableLoc=*/NoLoc, EST_None, + /*ESpecRange=*/SourceRange(), + /*Exceptions=*/nullptr, + /*ExceptionRanges=*/nullptr, + /*NumExceptions=*/0, + /*NoexceptExpr=*/nullptr, + /*ExceptionSpecTokens=*/nullptr, + /*DeclsInPrototype=*/None, CaretLoc, + CaretLoc, ParamInfo), + CaretLoc); MaybeParseGNUAttributes(ParamInfo); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 77f758b159f..e23581d2033 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1109,12 +1109,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // after '(...)'. nvcc doesn't accept this. auto WarnIfHasCUDATargetAttr = [&] { if (getLangOpts().CUDA) - for (auto *A = Attr.getList(); A != nullptr; A = A->getNext()) - if (A->getKind() == AttributeList::AT_CUDADevice || - A->getKind() == AttributeList::AT_CUDAHost || - A->getKind() == AttributeList::AT_CUDAGlobal) - Diag(A->getLoc(), diag::warn_cuda_attr_lambda_position) - << A->getName()->getName(); + for (const AttributeList &A : Attr) + if (A.getKind() == AttributeList::AT_CUDADevice || + A.getKind() == AttributeList::AT_CUDAHost || + A.getKind() == AttributeList::AT_CUDAGlobal) + Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) + << A.getName()->getName(); }; TypeResult TrailingReturnType; @@ -1197,29 +1197,23 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( WarnIfHasCUDATargetAttr(); SourceLocation NoLoc; - D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, - /*isAmbiguous=*/false, - LParenLoc, - ParamInfo.data(), ParamInfo.size(), - EllipsisLoc, RParenLoc, - DS.getTypeQualifiers(), - /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, - MutableLoc, - ESpecType, ESpecRange, - DynamicExceptions.data(), - DynamicExceptionRanges.data(), - DynamicExceptions.size(), - NoexceptExpr.isUsable() ? - NoexceptExpr.get() : nullptr, - /*ExceptionSpecTokens*/nullptr, - /*DeclsInPrototype=*/None, - LParenLoc, FunLocalRangeEnd, D, - TrailingReturnType), - Attr, DeclEndLoc); + D.AddTypeInfo(DeclaratorChunk::getFunction( + /*hasProto=*/true, + /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(), + ParamInfo.size(), EllipsisLoc, RParenLoc, + DS.getTypeQualifiers(), + /*RefQualifierIsLValueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType, + ESpecRange, DynamicExceptions.data(), + DynamicExceptionRanges.data(), DynamicExceptions.size(), + NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, + /*ExceptionSpecTokens*/ nullptr, + /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, + TrailingReturnType), + std::move(Attr), DeclEndLoc); } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, tok::kw_constexpr) || (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { @@ -1266,31 +1260,29 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( WarnIfHasCUDATargetAttr(); SourceLocation NoLoc; - D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, - /*isAmbiguous=*/false, - /*LParenLoc=*/NoLoc, - /*Params=*/nullptr, - /*NumParams=*/0, - /*EllipsisLoc=*/NoLoc, - /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, - /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, - MutableLoc, - EST_None, - /*ESpecRange=*/SourceRange(), - /*Exceptions=*/nullptr, - /*ExceptionRanges=*/nullptr, - /*NumExceptions=*/0, - /*NoexceptExpr=*/nullptr, - /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, - DeclLoc, DeclEndLoc, D, - TrailingReturnType), - Attr, DeclEndLoc); + D.AddTypeInfo(DeclaratorChunk::getFunction( + /*hasProto=*/true, + /*isAmbiguous=*/false, + /*LParenLoc=*/NoLoc, + /*Params=*/nullptr, + /*NumParams=*/0, + /*EllipsisLoc=*/NoLoc, + /*RParenLoc=*/NoLoc, + /*TypeQuals=*/0, + /*RefQualifierIsLValueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None, + /*ESpecRange=*/SourceRange(), + /*Exceptions=*/nullptr, + /*ExceptionRanges=*/nullptr, + /*NumExceptions=*/0, + /*NoexceptExpr=*/nullptr, + /*ExceptionSpecTokens=*/nullptr, + /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, + TrailingReturnType), + std::move(Attr), DeclEndLoc); } // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using @@ -2889,10 +2881,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, - Size.get(), - T.getOpenLocation(), + Size.get(), T.getOpenLocation(), T.getCloseLocation()), - Attrs, T.getCloseLocation()); + std::move(Attrs), T.getCloseLocation()); if (T.getCloseLocation().isInvalid()) return; diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 81b930a2284..447eb9610b0 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -287,7 +287,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, Decl *CategoryType = Actions.ActOnStartCategoryInterface( AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc, ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(), - EndProtoLoc, attrs.getList()); + EndProtoLoc, attrs); if (Tok.is(tok::l_brace)) ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc); @@ -353,17 +353,12 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::less)) Actions.ActOnTypedefedProtocols(protocols, protocolLocs, superClassId, superClassLoc); - - Decl *ClsType = - Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc, - typeParameterList, superClassId, - superClassLoc, - typeArgs, - SourceRange(typeArgsLAngleLoc, - typeArgsRAngleLoc), - protocols.data(), protocols.size(), - protocolLocs.data(), - EndProtoLoc, attrs.getList()); + + Decl *ClsType = Actions.ActOnStartClassInterface( + getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId, + superClassLoc, typeArgs, + SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(), + protocols.size(), protocolLocs.data(), EndProtoLoc, attrs); if (Tok.is(tok::l_brace)) ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc); @@ -389,15 +384,13 @@ static void addContextSensitiveTypeNullability(Parser &P, if (D.getNumTypeObjects() > 0) { // Add the attribute to the declarator chunk nearest the declarator. - auto nullabilityAttr = getNullabilityAttr(D.getAttributePool()); - DeclaratorChunk &chunk = D.getTypeObject(0); - nullabilityAttr->setNext(chunk.getAttrListRef()); - chunk.getAttrListRef() = nullabilityAttr; + D.getTypeObject(0).getAttrs().addAtStart( + getNullabilityAttr(D.getAttributePool())); } else if (!addedToDeclSpec) { // Otherwise, just put it on the declaration specifiers (if one // isn't there already). - D.getMutableDeclSpec().addAttributes( - getNullabilityAttr(D.getDeclSpec().getAttributePool())); + D.getMutableDeclSpec().getAttributes().addAtStart( + getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool())); addedToDeclSpec = true; } } @@ -1200,18 +1193,12 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, /// Take all the decl attributes out of the given list and add /// them to the given attribute set. -static void takeDeclAttributes(ParsedAttributes &attrs, - AttributeList *list) { - while (list) { - AttributeList *cur = list; - list = cur->getNext(); - - if (!cur->isUsedAsTypeAttr()) { - // Clear out the next pointer. We're really completely - // destroying the internal invariants of the declarator here, - // but it doesn't matter because we're done with it. - cur->setNext(nullptr); - attrs.add(cur); +static void takeDeclAttributes(ParsedAttributesView &attrs, + ParsedAttributesView &from) { + for (auto &AL : llvm::reverse(from)) { + if (!AL.isUsedAsTypeAttr()) { + from.remove(&AL); + attrs.addAtStart(&AL); } } } @@ -1225,11 +1212,10 @@ static void takeDeclAttributes(ParsedAttributes &attrs, attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool()); // Now actually move the attributes over. - takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList()); + takeDeclAttributes(attrs, D.getMutableDeclSpec().getAttributes()); takeDeclAttributes(attrs, D.getAttributes()); for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) - takeDeclAttributes(attrs, - const_cast<AttributeList*>(D.getTypeObject(i).getAttrs())); + takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs()); } /// objc-type-name: @@ -1384,13 +1370,10 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, MaybeParseCXX11Attributes(methodAttrs); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); - Decl *Result - = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, - selLoc, Sel, nullptr, - CParamInfo.data(), CParamInfo.size(), - methodAttrs.getList(), MethodImplKind, - false, MethodDefinition); + Decl *Result = Actions.ActOnMethodDeclaration( + getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, + selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs, + MethodImplKind, false, MethodDefinition); PD.complete(Result); return Result; } @@ -1421,7 +1404,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, if (getLangOpts().ObjC2) MaybeParseGNUAttributes(paramAttrs); MaybeParseCXX11Attributes(paramAttrs); - ArgInfo.ArgAttrs = paramAttrs.getList(); + ArgInfo.ArgAttrs = paramAttrs; // Code completion for the next piece of the selector. if (Tok.is(tok::code_completion)) { @@ -1511,14 +1494,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); - Decl *Result - = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, - KeyLocs, Sel, &ArgInfos[0], - CParamInfo.data(), CParamInfo.size(), - methodAttrs.getList(), - MethodImplKind, isVariadic, MethodDefinition); - + Decl *Result = Actions.ActOnMethodDeclaration( + getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs, + Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs, + MethodImplKind, isVariadic, MethodDefinition); + PD.complete(Result); return Result; } @@ -1883,9 +1863,9 @@ void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocatio Actions.ActOnObjCContainerFinishDefinition(); // Call ActOnFields() even if we don't have any decls. This is useful // for code rewriting tools that need to be aware of the empty list. - Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, - AllIvarDecls, - T.getOpenLocation(), T.getCloseLocation(), nullptr); + Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls, + T.getOpenLocation(), T.getCloseLocation(), + ParsedAttributesView()); } /// objc-class-instance-variables: @@ -2035,8 +2015,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol. IdentifierLocPair ProtoInfo(protocolName, nameLoc); - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, - attrs.getList()); + return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs); } CheckNestedObjCContexts(AtLoc); @@ -2063,8 +2042,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol")) return nullptr; - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, - attrs.getList()); + return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs); } // Last, and definitely not least, parse a protocol declaration. @@ -2078,12 +2056,9 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, /*consumeLastToken=*/true)) return nullptr; - Decl *ProtoType = - Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, - ProtocolRefs.data(), - ProtocolRefs.size(), - ProtocolLocs.data(), - EndProtoLoc, attrs.getList()); + Decl *ProtoType = Actions.ActOnStartProtocolInterface( + AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(), + ProtocolLocs.data(), EndProtoLoc, attrs); ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType); return Actions.ConvertDeclToDeclGroup(ProtoType); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index afd99b23a89..553b490f48a 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -1410,26 +1410,26 @@ void Parser::HandlePragmaAttribute() { return; } - if (!Attrs.getList() || Attrs.getList()->isInvalid()) { + if (Attrs.empty() || Attrs.begin()->isInvalid()) { SkipToEnd(); return; } // Ensure that we don't have more than one attribute. - if (Attrs.getList()->getNext()) { - SourceLocation Loc = Attrs.getList()->getNext()->getLoc(); + if (Attrs.size() > 1) { + SourceLocation Loc = Attrs[1].getLoc(); Diag(Loc, diag::err_pragma_attribute_multiple_attributes); SkipToEnd(); return; } - if (!Attrs.getList()->isSupportedByPragmaAttribute()) { + AttributeList &Attribute = *Attrs.begin(); + if (!Attribute.isSupportedByPragmaAttribute()) { Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute) - << Attrs.getList()->getName(); + << Attribute.getName(); SkipToEnd(); return; } - AttributeList &Attribute = *Attrs.getList(); // Parse the subject-list. if (!TryConsumeToken(tok::comma)) { diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 8dba6386d0a..1127158a051 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -116,7 +116,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, if (Attrs.empty() || Res.isInvalid()) return Res; - return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range); + return Actions.ProcessStmtAttributes(Res.get(), Attrs, Attrs.Range); } namespace { @@ -610,8 +610,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { Stmts, /*Allowed=*/ACK_StatementsOpenMPNonStandalone, nullptr, TempAttrs); if (!TempAttrs.empty() && !SubStmt.isInvalid()) - SubStmt = Actions.ProcessStmtAttributes( - SubStmt.get(), TempAttrs.getList(), TempAttrs.Range); + SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs, + TempAttrs.Range); } else { Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi; } @@ -627,10 +627,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) { LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), IdentTok.getLocation()); - if (AttributeList *Attrs = attrs.getList()) { - Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs); - attrs.clear(); - } + Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs); + attrs.clear(); return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc, SubStmt.get()); @@ -2269,7 +2267,7 @@ bool Parser::ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) { if (Attrs.empty()) return true; - if (Attrs.getList()->getKind() != AttributeList::AT_OpenCLUnrollHint) + if (Attrs.begin()->getKind() != AttributeList::AT_OpenCLUnrollHint) return true; if (!(Tok.is(tok::kw_for) || Tok.is(tok::kw_while) || Tok.is(tok::kw_do))) { diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index f701f4639c2..f7a69c482e1 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -23,24 +23,19 @@ using namespace clang; /// Parse a template declaration, explicit instantiation, or /// explicit specialization. -Decl * -Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context, - SourceLocation &DeclEnd, - AccessSpecifier AS, - AttributeList *AccessAttrs) { +Decl *Parser::ParseDeclarationStartingWithTemplate( + DeclaratorContext Context, SourceLocation &DeclEnd, + ParsedAttributes &AccessAttrs, AccessSpecifier AS) { ObjCDeclContextSwitch ObjCDC(*this); if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) { - return ParseExplicitInstantiation(Context, - SourceLocation(), ConsumeToken(), - DeclEnd, AS); + return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(), + DeclEnd, AccessAttrs, AS); } - return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS, - AccessAttrs); + return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs, + AS); } - - /// Parse a template declaration or an explicit specialization. /// /// Template declarations include one or more template parameter lists @@ -56,11 +51,9 @@ Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context, /// /// explicit-specialization: [ C++ temp.expl.spec] /// 'template' '<' '>' declaration -Decl * -Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context, - SourceLocation &DeclEnd, - AccessSpecifier AS, - AttributeList *AccessAttrs) { +Decl *Parser::ParseTemplateDeclarationOrSpecialization( + DeclaratorContext Context, SourceLocation &DeclEnd, + ParsedAttributes &AccessAttrs, AccessSpecifier AS) { assert(Tok.isOneOf(tok::kw_export, tok::kw_template) && "Token does not start a template declaration."); @@ -149,12 +142,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context, ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization); // Parse the actual template declaration. - return ParseSingleDeclarationAfterTemplate(Context, - ParsedTemplateInfo(&ParamLists, - isSpecialization, - LastParamListWasEmpty), - ParsingTemplateParams, - DeclEnd, AS, AccessAttrs); + return ParseSingleDeclarationAfterTemplate( + Context, + ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty), + ParsingTemplateParams, DeclEnd, AccessAttrs, AS); } /// Parse a single declaration that declares a template, @@ -167,14 +158,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context, /// declaration. Will be AS_none for namespace-scope declarations. /// /// \returns the new declaration. -Decl * -Parser::ParseSingleDeclarationAfterTemplate( - DeclaratorContext Context, - const ParsedTemplateInfo &TemplateInfo, - ParsingDeclRAIIObject &DiagsFromTParams, - SourceLocation &DeclEnd, - AccessSpecifier AS, - AttributeList *AccessAttrs) { +Decl *Parser::ParseSingleDeclarationAfterTemplate( + DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo, + ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd, + ParsedAttributes &AccessAttrs, AccessSpecifier AS) { assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && "Template information required"); @@ -1342,16 +1329,15 @@ Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context, SourceLocation ExternLoc, SourceLocation TemplateLoc, SourceLocation &DeclEnd, + ParsedAttributes &AccessAttrs, AccessSpecifier AS) { // This isn't really required here. ParsingDeclRAIIObject ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent); - return ParseSingleDeclarationAfterTemplate(Context, - ParsedTemplateInfo(ExternLoc, - TemplateLoc), - ParsingTemplateParams, - DeclEnd, AS); + return ParseSingleDeclarationAfterTemplate( + Context, ParsedTemplateInfo(ExternLoc, TemplateLoc), + ParsingTemplateParams, DeclEnd, AccessAttrs, AS); } SourceRange Parser::ParsedTemplateInfo::getSourceRange() const { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index d1c35352ae4..7bda21b5510 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -698,9 +698,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, return nullptr; case tok::semi: // Either a C++11 empty-declaration or attribute-declaration. - SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(), - attrs.getList(), - Tok.getLocation()); + SingleDecl = + Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation()); ConsumeExtraSemi(OutsideFunction); break; case tok::r_brace: @@ -829,8 +828,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc); SourceLocation DeclEnd; return Actions.ConvertDeclToDeclGroup( - ParseExplicitInstantiation(DeclaratorContext::FileContext, - ExternLoc, TemplateLoc, DeclEnd)); + ParseExplicitInstantiation(DeclaratorContext::FileContext, ExternLoc, + TemplateLoc, DeclEnd, attrs)); } goto dont_know; @@ -1090,15 +1089,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Check to make sure that any normal attributes are allowed to be on // a definition. Late parsed attributes are checked at the end. if (Tok.isNot(tok::equal)) { - AttributeList *DtorAttrs = D.getAttributes(); - while (DtorAttrs) { - if (DtorAttrs->isKnownToGCC() && - !DtorAttrs->isCXX11Attribute()) { - Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition) - << DtorAttrs->getName(); - } - DtorAttrs = DtorAttrs->getNext(); - } + for (const AttributeList &AL : D.getAttributes()) + if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) + Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) + << AL.getName(); } // In delayed template parsing mode, for function template we consume the |