Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(470)

Side by Side Diff: src/parsing/parser.cc

Issue 1566053002: Clean up FunctionLiteral AST node cruft (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/ast.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-visitor.h" 9 #include "src/ast/ast-expression-visitor.h"
10 #include "src/ast/ast-literal-reindexer.h" 10 #include "src/ast/ast-literal-reindexer.h"
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 CallRuntime* call = factory()->NewCallRuntime( 385 CallRuntime* call = factory()->NewCallRuntime(
386 Context::REFLECT_CONSTRUCT_INDEX, args, pos); 386 Context::REFLECT_CONSTRUCT_INDEX, args, pos);
387 body->Add(factory()->NewReturnStatement(call, pos), zone()); 387 body->Add(factory()->NewReturnStatement(call, pos), zone());
388 } 388 }
389 389
390 materialized_literal_count = function_state.materialized_literal_count(); 390 materialized_literal_count = function_state.materialized_literal_count();
391 expected_property_count = function_state.expected_property_count(); 391 expected_property_count = function_state.expected_property_count();
392 } 392 }
393 393
394 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 394 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
395 name, ast_value_factory(), function_scope, body, 395 name, function_scope, body, materialized_literal_count,
396 materialized_literal_count, expected_property_count, parameter_count, 396 expected_property_count, parameter_count,
397 FunctionLiteral::kNoDuplicateParameters, 397 FunctionLiteral::kNoDuplicateParameters,
398 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, 398 FunctionLiteral::kAnonymousExpression,
399 FunctionLiteral::kShouldLazyCompile, kind, pos); 399 FunctionLiteral::kShouldLazyCompile, kind, pos);
400 400
401 return function_literal; 401 return function_literal;
402 } 402 }
403 403
404 404
405 // ---------------------------------------------------------------------------- 405 // ----------------------------------------------------------------------------
406 // Target is a support class to facilitate manipulation of the 406 // Target is a support class to facilitate manipulation of the
407 // Parser's target_stack_ (the stack of potential 'break' and 407 // Parser's target_stack_ (the stack of potential 'break' and
408 // 'continue' statement targets). Upon construction, a new target is 408 // 'continue' statement targets). Upon construction, a new target is
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 !body->at(0)->AsExpressionStatement()-> 1096 !body->at(0)->AsExpressionStatement()->
1097 expression()->IsFunctionLiteral()) { 1097 expression()->IsFunctionLiteral()) {
1098 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 1098 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1099 ok = false; 1099 ok = false;
1100 } 1100 }
1101 } 1101 }
1102 1102
1103 if (ok) { 1103 if (ok) {
1104 ParserTraits::RewriteDestructuringAssignments(); 1104 ParserTraits::RewriteDestructuringAssignments();
1105 result = factory()->NewFunctionLiteral( 1105 result = factory()->NewFunctionLiteral(
1106 ast_value_factory()->empty_string(), ast_value_factory(), scope_, 1106 ast_value_factory()->empty_string(), scope_, body,
1107 body, function_state.materialized_literal_count(), 1107 function_state.materialized_literal_count(),
1108 function_state.expected_property_count(), 0, 1108 function_state.expected_property_count(), 0,
1109 FunctionLiteral::kNoDuplicateParameters, 1109 FunctionLiteral::kNoDuplicateParameters,
1110 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, 1110 FunctionLiteral::kGlobalOrEval, FunctionLiteral::kShouldLazyCompile,
1111 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, 1111 FunctionKind::kNormalFunction, 0);
1112 0);
1113 } 1112 }
1114 } 1113 }
1115 1114
1116 // Make sure the target stack is empty. 1115 // Make sure the target stack is empty.
1117 DCHECK(target_stack_ == NULL); 1116 DCHECK(target_stack_ == NULL);
1118 1117
1119 return result; 1118 return result;
1120 } 1119 }
1121 1120
1122 1121
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 scope = Scope::DeserializeScopeChain(isolate, zone(), 1187 scope = Scope::DeserializeScopeChain(isolate, zone(),
1189 info->closure()->context(), scope); 1188 info->closure()->context(), scope);
1190 } 1189 }
1191 original_scope_ = scope; 1190 original_scope_ = scope;
1192 AstNodeFactory function_factory(ast_value_factory()); 1191 AstNodeFactory function_factory(ast_value_factory());
1193 FunctionState function_state(&function_state_, &scope_, scope, 1192 FunctionState function_state(&function_state_, &scope_, scope,
1194 shared_info->kind(), &function_factory); 1193 shared_info->kind(), &function_factory);
1195 DCHECK(is_sloppy(scope->language_mode()) || 1194 DCHECK(is_sloppy(scope->language_mode()) ||
1196 is_strict(info->language_mode())); 1195 is_strict(info->language_mode()));
1197 DCHECK(info->language_mode() == shared_info->language_mode()); 1196 DCHECK(info->language_mode() == shared_info->language_mode());
1198 FunctionLiteral::FunctionType function_type = shared_info->is_expression() 1197 FunctionLiteral::FunctionType function_type =
1199 ? (shared_info->is_anonymous() 1198 shared_info->is_expression()
1200 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1199 ? (shared_info->is_anonymous()
1201 : FunctionLiteral::NAMED_EXPRESSION) 1200 ? FunctionLiteral::kAnonymousExpression
1202 : FunctionLiteral::DECLARATION; 1201 : FunctionLiteral::kNamedExpression)
1202 : FunctionLiteral::kDeclaration;
1203 bool ok = true; 1203 bool ok = true;
1204 1204
1205 if (shared_info->is_arrow()) { 1205 if (shared_info->is_arrow()) {
1206 Scope* scope = 1206 Scope* scope =
1207 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); 1207 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1208 SetLanguageMode(scope, shared_info->language_mode()); 1208 SetLanguageMode(scope, shared_info->language_mode());
1209 scope->set_start_position(shared_info->start_position()); 1209 scope->set_start_position(shared_info->start_position());
1210 ExpressionClassifier formals_classifier; 1210 ExpressionClassifier formals_classifier;
1211 ParserFormalParameters formals(scope); 1211 ParserFormalParameters formals(scope);
1212 Checkpoint checkpoint(this); 1212 Checkpoint checkpoint(this);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 } 1254 }
1255 } else if (shared_info->is_default_constructor()) { 1255 } else if (shared_info->is_default_constructor()) {
1256 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), 1256 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()),
1257 scope, shared_info->start_position(), 1257 scope, shared_info->start_position(),
1258 shared_info->end_position(), 1258 shared_info->end_position(),
1259 shared_info->language_mode()); 1259 shared_info->language_mode());
1260 } else { 1260 } else {
1261 result = ParseFunctionLiteral( 1261 result = ParseFunctionLiteral(
1262 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, 1262 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck,
1263 shared_info->kind(), RelocInfo::kNoPosition, function_type, 1263 shared_info->kind(), RelocInfo::kNoPosition, function_type,
1264 FunctionLiteral::NORMAL_ARITY, shared_info->language_mode(), &ok); 1264 FunctionLiteral::kNormalArity, shared_info->language_mode(), &ok);
1265 } 1265 }
1266 // Make sure the results agree. 1266 // Make sure the results agree.
1267 DCHECK(ok == (result != NULL)); 1267 DCHECK(ok == (result != NULL));
1268 } 1268 }
1269 1269
1270 // Make sure the target stack is empty. 1270 // Make sure the target stack is empty.
1271 DCHECK(target_stack_ == NULL); 1271 DCHECK(target_stack_ == NULL);
1272 1272
1273 if (result != NULL) { 1273 if (result != NULL) {
1274 Handle<String> inferred_name(shared_info->inferred_name()); 1274 Handle<String> inferred_name(shared_info->inferred_name());
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 &is_strict_reserved, CHECK_OK); 2259 &is_strict_reserved, CHECK_OK);
2260 2260
2261 FuncNameInferrer::State fni_state(fni_); 2261 FuncNameInferrer::State fni_state(fni_);
2262 if (fni_ != NULL) fni_->PushEnclosingName(name); 2262 if (fni_ != NULL) fni_->PushEnclosingName(name);
2263 FunctionLiteral* fun = ParseFunctionLiteral( 2263 FunctionLiteral* fun = ParseFunctionLiteral(
2264 name, scanner()->location(), 2264 name, scanner()->location(),
2265 is_strict_reserved ? kFunctionNameIsStrictReserved 2265 is_strict_reserved ? kFunctionNameIsStrictReserved
2266 : kFunctionNameValidityUnknown, 2266 : kFunctionNameValidityUnknown,
2267 is_generator ? FunctionKind::kGeneratorFunction 2267 is_generator ? FunctionKind::kGeneratorFunction
2268 : FunctionKind::kNormalFunction, 2268 : FunctionKind::kNormalFunction,
2269 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY, 2269 pos, FunctionLiteral::kDeclaration, FunctionLiteral::kNormalArity,
2270 language_mode(), CHECK_OK); 2270 language_mode(), CHECK_OK);
2271 2271
2272 // Even if we're not at the top-level of the global or a function 2272 // Even if we're not at the top-level of the global or a function
2273 // scope, we treat it as such and introduce the function with its 2273 // scope, we treat it as such and introduce the function with its
2274 // initial value upon entering the corresponding scope. 2274 // initial value upon entering the corresponding scope.
2275 // In ES6, a function behaves as a lexical binding, except in 2275 // In ES6, a function behaves as a lexical binding, except in
2276 // a script scope, or the initial scope of eval or another function. 2276 // a script scope, or the initial scope of eval or another function.
2277 VariableMode mode = 2277 VariableMode mode =
2278 is_strong(language_mode()) 2278 is_strong(language_mode())
2279 ? CONST 2279 ? CONST
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
4258 // - (1) is the case iff the innermost scope of the deserialized scope chain 4258 // - (1) is the case iff the innermost scope of the deserialized scope chain
4259 // under which we compile is _not_ a declaration scope. This holds because 4259 // under which we compile is _not_ a declaration scope. This holds because
4260 // in all normal cases, function declarations are fully hoisted to a 4260 // in all normal cases, function declarations are fully hoisted to a
4261 // declaration scope and compiled relative to that. 4261 // declaration scope and compiled relative to that.
4262 // - (2) is the case iff the current declaration scope is still the original 4262 // - (2) is the case iff the current declaration scope is still the original
4263 // one relative to the deserialized scope chain. Otherwise we must be 4263 // one relative to the deserialized scope chain. Otherwise we must be
4264 // compiling a function in an inner declaration scope in the eval, e.g. a 4264 // compiling a function in an inner declaration scope in the eval, e.g. a
4265 // nested function, and hoisting works normally relative to that. 4265 // nested function, and hoisting works normally relative to that.
4266 Scope* declaration_scope = scope_->DeclarationScope(); 4266 Scope* declaration_scope = scope_->DeclarationScope();
4267 Scope* original_declaration_scope = original_scope_->DeclarationScope(); 4267 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4268 Scope* scope = function_type == FunctionLiteral::DECLARATION && 4268 Scope* scope = function_type == FunctionLiteral::kDeclaration &&
4269 is_sloppy(language_mode) && 4269 is_sloppy(language_mode) &&
4270 !allow_harmony_sloppy_function() && 4270 !allow_harmony_sloppy_function() &&
4271 (original_scope_ == original_declaration_scope || 4271 (original_scope_ == original_declaration_scope ||
4272 declaration_scope != original_declaration_scope) 4272 declaration_scope != original_declaration_scope)
4273 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) 4273 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
4274 : NewScope(scope_, FUNCTION_SCOPE, kind); 4274 : NewScope(scope_, FUNCTION_SCOPE, kind);
4275 SetLanguageMode(scope, language_mode); 4275 SetLanguageMode(scope, language_mode);
4276 ZoneList<Statement*>* body = NULL; 4276 ZoneList<Statement*>* body = NULL;
4277 int arity = -1; 4277 int arity = -1;
4278 int materialized_literal_count = -1; 4278 int materialized_literal_count = -1;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
4392 // eagerly compiled. 4392 // eagerly compiled.
4393 // - The invoker of this parser can't depend on the AST being eagerly 4393 // - The invoker of this parser can't depend on the AST being eagerly
4394 // built (either because the function is about to be compiled, or 4394 // built (either because the function is about to be compiled, or
4395 // because the AST is going to be inspected for some reason). 4395 // because the AST is going to be inspected for some reason).
4396 // - Because of the above, we can't be attempting to parse a 4396 // - Because of the above, we can't be attempting to parse a
4397 // FunctionExpression; even without enclosing parentheses it might be 4397 // FunctionExpression; even without enclosing parentheses it might be
4398 // immediately invoked. 4398 // immediately invoked.
4399 // - The function literal shouldn't be hinted to eagerly compile. 4399 // - The function literal shouldn't be hinted to eagerly compile.
4400 bool use_temp_zone = 4400 bool use_temp_zone =
4401 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() && 4401 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
4402 function_type == FunctionLiteral::DECLARATION && 4402 function_type == FunctionLiteral::kDeclaration &&
4403 eager_compile_hint != FunctionLiteral::kShouldEagerCompile; 4403 eager_compile_hint != FunctionLiteral::kShouldEagerCompile;
4404 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the 4404 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the
4405 // new temporary zone if the preconditions are satisfied, and ensures that 4405 // new temporary zone if the preconditions are satisfied, and ensures that
4406 // the previous zone is always restored after parsing the body. 4406 // the previous zone is always restored after parsing the body.
4407 // For the purpose of scope analysis, some ZoneObjects allocated by the 4407 // For the purpose of scope analysis, some ZoneObjects allocated by the
4408 // factory must persist after the function body is thrown away and 4408 // factory must persist after the function body is thrown away and
4409 // temp_zone is deallocated. These objects are instead allocated in a 4409 // temp_zone is deallocated. These objects are instead allocated in a
4410 // parser-persistent zone (see parser_zone_ in AstNodeFactory). 4410 // parser-persistent zone (see parser_zone_ in AstNodeFactory).
4411 { 4411 {
4412 Zone temp_zone; 4412 Zone temp_zone;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4464 } 4464 }
4465 } 4465 }
4466 4466
4467 bool has_duplicate_parameters = 4467 bool has_duplicate_parameters =
4468 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); 4468 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4469 FunctionLiteral::ParameterFlag duplicate_parameters = 4469 FunctionLiteral::ParameterFlag duplicate_parameters =
4470 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 4470 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4471 : FunctionLiteral::kNoDuplicateParameters; 4471 : FunctionLiteral::kNoDuplicateParameters;
4472 4472
4473 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4473 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4474 function_name, ast_value_factory(), scope, body, 4474 function_name, scope, body, materialized_literal_count,
4475 materialized_literal_count, expected_property_count, arity, 4475 expected_property_count, arity, duplicate_parameters, function_type,
4476 duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
4477 eager_compile_hint, kind, pos); 4476 eager_compile_hint, kind, pos);
4478 function_literal->set_function_token_position(function_token_pos); 4477 function_literal->set_function_token_position(function_token_pos);
4479 if (should_be_used_once_hint) 4478 if (should_be_used_once_hint)
4480 function_literal->set_should_be_used_once_hint(); 4479 function_literal->set_should_be_used_once_hint();
4481 4480
4482 if (scope->has_rest_parameter()) { 4481 if (scope->has_rest_parameter()) {
4483 function_literal->set_dont_optimize_reason(kRestParameter); 4482 function_literal->set_dont_optimize_reason(kRestParameter);
4484 } 4483 }
4485 4484
4486 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4485 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4706 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4705 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4707 const AstRawString* function_name, int pos, 4706 const AstRawString* function_name, int pos,
4708 const ParserFormalParameters& parameters, FunctionKind kind, 4707 const ParserFormalParameters& parameters, FunctionKind kind,
4709 FunctionLiteral::FunctionType function_type, bool* ok) { 4708 FunctionLiteral::FunctionType function_type, bool* ok) {
4710 // Everything inside an eagerly parsed function will be parsed eagerly 4709 // Everything inside an eagerly parsed function will be parsed eagerly
4711 // (see comment above). 4710 // (see comment above).
4712 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4711 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4713 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4712 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4714 4713
4715 static const int kFunctionNameAssignmentIndex = 0; 4714 static const int kFunctionNameAssignmentIndex = 0;
4716 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 4715 if (function_type == FunctionLiteral::kNamedExpression) {
4717 DCHECK(function_name != NULL); 4716 DCHECK(function_name != NULL);
4718 // If we have a named function expression, we add a local variable 4717 // If we have a named function expression, we add a local variable
4719 // declaration to the body of the function with the name of the 4718 // declaration to the body of the function with the name of the
4720 // function and let it refer to the function itself (closure). 4719 // function and let it refer to the function itself (closure).
4721 // Not having parsed the function body, the language mode may still change, 4720 // Not having parsed the function body, the language mode may still change,
4722 // so we reserve a spot and create the actual const assignment later. 4721 // so we reserve a spot and create the actual const assignment later.
4723 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); 4722 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4724 result->Add(NULL, zone()); 4723 result->Add(NULL, zone());
4725 } 4724 }
4726 4725
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4793 inner_scope = inner_scope->FinalizeBlockScope(); 4792 inner_scope = inner_scope->FinalizeBlockScope();
4794 if (inner_scope != nullptr) { 4793 if (inner_scope != nullptr) {
4795 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); 4794 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4796 InsertShadowingVarBindingInitializers(inner_block); 4795 InsertShadowingVarBindingInitializers(inner_block);
4797 } 4796 }
4798 4797
4799 result->Add(init_block, zone()); 4798 result->Add(init_block, zone());
4800 result->Add(inner_block, zone()); 4799 result->Add(inner_block, zone());
4801 } 4800 }
4802 4801
4803 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 4802 if (function_type == FunctionLiteral::kNamedExpression) {
4804 // Now that we know the language mode, we can create the const assignment 4803 // Now that we know the language mode, we can create the const assignment
4805 // in the previously reserved spot. 4804 // in the previously reserved spot.
4806 // NOTE: We create a proxy and resolve it here so that in the 4805 // NOTE: We create a proxy and resolve it here so that in the
4807 // future we can change the AST to only refer to VariableProxies 4806 // future we can change the AST to only refer to VariableProxies
4808 // instead of Variables and Proxies as is the case now. 4807 // instead of Variables and Proxies as is the case now.
4809 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY; 4808 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY;
4810 Variable* fvar = new (zone()) 4809 Variable* fvar = new (zone())
4811 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, 4810 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4812 kCreatedInitialized, kNotAssigned); 4811 kCreatedInitialized, kNotAssigned);
4813 VariableProxy* proxy = factory()->NewVariableProxy(fvar); 4812 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
6560 auto class_literal = value->AsClassLiteral(); 6559 auto class_literal = value->AsClassLiteral();
6561 if (class_literal->raw_name() == nullptr) { 6560 if (class_literal->raw_name() == nullptr) {
6562 class_literal->set_raw_name(name); 6561 class_literal->set_raw_name(name);
6563 } 6562 }
6564 } 6563 }
6565 } 6564 }
6566 6565
6567 6566
6568 } // namespace internal 6567 } // namespace internal
6569 } // namespace v8 6568 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698