objc - Simplify switing objc decl context by using

a context switching object.

llvm-svn: 138248
This commit is contained in:
Fariborz Jahanian 2011-08-22 17:59:19 +00:00
parent 1dc9a20c16
commit 4bf8262a43
5 changed files with 35 additions and 50 deletions

View File

@ -503,6 +503,23 @@ private:
}
};
/// ObjCDeclContextSwitch - An object used to switch context from
/// an objective-c decl context to its enclosing decl context and
/// back.
class ObjCDeclContextSwitch {
Parser &P;
Decl *DC;
public:
explicit ObjCDeclContextSwitch(Parser &p) : P(p),
DC(p.getObjCDeclContext()) {
if (DC)
P.Actions.ActOnObjCContainerFinishDefinition(DC);
}
~ObjCDeclContextSwitch() {
if (DC)
P.Actions.ActOnObjCContainerStartDefinition(DC);
}
};
SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
SourceLocation LHSLoc);

View File

@ -52,9 +52,7 @@ Decl *Parser::ParseNamespace(unsigned Context,
SourceLocation InlineLoc) {
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
Decl *DC = getObjCDeclContext();
if (DC)
Actions.ActOnObjCContainerFinishDefinition(DC);
ObjCDeclContextSwitch ObjCDC(*this);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteNamespaceDecl(getCurScope());
@ -92,10 +90,7 @@ Decl *Parser::ParseNamespace(unsigned Context,
if (InlineLoc.isValid())
Diag(InlineLoc, diag::err_inline_namespace_alias)
<< FixItHint::CreateRemoval(InlineLoc);
Decl *Res = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Res;
return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
}
@ -106,8 +101,6 @@ Decl *Parser::ParseNamespace(unsigned Context,
}
Diag(Tok, Ident ? diag::err_expected_lbrace :
diag::err_expected_ident_lbrace);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return 0;
}
@ -122,8 +115,6 @@ Decl *Parser::ParseNamespace(unsigned Context,
}
Diag(LBrace, diag::err_namespace_nonnamespace_scope);
SkipUntil(tok::r_brace, false);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return 0;
}
@ -182,8 +173,6 @@ Decl *Parser::ParseNamespace(unsigned Context,
Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
DeclEnd = RBraceLoc;
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return NamespcDecl;
}
@ -328,9 +317,8 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
ParsedAttributesWithRange &attrs,
Decl **OwnedType) {
assert(Tok.is(tok::kw_using) && "Not using token");
Decl *DC = getObjCDeclContext();
if (DC)
Actions.ActOnObjCContainerFinishDefinition(DC);
ObjCDeclContextSwitch ObjCDC(*this);
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
@ -348,10 +336,7 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
<< R << FixItHint::CreateRemoval(R);
}
Decl *Res = ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Res;
return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
}
// Otherwise, it must be a using-declaration or an alias-declaration.
@ -359,11 +344,8 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
// Using declarations can't have attributes.
ProhibitAttributes(attrs);
Decl *Res = ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
AS_none, OwnedType);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Res;
}
/// ParseUsingDirective - Parse C++ using-directive, assumes

View File

@ -776,9 +776,8 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
SourceLocation LParenLoc = ConsumeParen();
SourceLocation TypeStartLoc = Tok.getLocation();
Decl *DC = getObjCDeclContext();
if (DC)
Actions.ActOnObjCContainerFinishDefinition(DC);
ObjCDeclContextSwitch ObjCDC(*this);
// Parse type qualifiers, in, inout, etc.
ParseObjCTypeQualifierList(DS, Context);
@ -801,8 +800,6 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
// place. Emit an error then return what we have as the type.
MatchRHSPunctuation(tok::r_paren, LParenLoc);
}
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Ty;
}

View File

@ -27,20 +27,13 @@ Decl *
Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
SourceLocation &DeclEnd,
AccessSpecifier AS) {
Decl *DC = getObjCDeclContext();
if (DC)
Actions.ActOnObjCContainerFinishDefinition(DC);
ObjCDeclContextSwitch ObjCDC(*this);
if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
Decl *Res = ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
DeclEnd);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Res;
}
Decl *Res = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return Res;
return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
}
/// \brief RAII class that manages the template parameter depth.

View File

@ -811,16 +811,12 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
AccessSpecifier AS) {
ParsingDeclSpec DS(*this);
DS.takeAttributesFrom(attrs);
Decl *DC = getObjCDeclContext();
if (DC)
// Must temporarily exit the objective-c container scope for
// parsing c constructs and re-enter objc container scope
// afterwards.
Actions.ActOnObjCContainerFinishDefinition(DC);
DeclGroupPtrTy resPtrTy = ParseDeclarationOrFunctionDefinition(DS, AS);
if (DC)
Actions.ActOnObjCContainerStartDefinition(DC);
return resPtrTy;
// Must temporarily exit the objective-c container scope for
// parsing c constructs and re-enter objc container scope
// afterwards.
ObjCDeclContextSwitch ObjCDC(*this);
return ParseDeclarationOrFunctionDefinition(DS, AS);
}
/// ParseFunctionDefinition - We parsed and verified that the specified