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