1//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines interfaces used to represent designators (a la 11// C99 designated initializers) during parsing. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H 16#define LLVM_CLANG_SEMA_DESIGNATOR_H 17 18#include "clang/Basic/SourceLocation.h" 19#include "llvm/ADT/SmallVector.h" 20 21namespace clang { 22 23class Expr; 24class IdentifierInfo; 25class Sema; 26 27/// Designator - A designator in a C99 designated initializer. 28/// 29/// This class is a discriminated union which holds the various 30/// different sorts of designators possible. A Designation is an array of 31/// these. An example of a designator are things like this: 32/// [8] .field [47] // C99 designation: 3 designators 33/// [8 ... 47] field: // GNU extensions: 2 designators 34/// These occur in initializers, e.g.: 35/// int a[10] = {2, 4, [8]=9, 10}; 36/// 37class Designator { 38public: 39 enum DesignatorKind { 40 FieldDesignator, ArrayDesignator, ArrayRangeDesignator 41 }; 42private: 43 DesignatorKind Kind; 44 45 struct FieldDesignatorInfo { 46 const IdentifierInfo *II; 47 unsigned DotLoc; 48 unsigned NameLoc; 49 }; 50 struct ArrayDesignatorInfo { 51 Expr *Index; 52 unsigned LBracketLoc; 53 mutable unsigned RBracketLoc; 54 }; 55 struct ArrayRangeDesignatorInfo { 56 Expr *Start, *End; 57 unsigned LBracketLoc, EllipsisLoc; 58 mutable unsigned RBracketLoc; 59 }; 60 61 union { 62 FieldDesignatorInfo FieldInfo; 63 ArrayDesignatorInfo ArrayInfo; 64 ArrayRangeDesignatorInfo ArrayRangeInfo; 65 }; 66 67public: 68 69 DesignatorKind getKind() const { return Kind; } 70 bool isFieldDesignator() const { return Kind == FieldDesignator; } 71 bool isArrayDesignator() const { return Kind == ArrayDesignator; } 72 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 73 74 const IdentifierInfo *getField() const { 75 assert(isFieldDesignator() && "Invalid accessor"); 76 return FieldInfo.II; 77 } 78 79 SourceLocation getDotLoc() const { 80 assert(isFieldDesignator() && "Invalid accessor"); 81 return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); 82 } 83 84 SourceLocation getFieldLoc() const { 85 assert(isFieldDesignator() && "Invalid accessor"); 86 return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); 87 } 88 89 Expr *getArrayIndex() const { 90 assert(isArrayDesignator() && "Invalid accessor"); 91 return ArrayInfo.Index; 92 } 93 94 Expr *getArrayRangeStart() const { 95 assert(isArrayRangeDesignator() && "Invalid accessor"); 96 return ArrayRangeInfo.Start; 97 } 98 Expr *getArrayRangeEnd() const { 99 assert(isArrayRangeDesignator() && "Invalid accessor"); 100 return ArrayRangeInfo.End; 101 } 102 103 SourceLocation getLBracketLoc() const { 104 assert((isArrayDesignator() || isArrayRangeDesignator()) && 105 "Invalid accessor"); 106 if (isArrayDesignator()) 107 return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc); 108 else 109 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc); 110 } 111 112 SourceLocation getRBracketLoc() const { 113 assert((isArrayDesignator() || isArrayRangeDesignator()) && 114 "Invalid accessor"); 115 if (isArrayDesignator()) 116 return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc); 117 else 118 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc); 119 } 120 121 SourceLocation getEllipsisLoc() const { 122 assert(isArrayRangeDesignator() && "Invalid accessor"); 123 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); 124 } 125 126 static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, 127 SourceLocation NameLoc) { 128 Designator D; 129 D.Kind = FieldDesignator; 130 D.FieldInfo.II = II; 131 D.FieldInfo.DotLoc = DotLoc.getRawEncoding(); 132 D.FieldInfo.NameLoc = NameLoc.getRawEncoding(); 133 return D; 134 } 135 136 static Designator getArray(Expr *Index, 137 SourceLocation LBracketLoc) { 138 Designator D; 139 D.Kind = ArrayDesignator; 140 D.ArrayInfo.Index = Index; 141 D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 142 D.ArrayInfo.RBracketLoc = 0; 143 return D; 144 } 145 146 static Designator getArrayRange(Expr *Start, 147 Expr *End, 148 SourceLocation LBracketLoc, 149 SourceLocation EllipsisLoc) { 150 Designator D; 151 D.Kind = ArrayRangeDesignator; 152 D.ArrayRangeInfo.Start = Start; 153 D.ArrayRangeInfo.End = End; 154 D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 155 D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding(); 156 D.ArrayRangeInfo.RBracketLoc = 0; 157 return D; 158 } 159 160 void setRBracketLoc(SourceLocation RBracketLoc) const { 161 assert((isArrayDesignator() || isArrayRangeDesignator()) && 162 "Invalid accessor"); 163 if (isArrayDesignator()) 164 ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 165 else 166 ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 167 } 168 169 /// ClearExprs - Null out any expression references, which prevents 170 /// them from being 'delete'd later. 171 void ClearExprs(Sema &Actions) {} 172 173 /// FreeExprs - Release any unclaimed memory for the expressions in 174 /// this designator. 175 void FreeExprs(Sema &Actions) {} 176}; 177 178 179/// Designation - Represent a full designation, which is a sequence of 180/// designators. This class is mostly a helper for InitListDesignations. 181class Designation { 182 /// InitIndex - The index of the initializer expression this is for. For 183 /// example, if the initializer were "{ A, .foo=B, C }" a Designation would 184 /// exist with InitIndex=1, because element #1 has a designation. 185 unsigned InitIndex; 186 187 /// Designators - The actual designators for this initializer. 188 SmallVector<Designator, 2> Designators; 189 190 Designation(unsigned Idx) : InitIndex(Idx) {} 191public: 192 Designation() : InitIndex(4000) {} 193 194 /// AddDesignator - Add a designator to the end of this list. 195 void AddDesignator(Designator D) { 196 Designators.push_back(D); 197 } 198 199 bool empty() const { return Designators.empty(); } 200 201 unsigned getNumDesignators() const { return Designators.size(); } 202 const Designator &getDesignator(unsigned Idx) const { 203 assert(Idx < Designators.size()); 204 return Designators[Idx]; 205 } 206 207 /// ClearExprs - Null out any expression references, which prevents them from 208 /// being 'delete'd later. 209 void ClearExprs(Sema &Actions) {} 210 211 /// FreeExprs - Release any unclaimed memory for the expressions in this 212 /// designation. 213 void FreeExprs(Sema &Actions) {} 214}; 215 216} // end namespace clang 217 218#endif 219