1//===------------------------- DeclOrExpr.h ---------------------*- 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#ifndef LLVM_CLANG_AST_INTERP_DECLOREXPR_H
10#define LLVM_CLANG_AST_INTERP_DECLOREXPR_H
11
12#include "clang/AST/Decl.h"
13#include "clang/AST/Expr.h"
14#include "clang/AST/TypeBase.h"
15#include "llvm/ADT/PointerUnion.h"
16
17namespace clang {
18namespace interp {
19
20struct DeclOrExpr {
21 llvm::PointerUnion<const Decl *, const Expr *> V;
22
23 DeclOrExpr() : V(nullptr) {}
24 DeclOrExpr(std::nullptr_t) : V(nullptr) {}
25 DeclOrExpr(const Decl *VD) : V(VD) {}
26 DeclOrExpr(const Expr *E) : V(E) {}
27
28 bool isExpr() const { return isa_and_nonnull<const Expr *>(Val: V); }
29 bool isDecl() const { return isa_and_nonnull<const Decl *>(Val: V); }
30 bool isValueDecl() const { return isa_and_nonnull<ValueDecl>(Val: asDecl()); }
31
32 const Expr *asExpr() const { return V.dyn_cast<const Expr *>(); }
33 const Decl *asDecl() const { return V.dyn_cast<const Decl *>(); }
34 const ValueDecl *asValueDecl() const {
35 return dyn_cast_if_present<ValueDecl>(Val: asDecl());
36 }
37 const VarDecl *asVarDecl() const {
38 return dyn_cast_if_present<VarDecl>(Val: asDecl());
39 }
40
41 const void *getOpaqueValue() const { return V.getOpaqueValue(); }
42
43 bool operator==(DeclOrExpr O) const { return O.V == V; }
44 bool operator!=(DeclOrExpr O) const { return O.V != V; }
45 explicit operator bool() const { return !V.isNull(); }
46
47 QualType getType() const {
48 if (const auto *VD = asValueDecl())
49 return VD->getType();
50 return asExpr()->getType();
51 }
52};
53static_assert(sizeof(DeclOrExpr) == sizeof(void *));
54
55inline DeclOrExpr getSwappedBytes(DeclOrExpr F) { return F; }
56
57inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclOrExpr D) {
58 OS << D.getOpaqueValue();
59 return OS;
60}
61
62} // namespace interp
63} // namespace clang
64
65#endif
66