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 union { 00030 unsigned NumDecls; 00031 00032 Decl *Aligner; 00033 }; 00034 00035 private: 00036 DeclGroup() : NumDecls(0) {} 00037 DeclGroup(unsigned numdecls, Decl** decls); 00038 00039 public: 00040 static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); 00041 00042 unsigned size() const { return NumDecls; } 00043 00044 Decl*& operator[](unsigned i) { 00045 assert (i < NumDecls && "Out-of-bounds access."); 00046 return ((Decl**) (this+1))[i]; 00047 } 00048 00049 Decl* const& operator[](unsigned i) const { 00050 assert (i < NumDecls && "Out-of-bounds access."); 00051 return ((Decl* const*) (this+1))[i]; 00052 } 00053 }; 00054 00055 class DeclGroupRef { 00056 // Note this is not a PointerIntPair because we need the address of the 00057 // non-group case to be valid as a Decl** for iteration. 00058 enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; 00059 Decl* D; 00060 00061 Kind getKind() const { 00062 return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); 00063 } 00064 00065 public: 00066 DeclGroupRef() : D(nullptr) {} 00067 00068 explicit DeclGroupRef(Decl* d) : D(d) {} 00069 explicit DeclGroupRef(DeclGroup* dg) 00070 : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} 00071 00072 static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { 00073 if (NumDecls == 0) 00074 return DeclGroupRef(); 00075 if (NumDecls == 1) 00076 return DeclGroupRef(Decls[0]); 00077 return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); 00078 } 00079 00080 typedef Decl** iterator; 00081 typedef Decl* const * const_iterator; 00082 00083 bool isNull() const { return D == nullptr; } 00084 bool isSingleDecl() const { return getKind() == SingleDeclKind; } 00085 bool isDeclGroup() const { return getKind() == DeclGroupKind; } 00086 00087 Decl *getSingleDecl() { 00088 assert(isSingleDecl() && "Isn't a declgroup"); 00089 return D; 00090 } 00091 const Decl *getSingleDecl() const { 00092 return const_cast<DeclGroupRef*>(this)->getSingleDecl(); 00093 } 00094 00095 DeclGroup &getDeclGroup() { 00096 assert(isDeclGroup() && "Isn't a declgroup"); 00097 return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask)); 00098 } 00099 const DeclGroup &getDeclGroup() const { 00100 return const_cast<DeclGroupRef*>(this)->getDeclGroup(); 00101 } 00102 00103 iterator begin() { 00104 if (isSingleDecl()) 00105 return D ? &D : nullptr; 00106 return &getDeclGroup()[0]; 00107 } 00108 00109 iterator end() { 00110 if (isSingleDecl()) 00111 return D ? &D+1 : nullptr; 00112 DeclGroup &G = getDeclGroup(); 00113 return &G[0] + G.size(); 00114 } 00115 00116 const_iterator begin() const { 00117 if (isSingleDecl()) 00118 return D ? &D : nullptr; 00119 return &getDeclGroup()[0]; 00120 } 00121 00122 const_iterator end() const { 00123 if (isSingleDecl()) 00124 return D ? &D+1 : nullptr; 00125 const DeclGroup &G = getDeclGroup(); 00126 return &G[0] + G.size(); 00127 } 00128 00129 void *getAsOpaquePtr() const { return D; } 00130 static DeclGroupRef getFromOpaquePtr(void *Ptr) { 00131 DeclGroupRef X; 00132 X.D = static_cast<Decl*>(Ptr); 00133 return X; 00134 } 00135 }; 00136 00137 } // end clang namespace 00138 00139 namespace llvm { 00140 // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. 00141 template <typename T> 00142 class PointerLikeTypeTraits; 00143 template <> 00144 class PointerLikeTypeTraits<clang::DeclGroupRef> { 00145 public: 00146 static inline void *getAsVoidPointer(clang::DeclGroupRef P) { 00147 return P.getAsOpaquePtr(); 00148 } 00149 static inline clang::DeclGroupRef getFromVoidPointer(void *P) { 00150 return clang::DeclGroupRef::getFromOpaquePtr(P); 00151 } 00152 enum { NumLowBitsAvailable = 0 }; 00153 }; 00154 } 00155 #endif