| // Copyright 2018 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_ | |
| #define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_ | |
| #include "src/developer/debug/zxdb/expr/found_member.h" | |
| #include "src/developer/debug/zxdb/expr/parsed_identifier.h" | |
| #include "src/developer/debug/zxdb/symbols/function.h" | |
| #include "src/developer/debug/zxdb/symbols/variable.h" | |
| namespace zxdb { | |
| // This class represents the result of looking up a variable by name. It could be a local or global | |
| // variable (simple Variable* object), or it could be a member of the current implicit object | |
| // ("this" in C++). This class represents either state. | |
| class FoundName { | |
| public: | |
| // Since identifiers with template parameters at the end are assumed to be a type, we don't need | |
| // to check that "std::vector<int>" is a type. This will need to be revisited if we support | |
| // templatized function names in expressions ("auto a = &MyClass::MyFunc<int>;"); | |
| enum Kind { | |
| kNone, // Nothing with this name found. | |
| kVariable, // Local and global variables. | |
| kMemberVariable, // Class and struct member vars that require an object. | |
| kNamespace, // Namespace name like "std". | |
| kTemplate, // Template name without parameters like "std::vector". | |
| kType, // Full type name like "std::string" or "int". | |
| kFunction, // Normal DWARF functions, including inlines. | |
| kOtherSymbol, // Any other symbol, including ELF symbols. | |
| }; | |
| // Default constructor for a "not found" name. | |
| FoundName(); | |
| // Constructor for templates and namespaces that have no extra data. | |
| FoundName(Kind kind, ParsedIdentifier name); | |
| // Takes a reference to the object. | |
| explicit FoundName(const Variable* variable); | |
| explicit FoundName(const Function* function); | |
| // Takes a reference to the object. This will forward to variable/function if the Symbol is of | |
| // that type, otherwise it will be an "other symbol". | |
| explicit FoundName(const Symbol* symbol); | |
| // Constructor for data member variables. The object_ptr may be null if this represents a query on | |
| // a type with no corresponding variable). | |
| FoundName(const Variable* object_ptr, FoundMember member); | |
| FoundName(const Variable* object_ptr, InheritancePath path, const DataMember* data_member); | |
| // Constructor for types. | |
| explicit FoundName(fxl::RefPtr<Type> type); | |
| ~FoundName(); | |
| Kind kind() const { return kind_; } | |
| // Implicit conversion to bool to test for a found value. | |
| bool is_found() const { return kind_ != kNone; } | |
| operator bool() const { return kind_ != kNone; } | |
| // Abstracts away the kind and returns the full name of the match. | |
| ParsedIdentifier GetName() const; | |
| // Use when kind == kVariable and kMemberVariable. The variable may be null for member pointers if | |
| // the call is just looking up the | |
| const Variable* variable() const { return variable_.get(); } | |
| fxl::RefPtr<Variable> variable_ref() { return variable_; } | |
| // Used when kind == kMemberVariable. The object_ptr() will be valid if there's a variable | |
| // associated with the member, and will be null otherwise. | |
| // | |
| // See FoundMember for how to resolve the value as there are some subtleties. | |
| const Variable* object_ptr() const { return object_ptr_.get(); } | |
| fxl::RefPtr<Variable> object_ptr_ref() const { return object_ptr_; } | |
| const FoundMember& member() const { return member_; } | |
| // Valid when kind == kType. | |
| fxl::RefPtr<Type>& type() { return type_; } | |
| const fxl::RefPtr<Type>& type() const { return type_; } | |
| // Valid when kind == kFunction. | |
| fxl::RefPtr<Function>& function() { return function_; } | |
| const fxl::RefPtr<Function>& function() const { return function_; } | |
| // Valid when kind == kOtherSymbol. | |
| fxl::RefPtr<Symbol>& other_symbol() { return other_symbol_; } | |
| const fxl::RefPtr<Symbol>& other_symbol() const { return other_symbol_; } | |
| private: | |
| Kind kind_ = kNone; | |
| // Represents the found variable when it's not a class member. When null, the result will be in | |
| // object_member/data_member. | |
| fxl::RefPtr<Variable> variable_; | |
| // Represents the "this" object the data member is associated with it. Non-null when the found | |
| // variable is a collection member. In this case, data_member and data_member_offset will be | |
| // valid. | |
| // | |
| // This is the outermost object which one would evaluate to get the value of the object pointer | |
| // rather than the class the data member is declared in (it could be a base class). | |
| fxl::RefPtr<Variable> object_ptr_; | |
| // Valid when object_ptr_ is non-null. This indicates the location of the data inside the object. | |
| FoundMember member_; | |
| fxl::RefPtr<Type> type_; | |
| fxl::RefPtr<Function> function_; | |
| fxl::RefPtr<Symbol> other_symbol_; | |
| // Valid only when there's no object to hold the intrinsic name. This is for templates and | |
| // namespaces. | |
| ParsedIdentifier name_; | |
| }; | |
| } // namespace zxdb | |
| #endif // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_ |