1//===--- 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;
24
25/// Designator - A designator in a C99 designated initializer.
26///
27/// This class is a discriminated union which holds the various
28/// different sorts of designators possible. A Designation is an array of
29/// these. An example of a designator are things like this:
30///
31/// [8] .field [47] // C99 designation: 3 designators
32/// [8 ... 47] field: // GNU extensions: 2 designators
33///
34/// These occur in initializers, e.g.:
35///
36/// int a[10] = {2, 4, [8]=9, 10};
37///
38class Designator {
39 /// A field designator, e.g., ".x = 42".
40 struct FieldDesignatorInfo {
41 /// Refers to the field being initialized.
42 const IdentifierInfo *FieldName;
43
44 /// The location of the '.' in the designated initializer.
45 SourceLocation DotLoc;
46
47 /// The location of the field name in the designated initializer.
48 SourceLocation FieldLoc;
49
50 FieldDesignatorInfo(const IdentifierInfo *FieldName, SourceLocation DotLoc,
51 SourceLocation FieldLoc)
52 : FieldName(FieldName), DotLoc(DotLoc), FieldLoc(FieldLoc) {}
53 };
54
55 /// An array designator, e.g., "[42] = 0".
56 struct ArrayDesignatorInfo {
57 Expr *Index;
58
59 // The location of the '[' in the designated initializer.
60 SourceLocation LBracketLoc;
61
62 // The location of the ']' in the designated initializer.
63 mutable SourceLocation RBracketLoc;
64
65 ArrayDesignatorInfo(Expr *Index, SourceLocation LBracketLoc)
66 : Index(Index), LBracketLoc(LBracketLoc) {}
67 };
68
69 /// An array range designator, e.g. "[42 ... 50] = 1".
70 struct ArrayRangeDesignatorInfo {
71 Expr *Start;
72 Expr *End;
73
74 // The location of the '[' in the designated initializer.
75 SourceLocation LBracketLoc;
76
77 // The location of the '...' in the designated initializer.
78 SourceLocation EllipsisLoc;
79
80 // The location of the ']' in the designated initializer.
81 mutable SourceLocation RBracketLoc;
82
83 ArrayRangeDesignatorInfo(Expr *Start, Expr *End, SourceLocation LBracketLoc,
84 SourceLocation EllipsisLoc)
85 : Start(Start), End(End), LBracketLoc(LBracketLoc),
86 EllipsisLoc(EllipsisLoc) {}
87 };
88
89 /// The kind of designator this describes.
90 enum DesignatorKind {
91 FieldDesignator,
92 ArrayDesignator,
93 ArrayRangeDesignator
94 };
95
96 DesignatorKind Kind;
97
98 union {
99 FieldDesignatorInfo FieldInfo;
100 ArrayDesignatorInfo ArrayInfo;
101 ArrayRangeDesignatorInfo ArrayRangeInfo;
102 };
103
104 Designator(DesignatorKind Kind) : Kind(Kind) {}
105
106public:
107 bool isFieldDesignator() const { return Kind == FieldDesignator; }
108 bool isArrayDesignator() const { return Kind == ArrayDesignator; }
109 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
110
111 //===--------------------------------------------------------------------===//
112 // FieldDesignatorInfo
113
114 /// Creates a field designator.
115 static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
116 SourceLocation DotLoc,
117 SourceLocation FieldLoc) {
118 Designator D(FieldDesignator);
119 new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
120 return D;
121 }
122
123 const IdentifierInfo *getFieldDecl() const {
124 assert(isFieldDesignator() && "Invalid accessor");
125 return FieldInfo.FieldName;
126 }
127
128 SourceLocation getDotLoc() const {
129 assert(isFieldDesignator() && "Invalid accessor");
130 return FieldInfo.DotLoc;
131 }
132
133 SourceLocation getFieldLoc() const {
134 assert(isFieldDesignator() && "Invalid accessor");
135 return FieldInfo.FieldLoc;
136 }
137
138 //===--------------------------------------------------------------------===//
139 // ArrayDesignatorInfo:
140
141 /// Creates an array designator.
142 static Designator CreateArrayDesignator(Expr *Index,
143 SourceLocation LBracketLoc) {
144 Designator D(ArrayDesignator);
145 new (&D.ArrayInfo) ArrayDesignatorInfo(Index, LBracketLoc);
146 return D;
147 }
148
149 Expr *getArrayIndex() const {
150 assert(isArrayDesignator() && "Invalid accessor");
151 return ArrayInfo.Index;
152 }
153
154 SourceLocation getLBracketLoc() const {
155 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
156 "Invalid accessor");
157 return isArrayDesignator() ? ArrayInfo.LBracketLoc
158 : ArrayRangeInfo.LBracketLoc;
159 }
160
161 SourceLocation getRBracketLoc() const {
162 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
163 "Invalid accessor");
164 return isArrayDesignator() ? ArrayInfo.RBracketLoc
165 : ArrayRangeInfo.RBracketLoc;
166 }
167
168 //===--------------------------------------------------------------------===//
169 // ArrayRangeDesignatorInfo:
170
171 /// Creates a GNU array-range designator.
172 static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End,
173 SourceLocation LBracketLoc,
174 SourceLocation EllipsisLoc) {
175 Designator D(ArrayRangeDesignator);
176 new (&D.ArrayRangeInfo)
177 ArrayRangeDesignatorInfo(Start, End, LBracketLoc, EllipsisLoc);
178 return D;
179 }
180
181 Expr *getArrayRangeStart() const {
182 assert(isArrayRangeDesignator() && "Invalid accessor");
183 return ArrayRangeInfo.Start;
184 }
185
186 Expr *getArrayRangeEnd() const {
187 assert(isArrayRangeDesignator() && "Invalid accessor");
188 return ArrayRangeInfo.End;
189 }
190
191 SourceLocation getEllipsisLoc() const {
192 assert(isArrayRangeDesignator() && "Invalid accessor");
193 return ArrayRangeInfo.EllipsisLoc;
194 }
195
196 void setRBracketLoc(SourceLocation RBracketLoc) const {
197 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
198 "Invalid accessor");
199 if (isArrayDesignator())
200 ArrayInfo.RBracketLoc = RBracketLoc;
201 else
202 ArrayRangeInfo.RBracketLoc = RBracketLoc;
203 }
204};
205
206/// Designation - Represent a full designation, which is a sequence of
207/// designators. This class is mostly a helper for InitListDesignations.
208class Designation {
209 /// Designators - The actual designators for this initializer.
210 SmallVector<Designator, 2> Designators;
211
212public:
213 /// AddDesignator - Add a designator to the end of this list.
214 void AddDesignator(Designator D) { Designators.push_back(Elt: D); }
215
216 bool empty() const { return Designators.empty(); }
217
218 unsigned getNumDesignators() const { return Designators.size(); }
219 const Designator &getDesignator(unsigned Idx) const {
220 assert(Idx < Designators.size());
221 return Designators[Idx];
222 }
223};
224
225} // end namespace clang
226
227#endif
228

source code of clang/include/clang/Sema/Designator.h