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