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