clang API Documentation
00001 //===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_DECLGROUP_H 00015 #define LLVM_CLANG_AST_DECLGROUP_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include <cassert> 00019 00020 namespace clang { 00021 00022 class ASTContext; 00023 class Decl; 00024 class DeclGroup; 00025 class DeclGroupIterator; 00026 00027 class DeclGroup { 00028 // FIXME: Include a TypeSpecifier object. 00029 unsigned NumDecls; 00030 00031 private: 00032 DeclGroup() : NumDecls(0) {} 00033 DeclGroup(unsigned numdecls, Decl** decls); 00034 00035 public: 00036 static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); 00037 00038 unsigned size() const { return NumDecls; } 00039 00040 Decl*& operator[](unsigned i) { 00041 assert (i < NumDecls && "Out-of-bounds access."); 00042 return ((Decl**) (this+1))[i]; 00043 } 00044 00045 Decl* const& operator[](unsigned i) const { 00046 assert (i < NumDecls && "Out-of-bounds access."); 00047 return ((Decl* const*) (this+1))[i]; 00048 } 00049 }; 00050 00051 class DeclGroupRef { 00052 // Note this is not a PointerIntPair because we need the address of the 00053 // non-group case to be valid as a Decl** for iteration. 00054 enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; 00055 Decl* D; 00056 00057 Kind getKind() const { 00058 return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); 00059 } 00060 00061 public: 00062 DeclGroupRef() : D(0) {} 00063 00064 explicit DeclGroupRef(Decl* d) : D(d) {} 00065 explicit DeclGroupRef(DeclGroup* dg) 00066 : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} 00067 00068 static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { 00069 if (NumDecls == 0) 00070 return DeclGroupRef(); 00071 if (NumDecls == 1) 00072 return DeclGroupRef(Decls[0]); 00073 return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); 00074 } 00075 00076 typedef Decl** iterator; 00077 typedef Decl* const * const_iterator; 00078 00079 bool isNull() const { return D == 0; } 00080 bool isSingleDecl() const { return getKind() == SingleDeclKind; } 00081 bool isDeclGroup() const { return getKind() == DeclGroupKind; } 00082 00083 Decl *getSingleDecl() { 00084 assert(isSingleDecl() && "Isn't a declgroup"); 00085 return D; 00086 } 00087 const Decl *getSingleDecl() const { 00088 return const_cast<DeclGroupRef*>(this)->getSingleDecl(); 00089 } 00090 00091 DeclGroup &getDeclGroup() { 00092 assert(isDeclGroup() && "Isn't a declgroup"); 00093 return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask)); 00094 } 00095 const DeclGroup &getDeclGroup() const { 00096 return const_cast<DeclGroupRef*>(this)->getDeclGroup(); 00097 } 00098 00099 iterator begin() { 00100 if (isSingleDecl()) 00101 return D ? &D : 0; 00102 return &getDeclGroup()[0]; 00103 } 00104 00105 iterator end() { 00106 if (isSingleDecl()) 00107 return D ? &D+1 : 0; 00108 DeclGroup &G = getDeclGroup(); 00109 return &G[0] + G.size(); 00110 } 00111 00112 const_iterator begin() const { 00113 if (isSingleDecl()) 00114 return D ? &D : 0; 00115 return &getDeclGroup()[0]; 00116 } 00117 00118 const_iterator end() const { 00119 if (isSingleDecl()) 00120 return D ? &D+1 : 0; 00121 const DeclGroup &G = getDeclGroup(); 00122 return &G[0] + G.size(); 00123 } 00124 00125 void *getAsOpaquePtr() const { return D; } 00126 static DeclGroupRef getFromOpaquePtr(void *Ptr) { 00127 DeclGroupRef X; 00128 X.D = static_cast<Decl*>(Ptr); 00129 return X; 00130 } 00131 }; 00132 00133 } // end clang namespace 00134 00135 namespace llvm { 00136 // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. 00137 template <typename T> 00138 class PointerLikeTypeTraits; 00139 template <> 00140 class PointerLikeTypeTraits<clang::DeclGroupRef> { 00141 public: 00142 static inline void *getAsVoidPointer(clang::DeclGroupRef P) { 00143 return P.getAsOpaquePtr(); 00144 } 00145 static inline clang::DeclGroupRef getFromVoidPointer(void *P) { 00146 return clang::DeclGroupRef::getFromOpaquePtr(P); 00147 } 00148 enum { NumLowBitsAvailable = 0 }; 00149 }; 00150 } 00151 #endif