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 unordered_set<Symbol>& used_undefined_vars() { 82 return used_undefined_vars_; 83 } 84 eval_depth()85 int eval_depth() const { return eval_depth_; } IncrementEvalDepth()86 void IncrementEvalDepth() { eval_depth_++; } DecrementEvalDepth()87 void DecrementEvalDepth() { eval_depth_--; } 88 89 string GetShell(); 90 string GetShellFlag(); 91 string GetShellAndFlag(); 92 CheckStack()93 void CheckStack() { 94 void* addr = __builtin_frame_address(0); 95 if (__builtin_expect(addr < lowest_stack_ && addr >= stack_addr_, 0)) { 96 lowest_stack_ = addr; 97 lowest_loc_ = loc_; 98 } 99 } 100 void DumpStackStats() const; 101 ExportDeprecated()102 bool ExportDeprecated() const { return export_message_ && !export_error_; }; ExportObsolete()103 bool ExportObsolete() const { return export_error_; }; SetExportDeprecated(StringPiece msg)104 void SetExportDeprecated(StringPiece msg) { 105 export_message_.reset(new string(msg.as_string())); 106 } SetExportObsolete(StringPiece msg)107 void SetExportObsolete(StringPiece msg) { 108 export_message_.reset(new string(msg.as_string())); 109 export_error_ = true; 110 } 111 112 private: 113 Var* EvalRHS(Symbol lhs, 114 Value* rhs, 115 StringPiece orig_rhs, 116 AssignOp op, 117 bool is_override = false); 118 void DoInclude(const string& fname); 119 120 Var* LookupVarGlobal(Symbol name); 121 122 // Equivalent to LookupVarInCurrentScope, but doesn't mark as used. 123 Var* PeekVarInCurrentScope(Symbol name); 124 125 unordered_map<Symbol, Vars*> rule_vars_; 126 vector<const Rule*> rules_; 127 unordered_map<Symbol, bool> exports_; 128 129 Rule* last_rule_; 130 Vars* current_scope_; 131 132 Loc loc_; 133 bool is_bootstrap_; 134 bool is_commandline_; 135 136 bool avoid_io_; 137 // This value tracks the nest level of make expressions. For 138 // example, $(YYY) in $(XXX $(YYY)) is evaluated with depth==2. 139 // This will be used to disallow $(shell) in other make constructs. 140 int eval_depth_; 141 // Commands which should run at ninja-time (i.e., info, warning, and 142 // error). 143 vector<string> delayed_output_commands_; 144 145 Symbol posix_sym_; 146 bool is_posix_; 147 148 void* stack_addr_; 149 size_t stack_size_; 150 void* lowest_stack_; 151 Loc lowest_loc_; 152 153 unique_ptr<string> export_message_; 154 bool export_error_; 155 156 static unordered_set<Symbol> used_undefined_vars_; 157 158 Symbol kati_readonly_; 159 }; 160 161 #endif // EVAL_H_ 162