File indexing completed on 2026-05-10 08:36:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_DECLGROUP_H
0014 #define LLVM_CLANG_AST_DECLGROUP_H
0015
0016 #include "llvm/Support/TrailingObjects.h"
0017 #include <cassert>
0018 #include <cstdint>
0019
0020 namespace clang {
0021
0022 class ASTContext;
0023 class Decl;
0024
0025 class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
0026
0027 unsigned NumDecls = 0;
0028
0029 private:
0030 DeclGroup() = default;
0031 DeclGroup(unsigned numdecls, Decl** decls);
0032
0033 public:
0034 friend TrailingObjects;
0035
0036 static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
0037
0038 unsigned size() const { return NumDecls; }
0039
0040 Decl*& operator[](unsigned i) {
0041 assert (i < NumDecls && "Out-of-bounds access.");
0042 return getTrailingObjects<Decl *>()[i];
0043 }
0044
0045 Decl* const& operator[](unsigned i) const {
0046 assert (i < NumDecls && "Out-of-bounds access.");
0047 return getTrailingObjects<Decl *>()[i];
0048 }
0049 };
0050
0051 class DeclGroupRef {
0052
0053
0054 enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
0055
0056 Decl* D = nullptr;
0057
0058 Kind getKind() const {
0059 return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
0060 }
0061
0062 public:
0063 DeclGroupRef() = default;
0064 explicit DeclGroupRef(Decl* d) : D(d) {}
0065 explicit DeclGroupRef(DeclGroup* dg)
0066 : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
0067
0068 static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
0069 if (NumDecls == 0)
0070 return DeclGroupRef();
0071 if (NumDecls == 1)
0072 return DeclGroupRef(Decls[0]);
0073 return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
0074 }
0075
0076 using iterator = Decl **;
0077 using const_iterator = Decl * const *;
0078
0079 bool isNull() const { return D == nullptr; }
0080 bool isSingleDecl() const { return getKind() == SingleDeclKind; }
0081 bool isDeclGroup() const { return getKind() == DeclGroupKind; }
0082
0083 Decl *getSingleDecl() {
0084 assert(isSingleDecl() && "Isn't a single decl");
0085 return D;
0086 }
0087 const Decl *getSingleDecl() const {
0088 return const_cast<DeclGroupRef*>(this)->getSingleDecl();
0089 }
0090
0091 DeclGroup &getDeclGroup() {
0092 assert(isDeclGroup() && "Isn't a declgroup");
0093 return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
0094 }
0095 const DeclGroup &getDeclGroup() const {
0096 return const_cast<DeclGroupRef*>(this)->getDeclGroup();
0097 }
0098
0099 iterator begin() {
0100 if (isSingleDecl())
0101 return D ? &D : nullptr;
0102 return &getDeclGroup()[0];
0103 }
0104
0105 iterator end() {
0106 if (isSingleDecl())
0107 return D ? &D+1 : nullptr;
0108 DeclGroup &G = getDeclGroup();
0109 return &G[0] + G.size();
0110 }
0111
0112 const_iterator begin() const {
0113 if (isSingleDecl())
0114 return D ? &D : nullptr;
0115 return &getDeclGroup()[0];
0116 }
0117
0118 const_iterator end() const {
0119 if (isSingleDecl())
0120 return D ? &D+1 : nullptr;
0121 const DeclGroup &G = getDeclGroup();
0122 return &G[0] + G.size();
0123 }
0124
0125 void *getAsOpaquePtr() const { return D; }
0126 static DeclGroupRef getFromOpaquePtr(void *Ptr) {
0127 DeclGroupRef X;
0128 X.D = static_cast<Decl*>(Ptr);
0129 return X;
0130 }
0131 };
0132
0133 }
0134
0135 namespace llvm {
0136
0137
0138 template <typename T>
0139 struct PointerLikeTypeTraits;
0140 template <>
0141 struct PointerLikeTypeTraits<clang::DeclGroupRef> {
0142 static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
0143 return P.getAsOpaquePtr();
0144 }
0145
0146 static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
0147 return clang::DeclGroupRef::getFromOpaquePtr(P);
0148 }
0149
0150 static constexpr int NumLowBitsAvailable = 0;
0151 };
0152
0153 }
0154
0155 #endif