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