1 //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines interfaces used to represent designators (a la
10 // C99 designated initializers) during parsing.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
15 #define LLVM_CLANG_SEMA_DESIGNATOR_H
17 #include "clang/Basic/SourceLocation.h"
18 #include "llvm/ADT/SmallVector.h"
26 /// Designator - A designator in a C99 designated initializer.
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};
39 FieldDesignator, ArrayDesignator, ArrayRangeDesignator
44 struct FieldDesignatorInfo {
45 const IdentifierInfo *II;
49 struct ArrayDesignatorInfo {
52 mutable unsigned RBracketLoc;
54 struct ArrayRangeDesignatorInfo {
56 unsigned LBracketLoc, EllipsisLoc;
57 mutable unsigned RBracketLoc;
61 FieldDesignatorInfo FieldInfo;
62 ArrayDesignatorInfo ArrayInfo;
63 ArrayRangeDesignatorInfo ArrayRangeInfo;
68 DesignatorKind getKind() const { return Kind; }
69 bool isFieldDesignator() const { return Kind == FieldDesignator; }
70 bool isArrayDesignator() const { return Kind == ArrayDesignator; }
71 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
73 const IdentifierInfo *getField() const {
74 assert(isFieldDesignator() && "Invalid accessor");
78 SourceLocation getDotLoc() const {
79 assert(isFieldDesignator() && "Invalid accessor");
80 return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
83 SourceLocation getFieldLoc() const {
84 assert(isFieldDesignator() && "Invalid accessor");
85 return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
88 Expr *getArrayIndex() const {
89 assert(isArrayDesignator() && "Invalid accessor");
90 return ArrayInfo.Index;
93 Expr *getArrayRangeStart() const {
94 assert(isArrayRangeDesignator() && "Invalid accessor");
95 return ArrayRangeInfo.Start;
97 Expr *getArrayRangeEnd() const {
98 assert(isArrayRangeDesignator() && "Invalid accessor");
99 return ArrayRangeInfo.End;
102 SourceLocation getLBracketLoc() const {
103 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
105 if (isArrayDesignator())
106 return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
108 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
111 SourceLocation getRBracketLoc() const {
112 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
114 if (isArrayDesignator())
115 return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
117 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
120 SourceLocation getEllipsisLoc() const {
121 assert(isArrayRangeDesignator() && "Invalid accessor");
122 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
125 static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
126 SourceLocation NameLoc) {
128 D.Kind = FieldDesignator;
130 D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
131 D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
135 static Designator getArray(Expr *Index,
136 SourceLocation LBracketLoc) {
138 D.Kind = ArrayDesignator;
139 D.ArrayInfo.Index = Index;
140 D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
141 D.ArrayInfo.RBracketLoc = 0;
145 static Designator getArrayRange(Expr *Start,
147 SourceLocation LBracketLoc,
148 SourceLocation EllipsisLoc) {
150 D.Kind = ArrayRangeDesignator;
151 D.ArrayRangeInfo.Start = Start;
152 D.ArrayRangeInfo.End = End;
153 D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
154 D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
155 D.ArrayRangeInfo.RBracketLoc = 0;
159 void setRBracketLoc(SourceLocation RBracketLoc) const {
160 assert((isArrayDesignator() || isArrayRangeDesignator()) &&
162 if (isArrayDesignator())
163 ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
165 ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
168 /// ClearExprs - Null out any expression references, which prevents
169 /// them from being 'delete'd later.
170 void ClearExprs(Sema &Actions) {}
172 /// FreeExprs - Release any unclaimed memory for the expressions in
174 void FreeExprs(Sema &Actions) {}
178 /// Designation - Represent a full designation, which is a sequence of
179 /// designators. This class is mostly a helper for InitListDesignations.
181 /// Designators - The actual designators for this initializer.
182 SmallVector<Designator, 2> Designators;
185 /// AddDesignator - Add a designator to the end of this list.
186 void AddDesignator(Designator D) {
187 Designators.push_back(D);
190 bool empty() const { return Designators.empty(); }
192 unsigned getNumDesignators() const { return Designators.size(); }
193 const Designator &getDesignator(unsigned Idx) const {
194 assert(Idx < Designators.size());
195 return Designators[Idx];
198 /// ClearExprs - Null out any expression references, which prevents them from
199 /// being 'delete'd later.
200 void ClearExprs(Sema &Actions) {}
202 /// FreeExprs - Release any unclaimed memory for the expressions in this
204 void FreeExprs(Sema &Actions) {}
207 } // end namespace clang