// 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 VAR_H_ #define VAR_H_ #include #include #include #include #include "eval.h" #include "expr.h" #include "log.h" #include "stmt.h" #include "string_piece.h" #include "symtab.h" using namespace std; class Evaluator; class Value; enum struct VarOrigin : char { UNDEFINED, DEFAULT, ENVIRONMENT, ENVIRONMENT_OVERRIDE, FILE, COMMAND_LINE, OVERRIDE, AUTOMATIC, }; const char* GetOriginStr(VarOrigin origin); class Var : public Evaluable { public: virtual ~Var(); virtual const char* Flavor() const = 0; VarOrigin Origin() { return origin_; } virtual bool IsDefined() const { return true; } virtual void AppendVar(Evaluator* ev, Value* v); virtual StringPiece String() const = 0; virtual string DebugString() const = 0; bool ReadOnly() const { return readonly_; } void SetReadOnly() { readonly_ = true; } bool Deprecated() const { return deprecated_; } void SetDeprecated(const StringPiece& msg); bool Obsolete() const { return obsolete_; } void SetObsolete(const StringPiece& msg); const string& DeprecatedMessage() const; // This variable was used (either written or read from) void Used(Evaluator* ev, const Symbol& sym) const; AssignOp op() const { return assign_op_; } void SetAssignOp(AssignOp op) { assign_op_ = op; } static Var *Undefined(); protected: Var(); explicit Var(VarOrigin origin); private: const VarOrigin origin_; AssignOp assign_op_; bool readonly_:1; bool deprecated_:1; bool obsolete_:1; const char *diagnostic_message_text() const; static unordered_map diagnostic_messages_; }; class SimpleVar : public Var { public: explicit SimpleVar(VarOrigin origin); SimpleVar(const string& v, VarOrigin origin); SimpleVar(VarOrigin, Evaluator* ev, Value* v); virtual const char* Flavor() const override { return "simple"; } virtual void Eval(Evaluator* ev, string* s) const override; virtual void AppendVar(Evaluator* ev, Value* v) override; virtual StringPiece String() const override; virtual string DebugString() const override; private: string v_; }; class RecursiveVar : public Var { public: RecursiveVar(Value* v, VarOrigin origin, StringPiece orig); virtual const char* Flavor() const override { return "recursive"; } virtual void Eval(Evaluator* ev, string* s) const override; virtual void AppendVar(Evaluator* ev, Value* v) override; virtual StringPiece String() const override; virtual string DebugString() const override; private: Value* v_; StringPiece orig_; }; class UndefinedVar : public Var { public: UndefinedVar(); virtual const char* Flavor() const override { return "undefined"; } virtual bool IsDefined() const override { return false; } virtual void Eval(Evaluator* ev, string* s) const override; virtual StringPiece String() const override; virtual string DebugString() const override; }; class Vars : public unordered_map { public: ~Vars(); Var* Lookup(Symbol name) const; Var* Peek(Symbol name) const; void Assign(Symbol name, Var* v, bool* readonly); static void add_used_env_vars(Symbol v); static const SymbolSet used_env_vars() { return used_env_vars_; } private: static SymbolSet used_env_vars_; }; class ScopedVar { public: // Does not take ownerships of arguments. ScopedVar(Vars* vars, Symbol name, Var* var); ~ScopedVar(); private: Vars* vars_; Var* orig_; Vars::iterator iter_; }; #endif // VAR_H_