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 VAR_H_ 16 #define VAR_H_ 17 18 #include <string> 19 #include <unordered_map> 20 #include <unordered_set> 21 22 #include "expr.h" 23 #include "stmt.h" 24 #include "string_piece.h" 25 #include "symtab.h" 26 27 using namespace std; 28 29 class Evaluator; 30 class Value; 31 32 enum struct VarOrigin { 33 UNDEFINED, 34 DEFAULT, 35 ENVIRONMENT, 36 ENVIRONMENT_OVERRIDE, 37 FILE, 38 COMMAND_LINE, 39 OVERRIDE, 40 AUTOMATIC, 41 }; 42 43 const char* GetOriginStr(VarOrigin origin); 44 45 class Var : public Evaluable { 46 public: 47 virtual ~Var(); 48 49 virtual const char* Flavor() const = 0; 50 virtual VarOrigin Origin() const = 0; 51 virtual bool IsDefined() const { return true; } 52 53 virtual void AppendVar(Evaluator* ev, Value* v); 54 55 virtual StringPiece String() const = 0; 56 57 virtual string DebugString() const = 0; 58 59 protected: 60 Var(); 61 }; 62 63 class SimpleVar : public Var { 64 public: 65 explicit SimpleVar(VarOrigin origin); 66 SimpleVar(const string& v, VarOrigin origin); 67 68 virtual const char* Flavor() const override { 69 return "simple"; 70 } 71 virtual VarOrigin Origin() const override { 72 return origin_; 73 } 74 75 virtual void Eval(Evaluator* ev, string* s) const override; 76 77 virtual void AppendVar(Evaluator* ev, Value* v) override; 78 79 virtual StringPiece String() const override; 80 81 virtual string DebugString() const override; 82 83 string* mutable_value() { return &v_; } 84 85 private: 86 string v_; 87 VarOrigin origin_; 88 }; 89 90 class RecursiveVar : public Var { 91 public: 92 RecursiveVar(Value* v, VarOrigin origin, StringPiece orig); 93 94 virtual const char* Flavor() const override { 95 return "recursive"; 96 } 97 virtual VarOrigin Origin() const override { 98 return origin_; 99 } 100 101 virtual void Eval(Evaluator* ev, string* s) const override; 102 103 virtual void AppendVar(Evaluator* ev, Value* v) override; 104 105 virtual StringPiece String() const override; 106 107 virtual string DebugString() const override; 108 109 private: 110 Value* v_; 111 VarOrigin origin_; 112 StringPiece orig_; 113 }; 114 115 class UndefinedVar : public Var { 116 public: 117 UndefinedVar(); 118 119 virtual const char* Flavor() const override { 120 return "undefined"; 121 } 122 virtual VarOrigin Origin() const override { 123 return VarOrigin::UNDEFINED; 124 } 125 virtual bool IsDefined() const override { return false; } 126 127 virtual void Eval(Evaluator* ev, string* s) const override; 128 129 virtual StringPiece String() const override; 130 131 virtual string DebugString() const override; 132 }; 133 134 extern UndefinedVar* kUndefined; 135 136 class RuleVar : public Var { 137 public: 138 RuleVar(Var* v, AssignOp op) 139 : v_(v), op_(op) {} 140 virtual ~RuleVar() { 141 delete v_; 142 } 143 144 virtual const char* Flavor() const override { 145 return v_->Flavor(); 146 } 147 virtual VarOrigin Origin() const override { 148 return v_->Origin(); 149 } 150 virtual bool IsDefined() const override { 151 return v_->IsDefined(); 152 } 153 virtual void Eval(Evaluator* ev, string* s) const override { 154 v_->Eval(ev, s); 155 } 156 virtual void AppendVar(Evaluator* ev, Value* v) override { 157 v_->AppendVar(ev, v); 158 } 159 virtual StringPiece String() const override { 160 return v_->String(); 161 } 162 virtual string DebugString() const override { 163 return v_->DebugString(); 164 } 165 166 Var* v() const { return v_; } 167 AssignOp op() const { return op_; } 168 169 private: 170 Var* v_; 171 AssignOp op_; 172 }; 173 174 class Vars : public unordered_map<Symbol, Var*> { 175 public: 176 ~Vars(); 177 178 Var* Lookup(Symbol name) const; 179 180 void Assign(Symbol name, Var* v); 181 182 static void add_used_env_vars(Symbol v); 183 184 static const unordered_set<Symbol>& used_env_vars() { 185 return used_env_vars_; 186 } 187 188 private: 189 static unordered_set<Symbol> used_env_vars_; 190 }; 191 192 class ScopedVar { 193 public: 194 // Does not take ownerships of arguments. 195 ScopedVar(Vars* vars, Symbol name, Var* var); 196 ~ScopedVar(); 197 198 private: 199 Vars* vars_; 200 Var* orig_; 201 Vars::iterator iter_; 202 }; 203 204 #endif // VAR_H_ 205