// 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_SYMBOLS_LOCATION_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_LOCATION_H_

#include <stdint.h>

#include "src/developer/debug/zxdb/symbols/file_line.h"
#include "src/developer/debug/zxdb/symbols/lazy_symbol.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"

namespace zxdb {

class CodeBlock;
class Function;

// Represents all the symbol information for a code location.
class Location {
 public:
  // A location can be invalid (has no address), can have an address that we haven't tried to
  // symbolize, and a symbolized address. The latter two states allow symbolizing on demand without
  // having additional types.
  //
  // The "symbolized" state doesn't necessarily mean there are symbols, it just means we tried to
  // symbolize it.
  enum class State {
    // There is no address or data for this location.
    kInvalid,

    // There is an address for this location but we haven't tried to symbolize it.
    kAddress,

    // There is an address for the location and we tried to symbolize it. This doesn't mean that
    // symbolization succeeded, so the symbol() and file/line could still be empty.
    kSymbolized,

    // The symbol corresponds to a Variable, but its location has not been computed so it will have
    // a null address.
    //
    // Some global variables actually need to be evaluated asynchronously based on the current CPU
    // state. For example, TLS values are located relative to the CPU register that indicates the
    // TLS base. When resolving a symbolic name, we can encounter these which can't be evaluated in
    // the global context of the symbol system.
    //
    // Currently these aren't handled in most places. But if a caller is in a position to evaluate
    // this it can fill out the address from the symbol.
    kUnlocatedVariable,
  };

  Location();
  Location(State state, uint64_t address);

  // Symbolized location.
  Location(uint64_t address, FileLine file_line, int column, const SymbolContext& symbol_context,
           LazySymbol symbol = LazySymbol());

  // Unlocated variable.
  Location(const SymbolContext& symbol_context, LazySymbol symbol);

  ~Location();

  bool is_valid() const { return state_ != State::kInvalid; }

  // The different between "symbolized" and "has_symbols" is that the former means we tried to
  // symbolize it, and the latter means we actually succeeded to symbolize EITHER the line or the
  // function. One or the other could be missing, however.
  bool is_symbolized() const { return state_ == State::kSymbolized; }
  bool has_symbols() const { return file_line_.is_valid() || symbol_; }

  // The absolute address of this location.
  uint64_t address() const { return address_; }

  const FileLine& file_line() const { return file_line_; }
  int column() const { return column_; }

  // The symbol associated with this address, if any. In the case of code this will most commonly be
  // a Function. It will not be a non-function code block inside the function (code wanting lexical
  // blocks can look inside the function's children as needed). It could also be a variable symbol
  // corresponding to a global or static variable or an ELF symbol.
  //
  // When looking up code locations from the symbol system and the address is non-ambiguous,
  // this will be the most specific (possibly inline) function covering the address in
  // question. For ambiguous inline locations this will either be the most specific inline function
  // or the non-inline function (least-specific) according to ResolveOptions.ambiguous_inline (see
  // that variable for more on ambiguous inline locations).
  //
  // A function can have different scopes inside of it. To get the current lexical scope inside the
  // function, use GetMostSpecificChild() on it.
  //
  // This isn't necessarily valid, even if the State == kSymbolized. It could be the symbol table
  // indicates file/line info for this address but could lack a function record for it.
  const LazySymbol& symbol() const { return symbol_; }

  // Symbolized locations will have a valid symbol context for converting addresses.
  const SymbolContext& symbol_context() const { return symbol_context_; }

  // Offsets the code addresses in this by adding an amount. This is used to convert module-relative
  // addresses to global ones by adding the module load address.
  void AddAddressOffset(uint64_t offset);

  // Returns if this location is the same as the other one, ignoring the symbol() object. Comparing
  // symbol objects is dicy because the same symbol can result in a different object depending on
  // how it is found or whether it was re-queried.
  //
  // This function is primarily used for tests, in which case comparing object pointer equality
  // might be good enough. For non-tests, one might compare symbols by name.
  bool EqualsIgnoringSymbol(const Location& other) const;

  // Returns a string version of the State enum for debugging purposes.
  static const char* StateToString(State state);

  // Returns a description of this Location for debugging purposes.
  std::string GetDebugString() const;

 private:
  State state_ = State::kInvalid;
  uint64_t address_ = 0;
  FileLine file_line_;
  int column_ = 0;
  LazySymbol symbol_;
  SymbolContext symbol_context_ = SymbolContext::ForRelativeAddresses();
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_LOCATION_H_
