Home | History | Annotate | Download | only in kati
      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 
     56   const Loc& loc() const { return loc_; }
     57   void set_loc(const Loc& loc) { loc_ = loc; }
     58 
     59   const vector<const Rule*>& rules() const { return rules_; }
     60   const unordered_map<Symbol, Vars*>& rule_vars() const { return rule_vars_; }
     61   const unordered_map<Symbol, bool>& exports() const { return exports_; }
     62 
     63   void Error(const string& msg);
     64 
     65   void set_is_bootstrap(bool b) { is_bootstrap_ = b; }
     66   void set_is_commandline(bool c) { is_commandline_ = c; }
     67 
     68   void set_current_scope(Vars* v) { current_scope_ = v; }
     69 
     70   bool avoid_io() const { return avoid_io_; }
     71   void set_avoid_io(bool a) { avoid_io_ = a; }
     72 
     73   const vector<string>& delayed_output_commands() const {
     74     return delayed_output_commands_;
     75   }
     76   void add_delayed_output_command(const string& c) {
     77     delayed_output_commands_.push_back(c);
     78   }
     79   void clear_delayed_output_commands() { delayed_output_commands_.clear(); }
     80 
     81   static const SymbolSet& used_undefined_vars() { return used_undefined_vars_; }
     82 
     83   int eval_depth() const { return eval_depth_; }
     84   void IncrementEvalDepth() { eval_depth_++; }
     85   void DecrementEvalDepth() { eval_depth_--; }
     86 
     87   string GetShell();
     88   string GetShellFlag();
     89   string GetShellAndFlag();
     90 
     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 
    100   bool ExportDeprecated() const { return export_message_ && !export_error_; };
    101   bool ExportObsolete() const { return export_error_; };
    102   void SetExportDeprecated(StringPiece msg) {
    103     export_message_.reset(new string(msg.as_string()));
    104   }
    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