Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- DeclGroup.h - Classes for representing groups of Decls ---*- 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. //  This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_AST_DECLGROUP_H
  14. #define LLVM_CLANG_AST_DECLGROUP_H
  15.  
  16. #include "llvm/Support/TrailingObjects.h"
  17. #include <cassert>
  18. #include <cstdint>
  19.  
  20. namespace clang {
  21.  
  22. class ASTContext;
  23. class Decl;
  24.  
  25. class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
  26.   // FIXME: Include a TypeSpecifier object.
  27.   unsigned NumDecls = 0;
  28.  
  29. private:
  30.   DeclGroup() = default;
  31.   DeclGroup(unsigned numdecls, Decl** decls);
  32.  
  33. public:
  34.   friend TrailingObjects;
  35.  
  36.   static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
  37.  
  38.   unsigned size() const { return NumDecls; }
  39.  
  40.   Decl*& operator[](unsigned i) {
  41.     assert (i < NumDecls && "Out-of-bounds access.");
  42.     return getTrailingObjects<Decl *>()[i];
  43.   }
  44.  
  45.   Decl* const& operator[](unsigned i) const {
  46.     assert (i < NumDecls && "Out-of-bounds access.");
  47.     return getTrailingObjects<Decl *>()[i];
  48.   }
  49. };
  50.  
  51. class DeclGroupRef {
  52.   // Note this is not a PointerIntPair because we need the address of the
  53.   // non-group case to be valid as a Decl** for iteration.
  54.   enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
  55.  
  56.   Decl* D = nullptr;
  57.  
  58.   Kind getKind() const {
  59.     return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
  60.   }
  61.  
  62. public:
  63.   DeclGroupRef() = default;
  64.   explicit DeclGroupRef(Decl* d) : D(d) {}
  65.   explicit DeclGroupRef(DeclGroup* dg)
  66.     : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
  67.  
  68.   static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
  69.     if (NumDecls == 0)
  70.       return DeclGroupRef();
  71.     if (NumDecls == 1)
  72.       return DeclGroupRef(Decls[0]);
  73.     return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
  74.   }
  75.  
  76.   using iterator = Decl **;
  77.   using const_iterator = Decl * const *;
  78.  
  79.   bool isNull() const { return D == nullptr; }
  80.   bool isSingleDecl() const { return getKind() == SingleDeclKind; }
  81.   bool isDeclGroup() const { return getKind() == DeclGroupKind; }
  82.  
  83.   Decl *getSingleDecl() {
  84.     assert(isSingleDecl() && "Isn't a single decl");
  85.     return D;
  86.   }
  87.   const Decl *getSingleDecl() const {
  88.     return const_cast<DeclGroupRef*>(this)->getSingleDecl();
  89.   }
  90.  
  91.   DeclGroup &getDeclGroup() {
  92.     assert(isDeclGroup() && "Isn't a declgroup");
  93.     return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
  94.   }
  95.   const DeclGroup &getDeclGroup() const {
  96.     return const_cast<DeclGroupRef*>(this)->getDeclGroup();
  97.   }
  98.  
  99.   iterator begin() {
  100.     if (isSingleDecl())
  101.       return D ? &D : nullptr;
  102.     return &getDeclGroup()[0];
  103.   }
  104.  
  105.   iterator end() {
  106.     if (isSingleDecl())
  107.       return D ? &D+1 : nullptr;
  108.     DeclGroup &G = getDeclGroup();
  109.     return &G[0] + G.size();
  110.   }
  111.  
  112.   const_iterator begin() const {
  113.     if (isSingleDecl())
  114.       return D ? &D : nullptr;
  115.     return &getDeclGroup()[0];
  116.   }
  117.  
  118.   const_iterator end() const {
  119.     if (isSingleDecl())
  120.       return D ? &D+1 : nullptr;
  121.     const DeclGroup &G = getDeclGroup();
  122.     return &G[0] + G.size();
  123.   }
  124.  
  125.   void *getAsOpaquePtr() const { return D; }
  126.   static DeclGroupRef getFromOpaquePtr(void *Ptr) {
  127.     DeclGroupRef X;
  128.     X.D = static_cast<Decl*>(Ptr);
  129.     return X;
  130.   }
  131. };
  132.  
  133. } // namespace clang
  134.  
  135. namespace llvm {
  136.  
  137.   // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
  138.   template <typename T>
  139.   struct PointerLikeTypeTraits;
  140.   template <>
  141.   struct PointerLikeTypeTraits<clang::DeclGroupRef> {
  142.     static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
  143.       return P.getAsOpaquePtr();
  144.     }
  145.  
  146.     static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
  147.       return clang::DeclGroupRef::getFromOpaquePtr(P);
  148.     }
  149.  
  150.     static constexpr int NumLowBitsAvailable = 0;
  151.   };
  152.  
  153. } // namespace llvm
  154.  
  155. #endif // LLVM_CLANG_AST_DECLGROUP_H
  156.