#include <list>
namespace clang {
- class AttributeList;
- struct CXX0XAttributeList;
class PragmaHandler;
class Scope;
class DeclGroupRef;
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
+
+ /// Factory object for creating AttributeList objects.
+ AttributeList::Factory AttrFactory;
public:
Parser(Preprocessor &PP, Sema &Actions);
#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
#define LLVM_CLANG_SEMA_ATTRLIST_H
+#include "llvm/Support/Allocator.h"
#include "clang/Sema/Ownership.h"
#include "clang/Basic/SourceLocation.h"
#include <cassert>
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
class AttributeList {
+public:
+ class Factory;
+private:
IdentifierInfo *AttrName;
SourceLocation AttrLoc;
IdentifierInfo *ScopeName;
mutable bool Invalid; /// True if already diagnosed as invalid.
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
-public:
- AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ void operator delete(void *); // DO NOT IMPLEMENT
+ ~AttributeList(); // DO NOT IMPLEMENT
+ AttributeList(llvm::BumpPtrAllocator &Alloc,
+ IdentifierInfo *AttrName, SourceLocation AttrLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
IdentifierInfo *ParmName, SourceLocation ParmLoc,
Expr **args, unsigned numargs,
- AttributeList *Next, bool declspec = false, bool cxx0x = false);
- ~AttributeList();
-
+ AttributeList *Next, bool declspec, bool cxx0x);
+public:
+ class Factory {
+ llvm::BumpPtrAllocator Alloc;
+ public:
+ Factory() {}
+ ~Factory() {}
+ AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ IdentifierInfo *ParmName, SourceLocation ParmLoc,
+ Expr **args, unsigned numargs,
+ AttributeList *Next, bool declspec = false, bool cxx0x = false) {
+ AttributeList *Mem = Alloc.Allocate<AttributeList>();
+ new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
+ ParmName, ParmLoc, args, numargs,
+ Next, declspec, cxx0x);
+ return Mem;
+ }
+ };
+
enum Kind { // Please keep this list alphabetized.
AT_IBAction, // Clang-specific.
AT_IBOutlet, // Clang-specific.
writtenBS() {
}
~DeclSpec() {
- delete AttrList;
delete [] ProtocolQualifiers;
delete [] ProtocolLocs;
}
unsigned TypeQuals : 3;
AttributeList *AttrList;
void destroy() {
- delete AttrList;
}
};
bool LValueRef : 1;
AttributeList *AttrList;
void destroy() {
- delete AttrList;
}
};
unsigned TypeQuals : 3;
AttributeList *AttrList;
void destroy() {
- delete AttrList;
}
};
return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem);
}
void destroy() {
- delete AttrList;
Scope().~CXXScopeSpec();
}
};
for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
DeclTypeInfo[i].destroy();
DeclTypeInfo.clear();
- delete AttrList;
AttrList = 0;
AsmLabel = 0;
InlineParamsUsed = false;
if (Tok.is(tok::r_paren)) {
// __attribute__(( mode(byte) ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
- ParmName, ParmLoc, 0, 0, CurrAttr);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ ParmName, ParmLoc, 0, 0, CurrAttr);
} else if (Tok.is(tok::comma)) {
ConsumeToken();
// __attribute__(( format(printf, 1, 2) ))
}
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
- AttrNameLoc, ParmName, ParmLoc,
- ArgExprs.take(), ArgExprs.size(),
- CurrAttr);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
+ AttrNameLoc, ParmName, ParmLoc,
+ ArgExprs.take(), ArgExprs.size(),
+ CurrAttr);
}
}
} else { // not an identifier
// parse a possibly empty comma separated list of expressions
// __attribute__(( nonnull() ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, CurrAttr);
break;
case tok::kw_char:
case tok::kw_wchar_t:
case tok::kw_double:
case tok::kw_void:
case tok::kw_typeof:
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, CurrAttr);
if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection)
Diag(Tok, diag::err_iboutletcollection_builtintype);
// If it's a builtin type name, eat it and expect a rparen
// Match the ')'.
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
ArgExprs.size(),
CurrAttr);
}
}
} else {
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, CurrAttr);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
ExprResult ArgExpr(ParseAssignmentExpression());
if (!ArgExpr.isInvalid()) {
Expr *ExprList = ArgExpr.take();
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), &ExprList, 1,
- CurrAttr, true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), &ExprList, 1,
+ CurrAttr, true);
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
} else {
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr, true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, CurrAttr, true);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
// FIXME: Support these properly!
continue;
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0, CurrAttr, true);
}
return CurrAttr;
}
while (Tok.is(tok::kw___pascal)) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0, CurrAttr, true);
}
return CurrAttr;
}
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- llvm::OwningPtr<AttributeList> AttrList;
+ AttributeList *AttrList = 0;
// If attributes exist after struct contents, parse them.
if (Tok.is(tok::kw___attribute))
- AttrList.reset(ParseGNUAttributes());
+ AttrList = ParseGNUAttributes();
Actions.ActOnFields(getCurScope(),
RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
LBraceLoc, RBraceLoc,
- AttrList.get());
+ AttrList);
StructScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
}
ConsumeCodeCompletionToken();
}
- llvm::OwningPtr<AttributeList> Attr;
+ AttributeList *Attr = 0;
// If attributes exist after tag, parse them.
if (Tok.is(tok::kw___attribute))
- Attr.reset(ParseGNUAttributes());
+ Attr = ParseGNUAttributes();
CXXScopeSpec &SS = DS.getTypeSpecScope();
if (getLang().CPlusPlus) {
const char *PrevSpec = 0;
unsigned DiagID;
Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
- StartLoc, SS, Name, NameLoc, Attr.get(),
+ StartLoc, SS, Name, NameLoc, Attr,
AS,
MultiTemplateParamsArg(Actions),
Owned, IsDependent, IsScopedEnum,
SourceLocation IdentLoc = ConsumeToken();
// If attributes exist after the enumerator, parse them.
- llvm::OwningPtr<AttributeList> Attr;
+ AttributeList *Attr = 0;
if (Tok.is(tok::kw___attribute))
- Attr.reset(ParseGNUAttributes());
+ Attr = ParseGNUAttributes();
SourceLocation EqualLoc;
ExprResult AssignedVal;
Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
LastEnumConstDecl,
IdentLoc, Ident,
- Attr.get(), EqualLoc,
+ Attr, EqualLoc,
AssignedVal.release());
EnumConstantDecls.push_back(EnumConstDecl);
LastEnumConstDecl = EnumConstDecl;
// Eat the }.
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- llvm::OwningPtr<AttributeList> Attr;
+ AttributeList *Attr = 0;
// If attributes exist after the identifier list, parse them.
if (Tok.is(tok::kw___attribute))
- Attr.reset(ParseGNUAttributes()); // FIXME: where do they do?
+ Attr = ParseGNUAttributes(); // FIXME: where do they do?
Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
EnumConstantDecls.data(), EnumConstantDecls.size(),
- getCurScope(), Attr.get());
+ getCurScope(), Attr);
EnumScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
// In either case, we need to eat any attributes to be able to determine what
// sort of paren this is.
//
- llvm::OwningPtr<AttributeList> AttrList;
+ AttributeList *AttrList = 0;
bool RequiresArg = false;
if (Tok.is(tok::kw___attribute)) {
- AttrList.reset(ParseGNUAttributes());
+ AttrList = ParseGNUAttributes();
// We require that the argument list (if this is a non-grouping paren) be
// present even if the attribute list was empty.
if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
- AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take()));
+ AttrList = ParseMicrosoftTypeAttributes(AttrList);
}
// Eat any Borland extensions.
- if (Tok.is(tok::kw___pascal)) {
- AttrList.reset(ParseBorlandTypeAttributes(AttrList.take()));
- }
+ if (Tok.is(tok::kw___pascal))
+ AttrList = ParseBorlandTypeAttributes(AttrList);
// If we haven't past the identifier yet (or where the identifier would be
// stored, if this is an abstract declarator), then this is probably just
bool hadGroupingParens = D.hasGroupingParens();
D.setGroupingParens(true);
if (AttrList)
- D.AddAttributes(AttrList.take(), SourceLocation());
+ D.AddAttributes(AttrList, SourceLocation());
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
// Match the ')'.
// ParseFunctionDeclarator to handle of argument list.
D.SetIdentifier(0, Tok.getLocation());
- ParseFunctionDeclarator(StartLoc, D, AttrList.take(), RequiresArg);
+ ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
}
/// ParseFunctionDeclarator - We are after the identifier and have parsed the
// This parameter list may be empty.
if (Tok.is(tok::r_paren)) {
- if (RequiresArg) {
+ if (RequiresArg)
Diag(Tok, diag::err_argument_required_after_attribute);
- delete AttrList;
- }
SourceLocation RParenLoc = ConsumeParen(); // Eat the closing ')'.
SourceLocation EndLoc = RParenLoc;
if (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) {
// K&R identifier lists can't have typedefs as identifiers, per
// C99 6.7.5.3p11.
- if (RequiresArg) {
+ if (RequiresArg)
Diag(Tok, diag::err_argument_required_after_attribute);
- delete AttrList;
- }
// Identifier list. Note that '(' identifier-list ')' is only allowed for
// normal declarators, not for abstract-declarators. Get the first
}
// Read label attributes, if present.
- llvm::OwningPtr<AttributeList> AttrList;
+ AttributeList *AttrList = 0;
if (Tok.is(tok::kw___attribute)) {
attrTok = Tok;
// FIXME: save these somewhere.
- AttrList.reset(ParseGNUAttributes());
+ AttrList = ParseGNUAttributes();
}
if (Tok.is(tok::equal)) {
Decl *NamespcDecl =
Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
- LBrace, AttrList.get());
+ LBrace, AttrList);
PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
"parsing namespace");
}
// Parse (optional) attributes (most likely GNU strong-using extension).
- llvm::OwningPtr<AttributeList> AttrList;
+ AttributeList *AttrList = 0;
if (Tok.is(tok::kw___attribute))
- AttrList.reset(ParseGNUAttributes());
+ AttrList = ParseGNUAttributes();
// Eat ';'.
DeclEnd = Tok.getLocation();
return 0;
}
- return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, Name,
- AttrList.get(), IsTypeName, TypenameLoc);
+ return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
+ Name, AttrList, IsTypeName, TypenameLoc);
}
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
}
// If attributes exist after class contents, parse them.
- llvm::OwningPtr<AttributeList> AttrList;
+ AttributeList *AttrList = 0;
if (Tok.is(tok::kw___attribute))
- AttrList.reset(ParseGNUAttributes());
+ AttrList = ParseGNUAttributes();
if (TagDecl)
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
LBraceLoc, RBraceLoc,
- AttrList.get());
+ AttrList);
// C++ 9.2p2: Within the class member-specification, the class is regarded as
// complete within function bodies, default arguments,
break;
}
- CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, false,
- true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
+ SourceLocation(), 0, 0, CurrAttr, false,
+ true);
AttrParsed = true;
break;
}
ExprVector ArgExprs(Actions);
ArgExprs.push_back(ArgExpr.release());
- CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc,
- 0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
- false, true);
+ CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
+ 0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
+ false, true);
AttrParsed = true;
break;
ReturnType = ParseObjCTypeName(DSRet, false);
// If attributes exist before the method, parse them.
- llvm::OwningPtr<AttributeList> MethodAttrs;
+ AttributeList *MethodAttrs = 0;
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs.reset(ParseGNUAttributes());
+ MethodAttrs = ParseGNUAttributes();
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
if (Tok.isNot(tok::colon)) {
// If attributes exist after the method, parse them.
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
- ParseGNUAttributes()));
+ MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
Decl *Result
mType, IDecl, DSRet, ReturnType, Sel,
0,
CParamInfo.data(), CParamInfo.size(),
- MethodAttrs.get(),
- MethodImplKind);
+ MethodAttrs, MethodImplKind);
PD.complete(Result);
return Result;
}
// FIXME: Add support for optional parameter list...
// If attributes exist after the method, parse them.
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
- ParseGNUAttributes()));
+ MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
if (KeyIdents.size() == 0)
return 0;
mType, IDecl, DSRet, ReturnType, Sel,
&ArgInfos[0],
CParamInfo.data(), CParamInfo.size(),
- MethodAttrs.get(),
+ MethodAttrs,
MethodImplKind, isVariadic);
PD.complete(Result);
-
- // Delete referenced AttributeList objects.
- for (llvm::SmallVectorImpl<Sema::ObjCArgInfo>::iterator
- I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I)
- delete I->ArgAttrs;
-
return Result;
}
CXX0XAttributeList Attr;
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
Attr = ParseCXX0XAttributes();
- llvm::OwningPtr<AttributeList> AttrList(Attr.AttrList);
+ AttributeList *AttrList = Attr.AttrList;
// Cases in this switch statement should fall through if the parser expects
// the token to end in a semicolon (in which case SemiError should be set),
case tok::identifier:
if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
// identifier ':' statement
- return ParseLabeledStatement(AttrList.take());
+ return ParseLabeledStatement(AttrList);
}
// PASS THROUGH.
default: {
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
- AttrList.take(); //Passing 'Attr' to ParseDeclaration transfers ownership.
- DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext, DeclEnd,
- Attr);
+ DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
+ DeclEnd, Attr);
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
}
case tok::kw_case: // C99 6.8.1: labeled-statement
- return ParseCaseStatement(AttrList.take());
+ return ParseCaseStatement(AttrList);
case tok::kw_default: // C99 6.8.1: labeled-statement
- return ParseDefaultStatement(AttrList.take());
+ return ParseDefaultStatement(AttrList);
case tok::l_brace: // C99 6.8.2: compound-statement
- return ParseCompoundStatement(AttrList.take());
+ return ParseCompoundStatement(AttrList);
case tok::semi: // C99 6.8.3p3: expression[opt] ';'
return Actions.ActOnNullStmt(ConsumeToken());
case tok::kw_if: // C99 6.8.4.1: if-statement
- return ParseIfStatement(AttrList.take());
+ return ParseIfStatement(AttrList);
case tok::kw_switch: // C99 6.8.4.2: switch-statement
- return ParseSwitchStatement(AttrList.take());
+ return ParseSwitchStatement(AttrList);
case tok::kw_while: // C99 6.8.5.1: while-statement
- return ParseWhileStatement(AttrList.take());
+ return ParseWhileStatement(AttrList);
case tok::kw_do: // C99 6.8.5.2: do-statement
- Res = ParseDoStatement(AttrList.take());
+ Res = ParseDoStatement(AttrList);
SemiError = "do/while";
break;
case tok::kw_for: // C99 6.8.5.3: for-statement
- return ParseForStatement(AttrList.take());
+ return ParseForStatement(AttrList);
case tok::kw_goto: // C99 6.8.6.1: goto-statement
- Res = ParseGotoStatement(AttrList.take());
+ Res = ParseGotoStatement(AttrList);
SemiError = "goto";
break;
case tok::kw_continue: // C99 6.8.6.2: continue-statement
- Res = ParseContinueStatement(AttrList.take());
+ Res = ParseContinueStatement(AttrList);
SemiError = "continue";
break;
case tok::kw_break: // C99 6.8.6.3: break-statement
- Res = ParseBreakStatement(AttrList.take());
+ Res = ParseBreakStatement(AttrList);
SemiError = "break";
break;
case tok::kw_return: // C99 6.8.6.4: return-statement
- Res = ParseReturnStatement(AttrList.take());
+ Res = ParseReturnStatement(AttrList);
SemiError = "return";
break;
}
case tok::kw_try: // C++ 15: try-block
- return ParseCXXTryBlock(AttrList.take());
+ return ParseCXXTryBlock(AttrList);
}
// If we reached this code, the statement must end in a semicolon.
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
- llvm::OwningPtr<AttributeList> AttrList(Attr);
Token IdentTok = Tok; // Save the whole token.
ConsumeToken(); // eat the identifier.
// Read label attributes, if present.
if (Tok.is(tok::kw___attribute))
- AttrList.reset(addAttributeLists(AttrList.take(), ParseGNUAttributes()));
+ Attr = addAttributeLists(Attr, ParseGNUAttributes());
StmtResult SubStmt(ParseStatement());
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.get(), AttrList.take());
+ ColonLoc, SubStmt.get(), Attr);
}
/// ParseCaseStatement
StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
// FIXME: Use attributes?
- delete Attr;
// It is very very common for code to contain many case statements recursively
// nested, as in (but usually without indentation):
///
StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
//FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
StmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
bool isStmtExpr) {
//FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
///
StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
SourceLocation IfLoc = ConsumeToken(); // eat the 'if'.
/// [C++] 'switch' '(' condition ')' statement
StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
/// [C++] 'while' '(' condition ')' statement
StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_while) && "Not a while stmt!");
SourceLocation WhileLoc = Tok.getLocation();
/// Note: this lets the caller parse the end ';'.
StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_do) && "Not a do stmt!");
SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
///
StmtResult Parser::ParseForStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
///
StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
///
StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
///
StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
/// 'return' expression[opt] ';'
StmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
// FIXME: Use attributes?
- delete Attr;
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
///
StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
// FIXME: Add attributes?
- delete Attr;
assert(Tok.is(tok::kw_try) && "Expected 'try'");
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
-AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
+AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
+ IdentifierInfo *aName, SourceLocation aLoc,
IdentifierInfo *sName, SourceLocation sLoc,
IdentifierInfo *pName, SourceLocation pLoc,
Expr **ExprList, unsigned numArgs,
AttributeList *n, bool declspec, bool cxx0x)
- : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
+ : AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
+ ScopeLoc(sLoc),
ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
if (numArgs == 0)
Args = 0;
else {
- Args = new Expr*[numArgs];
+ // Allocate the Args array using the BumpPtrAllocator.
+ Args = Alloc.Allocate<Expr*>(numArgs);
memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
}
}
-AttributeList::~AttributeList() {
- if (Args) {
- // FIXME: before we delete the vector, we need to make sure the Expr's
- // have been deleted. Since ActionBase::ExprTy is "void", we are dependent
- // on the actions module for actually freeing the memory. The specific
- // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType,
- // ParseField, ParseTag. Once these routines have freed the expression,
- // they should zero out the Args slot (to indicate the memory has been
- // freed). If any element of the vector is non-null, we should assert.
- delete [] Args;
- }
- delete Next;
-}
-
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
llvm::StringRef AttrName = Name->getName();
}
// FIXME: We ignore attributes for now.
- delete AttrList;
return UDir;
}
assert(IdentLoc.isValid() && "Invalid TargetName location.");
// FIXME: We ignore attributes for now.
- delete AttrList;
if (SS.isEmpty()) {
Diag(IdentLoc, diag::err_using_requires_qualname);
// According to GCC docs, "the only attribute that makes sense after a label
// is 'unused'".
bool HasUnusedAttr = false;
- llvm::OwningPtr<const AttributeList> AttrList(Attr);
- for (const AttributeList* a = AttrList.get(); a; a = a->getNext()) {
- if (a->getKind() == AttributeList::AT_unused) {
+ for ( ; Attr; Attr = Attr->getNext()) {
+ if (Attr->getKind() == AttributeList::AT_unused) {
HasUnusedAttr = true;
} else {
- Diag(a->getLoc(), diag::warn_label_attribute_not_unused);
- a->setInvalid(true);
+ Diag(Attr->getLoc(), diag::warn_label_attribute_not_unused);
+ Attr->setInvalid(true);
}
}