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