summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseCXXInlineMethods.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-27 23:11:45 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-27 23:11:45 +0000
commite44a2adf41f2cde4f8d10b7a13dd2b85fe6c7104 (patch)
treea847169f43e3e599af71199fe24120c45ad78673 /clang/lib/Parse/ParseCXXInlineMethods.cpp
parentb5f33c1634394b3e66ce0a2e945475016d4c5716 (diff)
downloadbcm5719-llvm-e44a2adf41f2cde4f8d10b7a13dd2b85fe6c7104.tar.gz
bcm5719-llvm-e44a2adf41f2cde4f8d10b7a13dd2b85fe6c7104.zip
Reimplement much of the way that we track nested classes in the
parser. Rather than placing all of the delayed member function declarations and inline definitions into a single bucket corresponding to the top-level class, we instead mirror the nesting structure of the nested classes and place the delayed member functions into their appropriate place. Then, when we actually parse the delayed member function declarations, set up the scope stack the same way as it was when we originally saw the declaration, so that we can find, e.g., template parameters that are in scope. llvm-svn: 72502
Diffstat (limited to 'clang/lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp47
1 files changed, 36 insertions, 11 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 525b088714d..af6fab7cb18 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -31,8 +31,8 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
// Consume the tokens and store them for later parsing.
- getCurTopClassStack().MethodDefs.push_back(LexedMethod(FnD));
- CachedTokens &Toks = getCurTopClassStack().MethodDefs.back().Toks;
+ getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));
+ CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks;
tok::TokenKind kind = Tok.getKind();
// We may have a constructor initializer or function-try-block here.
@@ -46,7 +46,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
// don't try to parse this method later.
Diag(Tok.getLocation(), diag::err_expected_lbrace);
ConsumeAnyToken();
- getCurTopClassStack().MethodDefs.pop_back();
+ getCurrentClass().MethodDefs.pop_back();
return FnD;
}
}
@@ -74,11 +74,22 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
/// specification of a top (non-nested) C++ class. Now go over the
/// stack of method declarations with some parts for which parsing was
/// delayed (such as default arguments) and parse them.
-void Parser::ParseLexedMethodDeclarations() {
- for (; !getCurTopClassStack().MethodDecls.empty();
- getCurTopClassStack().MethodDecls.pop_front()) {
- LateParsedMethodDeclaration &LM = getCurTopClassStack().MethodDecls.front();
+void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
+ bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
+ ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+ if (HasTemplateScope)
+ Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+
+ bool HasClassScope = !Class.TopLevelClass;
+ ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
+ HasClassScope);
+
+ for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) {
+ LateParsedMethodDeclaration &LM = Class.MethodDecls.front();
+ // FIXME: For member function templates, we'll need to introduce a
+ // scope for the template parameters.
+
// Start the delayed C++ method declaration
Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method);
@@ -117,15 +128,26 @@ void Parser::ParseLexedMethodDeclarations() {
// Finish the delayed C++ method declaration.
Actions.ActOnFinishDelayedCXXMethodDeclaration(CurScope, LM.Method);
}
+
+ for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
+ ParseLexedMethodDeclarations(*Class.NestedClasses[I]);
}
/// ParseLexedMethodDefs - We finished parsing the member specification of a top
/// (non-nested) C++ class. Now go over the stack of lexed methods that were
/// collected during its parsing and parse them all.
-void Parser::ParseLexedMethodDefs() {
- for (; !getCurTopClassStack().MethodDefs.empty();
- getCurTopClassStack().MethodDefs.pop_front()) {
- LexedMethod &LM = getCurTopClassStack().MethodDefs.front();
+void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
+ bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
+ ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+ if (HasTemplateScope)
+ Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+
+ bool HasClassScope = !Class.TopLevelClass;
+ ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
+ HasClassScope);
+
+ for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) {
+ LexedMethod &LM = Class.MethodDefs.front();
assert(!LM.Toks.empty() && "Empty body!");
// Append the current token at the end of the new token stream so that it
@@ -152,6 +174,9 @@ void Parser::ParseLexedMethodDefs() {
// FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'??
ParseFunctionStatementBody(LM.D);
}
+
+ for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
+ ParseLexedMethodDefs(*Class.NestedClasses[I]);
}
/// ConsumeAndStoreUntil - Consume and store the token at the passed token
OpenPOWER on IntegriCloud