blob: dddcdaa5bc8f312733df3a73be9eba0d849d2318 [file] [log] [blame]
// 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. This won't necessarily be a collection,
// it could be a "const pointer to a const collection" or some other complex type.
//
// 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_