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