1212795Sdim//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim// This file defines interfaces used to represent designators (a la
11212795Sdim// C99 designated initializers) during parsing.
12212795Sdim//
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim
15212795Sdim#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
16212795Sdim#define LLVM_CLANG_SEMA_DESIGNATOR_H
17212795Sdim
18212795Sdim#include "clang/Basic/SourceLocation.h"
19212795Sdim#include "llvm/ADT/SmallVector.h"
20212795Sdim
21212795Sdimnamespace clang {
22212795Sdim
23212795Sdimclass Expr;
24212795Sdimclass IdentifierInfo;
25212795Sdimclass Sema;
26212795Sdim
27212795Sdim/// Designator - A designator in a C99 designated initializer.
28212795Sdim///
29212795Sdim/// This class is a discriminated union which holds the various
30212795Sdim/// different sorts of designators possible.  A Designation is an array of
31212795Sdim/// these.  An example of a designator are things like this:
32212795Sdim///     [8] .field [47]        // C99 designation: 3 designators
33212795Sdim///     [8 ... 47]  field:     // GNU extensions: 2 designators
34212795Sdim/// These occur in initializers, e.g.:
35212795Sdim///  int a[10] = {2, 4, [8]=9, 10};
36212795Sdim///
37212795Sdimclass Designator {
38212795Sdimpublic:
39212795Sdim  enum DesignatorKind {
40212795Sdim    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
41212795Sdim  };
42212795Sdimprivate:
43212795Sdim  DesignatorKind Kind;
44212795Sdim
45212795Sdim  struct FieldDesignatorInfo {
46212795Sdim    const IdentifierInfo *II;
47212795Sdim    unsigned DotLoc;
48212795Sdim    unsigned NameLoc;
49212795Sdim  };
50212795Sdim  struct ArrayDesignatorInfo {
51212795Sdim    Expr *Index;
52212795Sdim    unsigned LBracketLoc;
53212795Sdim    mutable unsigned  RBracketLoc;
54212795Sdim  };
55212795Sdim  struct ArrayRangeDesignatorInfo {
56212795Sdim    Expr *Start, *End;
57212795Sdim    unsigned LBracketLoc, EllipsisLoc;
58212795Sdim    mutable unsigned RBracketLoc;
59212795Sdim  };
60212795Sdim
61212795Sdim  union {
62212795Sdim    FieldDesignatorInfo FieldInfo;
63212795Sdim    ArrayDesignatorInfo ArrayInfo;
64212795Sdim    ArrayRangeDesignatorInfo ArrayRangeInfo;
65212795Sdim  };
66212795Sdim
67212795Sdimpublic:
68212795Sdim
69212795Sdim  DesignatorKind getKind() const { return Kind; }
70212795Sdim  bool isFieldDesignator() const { return Kind == FieldDesignator; }
71212795Sdim  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
72212795Sdim  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
73212795Sdim
74212795Sdim  const IdentifierInfo *getField() const {
75212795Sdim    assert(isFieldDesignator() && "Invalid accessor");
76212795Sdim    return FieldInfo.II;
77212795Sdim  }
78212795Sdim
79212795Sdim  SourceLocation getDotLoc() const {
80212795Sdim    assert(isFieldDesignator() && "Invalid accessor");
81212795Sdim    return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
82212795Sdim  }
83212795Sdim
84212795Sdim  SourceLocation getFieldLoc() const {
85212795Sdim    assert(isFieldDesignator() && "Invalid accessor");
86212795Sdim    return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
87212795Sdim  }
88212795Sdim
89212795Sdim  Expr *getArrayIndex() const {
90212795Sdim    assert(isArrayDesignator() && "Invalid accessor");
91212795Sdim    return ArrayInfo.Index;
92212795Sdim  }
93212795Sdim
94212795Sdim  Expr *getArrayRangeStart() const {
95212795Sdim    assert(isArrayRangeDesignator() && "Invalid accessor");
96212795Sdim    return ArrayRangeInfo.Start;
97212795Sdim  }
98212795Sdim  Expr *getArrayRangeEnd() const {
99212795Sdim    assert(isArrayRangeDesignator() && "Invalid accessor");
100212795Sdim    return ArrayRangeInfo.End;
101212795Sdim  }
102212795Sdim
103212795Sdim  SourceLocation getLBracketLoc() const {
104212795Sdim    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
105212795Sdim           "Invalid accessor");
106212795Sdim    if (isArrayDesignator())
107212795Sdim      return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
108212795Sdim    else
109212795Sdim      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
110212795Sdim  }
111212795Sdim
112212795Sdim  SourceLocation getRBracketLoc() const {
113212795Sdim    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
114212795Sdim           "Invalid accessor");
115212795Sdim    if (isArrayDesignator())
116212795Sdim      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
117212795Sdim    else
118212795Sdim      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
119212795Sdim  }
120212795Sdim
121212795Sdim  SourceLocation getEllipsisLoc() const {
122212795Sdim    assert(isArrayRangeDesignator() && "Invalid accessor");
123212795Sdim    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
124212795Sdim  }
125212795Sdim
126212795Sdim  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
127212795Sdim                             SourceLocation NameLoc) {
128212795Sdim    Designator D;
129212795Sdim    D.Kind = FieldDesignator;
130212795Sdim    D.FieldInfo.II = II;
131212795Sdim    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
132212795Sdim    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
133212795Sdim    return D;
134212795Sdim  }
135212795Sdim
136212795Sdim  static Designator getArray(Expr *Index,
137212795Sdim                             SourceLocation LBracketLoc) {
138212795Sdim    Designator D;
139212795Sdim    D.Kind = ArrayDesignator;
140212795Sdim    D.ArrayInfo.Index = Index;
141212795Sdim    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
142212795Sdim    D.ArrayInfo.RBracketLoc = 0;
143212795Sdim    return D;
144212795Sdim  }
145212795Sdim
146212795Sdim  static Designator getArrayRange(Expr *Start,
147212795Sdim                                  Expr *End,
148212795Sdim                                  SourceLocation LBracketLoc,
149212795Sdim                                  SourceLocation EllipsisLoc) {
150212795Sdim    Designator D;
151212795Sdim    D.Kind = ArrayRangeDesignator;
152212795Sdim    D.ArrayRangeInfo.Start = Start;
153212795Sdim    D.ArrayRangeInfo.End = End;
154212795Sdim    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
155212795Sdim    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
156212795Sdim    D.ArrayRangeInfo.RBracketLoc = 0;
157212795Sdim    return D;
158212795Sdim  }
159212795Sdim
160212795Sdim  void setRBracketLoc(SourceLocation RBracketLoc) const {
161212795Sdim    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
162212795Sdim           "Invalid accessor");
163212795Sdim    if (isArrayDesignator())
164212795Sdim      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
165212795Sdim    else
166212795Sdim      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
167212795Sdim  }
168212795Sdim
169212795Sdim  /// ClearExprs - Null out any expression references, which prevents
170212795Sdim  /// them from being 'delete'd later.
171212795Sdim  void ClearExprs(Sema &Actions) {}
172212795Sdim
173212795Sdim  /// FreeExprs - Release any unclaimed memory for the expressions in
174212795Sdim  /// this designator.
175212795Sdim  void FreeExprs(Sema &Actions) {}
176212795Sdim};
177212795Sdim
178212795Sdim
179212795Sdim/// Designation - Represent a full designation, which is a sequence of
180212795Sdim/// designators.  This class is mostly a helper for InitListDesignations.
181212795Sdimclass Designation {
182212795Sdim  /// Designators - The actual designators for this initializer.
183226890Sdim  SmallVector<Designator, 2> Designators;
184212795Sdim
185212795Sdimpublic:
186212795Sdim  /// AddDesignator - Add a designator to the end of this list.
187212795Sdim  void AddDesignator(Designator D) {
188212795Sdim    Designators.push_back(D);
189212795Sdim  }
190212795Sdim
191212795Sdim  bool empty() const { return Designators.empty(); }
192212795Sdim
193212795Sdim  unsigned getNumDesignators() const { return Designators.size(); }
194212795Sdim  const Designator &getDesignator(unsigned Idx) const {
195212795Sdim    assert(Idx < Designators.size());
196212795Sdim    return Designators[Idx];
197212795Sdim  }
198212795Sdim
199212795Sdim  /// ClearExprs - Null out any expression references, which prevents them from
200212795Sdim  /// being 'delete'd later.
201212795Sdim  void ClearExprs(Sema &Actions) {}
202212795Sdim
203212795Sdim  /// FreeExprs - Release any unclaimed memory for the expressions in this
204212795Sdim  /// designation.
205212795Sdim  void FreeExprs(Sema &Actions) {}
206212795Sdim};
207212795Sdim
208212795Sdim} // end namespace clang
209212795Sdim
210212795Sdim#endif
211