blob: 652c7a3d339e08f0ebc5c1254acd4813dce52b34 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===- ConstantInitFuture.h - "Future" constant initializers ----*- 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 class defines the ConstantInitFuture class. This is split out
// from ConstantInitBuilder.h in order to allow APIs to work with it
// without having to include that entire header. This is particularly
// important because it is often useful to be able to default-construct
// a future in, say, a default argument.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
#define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
#include "llvm/ADT/PointerUnion.h"
#include "llvm/IR/Constant.h"
// Forward-declare ConstantInitBuilderBase and give it a
// PointerLikeTypeTraits specialization so that we can safely use it
// in a PointerUnion below.
namespace clang {
namespace CodeGen {
class ConstantInitBuilderBase;
}
}
namespace llvm {
template <>
struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
using T = ::clang::CodeGen::ConstantInitBuilderBase*;
static inline void *getAsVoidPointer(T p) { return p; }
static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
static constexpr int NumLowBitsAvailable = 2;
};
}
namespace clang {
namespace CodeGen {
/// A "future" for a completed constant initializer, which can be passed
/// around independently of any sub-builders (but not the original parent).
class ConstantInitFuture {
using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>;
PairTy Data;
friend class ConstantInitBuilderBase;
explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
public:
ConstantInitFuture() {}
/// A future can be explicitly created from a fixed initializer.
explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) {
assert(initializer && "creating null future");
}
/// Is this future non-null?
explicit operator bool() const { return bool(Data); }
/// Return the type of the initializer.
llvm::Type *getType() const;
/// Abandon this initializer.
void abandon();
/// Install the initializer into a global variable. This cannot
/// be called multiple times.
void installInGlobal(llvm::GlobalVariable *global);
void *getOpaqueValue() const { return Data.getOpaqueValue(); }
static ConstantInitFuture getFromOpaqueValue(void *value) {
ConstantInitFuture result;
result.Data = PairTy::getFromOpaqueValue(value);
return result;
}
static constexpr int NumLowBitsAvailable =
llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable;
};
} // end namespace CodeGen
} // end namespace clang
namespace llvm {
template <>
struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
using T = ::clang::CodeGen::ConstantInitFuture;
static inline void *getAsVoidPointer(T future) {
return future.getOpaqueValue();
}
static inline T getFromVoidPointer(void *p) {
return T::getFromOpaqueValue(p);
}
static constexpr int NumLowBitsAvailable = T::NumLowBitsAvailable;
};
} // end namespace llvm
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|