106f32e7eSjoerg //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file defines interfaces used to represent designators (a la
1006f32e7eSjoerg // C99 designated initializers) during parsing.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===----------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
1506f32e7eSjoerg #define LLVM_CLANG_SEMA_DESIGNATOR_H
1606f32e7eSjoerg 
1706f32e7eSjoerg #include "clang/Basic/SourceLocation.h"
1806f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
1906f32e7eSjoerg 
2006f32e7eSjoerg namespace clang {
2106f32e7eSjoerg 
2206f32e7eSjoerg class Expr;
2306f32e7eSjoerg class IdentifierInfo;
2406f32e7eSjoerg class Sema;
2506f32e7eSjoerg 
2606f32e7eSjoerg /// Designator - A designator in a C99 designated initializer.
2706f32e7eSjoerg ///
2806f32e7eSjoerg /// This class is a discriminated union which holds the various
2906f32e7eSjoerg /// different sorts of designators possible.  A Designation is an array of
3006f32e7eSjoerg /// these.  An example of a designator are things like this:
3106f32e7eSjoerg ///     [8] .field [47]        // C99 designation: 3 designators
3206f32e7eSjoerg ///     [8 ... 47]  field:     // GNU extensions: 2 designators
3306f32e7eSjoerg /// These occur in initializers, e.g.:
3406f32e7eSjoerg ///  int a[10] = {2, 4, [8]=9, 10};
3506f32e7eSjoerg ///
3606f32e7eSjoerg class Designator {
3706f32e7eSjoerg public:
3806f32e7eSjoerg   enum DesignatorKind {
3906f32e7eSjoerg     FieldDesignator, ArrayDesignator, ArrayRangeDesignator
4006f32e7eSjoerg   };
4106f32e7eSjoerg private:
Designator()42*13fbcb42Sjoerg   Designator() {};
43*13fbcb42Sjoerg 
4406f32e7eSjoerg   DesignatorKind Kind;
4506f32e7eSjoerg 
4606f32e7eSjoerg   struct FieldDesignatorInfo {
4706f32e7eSjoerg     const IdentifierInfo *II;
48*13fbcb42Sjoerg     SourceLocation DotLoc;
49*13fbcb42Sjoerg     SourceLocation NameLoc;
5006f32e7eSjoerg   };
5106f32e7eSjoerg   struct ArrayDesignatorInfo {
5206f32e7eSjoerg     Expr *Index;
53*13fbcb42Sjoerg     SourceLocation LBracketLoc;
54*13fbcb42Sjoerg     mutable SourceLocation RBracketLoc;
5506f32e7eSjoerg   };
5606f32e7eSjoerg   struct ArrayRangeDesignatorInfo {
5706f32e7eSjoerg     Expr *Start, *End;
58*13fbcb42Sjoerg     SourceLocation LBracketLoc, EllipsisLoc;
59*13fbcb42Sjoerg     mutable SourceLocation RBracketLoc;
6006f32e7eSjoerg   };
6106f32e7eSjoerg 
6206f32e7eSjoerg   union {
6306f32e7eSjoerg     FieldDesignatorInfo FieldInfo;
6406f32e7eSjoerg     ArrayDesignatorInfo ArrayInfo;
6506f32e7eSjoerg     ArrayRangeDesignatorInfo ArrayRangeInfo;
6606f32e7eSjoerg   };
6706f32e7eSjoerg 
6806f32e7eSjoerg public:
6906f32e7eSjoerg 
getKind()7006f32e7eSjoerg   DesignatorKind getKind() const { return Kind; }
isFieldDesignator()7106f32e7eSjoerg   bool isFieldDesignator() const { return Kind == FieldDesignator; }
isArrayDesignator()7206f32e7eSjoerg   bool isArrayDesignator() const { return Kind == ArrayDesignator; }
isArrayRangeDesignator()7306f32e7eSjoerg   bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
7406f32e7eSjoerg 
getField()7506f32e7eSjoerg   const IdentifierInfo *getField() const {
7606f32e7eSjoerg     assert(isFieldDesignator() && "Invalid accessor");
7706f32e7eSjoerg     return FieldInfo.II;
7806f32e7eSjoerg   }
7906f32e7eSjoerg 
getDotLoc()8006f32e7eSjoerg   SourceLocation getDotLoc() const {
8106f32e7eSjoerg     assert(isFieldDesignator() && "Invalid accessor");
82*13fbcb42Sjoerg     return FieldInfo.DotLoc;
8306f32e7eSjoerg   }
8406f32e7eSjoerg 
getFieldLoc()8506f32e7eSjoerg   SourceLocation getFieldLoc() const {
8606f32e7eSjoerg     assert(isFieldDesignator() && "Invalid accessor");
87*13fbcb42Sjoerg     return FieldInfo.NameLoc;
8806f32e7eSjoerg   }
8906f32e7eSjoerg 
getArrayIndex()9006f32e7eSjoerg   Expr *getArrayIndex() const {
9106f32e7eSjoerg     assert(isArrayDesignator() && "Invalid accessor");
9206f32e7eSjoerg     return ArrayInfo.Index;
9306f32e7eSjoerg   }
9406f32e7eSjoerg 
getArrayRangeStart()9506f32e7eSjoerg   Expr *getArrayRangeStart() const {
9606f32e7eSjoerg     assert(isArrayRangeDesignator() && "Invalid accessor");
9706f32e7eSjoerg     return ArrayRangeInfo.Start;
9806f32e7eSjoerg   }
getArrayRangeEnd()9906f32e7eSjoerg   Expr *getArrayRangeEnd() const {
10006f32e7eSjoerg     assert(isArrayRangeDesignator() && "Invalid accessor");
10106f32e7eSjoerg     return ArrayRangeInfo.End;
10206f32e7eSjoerg   }
10306f32e7eSjoerg 
getLBracketLoc()10406f32e7eSjoerg   SourceLocation getLBracketLoc() const {
10506f32e7eSjoerg     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
10606f32e7eSjoerg            "Invalid accessor");
10706f32e7eSjoerg     if (isArrayDesignator())
108*13fbcb42Sjoerg       return ArrayInfo.LBracketLoc;
10906f32e7eSjoerg     else
110*13fbcb42Sjoerg       return ArrayRangeInfo.LBracketLoc;
11106f32e7eSjoerg   }
11206f32e7eSjoerg 
getRBracketLoc()11306f32e7eSjoerg   SourceLocation getRBracketLoc() const {
11406f32e7eSjoerg     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
11506f32e7eSjoerg            "Invalid accessor");
11606f32e7eSjoerg     if (isArrayDesignator())
117*13fbcb42Sjoerg       return ArrayInfo.RBracketLoc;
11806f32e7eSjoerg     else
119*13fbcb42Sjoerg       return ArrayRangeInfo.RBracketLoc;
12006f32e7eSjoerg   }
12106f32e7eSjoerg 
getEllipsisLoc()12206f32e7eSjoerg   SourceLocation getEllipsisLoc() const {
12306f32e7eSjoerg     assert(isArrayRangeDesignator() && "Invalid accessor");
124*13fbcb42Sjoerg     return ArrayRangeInfo.EllipsisLoc;
12506f32e7eSjoerg   }
12606f32e7eSjoerg 
getField(const IdentifierInfo * II,SourceLocation DotLoc,SourceLocation NameLoc)12706f32e7eSjoerg   static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
12806f32e7eSjoerg                              SourceLocation NameLoc) {
12906f32e7eSjoerg     Designator D;
13006f32e7eSjoerg     D.Kind = FieldDesignator;
131*13fbcb42Sjoerg     new (&D.FieldInfo) FieldDesignatorInfo;
13206f32e7eSjoerg     D.FieldInfo.II = II;
133*13fbcb42Sjoerg     D.FieldInfo.DotLoc = DotLoc;
134*13fbcb42Sjoerg     D.FieldInfo.NameLoc = NameLoc;
13506f32e7eSjoerg     return D;
13606f32e7eSjoerg   }
13706f32e7eSjoerg 
getArray(Expr * Index,SourceLocation LBracketLoc)13806f32e7eSjoerg   static Designator getArray(Expr *Index,
13906f32e7eSjoerg                              SourceLocation LBracketLoc) {
14006f32e7eSjoerg     Designator D;
14106f32e7eSjoerg     D.Kind = ArrayDesignator;
142*13fbcb42Sjoerg     new (&D.ArrayInfo) ArrayDesignatorInfo;
14306f32e7eSjoerg     D.ArrayInfo.Index = Index;
144*13fbcb42Sjoerg     D.ArrayInfo.LBracketLoc = LBracketLoc;
145*13fbcb42Sjoerg     D.ArrayInfo.RBracketLoc = SourceLocation();
14606f32e7eSjoerg     return D;
14706f32e7eSjoerg   }
14806f32e7eSjoerg 
getArrayRange(Expr * Start,Expr * End,SourceLocation LBracketLoc,SourceLocation EllipsisLoc)14906f32e7eSjoerg   static Designator getArrayRange(Expr *Start,
15006f32e7eSjoerg                                   Expr *End,
15106f32e7eSjoerg                                   SourceLocation LBracketLoc,
15206f32e7eSjoerg                                   SourceLocation EllipsisLoc) {
15306f32e7eSjoerg     Designator D;
15406f32e7eSjoerg     D.Kind = ArrayRangeDesignator;
155*13fbcb42Sjoerg     new (&D.ArrayRangeInfo) ArrayRangeDesignatorInfo;
15606f32e7eSjoerg     D.ArrayRangeInfo.Start = Start;
15706f32e7eSjoerg     D.ArrayRangeInfo.End = End;
158*13fbcb42Sjoerg     D.ArrayRangeInfo.LBracketLoc = LBracketLoc;
159*13fbcb42Sjoerg     D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc;
160*13fbcb42Sjoerg     D.ArrayRangeInfo.RBracketLoc = SourceLocation();
16106f32e7eSjoerg     return D;
16206f32e7eSjoerg   }
16306f32e7eSjoerg 
setRBracketLoc(SourceLocation RBracketLoc)16406f32e7eSjoerg   void setRBracketLoc(SourceLocation RBracketLoc) const {
16506f32e7eSjoerg     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
16606f32e7eSjoerg            "Invalid accessor");
16706f32e7eSjoerg     if (isArrayDesignator())
168*13fbcb42Sjoerg       ArrayInfo.RBracketLoc = RBracketLoc;
16906f32e7eSjoerg     else
170*13fbcb42Sjoerg       ArrayRangeInfo.RBracketLoc = RBracketLoc;
17106f32e7eSjoerg   }
17206f32e7eSjoerg 
17306f32e7eSjoerg   /// ClearExprs - Null out any expression references, which prevents
17406f32e7eSjoerg   /// them from being 'delete'd later.
ClearExprs(Sema & Actions)17506f32e7eSjoerg   void ClearExprs(Sema &Actions) {}
17606f32e7eSjoerg 
17706f32e7eSjoerg   /// FreeExprs - Release any unclaimed memory for the expressions in
17806f32e7eSjoerg   /// this designator.
FreeExprs(Sema & Actions)17906f32e7eSjoerg   void FreeExprs(Sema &Actions) {}
18006f32e7eSjoerg };
18106f32e7eSjoerg 
18206f32e7eSjoerg 
18306f32e7eSjoerg /// Designation - Represent a full designation, which is a sequence of
18406f32e7eSjoerg /// designators.  This class is mostly a helper for InitListDesignations.
18506f32e7eSjoerg class Designation {
18606f32e7eSjoerg   /// Designators - The actual designators for this initializer.
18706f32e7eSjoerg   SmallVector<Designator, 2> Designators;
18806f32e7eSjoerg 
18906f32e7eSjoerg public:
19006f32e7eSjoerg   /// AddDesignator - Add a designator to the end of this list.
AddDesignator(Designator D)19106f32e7eSjoerg   void AddDesignator(Designator D) {
19206f32e7eSjoerg     Designators.push_back(D);
19306f32e7eSjoerg   }
19406f32e7eSjoerg 
empty()19506f32e7eSjoerg   bool empty() const { return Designators.empty(); }
19606f32e7eSjoerg 
getNumDesignators()19706f32e7eSjoerg   unsigned getNumDesignators() const { return Designators.size(); }
getDesignator(unsigned Idx)19806f32e7eSjoerg   const Designator &getDesignator(unsigned Idx) const {
19906f32e7eSjoerg     assert(Idx < Designators.size());
20006f32e7eSjoerg     return Designators[Idx];
20106f32e7eSjoerg   }
20206f32e7eSjoerg 
20306f32e7eSjoerg   /// ClearExprs - Null out any expression references, which prevents them from
20406f32e7eSjoerg   /// being 'delete'd later.
ClearExprs(Sema & Actions)20506f32e7eSjoerg   void ClearExprs(Sema &Actions) {}
20606f32e7eSjoerg 
20706f32e7eSjoerg   /// FreeExprs - Release any unclaimed memory for the expressions in this
20806f32e7eSjoerg   /// designation.
FreeExprs(Sema & Actions)20906f32e7eSjoerg   void FreeExprs(Sema &Actions) {}
21006f32e7eSjoerg };
21106f32e7eSjoerg 
21206f32e7eSjoerg } // end namespace clang
21306f32e7eSjoerg 
21406f32e7eSjoerg #endif
215