blob: 94edd83be336b5ca15dc824544452e675586a9c8 [file] [log] [blame]
//===-- LVLocation.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the LVOperation and LVLocation classes, which are used
// to describe variable locations.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
#include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
namespace llvm {
namespace logicalview {
using LVLineRange = std::pair<LVLine *, LVLine *>;
// The DW_AT_data_member_location attribute is a simple member offset.
const LVSmall LVLocationMemberOffset = 0;
class LVOperation final {
// To describe an operation:
// OpCode
// Operands[0]: First operand.
// Operands[1]: Second operand.
// OP_bregx, OP_bit_piece, OP_[GNU_]const_type,
// OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value,
// OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type.
LVSmall Opcode = 0;
uint64_t Operands[2];
public:
LVOperation() = delete;
LVOperation(LVSmall Opcode, LVUnsigned Operand1, LVUnsigned Operand2)
: Opcode(Opcode) {
Operands[0] = Operand1;
Operands[1] = Operand2;
}
LVOperation(const LVOperation &) = delete;
LVOperation &operator=(const LVOperation &) = delete;
~LVOperation() = default;
LVSmall getOpcode() const { return Opcode; }
uint64_t getOperand1() const { return Operands[0]; }
uint64_t getOperand2() const { return Operands[1]; }
std::string getOperandsDWARFInfo();
std::string getOperandsCodeViewInfo();
void print(raw_ostream &OS, bool Full = true) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() { print(dbgs()); }
#endif
};
class LVLocation : public LVObject {
enum class Property {
IsAddressRange,
IsBaseClassOffset,
IsBaseClassStep,
IsClassOffset,
IsFixedAddress,
IsLocationSimple,
IsGapEntry,
IsOperation,
IsOperationList,
IsRegister,
IsStackOffset,
IsDiscardedRange,
IsInvalidRange,
IsInvalidLower,
IsInvalidUpper,
IsCallSite,
LastEntry
};
// Typed bitvector with properties for this location.
LVProperties<Property> Properties;
// True if the location it is associated with a debug range.
bool hasAssociatedRange() const {
return !getIsClassOffset() && !getIsDiscardedRange();
}
protected:
// Line numbers associated with locations ranges.
LVLine *LowerLine = nullptr;
LVLine *UpperLine = nullptr;
// Active range:
// LowPC: an offset from an applicable base address, not a PC value.
// HighPC: an offset from an applicable base address, or a length.
LVAddress LowPC = 0;
LVAddress HighPC = 0;
void setKind();
public:
LVLocation() : LVObject() { setIsLocation(); }
LVLocation(const LVLocation &) = delete;
LVLocation &operator=(const LVLocation &) = delete;
virtual ~LVLocation() = default;
PROPERTY(Property, IsAddressRange);
PROPERTY(Property, IsBaseClassOffset);
PROPERTY(Property, IsBaseClassStep);
PROPERTY_1(Property, IsClassOffset, IsLocationSimple);
PROPERTY_1(Property, IsFixedAddress, IsLocationSimple);
PROPERTY(Property, IsLocationSimple);
PROPERTY(Property, IsGapEntry);
PROPERTY(Property, IsOperationList);
PROPERTY(Property, IsOperation);
PROPERTY(Property, IsRegister);
PROPERTY_1(Property, IsStackOffset, IsLocationSimple);
PROPERTY(Property, IsDiscardedRange);
PROPERTY(Property, IsInvalidRange);
PROPERTY(Property, IsInvalidLower);
PROPERTY(Property, IsInvalidUpper);
PROPERTY(Property, IsCallSite);
const char *kind() const override;
// Mark the locations that have only DW_OP_fbreg as stack offset based.
virtual void updateKind() {}
// Line numbers for locations.
const LVLine *getLowerLine() const { return LowerLine; }
void setLowerLine(LVLine *Line) { LowerLine = Line; }
const LVLine *getUpperLine() const { return UpperLine; }
void setUpperLine(LVLine *Line) { UpperLine = Line; }
// Addresses for locations.
LVAddress getLowerAddress() const override { return LowPC; }
void setLowerAddress(LVAddress Address) override { LowPC = Address; }
LVAddress getUpperAddress() const override { return HighPC; }
void setUpperAddress(LVAddress Address) override { HighPC = Address; }
std::string getIntervalInfo() const;
bool validateRanges();
// In order to calculate a symbol coverage (percentage), take the ranges
// and obtain the number of units (bytes) covered by those ranges. We can't
// use the line numbers, because they can be zero or invalid.
// We return:
// false: No locations or multiple locations.
// true: a single location.
static bool calculateCoverage(LVLocations *Locations, unsigned &Factor,
float &Percentage);
virtual void addObject(LVAddress LowPC, LVAddress HighPC,
LVUnsigned SectionOffset, uint64_t LocDescOffset) {}
virtual void addObject(LVSmall Opcode, LVUnsigned Operand1,
LVUnsigned Operand2) {}
static void print(LVLocations *Locations, raw_ostream &OS, bool Full = true);
void printInterval(raw_ostream &OS, bool Full = true) const;
void printRaw(raw_ostream &OS, bool Full = true) const;
virtual void printRawExtra(raw_ostream &OS, bool Full = true) const {}
void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() const override { print(dbgs()); }
#endif
};
class LVLocationSymbol final : public LVLocation {
// Location descriptors for the active range.
LVAutoOperations *Entries = nullptr;
void updateKind() override;
public:
LVLocationSymbol() : LVLocation() {}
LVLocationSymbol(const LVLocationSymbol &) = delete;
LVLocationSymbol &operator=(const LVLocationSymbol &) = delete;
~LVLocationSymbol() { delete Entries; };
void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset,
uint64_t LocDescOffset) override;
void addObject(LVSmall Opcode, LVUnsigned Operand1,
LVUnsigned Operand2) override;
void printRawExtra(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
} // end namespace logicalview
} // end namespace llvm
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H