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 25 /// Designator - A designator in a C99 designated initializer. 26 /// 27 /// This class is a discriminated union which holds the various 28 /// different sorts of designators possible. A Designation is an array of 29 /// these. An example of a designator are things like this: 30 /// 31 /// [8] .field [47] // C99 designation: 3 designators 32 /// [8 ... 47] field: // GNU extensions: 2 designators 33 /// 34 /// These occur in initializers, e.g.: 35 /// 36 /// int a[10] = {2, 4, [8]=9, 10}; 37 /// 38 class Designator { 39 /// A field designator, e.g., ".x = 42". 40 struct FieldDesignatorInfo { 41 /// Refers to the field being initialized. 42 const IdentifierInfo *FieldName; 43 44 /// The location of the '.' in the designated initializer. 45 SourceLocation DotLoc; 46 47 /// The location of the field name in the designated initializer. 48 SourceLocation FieldLoc; 49 FieldDesignatorInfoFieldDesignatorInfo50 FieldDesignatorInfo(const IdentifierInfo *FieldName, SourceLocation DotLoc, 51 SourceLocation FieldLoc) 52 : FieldName(FieldName), DotLoc(DotLoc), FieldLoc(FieldLoc) {} 53 }; 54 55 /// An array designator, e.g., "[42] = 0". 56 struct ArrayDesignatorInfo { 57 Expr *Index; 58 59 // The location of the '[' in the designated initializer. 60 SourceLocation LBracketLoc; 61 62 // The location of the ']' in the designated initializer. 63 mutable SourceLocation RBracketLoc; 64 ArrayDesignatorInfoArrayDesignatorInfo65 ArrayDesignatorInfo(Expr *Index, SourceLocation LBracketLoc) 66 : Index(Index), LBracketLoc(LBracketLoc) {} 67 }; 68 69 /// An array range designator, e.g. "[42 ... 50] = 1". 70 struct ArrayRangeDesignatorInfo { 71 Expr *Start; 72 Expr *End; 73 74 // The location of the '[' in the designated initializer. 75 SourceLocation LBracketLoc; 76 77 // The location of the '...' in the designated initializer. 78 SourceLocation EllipsisLoc; 79 80 // The location of the ']' in the designated initializer. 81 mutable SourceLocation RBracketLoc; 82 ArrayRangeDesignatorInfoArrayRangeDesignatorInfo83 ArrayRangeDesignatorInfo(Expr *Start, Expr *End, SourceLocation LBracketLoc, 84 SourceLocation EllipsisLoc) 85 : Start(Start), End(End), LBracketLoc(LBracketLoc), 86 EllipsisLoc(EllipsisLoc) {} 87 }; 88 89 /// The kind of designator this describes. 90 enum DesignatorKind { 91 FieldDesignator, 92 ArrayDesignator, 93 ArrayRangeDesignator 94 }; 95 96 DesignatorKind Kind; 97 98 union { 99 FieldDesignatorInfo FieldInfo; 100 ArrayDesignatorInfo ArrayInfo; 101 ArrayRangeDesignatorInfo ArrayRangeInfo; 102 }; 103 Designator(DesignatorKind Kind)104 Designator(DesignatorKind Kind) : Kind(Kind) {} 105 106 public: isFieldDesignator()107 bool isFieldDesignator() const { return Kind == FieldDesignator; } isArrayDesignator()108 bool isArrayDesignator() const { return Kind == ArrayDesignator; } isArrayRangeDesignator()109 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 110 111 //===--------------------------------------------------------------------===// 112 // FieldDesignatorInfo 113 114 /// Creates a field designator. CreateFieldDesignator(const IdentifierInfo * FieldName,SourceLocation DotLoc,SourceLocation FieldLoc)115 static Designator CreateFieldDesignator(const IdentifierInfo *FieldName, 116 SourceLocation DotLoc, 117 SourceLocation FieldLoc) { 118 Designator D(FieldDesignator); 119 new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc); 120 return D; 121 } 122 getFieldDecl()123 const IdentifierInfo *getFieldDecl() const { 124 assert(isFieldDesignator() && "Invalid accessor"); 125 return FieldInfo.FieldName; 126 } 127 getDotLoc()128 SourceLocation getDotLoc() const { 129 assert(isFieldDesignator() && "Invalid accessor"); 130 return FieldInfo.DotLoc; 131 } 132 getFieldLoc()133 SourceLocation getFieldLoc() const { 134 assert(isFieldDesignator() && "Invalid accessor"); 135 return FieldInfo.FieldLoc; 136 } 137 138 //===--------------------------------------------------------------------===// 139 // ArrayDesignatorInfo: 140 141 /// Creates an array designator. CreateArrayDesignator(Expr * Index,SourceLocation LBracketLoc)142 static Designator CreateArrayDesignator(Expr *Index, 143 SourceLocation LBracketLoc) { 144 Designator D(ArrayDesignator); 145 new (&D.ArrayInfo) ArrayDesignatorInfo(Index, LBracketLoc); 146 return D; 147 } 148 getArrayIndex()149 Expr *getArrayIndex() const { 150 assert(isArrayDesignator() && "Invalid accessor"); 151 return ArrayInfo.Index; 152 } 153 getLBracketLoc()154 SourceLocation getLBracketLoc() const { 155 assert((isArrayDesignator() || isArrayRangeDesignator()) && 156 "Invalid accessor"); 157 return isArrayDesignator() ? ArrayInfo.LBracketLoc 158 : ArrayRangeInfo.LBracketLoc; 159 } 160 getRBracketLoc()161 SourceLocation getRBracketLoc() const { 162 assert((isArrayDesignator() || isArrayRangeDesignator()) && 163 "Invalid accessor"); 164 return isArrayDesignator() ? ArrayInfo.RBracketLoc 165 : ArrayRangeInfo.RBracketLoc; 166 } 167 168 //===--------------------------------------------------------------------===// 169 // ArrayRangeDesignatorInfo: 170 171 /// Creates a GNU array-range designator. CreateArrayRangeDesignator(Expr * Start,Expr * End,SourceLocation LBracketLoc,SourceLocation EllipsisLoc)172 static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End, 173 SourceLocation LBracketLoc, 174 SourceLocation EllipsisLoc) { 175 Designator D(ArrayRangeDesignator); 176 new (&D.ArrayRangeInfo) 177 ArrayRangeDesignatorInfo(Start, End, LBracketLoc, EllipsisLoc); 178 return D; 179 } 180 getArrayRangeStart()181 Expr *getArrayRangeStart() const { 182 assert(isArrayRangeDesignator() && "Invalid accessor"); 183 return ArrayRangeInfo.Start; 184 } 185 getArrayRangeEnd()186 Expr *getArrayRangeEnd() const { 187 assert(isArrayRangeDesignator() && "Invalid accessor"); 188 return ArrayRangeInfo.End; 189 } 190 getEllipsisLoc()191 SourceLocation getEllipsisLoc() const { 192 assert(isArrayRangeDesignator() && "Invalid accessor"); 193 return ArrayRangeInfo.EllipsisLoc; 194 } 195 setRBracketLoc(SourceLocation RBracketLoc)196 void setRBracketLoc(SourceLocation RBracketLoc) const { 197 assert((isArrayDesignator() || isArrayRangeDesignator()) && 198 "Invalid accessor"); 199 if (isArrayDesignator()) 200 ArrayInfo.RBracketLoc = RBracketLoc; 201 else 202 ArrayRangeInfo.RBracketLoc = RBracketLoc; 203 } 204 }; 205 206 /// Designation - Represent a full designation, which is a sequence of 207 /// designators. This class is mostly a helper for InitListDesignations. 208 class Designation { 209 /// Designators - The actual designators for this initializer. 210 SmallVector<Designator, 2> Designators; 211 212 public: 213 /// AddDesignator - Add a designator to the end of this list. AddDesignator(Designator D)214 void AddDesignator(Designator D) { Designators.push_back(D); } 215 empty()216 bool empty() const { return Designators.empty(); } 217 getNumDesignators()218 unsigned getNumDesignators() const { return Designators.size(); } getDesignator(unsigned Idx)219 const Designator &getDesignator(unsigned Idx) const { 220 assert(Idx < Designators.size()); 221 return Designators[Idx]; 222 } 223 }; 224 225 } // end namespace clang 226 227 #endif 228