1193326Sed//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_DECLGROUP_H 15193326Sed#define LLVM_CLANG_AST_DECLGROUP_H 16193326Sed 17218893Sdim#include "llvm/Support/DataTypes.h" 18193326Sed#include <cassert> 19193326Sed 20193326Sednamespace clang { 21198092Srdivacky 22193326Sedclass ASTContext; 23193326Sedclass Decl; 24193326Sedclass DeclGroup; 25193326Sedclass DeclGroupIterator; 26193326Sed 27193326Sedclass DeclGroup { 28193326Sed // FIXME: Include a TypeSpecifier object. 29245431Sdim union { 30245431Sdim unsigned NumDecls; 31198092Srdivacky 32245431Sdim Decl *Aligner; 33245431Sdim }; 34245431Sdim 35193326Sedprivate: 36193326Sed DeclGroup() : NumDecls(0) {} 37193326Sed DeclGroup(unsigned numdecls, Decl** decls); 38193326Sed 39193326Sedpublic: 40193326Sed static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); 41193326Sed 42193326Sed unsigned size() const { return NumDecls; } 43193326Sed 44198092Srdivacky Decl*& operator[](unsigned i) { 45193326Sed assert (i < NumDecls && "Out-of-bounds access."); 46219077Sdim return ((Decl**) (this+1))[i]; 47193326Sed } 48198092Srdivacky 49198092Srdivacky Decl* const& operator[](unsigned i) const { 50193326Sed assert (i < NumDecls && "Out-of-bounds access."); 51219077Sdim return ((Decl* const*) (this+1))[i]; 52193326Sed } 53193326Sed}; 54198092Srdivacky 55193326Sedclass DeclGroupRef { 56193326Sed // Note this is not a PointerIntPair because we need the address of the 57193326Sed // non-group case to be valid as a Decl** for iteration. 58198092Srdivacky enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; 59193326Sed Decl* D; 60193326Sed 61193326Sed Kind getKind() const { 62193326Sed return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); 63198092Srdivacky } 64198092Srdivacky 65198092Srdivackypublic: 66193326Sed DeclGroupRef() : D(0) {} 67198092Srdivacky 68193326Sed explicit DeclGroupRef(Decl* d) : D(d) {} 69193326Sed explicit DeclGroupRef(DeclGroup* dg) 70193326Sed : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} 71198092Srdivacky 72193326Sed static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { 73193326Sed if (NumDecls == 0) 74193326Sed return DeclGroupRef(); 75193326Sed if (NumDecls == 1) 76193326Sed return DeclGroupRef(Decls[0]); 77193326Sed return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); 78193326Sed } 79198092Srdivacky 80193326Sed typedef Decl** iterator; 81193326Sed typedef Decl* const * const_iterator; 82198092Srdivacky 83193326Sed bool isNull() const { return D == 0; } 84193326Sed bool isSingleDecl() const { return getKind() == SingleDeclKind; } 85193326Sed bool isDeclGroup() const { return getKind() == DeclGroupKind; } 86193326Sed 87193326Sed Decl *getSingleDecl() { 88193326Sed assert(isSingleDecl() && "Isn't a declgroup"); 89193326Sed return D; 90193326Sed } 91193326Sed const Decl *getSingleDecl() const { 92193326Sed return const_cast<DeclGroupRef*>(this)->getSingleDecl(); 93193326Sed } 94198092Srdivacky 95193326Sed DeclGroup &getDeclGroup() { 96193326Sed assert(isDeclGroup() && "Isn't a declgroup"); 97193326Sed return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask)); 98193326Sed } 99193326Sed const DeclGroup &getDeclGroup() const { 100193326Sed return const_cast<DeclGroupRef*>(this)->getDeclGroup(); 101193326Sed } 102198092Srdivacky 103193326Sed iterator begin() { 104193326Sed if (isSingleDecl()) 105193326Sed return D ? &D : 0; 106193326Sed return &getDeclGroup()[0]; 107193326Sed } 108193326Sed 109193326Sed iterator end() { 110193326Sed if (isSingleDecl()) 111193326Sed return D ? &D+1 : 0; 112193326Sed DeclGroup &G = getDeclGroup(); 113193326Sed return &G[0] + G.size(); 114193326Sed } 115198092Srdivacky 116193326Sed const_iterator begin() const { 117193326Sed if (isSingleDecl()) 118193326Sed return D ? &D : 0; 119193326Sed return &getDeclGroup()[0]; 120193326Sed } 121198092Srdivacky 122193326Sed const_iterator end() const { 123193326Sed if (isSingleDecl()) 124193326Sed return D ? &D+1 : 0; 125193326Sed const DeclGroup &G = getDeclGroup(); 126193326Sed return &G[0] + G.size(); 127193326Sed } 128193326Sed 129193326Sed void *getAsOpaquePtr() const { return D; } 130193326Sed static DeclGroupRef getFromOpaquePtr(void *Ptr) { 131193326Sed DeclGroupRef X; 132193326Sed X.D = static_cast<Decl*>(Ptr); 133193326Sed return X; 134193326Sed } 135193326Sed}; 136198092Srdivacky 137193326Sed} // end clang namespace 138193326Sed 139193326Sednamespace llvm { 140193326Sed // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. 141193326Sed template <typename T> 142193326Sed class PointerLikeTypeTraits; 143193326Sed template <> 144193326Sed class PointerLikeTypeTraits<clang::DeclGroupRef> { 145193326Sed public: 146193326Sed static inline void *getAsVoidPointer(clang::DeclGroupRef P) { 147193326Sed return P.getAsOpaquePtr(); 148193326Sed } 149193326Sed static inline clang::DeclGroupRef getFromVoidPointer(void *P) { 150193326Sed return clang::DeclGroupRef::getFromOpaquePtr(P); 151193326Sed } 152193326Sed enum { NumLowBitsAvailable = 0 }; 153193326Sed }; 154193326Sed} 155193326Sed#endif 156