ParseCXXInlineMethods.cpp (193326) | ParseCXXInlineMethods.cpp (198092) |
---|---|
1//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 7 unchanged lines hidden (view full) --- 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Parse/Scope.h" 18using namespace clang; 19 20/// ParseCXXInlineMethodDef - We parsed and verified that the specified 21/// Declarator is a well formed C++ inline method definition. Now lex its body 22/// and store its tokens for parsing after the C++ class is complete. 23Parser::DeclPtrTy | 1//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 7 unchanged lines hidden (view full) --- 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Parse/Scope.h" 18using namespace clang; 19 20/// ParseCXXInlineMethodDef - We parsed and verified that the specified 21/// Declarator is a well formed C++ inline method definition. Now lex its body 22/// and store its tokens for parsing after the C++ class is complete. 23Parser::DeclPtrTy |
24Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) { | 24Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, 25 const ParsedTemplateInfo &TemplateInfo) { |
25 assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && 26 "This isn't a function declarator!"); 27 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && 28 "Current token not a '{', ':' or 'try'!"); 29 | 26 assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && 27 "This isn't a function declarator!"); 28 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && 29 "Current token not a '{', ':' or 'try'!"); 30 |
30 DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0); | 31 Action::MultiTemplateParamsArg TemplateParams(Actions, 32 TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 33 TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 34 DeclPtrTy FnD; 35 if (D.getDeclSpec().isFriendSpecified()) 36 // FIXME: Friend templates 37 FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true, move(TemplateParams)); 38 else // FIXME: pass template information through 39 FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 40 move(TemplateParams), 0, 0); |
31 | 41 |
42 HandleMemberFunctionDefaultArgs(D, FnD); 43 |
|
32 // Consume the tokens and store them for later parsing. 33 34 getCurrentClass().MethodDefs.push_back(LexedMethod(FnD)); | 44 // Consume the tokens and store them for later parsing. 45 46 getCurrentClass().MethodDefs.push_back(LexedMethod(FnD)); |
47 getCurrentClass().MethodDefs.back().TemplateScope 48 = CurScope->isTemplateParamScope(); |
|
35 CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks; 36 37 tok::TokenKind kind = Tok.getKind(); 38 // We may have a constructor initializer or function-try-block here. 39 if (kind == tok::colon || kind == tok::kw_try) { 40 // Consume everything up to (and including) the left brace. 41 if (!ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks, tok::semi)) { 42 // We didn't find the left-brace we expected after the | 49 CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks; 50 51 tok::TokenKind kind = Tok.getKind(); 52 // We may have a constructor initializer or function-try-block here. 53 if (kind == tok::colon || kind == tok::kw_try) { 54 // Consume everything up to (and including) the left brace. 55 if (!ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks, tok::semi)) { 56 // We didn't find the left-brace we expected after the |
43 // constructor initializer. | 57 // constructor initializer. |
44 if (Tok.is(tok::semi)) { 45 // We found a semicolon; complain, consume the semicolon, and 46 // don't try to parse this method later. 47 Diag(Tok.getLocation(), diag::err_expected_lbrace); 48 ConsumeAnyToken(); 49 getCurrentClass().MethodDefs.pop_back(); 50 return FnD; 51 } 52 } 53 54 } else { | 58 if (Tok.is(tok::semi)) { 59 // We found a semicolon; complain, consume the semicolon, and 60 // don't try to parse this method later. 61 Diag(Tok.getLocation(), diag::err_expected_lbrace); 62 ConsumeAnyToken(); 63 getCurrentClass().MethodDefs.pop_back(); 64 return FnD; 65 } 66 } 67 68 } else { |
55 // Begin by storing the '{' token. | 69 // Begin by storing the '{' token. |
56 Toks.push_back(Tok); 57 ConsumeBrace(); 58 } 59 // Consume everything up to (and including) the matching right brace. 60 ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); 61 62 // If we're in a function-try-block, we need to store all the catch blocks. 63 if (kind == tok::kw_try) { --- 17 unchanged lines hidden (view full) --- 81 Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate); 82 83 bool HasClassScope = !Class.TopLevelClass; 84 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 85 HasClassScope); 86 87 for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) { 88 LateParsedMethodDeclaration &LM = Class.MethodDecls.front(); | 70 Toks.push_back(Tok); 71 ConsumeBrace(); 72 } 73 // Consume everything up to (and including) the matching right brace. 74 ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); 75 76 // If we're in a function-try-block, we need to store all the catch blocks. 77 if (kind == tok::kw_try) { --- 17 unchanged lines hidden (view full) --- 95 Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate); 96 97 bool HasClassScope = !Class.TopLevelClass; 98 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 99 HasClassScope); 100 101 for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) { 102 LateParsedMethodDeclaration &LM = Class.MethodDecls.front(); |
89 90 // FIXME: For member function templates, we'll need to introduce a 91 // scope for the template parameters. | |
92 | 103 |
104 // If this is a member template, introduce the template parameter scope. 105 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 106 if (LM.TemplateScope) 107 Actions.ActOnReenterTemplateScope(CurScope, LM.Method); 108 |
|
93 // Start the delayed C++ method declaration 94 Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method); 95 96 // Introduce the parameters into scope and parse their default 97 // arguments. | 109 // Start the delayed C++ method declaration 110 Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method); 111 112 // Introduce the parameters into scope and parse their default 113 // arguments. |
98 ParseScope PrototypeScope(this, | 114 ParseScope PrototypeScope(this, |
99 Scope::FunctionPrototypeScope|Scope::DeclScope); 100 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 101 // Introduce the parameter into scope. 102 Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param); 103 104 if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { 105 // Parse the default argument from its saved token stream. 106 Toks->push_back(Tok); // So that the current token doesn't get lost --- 37 unchanged lines hidden (view full) --- 144 145 bool HasClassScope = !Class.TopLevelClass; 146 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 147 HasClassScope); 148 149 for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) { 150 LexedMethod &LM = Class.MethodDefs.front(); 151 | 115 Scope::FunctionPrototypeScope|Scope::DeclScope); 116 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 117 // Introduce the parameter into scope. 118 Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param); 119 120 if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { 121 // Parse the default argument from its saved token stream. 122 Toks->push_back(Tok); // So that the current token doesn't get lost --- 37 unchanged lines hidden (view full) --- 160 161 bool HasClassScope = !Class.TopLevelClass; 162 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 163 HasClassScope); 164 165 for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) { 166 LexedMethod &LM = Class.MethodDefs.front(); 167 |
168 // If this is a member template, introduce the template parameter scope. 169 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 170 if (LM.TemplateScope) 171 Actions.ActOnReenterTemplateScope(CurScope, LM.D); 172 |
|
152 assert(!LM.Toks.empty() && "Empty body!"); 153 // Append the current token at the end of the new token stream so that it 154 // doesn't get lost. 155 LM.Toks.push_back(Tok); | 173 assert(!LM.Toks.empty() && "Empty body!"); 174 // Append the current token at the end of the new token stream so that it 175 // doesn't get lost. 176 LM.Toks.push_back(Tok); |
156 PP.EnterTokenStream(&LM.Toks.front(), LM.Toks.size(), true, false); | 177 PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); |
157 158 // Consume the previously pushed token. 159 ConsumeAnyToken(); 160 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) 161 && "Inline method not starting with '{', ':' or 'try'"); 162 163 // Parse the method body. Function body parsing code is similar enough 164 // to be re-used for method bodies as well. 165 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); 166 Actions.ActOnStartOfFunctionDef(CurScope, LM.D); 167 168 if (Tok.is(tok::kw_try)) { 169 ParseFunctionTryBlock(LM.D); 170 continue; 171 } 172 if (Tok.is(tok::colon)) 173 ParseConstructorInitializer(LM.D); | 178 179 // Consume the previously pushed token. 180 ConsumeAnyToken(); 181 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) 182 && "Inline method not starting with '{', ':' or 'try'"); 183 184 // Parse the method body. Function body parsing code is similar enough 185 // to be re-used for method bodies as well. 186 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); 187 Actions.ActOnStartOfFunctionDef(CurScope, LM.D); 188 189 if (Tok.is(tok::kw_try)) { 190 ParseFunctionTryBlock(LM.D); 191 continue; 192 } 193 if (Tok.is(tok::colon)) 194 ParseConstructorInitializer(LM.D); |
195 else 196 Actions.ActOnDefaultCtorInitializers(LM.D); 197 |
|
174 // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? 175 ParseFunctionStatementBody(LM.D); 176 } 177 178 for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I) 179 ParseLexedMethodDefs(*Class.NestedClasses[I]); 180} 181 182/// ConsumeAndStoreUntil - Consume and store the token at the passed token 183/// container until the token 'T' is reached (which gets | 198 // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? 199 ParseFunctionStatementBody(LM.D); 200 } 201 202 for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I) 203 ParseLexedMethodDefs(*Class.NestedClasses[I]); 204} 205 206/// ConsumeAndStoreUntil - Consume and store the token at the passed token 207/// container until the token 'T' is reached (which gets |
184/// consumed/stored too, if ConsumeFinalToken). | 208/// consumed/stored too, if ConsumeFinalToken). |
185/// If EarlyAbortIf is specified, then we will stop early if we find that 186/// token at the top level. 187/// Returns true if token 'T1' or 'T2' was found. 188/// NOTE: This is a specialized version of Parser::SkipUntil. 189bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 190 CachedTokens &Toks, 191 tok::TokenKind EarlyAbortIf, 192 bool ConsumeFinalToken) { --- 79 unchanged lines hidden --- | 209/// If EarlyAbortIf is specified, then we will stop early if we find that 210/// token at the top level. 211/// Returns true if token 'T1' or 'T2' was found. 212/// NOTE: This is a specialized version of Parser::SkipUntil. 213bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 214 CachedTokens &Toks, 215 tok::TokenKind EarlyAbortIf, 216 bool ConsumeFinalToken) { --- 79 unchanged lines hidden --- |