clang  3.7.0
DeclGroup.h
Go to the documentation of this file.
1 //===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_DECLGROUP_H
15 #define LLVM_CLANG_AST_DECLGROUP_H
16 
17 #include "llvm/Support/DataTypes.h"
18 #include <cassert>
19 
20 namespace clang {
21 
22 class ASTContext;
23 class Decl;
24 class DeclGroup;
25 class DeclGroupIterator;
26 
27 class DeclGroup {
28  // FIXME: Include a TypeSpecifier object.
29  union {
30  unsigned NumDecls;
31 
33  };
34 
35 private:
36  DeclGroup() : NumDecls(0) {}
37  DeclGroup(unsigned numdecls, Decl** decls);
38 
39 public:
40  static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
41 
42  unsigned size() const { return NumDecls; }
43 
44  Decl*& operator[](unsigned i) {
45  assert (i < NumDecls && "Out-of-bounds access.");
46  return ((Decl**) (this+1))[i];
47  }
48 
49  Decl* const& operator[](unsigned i) const {
50  assert (i < NumDecls && "Out-of-bounds access.");
51  return ((Decl* const*) (this+1))[i];
52  }
53 };
54 
55 class DeclGroupRef {
56  // Note this is not a PointerIntPair because we need the address of the
57  // non-group case to be valid as a Decl** for iteration.
58  enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
59  Decl* D;
60 
61  Kind getKind() const {
62  return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
63  }
64 
65 public:
66  DeclGroupRef() : D(nullptr) {}
67 
68  explicit DeclGroupRef(Decl* d) : D(d) {}
69  explicit DeclGroupRef(DeclGroup* dg)
70  : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
71 
72  static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
73  if (NumDecls == 0)
74  return DeclGroupRef();
75  if (NumDecls == 1)
76  return DeclGroupRef(Decls[0]);
77  return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
78  }
79 
80  typedef Decl** iterator;
81  typedef Decl* const * const_iterator;
82 
83  bool isNull() const { return D == nullptr; }
84  bool isSingleDecl() const { return getKind() == SingleDeclKind; }
85  bool isDeclGroup() const { return getKind() == DeclGroupKind; }
86 
88  assert(isSingleDecl() && "Isn't a declgroup");
89  return D;
90  }
91  const Decl *getSingleDecl() const {
92  return const_cast<DeclGroupRef*>(this)->getSingleDecl();
93  }
94 
96  assert(isDeclGroup() && "Isn't a declgroup");
97  return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
98  }
99  const DeclGroup &getDeclGroup() const {
100  return const_cast<DeclGroupRef*>(this)->getDeclGroup();
101  }
102 
104  if (isSingleDecl())
105  return D ? &D : nullptr;
106  return &getDeclGroup()[0];
107  }
108 
110  if (isSingleDecl())
111  return D ? &D+1 : nullptr;
112  DeclGroup &G = getDeclGroup();
113  return &G[0] + G.size();
114  }
115 
117  if (isSingleDecl())
118  return D ? &D : nullptr;
119  return &getDeclGroup()[0];
120  }
121 
122  const_iterator end() const {
123  if (isSingleDecl())
124  return D ? &D+1 : nullptr;
125  const DeclGroup &G = getDeclGroup();
126  return &G[0] + G.size();
127  }
128 
129  void *getAsOpaquePtr() const { return D; }
130  static DeclGroupRef getFromOpaquePtr(void *Ptr) {
131  DeclGroupRef X;
132  X.D = static_cast<Decl*>(Ptr);
133  return X;
134  }
135 };
136 
137 } // end clang namespace
138 
139 namespace llvm {
140  // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
141  template <typename T>
143  template <>
144  class PointerLikeTypeTraits<clang::DeclGroupRef> {
145  public:
146  static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
147  return P.getAsOpaquePtr();
148  }
149  static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
151  }
152  enum { NumLowBitsAvailable = 0 };
153  };
154 }
155 #endif
bool isNull() const
Definition: DeclGroup.h:83
bool isDeclGroup() const
Definition: DeclGroup.h:85
DeclGroup & getDeclGroup()
Definition: DeclGroup.h:95
iterator end()
Definition: DeclGroup.h:109
const_iterator begin() const
Definition: DeclGroup.h:116
Decl *& operator[](unsigned i)
Definition: DeclGroup.h:44
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
const DeclGroup & getDeclGroup() const
Definition: DeclGroup.h:99
Decl * getSingleDecl()
Definition: DeclGroup.h:87
iterator begin()
Definition: DeclGroup.h:103
unsigned NumDecls
Definition: DeclGroup.h:30
unsigned size() const
Definition: DeclGroup.h:42
AnnotatingParser & P
Decl *const & operator[](unsigned i) const
Definition: DeclGroup.h:49
static DeclGroupRef getFromOpaquePtr(void *Ptr)
Definition: DeclGroup.h:130
DeclGroupRef(DeclGroup *dg)
Definition: DeclGroup.h:69
static DeclGroup * Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.cpp:20
void * getAsOpaquePtr() const
Definition: DeclGroup.h:129
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:72
const_iterator end() const
Definition: DeclGroup.h:122
DeclGroupRef(Decl *d)
Definition: DeclGroup.h:68
X
Definition: SemaDecl.cpp:11429
Decl *const * const_iterator
Definition: DeclGroup.h:81
static void * getAsVoidPointer(clang::DeclGroupRef P)
Definition: DeclGroup.h:146
static clang::DeclGroupRef getFromVoidPointer(void *P)
Definition: DeclGroup.h:149
const Decl * getSingleDecl() const
Definition: DeclGroup.h:91
bool isSingleDecl() const
Definition: DeclGroup.h:84
Decl * Aligner
Definition: DeclGroup.h:32