v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
expression-scope.h
Go to the documentation of this file.
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_PARSING_EXPRESSION_SCOPE_H_
6#define V8_PARSING_EXPRESSION_SCOPE_H_
7
8#include <utility>
9
10#include "src/ast/scopes.h"
13#include "src/parsing/scanner.h"
14#include "src/zone/zone.h" // For ScopedPtrList.
15
16namespace v8 {
17namespace internal {
18
19template <typename Types>
20class ExpressionParsingScope;
21template <typename Types>
22class AccumulationScope;
23template <typename Types>
24class ArrowHeadParsingScope;
25template <typename Types>
26class ParameterDeclarationParsingScope;
27template <typename Types>
28class VariableDeclarationParsingScope;
29class VariableProxy;
30
31// ExpressionScope is used in a stack fashion, and is used to specialize
32// expression parsing for the task at hand. It allows the parser to reuse the
33// same code to parse destructuring declarations, assignment patterns,
34// expressions, and (async) arrow function heads.
35//
36// One of the specific subclasses needs to be instantiated to tell the parser
37// the meaning of the expression it will parse next. The parser then calls
38// Record* on the expression_scope() to indicate errors. The expression_scope
39// will either discard those errors, immediately report those errors, or
40// classify the errors for later validation.
41// TODO(verwaest): Record is a slightly odd name since it will directly throw
42// for unambiguous scopes.
43template <typename Types>
45 public:
48
49 using ParserT = typename Types::Impl;
50 using ExpressionT = typename Types::Expression;
51
53 int pos = kNoSourcePosition) {
54 VariableProxy* result = parser_->NewRawVariable(name, pos);
55 if (CanBeExpression()) {
56 AsExpressionParsingScope()->TrackVariable(result);
57 } else {
58 Variable* var = Declare(name, pos);
59 if (IsVarDeclaration()) {
60 bool passed_through_with = false;
61 for (Scope* scope = parser()->scope(); !scope->is_declaration_scope();
62 scope = scope->outer_scope()) {
63 if (scope->is_with_scope()) {
64 passed_through_with = true;
65 } else if (scope->is_catch_scope()) {
66 Variable* masking_var = scope->LookupLocal(name);
67 // If a variable is declared in a catch scope with a masking
68 // catch-declared variable, the initializing assignment is an
69 // assignment to the catch-declared variable instead.
70 // https://tc39.es/ecma262/#sec-variablestatements-in-catch-blocks
71 if (masking_var != nullptr) {
72 result->set_is_assigned();
73 if (passed_through_with) break;
74 result->BindTo(masking_var);
75 masking_var->SetMaybeAssigned();
76 return result;
77 }
78 }
79 }
80 if (passed_through_with) {
81 // If a variable is declared in a with scope, the initializing
82 // assignment might target a with-declared variable instead.
83 parser()->scope()->AddUnresolved(result);
84 return result;
85 }
86 }
87 DCHECK_NOT_NULL(var);
88 result->BindTo(var);
89 }
90 return result;
91 }
92
94 ScopedList<std::pair<VariableProxy*, int>>* variable_list) {
95 if (!CanBeExpression()) return;
96 // Merged variables come from a CanBeDeclaration expression scope, and
97 // weren't added as unresolved references to the variable scope yet. Add
98 // them to the variable scope on the boundary where it becomes clear they
99 // aren't declarations. We explicitly delay declaring the variables up to
100 // that point to avoid trying to add them to the unresolved list multiple
101 // times, e.g., for (((a))).
102 if (!CanBeDeclaration()) {
103 for (auto& proxy_initializer_pair : *variable_list) {
104 VariableProxy* proxy = proxy_initializer_pair.first;
105 this->parser()->scope()->AddUnresolved(proxy);
106 }
107 }
108 variable_list->MergeInto(AsExpressionParsingScope()->variable_list());
109 }
110
113 return AsParameterDeclarationParsingScope()->Declare(name, pos);
114 }
115 return AsVariableDeclarationParsingScope()->Declare(name, pos);
116 }
117
119 if (!CanBeExpression()) return;
120 AsExpressionParsingScope()->MarkIdentifierAsAssigned();
121 }
122
123 void ValidateAsPattern(ExpressionT expression, int begin, int end) {
124 if (!CanBeExpression()) return;
125 AsExpressionParsingScope()->ValidatePattern(expression, begin, end);
126 AsExpressionParsingScope()->ClearExpressionError();
127 }
128
130 if (!CanBeExpression()) return;
131 AsExpressionParsingScope()->ValidateExpression();
132 AsExpressionParsingScope()->ClearPatternError();
133 }
134
135 // Record async arrow parameters errors in all ambiguous async arrow scopes in
136 // the chain up to the first unambiguous scope.
138 MessageTemplate message) {
139 // Only ambiguous scopes (ExpressionParsingScope, *ArrowHeadParsingScope)
140 // need to propagate errors to a possible kAsyncArrowHeadParsingScope, so
141 // immediately return if the current scope is not ambiguous.
142 if (!CanBeExpression()) return;
143 AsExpressionParsingScope()->RecordAsyncArrowParametersError(loc, message);
144 }
145
146 // Record initializer errors in all scopes that can turn into parameter scopes
147 // (ArrowHeadParsingScopes) up to the first known unambiguous parameter scope.
149 MessageTemplate message) {
150 ExpressionScope* scope = this;
151 while (!scope->IsCertainlyParameterDeclaration()) {
153 if (scope->CanBeParameterDeclaration()) {
154 scope->AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
155 }
156 scope = scope->parent();
157 if (scope == nullptr) return;
158 }
159 Report(loc, message);
160 }
161
163 ExpressionScope* scope = this;
164 do {
165 if (scope->IsArrowHeadParsingScope()) {
166 scope->AsArrowHeadParsingScope()->RecordThisUse();
167 }
168 scope = scope->parent();
169 } while (scope != nullptr);
170 }
171
173 MessageTemplate message) {
174 // TODO(verwaest): Non-assigning expression?
175 if (IsCertainlyPattern()) {
176 Report(loc, message);
177 } else {
178 AsExpressionParsingScope()->RecordPatternError(loc, message);
179 }
180 }
181
183 MessageTemplate message) {
184 DCHECK_IMPLIES(!has_error(), loc.IsValid());
185 if (!CanBeParameterDeclaration()) return;
187 if (is_strict(parser_->language_mode())) {
188 Report(loc, message);
189 } else {
190 parser_->parameters_->set_strict_parameter_error(loc, message);
191 }
192 } else {
193 parser_->next_arrow_function_info_.strict_parameter_error_location = loc;
194 parser_->next_arrow_function_info_.strict_parameter_error_message =
195 message;
196 }
197 }
198
200 MessageTemplate message) {
201 if (!CanBeDeclaration()) return;
203 Report(loc, message);
204 } else {
205 AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
206 }
207 }
208
210 MessageTemplate message) {
211 if (!CanBeExpression()) return;
212 // TODO(verwaest): Non-assigning expression?
213 // if (IsCertainlyExpression()) Report(loc, message);
214 AsExpressionParsingScope()->RecordExpressionError(loc, message);
215 }
216
218 if (!IsArrowHeadParsingScope()) return;
219 AsArrowHeadParsingScope()->RecordNonSimpleParameter();
220 }
221
225
226 int SetInitializers(int variable_index, int peek_position) {
227 if (CanBeExpression()) {
228 return AsExpressionParsingScope()->SetInitializers(variable_index,
229 peek_position);
230 }
231 return variable_index;
232 }
233
237
238 protected:
239 enum ScopeType : uint8_t {
240 // Expression or assignment target.
242
243 // Declaration or expression or assignment target.
246
247 // Declarations.
251 };
252
253 ParserT* parser() const { return parser_; }
254 ExpressionScope* parent() const { return parent_; }
255
256 void Report(const Scanner::Location& loc, MessageTemplate message) const {
257 parser_->ReportMessageAt(loc, message);
258 }
259
273
275 DCHECK(parser_->expression_scope_ == this ||
276 parser_->expression_scope_ == parent_);
277 parser_->expression_scope_ = parent_;
278 }
279
284
285#ifdef DEBUG
286 bool has_error() const { return parser_->has_error(); }
287#endif
288
304 bool IsVarDeclaration() const { return type_ == kVarDeclaration; }
305
306 private:
307 friend class AccumulationScope<Types>;
308 friend class ExpressionParsingScope<Types>;
309
314
320
325
342
348};
349
350// Used to unambiguously parse var, let, const declarations.
351template <typename Types>
353 public:
354 using ParserT = typename Types::Impl;
357
365
367 delete;
369 const VariableDeclarationParsingScope&) = delete;
370
371 Variable* Declare(const AstRawString* name, int pos) {
373 bool was_added;
374 Variable* var = this->parser()->DeclareVariable(
375 name, kind, mode_, Variable::DefaultInitializationFlag(mode_),
376 this->parser()->scope(), &was_added, pos);
377 if (was_added &&
378 this->parser()->scope()->num_var() > kMaxNumFunctionLocals) {
379 this->parser()->ReportMessage(MessageTemplate::kTooManyVariables);
380 }
381 if (names_) names_->Add(name, this->parser()->zone());
382 if (this->IsLexicalDeclaration()) {
383 if (this->parser()->IsLet(name)) {
384 this->parser()->ReportMessageAt(
385 Scanner::Location(pos, pos + name->length()),
386 MessageTemplate::kLetInLexicalBinding);
387 }
388 } else {
389 if (this->parser()->loop_nesting_depth() > 0) {
390 // Due to hoisting, the value of a 'var'-declared variable may actually
391 // change even if the code contains only the "initial" assignment,
392 // namely when that assignment occurs inside a loop. For example:
393 //
394 // let i = 10;
395 // do { var x = i } while (i--):
396 //
397 // Note that non-lexical variables include temporaries, which may also
398 // get assigned inside a loop due to the various rewritings that the
399 // parser performs.
400 //
401 // Pessimistically mark all vars in loops as assigned. This
402 // overapproximates the actual assigned vars due to unassigned var
403 // without initializer, but that's unlikely anyway.
404 //
405 // This also handles marking of loop variables in for-in and for-of
406 // loops, as determined by loop-nesting-depth.
407 DCHECK_NOT_NULL(var);
408 var->SetMaybeAssigned();
409 }
410 }
411 return var;
412 }
413
414 private:
415 // Limit the allowed number of local variables in a function. The hard limit
416 // in Ignition is 2^31-1 due to the size of register operands. We limit it to
417 // a more reasonable lower up-limit.
418 static const int kMaxNumFunctionLocals = (1 << 23) - 1;
419
422};
423
424template <typename Types>
426 public:
427 using ParserT = typename Types::Impl;
430
433
435 delete;
437 const ParameterDeclarationParsingScope&) = delete;
438
439 Variable* Declare(const AstRawString* name, int pos) {
442 bool was_added;
443 Variable* var = this->parser()->DeclareVariable(
444 name, kind, mode, Variable::DefaultInitializationFlag(mode),
445 this->parser()->scope(), &was_added, pos);
446 if (!has_duplicate() && !was_added) {
447 duplicate_loc_ = Scanner::Location(pos, pos + name->length());
448 }
449 return var;
450 }
451
452 bool has_duplicate() const { return duplicate_loc_.IsValid(); }
453
455
456 private:
458};
459
460// Parsing expressions is always ambiguous between at least left-hand-side and
461// right-hand-side of assignments. This class is used to keep track of errors
462// relevant for either side until it is clear what was being parsed.
463// The class also keeps track of all variable proxies that are created while the
464// scope was active. If the scope is an expression, the variable proxies will be
465// added to the unresolved list. Otherwise they are declarations and aren't
466// added. The list is also used to mark the variables as assigned in case we are
467// parsing an assignment expression.
468template <typename Types>
470 public:
471 using ParserT = typename Types::Impl;
472 using ExpressionT = typename Types::Expression;
475
490
493
495 MessageTemplate message) {
496 for (ExpressionScopeT* scope = this; scope != nullptr;
497 scope = scope->parent()) {
499 if (scope->type_ ==
501 scope->AsArrowHeadParsingScope()->RecordDeclarationError(loc, message);
502 }
503 }
504 }
505
506 ~ExpressionParsingScope() { DCHECK(this->has_error() || verified_); }
507
509 int end_pos) {
510 if (V8_LIKELY(this->parser()->IsAssignableIdentifier(expression))) {
512 this->mark_verified();
513 return expression;
514 } else if (V8_LIKELY(expression->IsProperty())) {
516 return expression;
517 }
518 this->mark_verified();
519 const bool early_error = false;
520 return this->parser()->RewriteInvalidReferenceExpression(
521 expression, beg_pos, end_pos, MessageTemplate::kInvalidLhsInFor,
522 early_error);
523 }
524
526 MessageTemplate message) {
527 Record(kExpressionIndex, loc, message);
528 }
529
531 MessageTemplate message) {
532 Record(kPatternIndex, loc, message);
533 }
534
536
537 void ValidatePattern(ExpressionT expression, int begin, int end) {
539 if (expression->is_parenthesized()) {
541 MessageTemplate::kInvalidDestructuringTarget);
542 }
543 for (auto& variable_initializer_pair : variable_list_) {
544 variable_initializer_pair.first->set_is_assigned();
545 }
546 }
547
549 DCHECK(verified_);
550#ifdef DEBUG
551 verified_ = false;
552#endif
554 }
555
557 DCHECK(verified_);
558#ifdef DEBUG
559 verified_ = false;
560#endif
562 }
563
564 void TrackVariable(VariableProxy* variable) {
565 if (!this->CanBeDeclaration()) {
566 this->parser()->scope()->AddUnresolved(variable);
567 }
568 variable_list_.Add({variable, kNoSourcePosition});
569 }
570
572 // It's possible we're parsing a syntax error. In that case it's not
573 // guaranteed that there's a variable in the list.
574 if (variable_list_.length() == 0) return;
575 variable_list_.at(variable_list_.length() - 1).first->set_is_assigned();
576 }
577
578 int SetInitializers(int first_variable_index, int position) {
579 int len = variable_list_.length();
580 if (len == 0) return 0;
581
582 int end = len - 1;
583 // Loop backwards and abort as soon as we see one that's already set to
584 // avoid a loop on expressions like a,b,c,d,e,f,g (outside of an arrowhead).
585 // TODO(delphick): Look into removing this loop.
586 for (int i = end; i >= first_variable_index &&
588 --i) {
589 variable_list_.at(i).second = position;
590 }
591 return end;
592 }
593
597
598 protected:
599 bool is_verified() const {
600#ifdef DEBUG
601 return verified_;
602#else
603 return false;
604#endif
605 }
606
608
609 private:
610 friend class AccumulationScope<Types>;
611
617 void clear(int index) {
618 messages_[index] = MessageTemplate::kNone;
620 }
621 bool is_valid(int index) const { return !locations_[index].IsValid(); }
622 void Record(int index, const Scanner::Location& loc,
623 MessageTemplate message) {
624 DCHECK_IMPLIES(!this->has_error(), loc.IsValid());
625 if (!is_valid(index)) return;
626 messages_[index] = message;
627 locations_[index] = loc;
628 }
629 void Validate(int index) {
630 DCHECK(!this->is_verified());
631 if (!is_valid(index)) Report(index);
632 this->mark_verified();
633 }
634 void Report(int index) const {
636 }
637
638 // Debug verification to make sure every scope is validated exactly once.
640#ifdef DEBUG
641 verified_ = true;
642#endif
643 }
645#ifdef DEBUG
646 verified_ = false;
647#endif
648 }
649#ifdef DEBUG
650 bool verified_ = false;
651#endif
652
657};
658
659// This class is used to parse multiple ambiguous expressions and declarations
660// in the same scope. E.g., in async(X,Y,Z) or [X,Y,Z], X and Y and Z will all
661// be parsed in the respective outer ArrowHeadParsingScope and
662// ExpressionParsingScope. It provides a clean error state in the underlying
663// scope to parse the individual expressions, while keeping track of the
664// expression and pattern errors since the start. The AccumulationScope is only
665// used to keep track of the errors so far, and the underlying ExpressionScope
666// keeps being used as the expression_scope(). If the expression_scope() isn't
667// ambiguous, this class does not do anything.
668template <typename Types>
670 public:
671 using ParserT = typename Types::Impl;
672
673 static const int kNumberOfErrors =
675 explicit AccumulationScope(ExpressionScope<Types>* scope) : scope_(nullptr) {
676 if (!scope->CanBeExpression()) return;
678 for (int i = 0; i < kNumberOfErrors; i++) {
679 copy(i);
680 scope_->clear(i);
681 }
682 }
683
686
687 // Merge errors from the underlying ExpressionParsingScope into this scope.
688 // Only keeps the first error across all accumulate calls, and removes the
689 // error from the underlying scope.
690 void Accumulate() {
691 if (scope_ == nullptr) return;
692 DCHECK(!scope_->is_verified());
693 for (int i = 0; i < kNumberOfErrors; i++) {
694 if (!locations_[i].IsValid()) copy(i);
695 scope_->clear(i);
696 }
697 }
698
699 // This is called instead of Accumulate in case the parsed member is already
700 // known to be an expression. In that case we don't need to accumulate the
701 // expression but rather validate it immediately. We also ignore the pattern
702 // error since the parsed member is known to not be a pattern. This is
703 // necessary for "{x:1}.y" parsed as part of an assignment pattern. {x:1} will
704 // record a pattern error, but "{x:1}.y" is actually a valid as part of an
705 // assignment pattern since it's a property access.
707 if (scope_ == nullptr) return;
708 DCHECK(!scope_->is_verified());
709 scope_->ValidateExpression();
710 DCHECK(scope_->is_verified());
712#ifdef DEBUG
713 scope_->clear_verified();
714#endif
715 }
716
718 if (scope_ == nullptr) return;
719 Accumulate();
720 for (int i = 0; i < kNumberOfErrors; i++) copy_back(i);
721 }
722
723 private:
724 void copy(int entry) {
725 messages_[entry] = scope_->messages_[entry];
726 locations_[entry] = scope_->locations_[entry];
727 }
728
729 void copy_back(int entry) {
730 if (!locations_[entry].IsValid()) return;
731 scope_->messages_[entry] = messages_[entry];
732 scope_->locations_[entry] = locations_[entry];
733 }
734
738};
739
740// The head of an arrow function is ambiguous between expression, assignment
741// pattern and declaration. This keeps track of the additional declaration
742// error and allows the scope to be validated as a declaration rather than an
743// expression or a pattern.
744template <typename Types>
746 public:
747 using ParserT = typename Types::Impl;
749
752 : ExpressionParsingScope<Types>(
753 parser,
760 DCHECK(this->CanBeDeclaration());
762 // clear last next_arrow_function_info tracked strict parameters error.
763 parser->next_arrow_function_info_.ClearStrictParameterError();
764 }
765
768
770 // Turns out this is not an arrow head. Clear any possible tracked strict
771 // parameter errors, and reinterpret tracked variables as unresolved
772 // references.
773 this->parser()->next_arrow_function_info_.ClearStrictParameterError();
775 this->parent()->MergeVariableList(this->variable_list());
776 }
777
779 DCHECK(!this->is_verified());
780 DeclarationScope* result = this->parser()->NewFunctionScope(kind());
784 return result;
785 }
786 this->ValidatePattern();
787
790 VariableMode mode =
792 for (auto& proxy_initializer_pair : *this->variable_list()) {
793 VariableProxy* proxy = proxy_initializer_pair.first;
794 int initializer_position = proxy_initializer_pair.second;
795 // Default values for parameters will have been parsed as assignments so
796 // clear the is_assigned bit as they are not actually assignments.
797 proxy->clear_is_assigned();
798 bool was_added;
799 this->parser()->DeclareAndBindVariable(proxy, kind, mode, result,
800 &was_added, initializer_position);
801 if (!was_added) {
803 MessageTemplate::kParamDupe);
804 }
805 }
806
807#ifdef DEBUG
808 if (!this->has_error()) {
809 for (auto declaration : *result->declarations()) {
810 DCHECK_NE(declaration->var()->initializer_position(),
812 }
813 }
814#endif // DEBUG
815
816 if (uses_this_) result->UsesThis();
817 return result;
818 }
819
821 MessageTemplate message) {
822 DCHECK_IMPLIES(!this->has_error(), loc.IsValid());
825 }
826
828 void RecordThisUse() { uses_this_ = true; }
830
831 private:
837
842 bool uses_this_ = false;
843};
844
845} // namespace internal
846} // namespace v8
847
848#endif // V8_PARSING_EXPRESSION_SCOPE_H_
Builtins::Kind kind
Definition builtins.cc:40
SourcePosition pos
AccumulationScope(ExpressionScope< Types > *scope)
ExpressionParsingScope< Types > * scope_
AccumulationScope(const AccumulationScope &)=delete
AccumulationScope & operator=(const AccumulationScope &)=delete
DeclarationScope * ValidateAndCreateScope()
ArrowHeadParsingScope(const ArrowHeadParsingScope &)=delete
ArrowHeadParsingScope(ParserT *parser, FunctionKind kind, int function_literal_id)
ArrowHeadParsingScope & operator=(const ArrowHeadParsingScope &)=delete
void RecordDeclarationError(const Scanner::Location &loc, MessageTemplate message)
typename ExpressionScope< Types >::ScopeType ScopeType
MessageTemplate messages_[kNumberOfErrors]
void Record(int index, const Scanner::Location &loc, MessageTemplate message)
ScopedList< std::pair< VariableProxy *, int > > variable_list_
void RecordExpressionError(const Scanner::Location &loc, MessageTemplate message)
typename Types::Expression ExpressionT
ExpressionParsingScope(const ExpressionParsingScope &)=delete
Scanner::Location locations_[kNumberOfErrors]
int SetInitializers(int first_variable_index, int position)
ExpressionT ValidateAndRewriteReference(ExpressionT expression, int beg_pos, int end_pos)
void TrackVariable(VariableProxy *variable)
typename ExpressionScopeT::ScopeType ScopeType
void RecordAsyncArrowParametersError(const Scanner::Location &loc, MessageTemplate message)
ScopedList< std::pair< VariableProxy *, int > > * variable_list()
ExpressionParsingScope & operator=(const ExpressionParsingScope &)=delete
void RecordPatternError(const Scanner::Location &loc, MessageTemplate message)
void ValidatePattern(ExpressionT expression, int begin, int end)
ExpressionParsingScope(ParserT *parser, ScopeType type=ExpressionScopeT::kExpression)
ArrowHeadParsingScope< Types > * AsArrowHeadParsingScope()
void RecordStrictModeParameterError(const Scanner::Location &loc, MessageTemplate message)
Variable * Declare(const AstRawString *name, int pos=kNoSourcePosition)
void Report(const Scanner::Location &loc, MessageTemplate message) const
void RecordDeclarationError(const Scanner::Location &loc, MessageTemplate message)
void RecordExpressionError(const Scanner::Location &loc, MessageTemplate message)
void MergeVariableList(ScopedList< std::pair< VariableProxy *, int > > *variable_list)
ParameterDeclarationParsingScope< Types > * AsParameterDeclarationParsingScope()
ExpressionParsingScope< Types > * AsExpressionParsingScope()
ExpressionScope & operator=(const ExpressionScope &)=delete
int SetInitializers(int variable_index, int peek_position)
ExpressionScope(ParserT *parser, ScopeType type)
typename Types::Expression ExpressionT
ExpressionScope(const ExpressionScope &)=delete
ExpressionScope * parent() const
void RecordParameterInitializerError(const Scanner::Location &loc, MessageTemplate message)
void RecordAsyncArrowParametersError(const Scanner::Location &loc, MessageTemplate message)
VariableDeclarationParsingScope< Types > * AsVariableDeclarationParsingScope()
void RecordPatternError(const Scanner::Location &loc, MessageTemplate message)
void ValidateAsPattern(ExpressionT expression, int begin, int end)
VariableProxy * NewVariable(const AstRawString *name, int pos=kNoSourcePosition)
bool has_possible_arrow_parameter_in_scope_chain() const
ExpressionScope< Types > * parent_
Variable * Declare(const AstRawString *name, int pos)
typename ExpressionScopeT::ScopeType ScopeType
const Scanner::Location & duplicate_location() const
ParameterDeclarationParsingScope(const ParameterDeclarationParsingScope &)=delete
ParameterDeclarationParsingScope & operator=(const ParameterDeclarationParsingScope &)=delete
bool is_declaration_scope() const
Definition scopes.h:372
VariableDeclarationParsingScope(const VariableDeclarationParsingScope &)=delete
typename ExpressionScopeT::ScopeType ScopeType
ZonePtrList< const AstRawString > * names_
VariableDeclarationParsingScope & operator=(const VariableDeclarationParsingScope &)=delete
Variable * Declare(const AstRawString *name, int pos)
VariableDeclarationParsingScope(ParserT *parser, VariableMode mode, ZonePtrList< const AstRawString > *names)
Scanner::Location location()
Definition ast.h:1527
int end
double second
ZoneVector< RpoNumber > & result
int position
Definition liveedit.cc:290
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
Definition bounds.h:20
constexpr int kNoSourcePosition
Definition globals.h:850
bool IsLexicalVariableMode(VariableMode mode)
Definition globals.h:2155
@ PARAMETER_VARIABLE
Definition globals.h:2110
bool is_strict(LanguageMode language_mode)
Definition globals.h:777
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
static Location invalid()
Definition scanner.h:270
Symbol declaration
Symbol * expression
#define V8_LIKELY(condition)
Definition v8config.h:661