/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Sema/Designator.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
20 | | namespace clang { |
21 | | |
22 | | class Expr; |
23 | | class IdentifierInfo; |
24 | | class 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 | | /// |
36 | | class Designator { |
37 | | public: |
38 | | enum DesignatorKind { |
39 | | FieldDesignator, ArrayDesignator, ArrayRangeDesignator |
40 | | }; |
41 | | private: |
42 | 2.49k | 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 | | |
68 | | public: |
69 | | |
70 | 2.47k | DesignatorKind getKind() const { return Kind; } |
71 | 6.29k | bool isFieldDesignator() const { return Kind == FieldDesignator; } |
72 | 2.86k | bool isArrayDesignator() const { return Kind == ArrayDesignator; } |
73 | 223 | bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } |
74 | | |
75 | 2.11k | const IdentifierInfo *getField() const { |
76 | 2.11k | assert(isFieldDesignator() && "Invalid accessor"); |
77 | 0 | return FieldInfo.II; |
78 | 2.11k | } |
79 | | |
80 | 2.06k | SourceLocation getDotLoc() const { |
81 | 2.06k | assert(isFieldDesignator() && "Invalid accessor"); |
82 | 0 | return FieldInfo.DotLoc; |
83 | 2.06k | } |
84 | | |
85 | 2.06k | SourceLocation getFieldLoc() const { |
86 | 2.06k | assert(isFieldDesignator() && "Invalid accessor"); |
87 | 0 | return FieldInfo.NameLoc; |
88 | 2.06k | } |
89 | | |
90 | 387 | Expr *getArrayIndex() const { |
91 | 387 | assert(isArrayDesignator() && "Invalid accessor"); |
92 | 0 | return ArrayInfo.Index; |
93 | 387 | } |
94 | | |
95 | 28 | Expr *getArrayRangeStart() const { |
96 | 28 | assert(isArrayRangeDesignator() && "Invalid accessor"); |
97 | 0 | return ArrayRangeInfo.Start; |
98 | 28 | } |
99 | 28 | Expr *getArrayRangeEnd() const { |
100 | 28 | assert(isArrayRangeDesignator() && "Invalid accessor"); |
101 | 0 | return ArrayRangeInfo.End; |
102 | 28 | } |
103 | | |
104 | 404 | SourceLocation getLBracketLoc() const { |
105 | 404 | assert((isArrayDesignator() || isArrayRangeDesignator()) && |
106 | 404 | "Invalid accessor"); |
107 | 404 | if (isArrayDesignator()) |
108 | 377 | return ArrayInfo.LBracketLoc; |
109 | 27 | else |
110 | 27 | return ArrayRangeInfo.LBracketLoc; |
111 | 404 | } |
112 | | |
113 | 404 | SourceLocation getRBracketLoc() const { |
114 | 404 | assert((isArrayDesignator() || isArrayRangeDesignator()) && |
115 | 404 | "Invalid accessor"); |
116 | 404 | if (isArrayDesignator()) |
117 | 377 | return ArrayInfo.RBracketLoc; |
118 | 27 | else |
119 | 27 | return ArrayRangeInfo.RBracketLoc; |
120 | 404 | } |
121 | | |
122 | 28 | SourceLocation getEllipsisLoc() const { |
123 | 28 | assert(isArrayRangeDesignator() && "Invalid accessor"); |
124 | 0 | return ArrayRangeInfo.EllipsisLoc; |
125 | 28 | } |
126 | | |
127 | | static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, |
128 | 2.06k | SourceLocation NameLoc) { |
129 | 2.06k | Designator D; |
130 | 2.06k | D.Kind = FieldDesignator; |
131 | 2.06k | new (&D.FieldInfo) FieldDesignatorInfo; |
132 | 2.06k | D.FieldInfo.II = II; |
133 | 2.06k | D.FieldInfo.DotLoc = DotLoc; |
134 | 2.06k | D.FieldInfo.NameLoc = NameLoc; |
135 | 2.06k | return D; |
136 | 2.06k | } |
137 | | |
138 | | static Designator getArray(Expr *Index, |
139 | 397 | SourceLocation LBracketLoc) { |
140 | 397 | Designator D; |
141 | 397 | D.Kind = ArrayDesignator; |
142 | 397 | new (&D.ArrayInfo) ArrayDesignatorInfo; |
143 | 397 | D.ArrayInfo.Index = Index; |
144 | 397 | D.ArrayInfo.LBracketLoc = LBracketLoc; |
145 | 397 | D.ArrayInfo.RBracketLoc = SourceLocation(); |
146 | 397 | return D; |
147 | 397 | } |
148 | | |
149 | | static Designator getArrayRange(Expr *Start, |
150 | | Expr *End, |
151 | | SourceLocation LBracketLoc, |
152 | 28 | SourceLocation EllipsisLoc) { |
153 | 28 | Designator D; |
154 | 28 | D.Kind = ArrayRangeDesignator; |
155 | 28 | new (&D.ArrayRangeInfo) ArrayRangeDesignatorInfo; |
156 | 28 | D.ArrayRangeInfo.Start = Start; |
157 | 28 | D.ArrayRangeInfo.End = End; |
158 | 28 | D.ArrayRangeInfo.LBracketLoc = LBracketLoc; |
159 | 28 | D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc; |
160 | 28 | D.ArrayRangeInfo.RBracketLoc = SourceLocation(); |
161 | 28 | return D; |
162 | 28 | } |
163 | | |
164 | 393 | void setRBracketLoc(SourceLocation RBracketLoc) const { |
165 | 393 | assert((isArrayDesignator() || isArrayRangeDesignator()) && |
166 | 393 | "Invalid accessor"); |
167 | 393 | if (isArrayDesignator()) |
168 | 373 | ArrayInfo.RBracketLoc = RBracketLoc; |
169 | 20 | else |
170 | 20 | ArrayRangeInfo.RBracketLoc = RBracketLoc; |
171 | 393 | } |
172 | | |
173 | | /// ClearExprs - Null out any expression references, which prevents |
174 | | /// them from being 'delete'd later. |
175 | 0 | void ClearExprs(Sema &Actions) {} |
176 | | |
177 | | /// FreeExprs - Release any unclaimed memory for the expressions in |
178 | | /// this designator. |
179 | 0 | 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. |
185 | | class Designation { |
186 | | /// Designators - The actual designators for this initializer. |
187 | | SmallVector<Designator, 2> Designators; |
188 | | |
189 | | public: |
190 | | /// AddDesignator - Add a designator to the end of this list. |
191 | 2.49k | void AddDesignator(Designator D) { |
192 | 2.49k | Designators.push_back(D); |
193 | 2.49k | } |
194 | | |
195 | 1.88k | bool empty() const { return Designators.empty(); } |
196 | | |
197 | 5.28k | unsigned getNumDesignators() const { return Designators.size(); } |
198 | 2.95k | const Designator &getDesignator(unsigned Idx) const { |
199 | 2.95k | assert(Idx < Designators.size()); |
200 | 0 | return Designators[Idx]; |
201 | 2.95k | } |
202 | | |
203 | | /// ClearExprs - Null out any expression references, which prevents them from |
204 | | /// being 'delete'd later. |
205 | 2.13k | void ClearExprs(Sema &Actions) {} |
206 | | |
207 | | /// FreeExprs - Release any unclaimed memory for the expressions in this |
208 | | /// designation. |
209 | 0 | void FreeExprs(Sema &Actions) {} |
210 | | }; |
211 | | |
212 | | } // end namespace clang |
213 | | |
214 | | #endif |