summaryrefslogtreecommitdiffstats
path: root/clang/include/clang/Parse/Parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Parse/Parser.h')
-rw-r--r--clang/include/clang/Parse/Parser.h76
1 files changed, 58 insertions, 18 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 910a921c448..9750cab5e78 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -512,11 +512,26 @@ private:
/// nested classes are lexed and stored here.
typedef std::list<LexedMethod> LexedMethodsForTopClass;
+ /// \brief Representation of a class that has been parsed, including
+ /// any member function declarations or definitions that need to be
+ /// parsed after the corresponding top-level class is complete.
+ struct ParsingClass {
+ ParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass)
+ : TopLevelClass(TopLevelClass), TemplateScope(false),
+ TagOrTemplate(TagOrTemplate) { }
+
+ /// \brief Whether this is a "top-level" class, meaning that it is
+ /// not nested within another class.
+ bool TopLevelClass : 1;
+
+ /// \brief Whether this class had an associated template
+ /// scope. When true, TagOrTemplate is a template declaration;
+ /// othewise, it is a tag declaration.
+ bool TemplateScope : 1;
+
+ /// \brief The class or class template whose definition we are parsing.
+ DeclPtrTy TagOrTemplate;
- /// TopClass - Contains information about parts of the top
- /// (non-nested) C++ class that will need to be parsed after the
- /// class is fully defined.
- struct TopClass {
/// MethodDecls - Method declarations that contain pieces whose
/// parsing will be delayed until the class is fully defined.
LateParsedMethodDecls MethodDecls;
@@ -524,27 +539,52 @@ private:
/// MethodDefs - Methods whose definitions will be parsed once the
/// class has been fully defined.
LexedMethodsForTopClass MethodDefs;
+
+ /// \brief Nested classes inside this class.
+ llvm::SmallVector<ParsingClass*, 4> NestedClasses;
};
- /// TopClassStacks - This is initialized with one TopClass used
- /// for lexing all top classes, until a local class in an inline method is
- /// encountered, at which point a new TopClass is pushed here
- /// and used until the parsing of that local class is finished.
- std::stack<TopClass> TopClassStacks;
+ /// \brief The stack of classes that is currently being
+ /// parsed. Nested and local classes will be pushed onto this stack
+ /// when they are parsed, and removed afterward.
+ std::stack<ParsingClass *> ClassStack;
- TopClass &getCurTopClassStack() {
- assert(!TopClassStacks.empty() && "No lexed method stacks!");
- return TopClassStacks.top();
+ ParsingClass &getCurrentClass() {
+ assert(!ClassStack.empty() && "No lexed method stacks!");
+ return *ClassStack.top();
}
- void PushTopClassStack() {
- TopClassStacks.push(TopClass());
- }
- void PopTopClassStack() { TopClassStacks.pop(); }
+ /// \brief RAII object used to
+ class ParsingClassDefinition {
+ Parser &P;
+ bool Popped;
+
+ public:
+ ParsingClassDefinition(Parser &P, DeclPtrTy TagOrTemplate, bool TopLevelClass)
+ : P(P), Popped(false) {
+ P.PushParsingClass(TagOrTemplate, TopLevelClass);
+ }
+
+ /// \brief Pop this class of the stack.
+ void Pop() {
+ assert(!Popped && "Nested class has already been popped");
+ Popped = true;
+ P.PopParsingClass();
+ }
+
+ ~ParsingClassDefinition() {
+ if (!Popped)
+ P.PopParsingClass();
+ }
+ };
+
+ void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
+ void DeallocateParsedClasses(ParsingClass *Class);
+ void PopParsingClass();
DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D);
- void ParseLexedMethodDeclarations();
- void ParseLexedMethodDefs();
+ void ParseLexedMethodDeclarations(ParsingClass &Class);
+ void ParseLexedMethodDefs(ParsingClass &Class);
bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
CachedTokens &Toks,
tok::TokenKind EarlyAbortIf = tok::unknown,
OpenPOWER on IntegriCloud