Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:32

0001 //===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
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   // FIXME: Include a TypeSpecifier object.
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   // Note this is not a PointerIntPair because we need the address of the
0053   // non-group case to be valid as a Decl** for iteration.
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 } // namespace clang
0134 
0135 namespace llvm {
0136 
0137   // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
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 } // namespace llvm
0154 
0155 #endif // LLVM_CLANG_AST_DECLGROUP_H