aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Frontend/ASTUnit.cpp1
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp294
-rw-r--r--lib/Parse/ParseDeclCXX.cpp16
3 files changed, 168 insertions, 143 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 4319df3e92..e8e80647b4 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -807,6 +807,7 @@ error:
SavedMainFileBuffer = 0;
}
+ StoredDiagnostics.clear();
Clang.takeSourceManager();
Clang.takeFileManager();
Invocation.reset(Clang.takeInvocation());
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 8b2fb55d9d..718c71be02 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -45,10 +45,10 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
// Consume the tokens and store them for later parsing.
- getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));
- getCurrentClass().MethodDefs.back().TemplateScope
- = getCurScope()->isTemplateParamScope();
- CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks;
+ LexedMethod* LM = new LexedMethod(this, FnD);
+ getCurrentClass().LateParsedDeclarations.push_back(LM);
+ LM->TemplateScope = getCurScope()->isTemplateParamScope();
+ CachedTokens &Toks = LM->Toks;
tok::TokenKind kind = Tok.getKind();
// We may have a constructor initializer or function-try-block here.
@@ -62,7 +62,8 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
// don't try to parse this method later.
Diag(Tok.getLocation(), diag::err_expected_lbrace);
ConsumeAnyToken();
- getCurrentClass().MethodDefs.pop_back();
+ delete getCurrentClass().LateParsedDeclarations.back();
+ getCurrentClass().LateParsedDeclarations.pop_back();
return FnD;
}
}
@@ -86,13 +87,40 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
return FnD;
}
+Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
+void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
+void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
+
+Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
+ : Self(P), Class(C) {}
+
+Parser::LateParsedClass::~LateParsedClass() {
+ Self->DeallocateParsedClasses(Class);
+}
+
+void Parser::LateParsedClass::ParseLexedMethodDeclarations() {
+ Self->ParseLexedMethodDeclarations(*Class);
+}
+
+void Parser::LateParsedClass::ParseLexedMethodDefs() {
+ Self->ParseLexedMethodDefs(*Class);
+}
+
+void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
+ Self->ParseLexedMethodDeclaration(*this);
+}
+
+void Parser::LexedMethod::ParseLexedMethodDefs() {
+ Self->ParseLexedMethodDef(*this);
+}
+
/// ParseLexedMethodDeclarations - We finished parsing the member
/// 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(ParsingClass &Class) {
bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
- ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+ ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
if (HasTemplateScope)
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
@@ -104,80 +132,79 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
if (HasClassScope)
Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
- for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) {
- LateParsedMethodDeclaration &LM = Class.MethodDecls.front();
-
- // If this is a member template, introduce the template parameter scope.
- ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
- if (LM.TemplateScope)
- Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
-
- // Start the delayed C++ method declaration
- Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
-
- // Introduce the parameters into scope and parse their default
- // arguments.
- ParseScope PrototypeScope(this,
- Scope::FunctionPrototypeScope|Scope::DeclScope);
- for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
- // Introduce the parameter into scope.
- Actions.ActOnDelayedCXXMethodParameter(getCurScope(), LM.DefaultArgs[I].Param);
+ for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
+ Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations();
+ }
- if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
- // Save the current token position.
- SourceLocation origLoc = Tok.getLocation();
+ if (HasClassScope)
+ Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
+}
- // Parse the default argument from its saved token stream.
- Toks->push_back(Tok); // So that the current token doesn't get lost
- PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
+void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
+ // If this is a member template, introduce the template parameter scope.
+ ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
+ if (LM.TemplateScope)
+ Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
+
+ // Start the delayed C++ method declaration
+ Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
+
+ // Introduce the parameters into scope and parse their default
+ // arguments.
+ ParseScope PrototypeScope(this,
+ Scope::FunctionPrototypeScope|Scope::DeclScope);
+ for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
+ // Introduce the parameter into scope.
+ Actions.ActOnDelayedCXXMethodParameter(getCurScope(), LM.DefaultArgs[I].Param);
+
+ if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
+ // Save the current token position.
+ SourceLocation origLoc = Tok.getLocation();
+
+ // Parse the default argument from its saved token stream.
+ Toks->push_back(Tok); // So that the current token doesn't get lost
+ PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
+
+ // Consume the previously-pushed token.
+ ConsumeAnyToken();
+
+ // Consume the '='.
+ assert(Tok.is(tok::equal) && "Default argument not starting with '='");
+ SourceLocation EqualLoc = ConsumeToken();
+
+ // The argument isn't actually potentially evaluated unless it is
+ // used.
+ EnterExpressionEvaluationContext Eval(Actions,
+ Sema::PotentiallyEvaluatedIfUsed);
+
+ ExprResult DefArgResult(ParseAssignmentExpression());
+ if (DefArgResult.isInvalid())
+ Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
+ else {
+ if (Tok.is(tok::cxx_defaultarg_end))
+ ConsumeToken();
+ else
+ Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
+ Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
+ DefArgResult.take());
+ }
- // Consume the previously-pushed token.
+ assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+ Tok.getLocation()) &&
+ "ParseAssignmentExpression went over the default arg tokens!");
+ // There could be leftover tokens (e.g. because of an error).
+ // Skip through until we reach the original token position.
+ while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
- // Consume the '='.
- assert(Tok.is(tok::equal) && "Default argument not starting with '='");
- SourceLocation EqualLoc = ConsumeToken();
-
- // The argument isn't actually potentially evaluated unless it is
- // used.
- EnterExpressionEvaluationContext Eval(Actions,
- Sema::PotentiallyEvaluatedIfUsed);
-
- ExprResult DefArgResult(ParseAssignmentExpression());
- if (DefArgResult.isInvalid())
- Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
- else {
- if (Tok.is(tok::cxx_defaultarg_end))
- ConsumeToken();
- else
- Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
- Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
- DefArgResult.take());
- }
-
- assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
- Tok.getLocation()) &&
- "ParseAssignmentExpression went over the default arg tokens!");
- // There could be leftover tokens (e.g. because of an error).
- // Skip through until we reach the original token position.
- while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
- ConsumeAnyToken();
-
- delete Toks;
- LM.DefaultArgs[I].Toks = 0;
- }
+ delete Toks;
+ LM.DefaultArgs[I].Toks = 0;
}
- PrototypeScope.Exit();
-
- // Finish the delayed C++ method declaration.
- Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
}
+ PrototypeScope.Exit();
- for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
- ParseLexedMethodDeclarations(*Class.NestedClasses[I]);
-
- if (HasClassScope)
- Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
+ // Finish the delayed C++ method declaration.
+ Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
}
/// ParseLexedMethodDefs - We finished parsing the member specification of a top
@@ -185,7 +212,7 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
/// collected during its parsing and parse them all.
void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
- ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+ ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
if (HasTemplateScope)
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
@@ -193,73 +220,72 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
HasClassScope);
- for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) {
- LexedMethod &LM = Class.MethodDefs.front();
-
- // If this is a member template, introduce the template parameter scope.
- ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
- if (LM.TemplateScope)
- Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
-
- // Save the current token position.
- SourceLocation origLoc = Tok.getLocation();
-
- assert(!LM.Toks.empty() && "Empty body!");
- // Append the current token at the end of the new token stream so that it
- // doesn't get lost.
- LM.Toks.push_back(Tok);
- PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
-
- // Consume the previously pushed token.
- ConsumeAnyToken();
- assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
- && "Inline method not starting with '{', ':' or 'try'");
+ for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
+ Class.LateParsedDeclarations[i]->ParseLexedMethodDefs();
+ }
+}
- // Parse the method body. Function body parsing code is similar enough
- // to be re-used for method bodies as well.
- ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
- Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
+void Parser::ParseLexedMethodDef(LexedMethod &LM) {
+ // If this is a member template, introduce the template parameter scope.
+ ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
+ if (LM.TemplateScope)
+ Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
+
+ // Save the current token position.
+ SourceLocation origLoc = Tok.getLocation();
+
+ assert(!LM.Toks.empty() && "Empty body!");
+ // Append the current token at the end of the new token stream so that it
+ // doesn't get lost.
+ LM.Toks.push_back(Tok);
+ PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
+
+ // Consume the previously pushed token.
+ ConsumeAnyToken();
+ assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
+ && "Inline method not starting with '{', ':' or 'try'");
+
+ // Parse the method body. Function body parsing code is similar enough
+ // to be re-used for method bodies as well.
+ ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
+ Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
+
+ if (Tok.is(tok::kw_try)) {
+ ParseFunctionTryBlock(LM.D);
+ assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+ Tok.getLocation()) &&
+ "ParseFunctionTryBlock went over the cached tokens!");
+ // There could be leftover tokens (e.g. because of an error).
+ // Skip through until we reach the original token position.
+ while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
+ ConsumeAnyToken();
+ return;
+ }
+ if (Tok.is(tok::colon)) {
+ ParseConstructorInitializer(LM.D);
- if (Tok.is(tok::kw_try)) {
- ParseFunctionTryBlock(LM.D);
- assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
- Tok.getLocation()) &&
- "ParseFunctionTryBlock went over the cached tokens!");
- // There could be leftover tokens (e.g. because of an error).
- // Skip through until we reach the original token position.
+ // Error recovery.
+ if (!Tok.is(tok::l_brace)) {
+ Actions.ActOnFinishFunctionBody(LM.D, 0);
+ return;
+ }
+ } else
+ Actions.ActOnDefaultCtorInitializers(LM.D);
+
+ ParseFunctionStatementBody(LM.D);
+
+ if (Tok.getLocation() != origLoc) {
+ // Due to parsing error, we either went over the cached tokens or
+ // there are still cached tokens left. If it's the latter case skip the
+ // leftover tokens.
+ // Since this is an uncommon situation that should be avoided, use the
+ // expensive isBeforeInTranslationUnit call.
+ if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
+ origLoc))
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
- continue;
- }
- if (Tok.is(tok::colon)) {
- ParseConstructorInitializer(LM.D);
-
- // Error recovery.
- if (!Tok.is(tok::l_brace)) {
- Actions.ActOnFinishFunctionBody(LM.D, 0);
- continue;
- }
- } else
- Actions.ActOnDefaultCtorInitializers(LM.D);
-
- ParseFunctionStatementBody(LM.D);
-
- if (Tok.getLocation() != origLoc) {
- // Due to parsing error, we either went over the cached tokens or
- // there are still cached tokens left. If it's the latter case skip the
- // leftover tokens.
- // Since this is an uncommon situation that should be avoided, use the
- // expensive isBeforeInTranslationUnit call.
- if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
- origLoc))
- while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
- ConsumeAnyToken();
- }
}
-
- 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
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index c02f41a268..8fed447bc2 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1203,9 +1203,8 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
if (!LateMethod) {
// Push this method onto the stack of late-parsed method
// declarations.
- getCurrentClass().MethodDecls.push_back(
- LateParsedMethodDeclaration(ThisDecl));
- LateMethod = &getCurrentClass().MethodDecls.back();
+ LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
+ getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
// Add all of the parameters prior to this one (they don't
@@ -1911,8 +1910,8 @@ void Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
/// \brief Deallocate the given parsed class and all of its nested
/// classes.
void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
- for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
- DeallocateParsedClasses(Class->NestedClasses[I]);
+ for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
+ delete Class->LateParsedDeclarations[I];
delete Class;
}
@@ -1938,13 +1937,12 @@ void Parser::PopParsingClass() {
}
assert(!ClassStack.empty() && "Missing top-level class?");
- if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
- Victim->NestedClasses.empty()) {
+ if (Victim->LateParsedDeclarations.empty()) {
// The victim is a nested class, but we will not need to perform
// any processing after the definition of this class since it has
// no members whose handling was delayed. Therefore, we can just
// remove this nested class.
- delete Victim;
+ DeallocateParsedClasses(Victim);
return;
}
@@ -1952,7 +1950,7 @@ void Parser::PopParsingClass() {
// after the top-level class is completely defined. Therefore, add
// it to the list of nested classes within its parent.
assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
- ClassStack.top()->NestedClasses.push_back(Victim);
+ ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
}