Insomniac refactoring: change how the parser allocates attributes so that
AttributeLists do not accumulate over the lifetime of parsing, but are
instead reused. Also make the arguments array not require a separate
allocation, and make availability attributes store their stuff in
augmented memory, too.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128209 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index dab6354..14f2bbe 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -41,11 +41,11 @@
case tok::objc_class:
return ParseObjCAtClassDeclaration(AtLoc);
case tok::objc_interface: {
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
}
case tok::objc_protocol: {
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
}
case tok::objc_implementation:
@@ -371,7 +371,7 @@
// FIXME: as the name implies, this rule allows function definitions.
// We could pass a flag or check for functions during semantic analysis.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
continue;
}
@@ -439,7 +439,7 @@
OCDS, AtLoc, MethodImplKind);
// Parse all the comma separated declarators.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseStructDeclaration(DS, Callback);
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
@@ -843,9 +843,9 @@
ReturnType = ParseObjCTypeName(DSRet, OTN_ResultType);
// If attributes exist before the method, parse them.
- ParsedAttributes attrs;
+ ParsedAttributes methodAttrs(AttrFactory);
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
@@ -870,7 +870,7 @@
if (Tok.isNot(tok::colon)) {
// If attributes exist after the method, parse them.
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
Decl *Result
@@ -878,8 +878,8 @@
mType, IDecl, DSRet, ReturnType, Sel,
0,
CParamInfo.data(), CParamInfo.size(),
- attrs.getList(), MethodImplKind, false,
- MethodDefinition);
+ methodAttrs.getList(), MethodImplKind,
+ false, MethodDefinition);
PD.complete(Result);
return Result;
}
@@ -888,8 +888,11 @@
llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
ParseScope PrototypeScope(this,
Scope::FunctionPrototypeScope|Scope::DeclScope);
+
+ AttributePool allParamAttrs(AttrFactory);
while (1) {
+ ParsedAttributes paramAttrs(AttrFactory);
Sema::ObjCArgInfo ArgInfo;
// Each iteration parses a single keyword argument.
@@ -906,9 +909,8 @@
// If attributes exist before the argument name, parse them.
ArgInfo.ArgAttrs = 0;
if (getLang().ObjC2) {
- ParsedAttributes attrs;
- MaybeParseGNUAttributes(attrs);
- ArgInfo.ArgAttrs = attrs.getList();
+ MaybeParseGNUAttributes(paramAttrs);
+ ArgInfo.ArgAttrs = paramAttrs.getList();
}
// Code completion for the next piece of the selector.
@@ -937,6 +939,9 @@
ArgInfos.push_back(ArgInfo);
KeyIdents.push_back(SelIdent);
+ // Make sure the attributes persist.
+ allParamAttrs.takeAllFrom(paramAttrs.getPool());
+
// Code completion for the next piece of the selector.
if (Tok.is(tok::code_completion)) {
ConsumeCodeCompletionToken();
@@ -967,7 +972,7 @@
ConsumeToken();
break;
}
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// Parse the declarator.
Declarator ParmDecl(DS, Declarator::PrototypeContext);
@@ -984,7 +989,7 @@
// FIXME: Add support for optional parameter list...
// If attributes exist after the method, parse them.
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
if (KeyIdents.size() == 0) {
// Leave prototype scope.
@@ -999,7 +1004,7 @@
mType, IDecl, DSRet, ReturnType, Sel,
&ArgInfos[0],
CParamInfo.data(), CParamInfo.size(),
- attrs.getList(),
+ methodAttrs.getList(),
MethodImplKind, isVariadic, MethodDefinition);
// Leave prototype scope.
PrototypeScope.Exit();
@@ -1172,7 +1177,7 @@
} Callback(*this, interfaceDecl, visibility, AllIvarDecls);
// Parse all the comma separated declarators.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseStructDeclaration(DS, Callback);
if (Tok.is(tok::semi)) {
@@ -1616,7 +1621,7 @@
ConsumeParen();
ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
if (Tok.isNot(tok::ellipsis)) {
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// For some odd reason, the name of the exception variable is
// optional. As a result, we need to use "PrototypeContext", because
@@ -1848,7 +1853,7 @@
// typename-specifier
// simple-type-specifier
// expression (that starts with one of the above)
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseCXXSimpleTypeSpecifier(DS);
if (Tok.is(tok::l_paren)) {