aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.h')
-rw-r--r--src/eval.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/eval.h b/src/eval.h
new file mode 100644
index 0000000..e8a95ed
--- /dev/null
+++ b/src/eval.h
@@ -0,0 +1,173 @@
+// Copyright 2015 Google Inc. All rights reserved
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef EVAL_H_
+#define EVAL_H_
+
+#include <memory>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "loc.h"
+#include "stmt.h"
+#include "string_piece.h"
+#include "symtab.h"
+
+using namespace std;
+
+class Makefile;
+class Rule;
+class Var;
+class Vars;
+
+class Evaluator {
+ public:
+ Evaluator();
+ ~Evaluator();
+
+ void EvalAssign(const AssignStmt* stmt);
+ void EvalRule(const RuleStmt* stmt);
+ void EvalCommand(const CommandStmt* stmt);
+ void EvalIf(const IfStmt* stmt);
+ void EvalInclude(const IncludeStmt* stmt);
+ void EvalExport(const ExportStmt* stmt);
+
+ Var* LookupVar(Symbol name);
+ // For target specific variables.
+ Var* LookupVarInCurrentScope(Symbol name);
+
+ // Equivalent to LookupVar, but doesn't mark as used.
+ Var* PeekVar(Symbol name);
+
+ string EvalVar(Symbol name);
+
+ const Loc& loc() const { return loc_; }
+ void set_loc(const Loc& loc) { loc_ = loc; }
+
+ const vector<const Rule*>& rules() const { return rules_; }
+ const unordered_map<Symbol, Vars*>& rule_vars() const { return rule_vars_; }
+ const unordered_map<Symbol, bool>& exports() const { return exports_; }
+
+ void Error(const string& msg);
+
+ void set_is_bootstrap(bool b) { is_bootstrap_ = b; }
+ void set_is_commandline(bool c) { is_commandline_ = c; }
+
+ void set_current_scope(Vars* v) { current_scope_ = v; }
+
+ bool avoid_io() const { return avoid_io_; }
+ void set_avoid_io(bool a) { avoid_io_ = a; }
+
+ const vector<string>& delayed_output_commands() const {
+ return delayed_output_commands_;
+ }
+ void add_delayed_output_command(const string& c) {
+ delayed_output_commands_.push_back(c);
+ }
+ void clear_delayed_output_commands() { delayed_output_commands_.clear(); }
+
+ static const SymbolSet& used_undefined_vars() { return used_undefined_vars_; }
+
+ int eval_depth() const { return eval_depth_; }
+ void IncrementEvalDepth() { eval_depth_++; }
+ void DecrementEvalDepth() { eval_depth_--; }
+
+ string GetShell();
+ string GetShellFlag();
+ string GetShellAndFlag();
+
+ void CheckStack() {
+ void* addr = __builtin_frame_address(0);
+ if (__builtin_expect(addr < lowest_stack_ && addr >= stack_addr_, 0)) {
+ lowest_stack_ = addr;
+ lowest_loc_ = loc_;
+ }
+ }
+ void DumpStackStats() const;
+
+ bool ExportDeprecated() const { return export_message_ && !export_error_; };
+ bool ExportObsolete() const { return export_error_; };
+ void SetExportDeprecated(StringPiece msg) {
+ export_message_.reset(new string(msg.as_string()));
+ }
+ void SetExportObsolete(StringPiece msg) {
+ export_message_.reset(new string(msg.as_string()));
+ export_error_ = true;
+ }
+
+ void ProfileMakefile(StringPiece mk) {
+ profiled_files_.emplace_back(mk.as_string());
+ }
+
+ private:
+ Var* EvalRHS(Symbol lhs,
+ Value* rhs,
+ StringPiece orig_rhs,
+ AssignOp op,
+ bool is_override,
+ bool* needs_assign);
+ void DoInclude(const string& fname);
+
+ Var* LookupVarGlobal(Symbol name);
+
+ // Equivalent to LookupVarInCurrentScope, but doesn't mark as used.
+ Var* PeekVarInCurrentScope(Symbol name);
+
+ void MarkVarsReadonly(Value* var_list);
+
+ void EvalRuleSpecificAssign(const vector<Symbol>& targets,
+ const RuleStmt* stmt,
+ const StringPiece& lhs_string,
+ size_t separator_pos);
+
+ unordered_map<Symbol, Vars*> rule_vars_;
+ vector<const Rule*> rules_;
+ unordered_map<Symbol, bool> exports_;
+
+ Rule* last_rule_;
+ Vars* current_scope_;
+
+ Loc loc_;
+ bool is_bootstrap_;
+ bool is_commandline_;
+
+ std::vector<Loc> include_stack_;
+
+ bool avoid_io_;
+ // This value tracks the nest level of make expressions. For
+ // example, $(YYY) in $(XXX $(YYY)) is evaluated with depth==2.
+ // This will be used to disallow $(shell) in other make constructs.
+ int eval_depth_;
+ // Commands which should run at ninja-time (i.e., info, warning, and
+ // error).
+ vector<string> delayed_output_commands_;
+
+ Symbol posix_sym_;
+ bool is_posix_;
+
+ void* stack_addr_;
+ size_t stack_size_;
+ void* lowest_stack_;
+ Loc lowest_loc_;
+
+ unique_ptr<string> export_message_;
+ bool export_error_;
+
+ vector<string> profiled_files_;
+
+ static SymbolSet used_undefined_vars_;
+};
+
+#endif // EVAL_H_