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 bool isVarDecl() const { return isa_and_nonnull<VarDecl>(Val: asDecl()); }
32
33 const Expr *asExpr() const { return V.dyn_cast<const Expr *>(); }
34 const Decl *asDecl() const { return V.dyn_cast<const Decl *>(); }
35 const ValueDecl *asValueDecl() const {
36 return dyn_cast_if_present<ValueDecl>(Val: asDecl());
37 }
38 const VarDecl *asVarDecl() const {
39 return dyn_cast_if_present<VarDecl>(Val: asDecl());
40 }
41
42 const void *getOpaqueValue() const { return V.getOpaqueValue(); }
43
44 bool operator==(DeclOrExpr O) const { return O.V == V; }
45 bool operator!=(DeclOrExpr O) const { return O.V != V; }
46 explicit operator bool() const { return !V.isNull(); }
47
48 QualType getType() const {
49 if (const auto *VD = asValueDecl())
50 return VD->getType();
51 return asExpr()->getType();
52 }
53
54 SourceLocation getLocation() const {
55 if (const auto *VD = asValueDecl())
56 return VD->getLocation();
57 return asExpr()->getExprLoc();
58 }
59};
60static_assert(sizeof(DeclOrExpr) == sizeof(void *));
61
62inline DeclOrExpr getSwappedBytes(DeclOrExpr F) { return F; }
63
64inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclOrExpr D) {
65 OS << D.getOpaqueValue();
66 return OS;
67}
68
69} // namespace interp
70} // namespace clang
71
72#endif
73