• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 Google Inc. All rights reserved
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef EVAL_H_
16 #define EVAL_H_
17 
18 #include <memory>
19 #include <unordered_map>
20 #include <unordered_set>
21 #include <vector>
22 
23 #include "loc.h"
24 #include "stmt.h"
25 #include "string_piece.h"
26 #include "symtab.h"
27 
28 using namespace std;
29 
30 class Makefile;
31 class Rule;
32 class Var;
33 class Vars;
34 
35 class Evaluator {
36  public:
37   Evaluator();
38   ~Evaluator();
39 
40   void EvalAssign(const AssignStmt* stmt);
41   void EvalRule(const RuleStmt* stmt);
42   void EvalCommand(const CommandStmt* stmt);
43   void EvalIf(const IfStmt* stmt);
44   void EvalInclude(const IncludeStmt* stmt);
45   void EvalExport(const ExportStmt* stmt);
46 
47   Var* LookupVar(Symbol name);
48   // For target specific variables.
49   Var* LookupVarInCurrentScope(Symbol name);
50 
51   // Equivalent to LookupVar, but doesn't mark as used.
52   Var* PeekVar(Symbol name);
53 
54   string EvalVar(Symbol name);
55 
loc()56   const Loc& loc() const { return loc_; }
set_loc(const Loc & loc)57   void set_loc(const Loc& loc) { loc_ = loc; }
58 
rules()59   const vector<const Rule*>& rules() const { return rules_; }
rule_vars()60   const unordered_map<Symbol, Vars*>& rule_vars() const { return rule_vars_; }
exports()61   const unordered_map<Symbol, bool>& exports() const { return exports_; }
62 
63   void Error(const string& msg);
64 
set_is_bootstrap(bool b)65   void set_is_bootstrap(bool b) { is_bootstrap_ = b; }
set_is_commandline(bool c)66   void set_is_commandline(bool c) { is_commandline_ = c; }
67 
set_current_scope(Vars * v)68   void set_current_scope(Vars* v) { current_scope_ = v; }
69 
avoid_io()70   bool avoid_io() const { return avoid_io_; }
set_avoid_io(bool a)71   void set_avoid_io(bool a) { avoid_io_ = a; }
72 
delayed_output_commands()73   const vector<string>& delayed_output_commands() const {
74     return delayed_output_commands_;
75   }
add_delayed_output_command(const string & c)76   void add_delayed_output_command(const string& c) {
77     delayed_output_commands_.push_back(c);
78   }
clear_delayed_output_commands()79   void clear_delayed_output_commands() { delayed_output_commands_.clear(); }
80 
used_undefined_vars()81   static const SymbolSet& used_undefined_vars() { return used_undefined_vars_; }
82 
eval_depth()83   int eval_depth() const { return eval_depth_; }
IncrementEvalDepth()84   void IncrementEvalDepth() { eval_depth_++; }
DecrementEvalDepth()85   void DecrementEvalDepth() { eval_depth_--; }
86 
87   string GetShell();
88   string GetShellFlag();
89   string GetShellAndFlag();
90 
CheckStack()91   void CheckStack() {
92     void* addr = __builtin_frame_address(0);
93     if (__builtin_expect(addr < lowest_stack_ && addr >= stack_addr_, 0)) {
94       lowest_stack_ = addr;
95       lowest_loc_ = loc_;
96     }
97   }
98   void DumpStackStats() const;
99 
ExportDeprecated()100   bool ExportDeprecated() const { return export_message_ && !export_error_; };
ExportObsolete()101   bool ExportObsolete() const { return export_error_; };
SetExportDeprecated(StringPiece msg)102   void SetExportDeprecated(StringPiece msg) {
103     export_message_.reset(new string(msg.as_string()));
104   }
SetExportObsolete(StringPiece msg)105   void SetExportObsolete(StringPiece msg) {
106     export_message_.reset(new string(msg.as_string()));
107     export_error_ = true;
108   }
109 
110  private:
111   Var* EvalRHS(Symbol lhs,
112                Value* rhs,
113                StringPiece orig_rhs,
114                AssignOp op,
115                bool is_override,
116                bool* needs_assign);
117   void DoInclude(const string& fname);
118 
119   Var* LookupVarGlobal(Symbol name);
120 
121   // Equivalent to LookupVarInCurrentScope, but doesn't mark as used.
122   Var* PeekVarInCurrentScope(Symbol name);
123 
124   void MarkVarsReadonly(Value* var_list);
125 
126   void EvalRuleSpecificAssign(const vector<Symbol>& targets,
127                               const RuleStmt* stmt,
128                               const StringPiece& lhs_string,
129                               size_t separator_pos);
130 
131   unordered_map<Symbol, Vars*> rule_vars_;
132   vector<const Rule*> rules_;
133   unordered_map<Symbol, bool> exports_;
134 
135   Rule* last_rule_;
136   Vars* current_scope_;
137 
138   Loc loc_;
139   bool is_bootstrap_;
140   bool is_commandline_;
141 
142   bool avoid_io_;
143   // This value tracks the nest level of make expressions. For
144   // example, $(YYY) in $(XXX $(YYY)) is evaluated with depth==2.
145   // This will be used to disallow $(shell) in other make constructs.
146   int eval_depth_;
147   // Commands which should run at ninja-time (i.e., info, warning, and
148   // error).
149   vector<string> delayed_output_commands_;
150 
151   Symbol posix_sym_;
152   bool is_posix_;
153 
154   void* stack_addr_;
155   size_t stack_size_;
156   void* lowest_stack_;
157   Loc lowest_loc_;
158 
159   unique_ptr<string> export_message_;
160   bool export_error_;
161 
162   static SymbolSet used_undefined_vars_;
163 };
164 
165 #endif  // EVAL_H_
166