Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/CodeGen/Address.h
Line
Count
Source (jump to first uncovered line)
1
//===-- Address.h - An aligned address -------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This class provides a simple wrapper for a pair of a pointer and an
10
// alignment.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
15
#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
16
17
#include "clang/AST/CharUnits.h"
18
#include "llvm/ADT/PointerIntPair.h"
19
#include "llvm/IR/Constants.h"
20
#include "llvm/Support/MathExtras.h"
21
22
namespace clang {
23
namespace CodeGen {
24
25
// Indicates whether a pointer is known not to be null.
26
enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
27
28
/// An aligned address.
29
class Address {
30
  llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull;
31
  llvm::Type *ElementType;
32
  CharUnits Alignment;
33
34
protected:
35
0
  Address(std::nullptr_t) : ElementType(nullptr) {}
36
37
public:
38
  Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
39
          KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
40
      : PointerAndKnownNonNull(Pointer, IsKnownNonNull),
41
0
        ElementType(ElementType), Alignment(Alignment) {
42
0
    assert(Pointer != nullptr && "Pointer cannot be null");
43
0
    assert(ElementType != nullptr && "Element type cannot be null");
44
0
  }
45
46
0
  static Address invalid() { return Address(nullptr); }
47
0
  bool isValid() const {
48
0
    return PointerAndKnownNonNull.getPointer() != nullptr;
49
0
  }
50
51
0
  llvm::Value *getPointer() const {
52
0
    assert(isValid());
53
0
    return PointerAndKnownNonNull.getPointer();
54
0
  }
55
56
  /// Return the type of the pointer value.
57
0
  llvm::PointerType *getType() const {
58
0
    return llvm::cast<llvm::PointerType>(getPointer()->getType());
59
0
  }
60
61
  /// Return the type of the values stored in this address.
62
0
  llvm::Type *getElementType() const {
63
0
    assert(isValid());
64
0
    return ElementType;
65
0
  }
66
67
  /// Return the address space that this address resides in.
68
0
  unsigned getAddressSpace() const {
69
0
    return getType()->getAddressSpace();
70
0
  }
71
72
  /// Return the IR name of the pointer value.
73
0
  llvm::StringRef getName() const {
74
0
    return getPointer()->getName();
75
0
  }
76
77
  /// Return the alignment of this pointer.
78
0
  CharUnits getAlignment() const {
79
0
    assert(isValid());
80
0
    return Alignment;
81
0
  }
82
83
  /// Return address with different pointer, but same element type and
84
  /// alignment.
85
  Address withPointer(llvm::Value *NewPointer,
86
0
                      KnownNonNull_t IsKnownNonNull) const {
87
0
    return Address(NewPointer, getElementType(), getAlignment(),
88
0
                   IsKnownNonNull);
89
0
  }
90
91
  /// Return address with different alignment, but same pointer and element
92
  /// type.
93
0
  Address withAlignment(CharUnits NewAlignment) const {
94
0
    return Address(getPointer(), getElementType(), NewAlignment,
95
0
                   isKnownNonNull());
96
0
  }
97
98
  /// Return address with different element type, but same pointer and
99
  /// alignment.
100
0
  Address withElementType(llvm::Type *ElemTy) const {
101
0
    return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull());
102
0
  }
103
104
  /// Whether the pointer is known not to be null.
105
0
  KnownNonNull_t isKnownNonNull() const {
106
0
    assert(isValid());
107
0
    return (KnownNonNull_t)PointerAndKnownNonNull.getInt();
108
0
  }
109
110
  /// Set the non-null bit.
111
0
  Address setKnownNonNull() {
112
0
    assert(isValid());
113
0
    PointerAndKnownNonNull.setInt(true);
114
0
    return *this;
115
0
  }
116
};
117
118
/// A specialization of Address that requires the address to be an
119
/// LLVM Constant.
120
class ConstantAddress : public Address {
121
0
  ConstantAddress(std::nullptr_t) : Address(nullptr) {}
122
123
public:
124
  ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType,
125
                  CharUnits alignment)
126
0
      : Address(pointer, elementType, alignment) {}
127
128
0
  static ConstantAddress invalid() {
129
0
    return ConstantAddress(nullptr);
130
0
  }
131
132
0
  llvm::Constant *getPointer() const {
133
0
    return llvm::cast<llvm::Constant>(Address::getPointer());
134
0
  }
135
136
0
  ConstantAddress withElementType(llvm::Type *ElemTy) const {
137
0
    return ConstantAddress(getPointer(), ElemTy, getAlignment());
138
0
  }
139
140
0
  static bool isaImpl(Address addr) {
141
0
    return llvm::isa<llvm::Constant>(addr.getPointer());
142
0
  }
143
0
  static ConstantAddress castImpl(Address addr) {
144
0
    return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
145
0
                           addr.getElementType(), addr.getAlignment());
146
0
  }
147
};
148
149
}
150
151
// Present a minimal LLVM-like casting interface.
152
template <class U> inline U cast(CodeGen::Address addr) {
153
  return U::castImpl(addr);
154
}
155
template <class U> inline bool isa(CodeGen::Address addr) {
156
  return U::isaImpl(addr);
157
}
158
159
}
160
161
#endif