1d17062cc23df2137378eb808545e24be484c321aTed Kremenek//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===// 2d17062cc23df2137378eb808545e24be484c321aTed Kremenek// 3d17062cc23df2137378eb808545e24be484c321aTed Kremenek// The LLVM Compiler Infrastructure 4d17062cc23df2137378eb808545e24be484c321aTed Kremenek// 5d17062cc23df2137378eb808545e24be484c321aTed Kremenek// This file is distributed under the University of Illinois Open Source 6d17062cc23df2137378eb808545e24be484c321aTed Kremenek// License. See LICENSE.TXT for details. 7d17062cc23df2137378eb808545e24be484c321aTed Kremenek// 8d17062cc23df2137378eb808545e24be484c321aTed Kremenek//===----------------------------------------------------------------------===// 9d17062cc23df2137378eb808545e24be484c321aTed Kremenek// 10d17062cc23df2137378eb808545e24be484c321aTed Kremenek// This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes. 11d17062cc23df2137378eb808545e24be484c321aTed Kremenek// 12d17062cc23df2137378eb808545e24be484c321aTed Kremenek//===----------------------------------------------------------------------===// 13d17062cc23df2137378eb808545e24be484c321aTed Kremenek 14d17062cc23df2137378eb808545e24be484c321aTed Kremenek#ifndef LLVM_CLANG_AST_DECLGROUP_H 15d17062cc23df2137378eb808545e24be484c321aTed Kremenek#define LLVM_CLANG_AST_DECLGROUP_H 16d17062cc23df2137378eb808545e24be484c321aTed Kremenek 1703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h" 18d17062cc23df2137378eb808545e24be484c321aTed Kremenek#include <cassert> 19d17062cc23df2137378eb808545e24be484c321aTed Kremenek 20d17062cc23df2137378eb808545e24be484c321aTed Kremeneknamespace clang { 211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 22d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass ASTContext; 23d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass Decl; 24d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass DeclGroup; 25d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass DeclGroupIterator; 26d17062cc23df2137378eb808545e24be484c321aTed Kremenek 27d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass DeclGroup { 28d17062cc23df2137378eb808545e24be484c321aTed Kremenek // FIXME: Include a TypeSpecifier object. 29aeb288123e51cbf5855b06eb9d8c108fd6124286Richard Smith union { 30aeb288123e51cbf5855b06eb9d8c108fd6124286Richard Smith unsigned NumDecls; 31aeb288123e51cbf5855b06eb9d8c108fd6124286Richard Smith 32aeb288123e51cbf5855b06eb9d8c108fd6124286Richard Smith Decl *Aligner; 33aeb288123e51cbf5855b06eb9d8c108fd6124286Richard Smith }; 341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35d17062cc23df2137378eb808545e24be484c321aTed Kremenekprivate: 36c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek DeclGroup() : NumDecls(0) {} 37d17062cc23df2137378eb808545e24be484c321aTed Kremenek DeclGroup(unsigned numdecls, Decl** decls); 38d17062cc23df2137378eb808545e24be484c321aTed Kremenek 39d17062cc23df2137378eb808545e24be484c321aTed Kremenekpublic: 40682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); 41d17062cc23df2137378eb808545e24be484c321aTed Kremenek 42d17062cc23df2137378eb808545e24be484c321aTed Kremenek unsigned size() const { return NumDecls; } 43401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Decl*& operator[](unsigned i) { 45d17062cc23df2137378eb808545e24be484c321aTed Kremenek assert (i < NumDecls && "Out-of-bounds access."); 46b80f66847d103aee7988b791a380fc563bf89a19Richard Smith return ((Decl**) (this+1))[i]; 47d17062cc23df2137378eb808545e24be484c321aTed Kremenek } 481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Decl* const& operator[](unsigned i) const { 50c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek assert (i < NumDecls && "Out-of-bounds access."); 51b80f66847d103aee7988b791a380fc563bf89a19Richard Smith return ((Decl* const*) (this+1))[i]; 52c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek } 53c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek}; 541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55d17062cc23df2137378eb808545e24be484c321aTed Kremenekclass DeclGroupRef { 56682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // Note this is not a PointerIntPair because we need the address of the 57682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // non-group case to be valid as a Decl** for iteration. 581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; 59e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek Decl* D; 60e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek 61e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek Kind getKind() const { 62e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 66e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek DeclGroupRef() : D(0) {} 671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68e7b8d400208e886a167a4481a9024295a3ce17d1Ted Kremenek explicit DeclGroupRef(Decl* d) : D(d) {} 69e7b8d400208e886a167a4481a9024295a3ce17d1Ted Kremenek explicit DeclGroupRef(DeclGroup* dg) 70c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 72682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) { 73682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (NumDecls == 0) 74682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return DeclGroupRef(); 75682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (NumDecls == 1) 76682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return DeclGroupRef(Decls[0]); 77682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); 78682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 80d17062cc23df2137378eb808545e24be484c321aTed Kremenek typedef Decl** iterator; 81401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek typedef Decl* const * const_iterator; 821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8320401698e3bd93a24bb5d9e18e435895cefe5fd1Chris Lattner bool isNull() const { return D == 0; } 84fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner bool isSingleDecl() const { return getKind() == SingleDeclKind; } 85fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner bool isDeclGroup() const { return getKind() == DeclGroupKind; } 86fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner 87fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner Decl *getSingleDecl() { 88fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner assert(isSingleDecl() && "Isn't a declgroup"); 89fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return D; 90fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner } 91fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner const Decl *getSingleDecl() const { 92fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return const_cast<DeclGroupRef*>(this)->getSingleDecl(); 93fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner } 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 95fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner DeclGroup &getDeclGroup() { 96fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner assert(isDeclGroup() && "Isn't a declgroup"); 97fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask)); 98fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner } 99fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner const DeclGroup &getDeclGroup() const { 100fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return const_cast<DeclGroupRef*>(this)->getDeclGroup(); 101401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek } 1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 103d17062cc23df2137378eb808545e24be484c321aTed Kremenek iterator begin() { 104fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner if (isSingleDecl()) 105fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return D ? &D : 0; 106fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return &getDeclGroup()[0]; 107d17062cc23df2137378eb808545e24be484c321aTed Kremenek } 108d17062cc23df2137378eb808545e24be484c321aTed Kremenek 109d17062cc23df2137378eb808545e24be484c321aTed Kremenek iterator end() { 110fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner if (isSingleDecl()) 111fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return D ? &D+1 : 0; 112fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner DeclGroup &G = getDeclGroup(); 113e285a9505c0be75d4b58e67aa32e82de55889235Ted Kremenek return &G[0] + G.size(); 114c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek } 1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 116401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek const_iterator begin() const { 117fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner if (isSingleDecl()) 118fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return D ? &D : 0; 119fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return &getDeclGroup()[0]; 120401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek } 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 122401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek const_iterator end() const { 123fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner if (isSingleDecl()) 124fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner return D ? &D+1 : 0; 125fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner const DeclGroup &G = getDeclGroup(); 126401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek return &G[0] + G.size(); 127401adfad4af45b083ad067f3ebec5cf23a1e91cfTed Kremenek } 128c7b07c19daa861880ad4bbf257d0fb2c7961355fTed Kremenek 129cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner void *getAsOpaquePtr() const { return D; } 130cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner static DeclGroupRef getFromOpaquePtr(void *Ptr) { 131cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner DeclGroupRef X; 132cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner X.D = static_cast<Decl*>(Ptr); 133cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner return X; 134cc1f8693df4c96d7a8db585e5c05e31b8520f6c2Chris Lattner } 135d17062cc23df2137378eb808545e24be484c321aTed Kremenek}; 1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 137d17062cc23df2137378eb808545e24be484c321aTed Kremenek} // end clang namespace 138d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner 139d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattnernamespace llvm { 140d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. 141d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner template <typename T> 142d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner class PointerLikeTypeTraits; 143d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner template <> 144d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner class PointerLikeTypeTraits<clang::DeclGroupRef> { 145d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner public: 146d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner static inline void *getAsVoidPointer(clang::DeclGroupRef P) { 147d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner return P.getAsOpaquePtr(); 148d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner } 149d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner static inline clang::DeclGroupRef getFromVoidPointer(void *P) { 150d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner return clang::DeclGroupRef::getFromOpaquePtr(P); 151d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner } 152d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner enum { NumLowBitsAvailable = 0 }; 153d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner }; 154d51a183ffd7de05374ef20977e17ab4444bd633cChris Lattner} 155d17062cc23df2137378eb808545e24be484c321aTed Kremenek#endif 156