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 21 namespace clang { 22 23 class Expr; 24 class IdentifierInfo; 25 class 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 /// 37 class Designator { 38 public: 39 enum DesignatorKind { 40 FieldDesignator, ArrayDesignator, ArrayRangeDesignator 41 }; 42 private: 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 67 public: 68 getKind()69 DesignatorKind getKind() const { return Kind; } isFieldDesignator()70 bool isFieldDesignator() const { return Kind == FieldDesignator; } isArrayDesignator()71 bool isArrayDesignator() const { return Kind == ArrayDesignator; } isArrayRangeDesignator()72 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 73 getField()74 const IdentifierInfo *getField() const { 75 assert(isFieldDesignator() && "Invalid accessor"); 76 return FieldInfo.II; 77 } 78 getDotLoc()79 SourceLocation getDotLoc() const { 80 assert(isFieldDesignator() && "Invalid accessor"); 81 return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); 82 } 83 getFieldLoc()84 SourceLocation getFieldLoc() const { 85 assert(isFieldDesignator() && "Invalid accessor"); 86 return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); 87 } 88 getArrayIndex()89 Expr *getArrayIndex() const { 90 assert(isArrayDesignator() && "Invalid accessor"); 91 return ArrayInfo.Index; 92 } 93 getArrayRangeStart()94 Expr *getArrayRangeStart() const { 95 assert(isArrayRangeDesignator() && "Invalid accessor"); 96 return ArrayRangeInfo.Start; 97 } getArrayRangeEnd()98 Expr *getArrayRangeEnd() const { 99 assert(isArrayRangeDesignator() && "Invalid accessor"); 100 return ArrayRangeInfo.End; 101 } 102 getLBracketLoc()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 getRBracketLoc()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 getEllipsisLoc()121 SourceLocation getEllipsisLoc() const { 122 assert(isArrayRangeDesignator() && "Invalid accessor"); 123 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); 124 } 125 getField(const IdentifierInfo * II,SourceLocation DotLoc,SourceLocation NameLoc)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 getArray(Expr * Index,SourceLocation LBracketLoc)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 getArrayRange(Expr * Start,Expr * End,SourceLocation LBracketLoc,SourceLocation EllipsisLoc)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 setRBracketLoc(SourceLocation RBracketLoc)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. ClearExprs(Sema & Actions)171 void ClearExprs(Sema &Actions) {} 172 173 /// FreeExprs - Release any unclaimed memory for the expressions in 174 /// this designator. FreeExprs(Sema & Actions)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. 181 class Designation { 182 /// Designators - The actual designators for this initializer. 183 SmallVector<Designator, 2> Designators; 184 185 public: 186 /// AddDesignator - Add a designator to the end of this list. AddDesignator(Designator D)187 void AddDesignator(Designator D) { 188 Designators.push_back(D); 189 } 190 empty()191 bool empty() const { return Designators.empty(); } 192 getNumDesignators()193 unsigned getNumDesignators() const { return Designators.size(); } getDesignator(unsigned Idx)194 const Designator &getDesignator(unsigned Idx) const { 195 assert(Idx < Designators.size()); 196 return Designators[Idx]; 197 } 198 199 /// ClearExprs - Null out any expression references, which prevents them from 200 /// being 'delete'd later. ClearExprs(Sema & Actions)201 void ClearExprs(Sema &Actions) {} 202 203 /// FreeExprs - Release any unclaimed memory for the expressions in this 204 /// designation. FreeExprs(Sema & Actions)205 void FreeExprs(Sema &Actions) {} 206 }; 207 208 } // end namespace clang 209 210 #endif 211