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   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   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.
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   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
215