Designator.h revision 212904
1191762Simp//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
2191762Simp//
3191762Simp//                     The LLVM Compiler Infrastructure
4191762Simp//
5191762Simp// This file is distributed under the University of Illinois Open Source
6191762Simp// License. See LICENSE.TXT for details.
7191762Simp//
8191762Simp//===----------------------------------------------------------------------===//
9191762Simp//
10191762Simp// This file defines interfaces used to represent designators (a la
11191762Simp// C99 designated initializers) during parsing.
12191762Simp//
13191762Simp//===----------------------------------------------------------------------===//
14191762Simp
15191762Simp#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
16191762Simp#define LLVM_CLANG_SEMA_DESIGNATOR_H
17191762Simp
18191762Simp#include "clang/Basic/SourceLocation.h"
19191762Simp#include "llvm/ADT/SmallVector.h"
20191762Simp
21191762Simpnamespace clang {
22191762Simp
23191762Simpclass Expr;
24191762Simpclass IdentifierInfo;
25191762Simpclass Sema;
26191762Simp
27191762Simp/// Designator - A designator in a C99 designated initializer.
28191762Simp///
29191762Simp/// This class is a discriminated union which holds the various
30191762Simp/// different sorts of designators possible.  A Designation is an array of
31191762Simp/// these.  An example of a designator are things like this:
32191762Simp///     [8] .field [47]        // C99 designation: 3 designators
33191762Simp///     [8 ... 47]  field:     // GNU extensions: 2 designators
34191762Simp/// These occur in initializers, e.g.:
35191762Simp///  int a[10] = {2, 4, [8]=9, 10};
36191762Simp///
37191762Simpclass Designator {
38191762Simppublic:
39191762Simp  enum DesignatorKind {
40191762Simp    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
41191762Simp  };
42191762Simpprivate:
43191762Simp  DesignatorKind Kind;
44191762Simp
45191762Simp  struct FieldDesignatorInfo {
46191762Simp    const IdentifierInfo *II;
47191762Simp    unsigned DotLoc;
48191762Simp    unsigned NameLoc;
49191762Simp  };
50191762Simp  struct ArrayDesignatorInfo {
51191762Simp    Expr *Index;
52191762Simp    unsigned LBracketLoc;
53191762Simp    mutable unsigned  RBracketLoc;
54191762Simp  };
55191762Simp  struct ArrayRangeDesignatorInfo {
56191762Simp    Expr *Start, *End;
57191762Simp    unsigned LBracketLoc, EllipsisLoc;
58191762Simp    mutable unsigned RBracketLoc;
59191762Simp  };
60191762Simp
61191762Simp  union {
62191762Simp    FieldDesignatorInfo FieldInfo;
63191762Simp    ArrayDesignatorInfo ArrayInfo;
64191762Simp    ArrayRangeDesignatorInfo ArrayRangeInfo;
65191762Simp  };
66191762Simp
67191762Simppublic:
68191762Simp
69191762Simp  DesignatorKind getKind() const { return Kind; }
70191762Simp  bool isFieldDesignator() const { return Kind == FieldDesignator; }
71191762Simp  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
72191762Simp  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
73191762Simp
74191762Simp  const IdentifierInfo *getField() const {
75191762Simp    assert(isFieldDesignator() && "Invalid accessor");
76191762Simp    return FieldInfo.II;
77191762Simp  }
78191762Simp
79191762Simp  SourceLocation getDotLoc() const {
80191762Simp    assert(isFieldDesignator() && "Invalid accessor");
81191762Simp    return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
82191762Simp  }
83191762Simp
84191762Simp  SourceLocation getFieldLoc() const {
85191762Simp    assert(isFieldDesignator() && "Invalid accessor");
86191762Simp    return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
87191762Simp  }
88191762Simp
89191762Simp  Expr *getArrayIndex() const {
90191762Simp    assert(isArrayDesignator() && "Invalid accessor");
91191762Simp    return ArrayInfo.Index;
92191762Simp  }
93191762Simp
94191762Simp  Expr *getArrayRangeStart() const {
95191762Simp    assert(isArrayRangeDesignator() && "Invalid accessor");
96191762Simp    return ArrayRangeInfo.Start;
97191762Simp  }
98191762Simp  Expr *getArrayRangeEnd() const {
99191762Simp    assert(isArrayRangeDesignator() && "Invalid accessor");
100191762Simp    return ArrayRangeInfo.End;
101191762Simp  }
102191762Simp
103191762Simp  SourceLocation getLBracketLoc() const {
104191762Simp    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
105191762Simp           "Invalid accessor");
106191762Simp    if (isArrayDesignator())
107191762Simp      return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
108191762Simp    else
109191762Simp      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
110191762Simp  }
111191762Simp
112191762Simp  SourceLocation getRBracketLoc() const {
113191762Simp    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
114191762Simp           "Invalid accessor");
115191762Simp    if (isArrayDesignator())
116191762Simp      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
117191762Simp    else
118191762Simp      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
119191762Simp  }
120191762Simp
121191762Simp  SourceLocation getEllipsisLoc() const {
122191762Simp    assert(isArrayRangeDesignator() && "Invalid accessor");
123191762Simp    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
124191762Simp  }
125191762Simp
126191762Simp  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
127191762Simp                             SourceLocation NameLoc) {
128191762Simp    Designator D;
129191762Simp    D.Kind = FieldDesignator;
130191762Simp    D.FieldInfo.II = II;
131191762Simp    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
132191762Simp    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
133191762Simp    return D;
134191762Simp  }
135191762Simp
136191762Simp  static Designator getArray(Expr *Index,
137191762Simp                             SourceLocation LBracketLoc) {
138191762Simp    Designator D;
139191762Simp    D.Kind = ArrayDesignator;
140191762Simp    D.ArrayInfo.Index = Index;
141191762Simp    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
142191762Simp    D.ArrayInfo.RBracketLoc = 0;
143191762Simp    return D;
144191762Simp  }
145191762Simp
146191762Simp  static Designator getArrayRange(Expr *Start,
147191762Simp                                  Expr *End,
148191762Simp                                  SourceLocation LBracketLoc,
149191762Simp                                  SourceLocation EllipsisLoc) {
150191762Simp    Designator D;
151191762Simp    D.Kind = ArrayRangeDesignator;
152191762Simp    D.ArrayRangeInfo.Start = Start;
153191762Simp    D.ArrayRangeInfo.End = End;
154191762Simp    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
155191762Simp    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
156191762Simp    D.ArrayRangeInfo.RBracketLoc = 0;
157191762Simp    return D;
158191762Simp  }
159191762Simp
160191762Simp  void setRBracketLoc(SourceLocation RBracketLoc) const {
161191762Simp    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
162191762Simp           "Invalid accessor");
163191762Simp    if (isArrayDesignator())
164191762Simp      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
165191762Simp    else
166191762Simp      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
167191762Simp  }
168191762Simp
169191762Simp  /// ClearExprs - Null out any expression references, which prevents
170191762Simp  /// them from being 'delete'd later.
171191762Simp  void ClearExprs(Sema &Actions) {}
172191762Simp
173191762Simp  /// FreeExprs - Release any unclaimed memory for the expressions in
174191762Simp  /// this designator.
175191762Simp  void FreeExprs(Sema &Actions) {}
176191762Simp};
177191762Simp
178191762Simp
179191762Simp/// Designation - Represent a full designation, which is a sequence of
180191762Simp/// designators.  This class is mostly a helper for InitListDesignations.
181191762Simpclass Designation {
182191762Simp  /// InitIndex - The index of the initializer expression this is for.  For
183191762Simp  /// example, if the initializer were "{ A, .foo=B, C }" a Designation would
184191762Simp  /// exist with InitIndex=1, because element #1 has a designation.
185191762Simp  unsigned InitIndex;
186191762Simp
187191762Simp  /// Designators - The actual designators for this initializer.
188191762Simp  llvm::SmallVector<Designator, 2> Designators;
189191762Simp
190191762Simp  Designation(unsigned Idx) : InitIndex(Idx) {}
191191762Simppublic:
192191762Simp  Designation() : InitIndex(4000) {}
193191762Simp
194191762Simp  /// AddDesignator - Add a designator to the end of this list.
195191762Simp  void AddDesignator(Designator D) {
196191762Simp    Designators.push_back(D);
197191762Simp  }
198191762Simp
199191762Simp  bool empty() const { return Designators.empty(); }
200191762Simp
201191762Simp  unsigned getNumDesignators() const { return Designators.size(); }
202191762Simp  const Designator &getDesignator(unsigned Idx) const {
203191762Simp    assert(Idx < Designators.size());
204191762Simp    return Designators[Idx];
205191762Simp  }
206191762Simp
207191762Simp  /// ClearExprs - Null out any expression references, which prevents them from
208191762Simp  /// being 'delete'd later.
209191762Simp  void ClearExprs(Sema &Actions) {}
210191762Simp
211191762Simp  /// FreeExprs - Release any unclaimed memory for the expressions in this
212191762Simp  /// designation.
213191762Simp  void FreeExprs(Sema &Actions) {}
214191762Simp};
215191762Simp
216191762Simp} // end namespace clang
217191762Simp
218191762Simp#endif
219191762Simp