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 DesignatorKind Kind; 43 44 struct FieldDesignatorInfo { 45 const IdentifierInfo *II; 46 unsigned DotLoc; 47 unsigned NameLoc; 48 }; 49 struct ArrayDesignatorInfo { 50 Expr *Index; 51 unsigned LBracketLoc; 52 mutable unsigned RBracketLoc; 53 }; 54 struct ArrayRangeDesignatorInfo { 55 Expr *Start, *End; 56 unsigned LBracketLoc, EllipsisLoc; 57 mutable unsigned RBracketLoc; 58 }; 59 60 union { 61 FieldDesignatorInfo FieldInfo; 62 ArrayDesignatorInfo ArrayInfo; 63 ArrayRangeDesignatorInfo ArrayRangeInfo; 64 }; 65 66 public: 67 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; } 72 73 const IdentifierInfo *getField() const { 74 assert(isFieldDesignator() && "Invalid accessor"); 75 return FieldInfo.II; 76 } 77 78 SourceLocation getDotLoc() const { 79 assert(isFieldDesignator() && "Invalid accessor"); 80 return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); 81 } 82 83 SourceLocation getFieldLoc() const { 84 assert(isFieldDesignator() && "Invalid accessor"); 85 return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); 86 } 87 88 Expr *getArrayIndex() const { 89 assert(isArrayDesignator() && "Invalid accessor"); 90 return ArrayInfo.Index; 91 } 92 93 Expr *getArrayRangeStart() const { 94 assert(isArrayRangeDesignator() && "Invalid accessor"); 95 return ArrayRangeInfo.Start; 96 } 97 Expr *getArrayRangeEnd() const { 98 assert(isArrayRangeDesignator() && "Invalid accessor"); 99 return ArrayRangeInfo.End; 100 } 101 102 SourceLocation getLBracketLoc() const { 103 assert((isArrayDesignator() || isArrayRangeDesignator()) && 104 "Invalid accessor"); 105 if (isArrayDesignator()) 106 return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc); 107 else 108 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc); 109 } 110 111 SourceLocation getRBracketLoc() const { 112 assert((isArrayDesignator() || isArrayRangeDesignator()) && 113 "Invalid accessor"); 114 if (isArrayDesignator()) 115 return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc); 116 else 117 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc); 118 } 119 120 SourceLocation getEllipsisLoc() const { 121 assert(isArrayRangeDesignator() && "Invalid accessor"); 122 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); 123 } 124 125 static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, 126 SourceLocation NameLoc) { 127 Designator D; 128 D.Kind = FieldDesignator; 129 D.FieldInfo.II = II; 130 D.FieldInfo.DotLoc = DotLoc.getRawEncoding(); 131 D.FieldInfo.NameLoc = NameLoc.getRawEncoding(); 132 return D; 133 } 134 135 static Designator getArray(Expr *Index, 136 SourceLocation LBracketLoc) { 137 Designator D; 138 D.Kind = ArrayDesignator; 139 D.ArrayInfo.Index = Index; 140 D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 141 D.ArrayInfo.RBracketLoc = 0; 142 return D; 143 } 144 145 static Designator getArrayRange(Expr *Start, 146 Expr *End, 147 SourceLocation LBracketLoc, 148 SourceLocation EllipsisLoc) { 149 Designator D; 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; 156 return D; 157 } 158 159 void setRBracketLoc(SourceLocation RBracketLoc) const { 160 assert((isArrayDesignator() || isArrayRangeDesignator()) && 161 "Invalid accessor"); 162 if (isArrayDesignator()) 163 ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 164 else 165 ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 166 } 167 168 /// ClearExprs - Null out any expression references, which prevents 169 /// them from being 'delete'd later. 170 void ClearExprs(Sema &Actions) {} 171 172 /// FreeExprs - Release any unclaimed memory for the expressions in 173 /// this designator. 174 void FreeExprs(Sema &Actions) {} 175 }; 176 177 178 /// Designation - Represent a full designation, which is a sequence of 179 /// designators. This class is mostly a helper for InitListDesignations. 180 class Designation { 181 /// Designators - The actual designators for this initializer. 182 SmallVector<Designator, 2> Designators; 183 184 public: 185 /// AddDesignator - Add a designator to the end of this list. 186 void AddDesignator(Designator D) { 187 Designators.push_back(D); 188 } 189 190 bool empty() const { return Designators.empty(); } 191 192 unsigned getNumDesignators() const { return Designators.size(); } 193 const Designator &getDesignator(unsigned Idx) const { 194 assert(Idx < Designators.size()); 195 return Designators[Idx]; 196 } 197 198 /// ClearExprs - Null out any expression references, which prevents them from 199 /// being 'delete'd later. 200 void ClearExprs(Sema &Actions) {} 201 202 /// FreeExprs - Release any unclaimed memory for the expressions in this 203 /// designation. 204 void FreeExprs(Sema &Actions) {} 205 }; 206 207 } // end namespace clang 208 209 #endif 210