diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index f9995e616284..f52ac9c649af 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1891,6 +1891,7 @@ private: IdentifierInfo *ScopeName, SourceLocation ScopeLoc, AttributeList::Syntax Syntax); + IdentifierLoc *ParseIdentifierLoc(); void MaybeParseCXX11Attributes(Declarator &D) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h index 909f4a2e613f..1ff3fe6c5168 100644 --- a/clang/include/clang/Sema/AttributeList.h +++ b/clang/include/clang/Sema/AttributeList.h @@ -46,10 +46,12 @@ struct AvailabilityChange { }; /// \brief Wraps an identifier and optional source location for the identifier. -/// It is expected that these will be created from the ASTContext memory pool. struct IdentifierLoc { SourceLocation Loc; IdentifierInfo *Ident; + + static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, + IdentifierInfo *Ident); }; /// \brief A union of the various pointer types that can be passed to an diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 76202cc146de..26ac6193bd50 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -13,7 +13,6 @@ #include "clang/Parse/Parser.h" #include "RAIIObjectsForParser.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" @@ -187,6 +186,15 @@ static bool attributeHasExprArgs(const IdentifierInfo &II) { .Default(false); } +IdentifierLoc *Parser::ParseIdentifierLoc() { + assert(Tok.is(tok::identifier) && "expected an identifier"); + IdentifierLoc *IL = IdentifierLoc::create(Actions.Context, + Tok.getLocation(), + Tok.getIdentifierInfo()); + ConsumeToken(); + return IL; +} + /// Parse the arguments to a parameterized GNU attribute or /// a C++11 attribute in "gnu" namespace. void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, @@ -259,10 +267,7 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName, if (attributeHasExprArgs(*AttrName)) break; - IdentifierLoc *Param = ::new (Actions.Context) IdentifierLoc; - Param->Ident = Tok.getIdentifierInfo(); - Param->Loc = ConsumeToken(); - ArgExprs.push_back(Param); + ArgExprs.push_back(ParseIdentifierLoc()); } break; default: @@ -828,10 +833,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, SkipUntil(tok::r_paren); return; } - - IdentifierLoc *Platform = new (Actions.Context) IdentifierLoc; - Platform->Ident = Tok.getIdentifierInfo(); - Platform->Loc = ConsumeToken(); + IdentifierLoc *Platform = ParseIdentifierLoc(); // Parse the ',' following the platform name. if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren)) @@ -1202,9 +1204,7 @@ void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, T.skipToEnd(); return; } - IdentifierLoc *ArgumentKind = new (Actions.Context) IdentifierLoc; - ArgumentKind->Ident = Tok.getIdentifierInfo(); - ArgumentKind->Loc = ConsumeToken(); + IdentifierLoc *ArgumentKind = ParseIdentifierLoc(); if (Tok.isNot(tok::comma)) { Diag(Tok, diag::err_expected_comma); diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index dd01aef73cb4..451b01c2ec15 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/lib/Sema/AttributeList.cpp @@ -19,6 +19,14 @@ #include "llvm/ADT/StringSwitch.h" using namespace clang; +IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc, + IdentifierInfo *Ident) { + IdentifierLoc *Result = new (Ctx) IdentifierLoc; + Result->Loc = Loc; + Result->Ident = Ident; + return Result; +} + size_t AttributeList::allocated_size() const { if (IsAvailability) return AttributeFactory::AvailabilityAllocSize; else if (IsTypeTagForDatatype)