Designator.h revision 686775deca8b8685eb90801495880e3abdd844c2
1//===--- Designator.h - Initialization Designator ---------------*- 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 interfaces used to represent designators (a la
11// C99 designated initializers) during parsing.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
16#define LLVM_CLANG_SEMA_DESIGNATOR_H
17
18#include "clang/Basic/SourceLocation.h"
19#include "llvm/ADT/SmallVector.h"
20
21namespace clang {
22
23class Expr;
24class IdentifierInfo;
25class Sema;
26
27/// Designator - A designator in a C99 designated initializer.
28///
29/// This class is a discriminated union which holds the various
30/// different sorts of designators possible.  A Designation is an array of
31/// these.  An example of a designator are things like this:
32///     [8] .field [47]        // C99 designation: 3 designators
33///     [8 ... 47]  field:     // GNU extensions: 2 designators
34/// These occur in initializers, e.g.:
35///  int a[10] = {2, 4, [8]=9, 10};
36///
37class Designator {
38public:
39  enum DesignatorKind {
40    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
41  };
42private:
43  DesignatorKind Kind;
44
45  struct FieldDesignatorInfo {
46    const IdentifierInfo *II;
47    unsigned DotLoc;
48    unsigned NameLoc;
49  };
50  struct ArrayDesignatorInfo {
51    Expr *Index;
52    unsigned LBracketLoc;
53    mutable unsigned  RBracketLoc;
54  };
55  struct ArrayRangeDesignatorInfo {
56    Expr *Start, *End;
57    unsigned LBracketLoc, EllipsisLoc;
58    mutable unsigned RBracketLoc;
59  };
60
61  union {
62    FieldDesignatorInfo FieldInfo;
63    ArrayDesignatorInfo ArrayInfo;
64    ArrayRangeDesignatorInfo ArrayRangeInfo;
65  };
66
67public:
68
69  DesignatorKind getKind() const { return Kind; }
70  bool isFieldDesignator() const { return Kind == FieldDesignator; }
71  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
72  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
73
74  const IdentifierInfo *getField() const {
75    assert(isFieldDesignator() && "Invalid accessor");
76    return FieldInfo.II;
77  }
78
79  SourceLocation getDotLoc() const {
80    assert(isFieldDesignator() && "Invalid accessor");
81    return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
82  }
83
84  SourceLocation getFieldLoc() const {
85    assert(isFieldDesignator() && "Invalid accessor");
86    return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
87  }
88
89  Expr *getArrayIndex() const {
90    assert(isArrayDesignator() && "Invalid accessor");
91    return ArrayInfo.Index;
92  }
93
94  Expr *getArrayRangeStart() const {
95    assert(isArrayRangeDesignator() && "Invalid accessor");
96    return ArrayRangeInfo.Start;
97  }
98  Expr *getArrayRangeEnd() const {
99    assert(isArrayRangeDesignator() && "Invalid accessor");
100    return ArrayRangeInfo.End;
101  }
102
103  SourceLocation getLBracketLoc() const {
104    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
105           "Invalid accessor");
106    if (isArrayDesignator())
107      return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
108    else
109      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
110  }
111
112  SourceLocation getRBracketLoc() const {
113    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
114           "Invalid accessor");
115    if (isArrayDesignator())
116      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
117    else
118      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
119  }
120
121  SourceLocation getEllipsisLoc() const {
122    assert(isArrayRangeDesignator() && "Invalid accessor");
123    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
124  }
125
126  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
127                             SourceLocation NameLoc) {
128    Designator D;
129    D.Kind = FieldDesignator;
130    D.FieldInfo.II = II;
131    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
132    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
133    return D;
134  }
135
136  static Designator getArray(Expr *Index,
137                             SourceLocation LBracketLoc) {
138    Designator D;
139    D.Kind = ArrayDesignator;
140    D.ArrayInfo.Index = Index;
141    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
142    D.ArrayInfo.RBracketLoc = 0;
143    return D;
144  }
145
146  static Designator getArrayRange(Expr *Start,
147                                  Expr *End,
148                                  SourceLocation LBracketLoc,
149                                  SourceLocation EllipsisLoc) {
150    Designator D;
151    D.Kind = ArrayRangeDesignator;
152    D.ArrayRangeInfo.Start = Start;
153    D.ArrayRangeInfo.End = End;
154    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
155    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
156    D.ArrayRangeInfo.RBracketLoc = 0;
157    return D;
158  }
159
160  void setRBracketLoc(SourceLocation RBracketLoc) const {
161    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
162           "Invalid accessor");
163    if (isArrayDesignator())
164      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
165    else
166      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
167  }
168
169  /// ClearExprs - Null out any expression references, which prevents
170  /// them from being 'delete'd later.
171  void ClearExprs(Sema &Actions) {}
172
173  /// FreeExprs - Release any unclaimed memory for the expressions in
174  /// this designator.
175  void FreeExprs(Sema &Actions) {}
176};
177
178
179/// Designation - Represent a full designation, which is a sequence of
180/// designators.  This class is mostly a helper for InitListDesignations.
181class Designation {
182  /// InitIndex - The index of the initializer expression this is for.  For
183  /// example, if the initializer were "{ A, .foo=B, C }" a Designation would
184  /// exist with InitIndex=1, because element #1 has a designation.
185  unsigned InitIndex;
186
187  /// Designators - The actual designators for this initializer.
188  SmallVector<Designator, 2> Designators;
189
190  Designation(unsigned Idx) : InitIndex(Idx) {}
191public:
192  Designation() : InitIndex(4000) {}
193
194  /// AddDesignator - Add a designator to the end of this list.
195  void AddDesignator(Designator D) {
196    Designators.push_back(D);
197  }
198
199  bool empty() const { return Designators.empty(); }
200
201  unsigned getNumDesignators() const { return Designators.size(); }
202  const Designator &getDesignator(unsigned Idx) const {
203    assert(Idx < Designators.size());
204    return Designators[Idx];
205  }
206
207  /// ClearExprs - Null out any expression references, which prevents them from
208  /// being 'delete'd later.
209  void ClearExprs(Sema &Actions) {}
210
211  /// FreeExprs - Release any unclaimed memory for the expressions in this
212  /// designation.
213  void FreeExprs(Sema &Actions) {}
214};
215
216} // end namespace clang
217
218#endif
219