clang API Documentation
00001 //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines interfaces used to represent designators (a la 00011 // C99 designated initializers) during parsing. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_SEMA_DESIGNATOR_H 00016 #define LLVM_CLANG_SEMA_DESIGNATOR_H 00017 00018 #include "clang/Basic/SourceLocation.h" 00019 #include "llvm/ADT/SmallVector.h" 00020 00021 namespace clang { 00022 00023 class Expr; 00024 class IdentifierInfo; 00025 class Sema; 00026 00027 /// Designator - A designator in a C99 designated initializer. 00028 /// 00029 /// This class is a discriminated union which holds the various 00030 /// different sorts of designators possible. A Designation is an array of 00031 /// these. An example of a designator are things like this: 00032 /// [8] .field [47] // C99 designation: 3 designators 00033 /// [8 ... 47] field: // GNU extensions: 2 designators 00034 /// These occur in initializers, e.g.: 00035 /// int a[10] = {2, 4, [8]=9, 10}; 00036 /// 00037 class Designator { 00038 public: 00039 enum DesignatorKind { 00040 FieldDesignator, ArrayDesignator, ArrayRangeDesignator 00041 }; 00042 private: 00043 DesignatorKind Kind; 00044 00045 struct FieldDesignatorInfo { 00046 const IdentifierInfo *II; 00047 unsigned DotLoc; 00048 unsigned NameLoc; 00049 }; 00050 struct ArrayDesignatorInfo { 00051 Expr *Index; 00052 unsigned LBracketLoc; 00053 mutable unsigned RBracketLoc; 00054 }; 00055 struct ArrayRangeDesignatorInfo { 00056 Expr *Start, *End; 00057 unsigned LBracketLoc, EllipsisLoc; 00058 mutable unsigned RBracketLoc; 00059 }; 00060 00061 union { 00062 FieldDesignatorInfo FieldInfo; 00063 ArrayDesignatorInfo ArrayInfo; 00064 ArrayRangeDesignatorInfo ArrayRangeInfo; 00065 }; 00066 00067 public: 00068 00069 DesignatorKind getKind() const { return Kind; } 00070 bool isFieldDesignator() const { return Kind == FieldDesignator; } 00071 bool isArrayDesignator() const { return Kind == ArrayDesignator; } 00072 bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 00073 00074 const IdentifierInfo *getField() const { 00075 assert(isFieldDesignator() && "Invalid accessor"); 00076 return FieldInfo.II; 00077 } 00078 00079 SourceLocation getDotLoc() const { 00080 assert(isFieldDesignator() && "Invalid accessor"); 00081 return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); 00082 } 00083 00084 SourceLocation getFieldLoc() const { 00085 assert(isFieldDesignator() && "Invalid accessor"); 00086 return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); 00087 } 00088 00089 Expr *getArrayIndex() const { 00090 assert(isArrayDesignator() && "Invalid accessor"); 00091 return ArrayInfo.Index; 00092 } 00093 00094 Expr *getArrayRangeStart() const { 00095 assert(isArrayRangeDesignator() && "Invalid accessor"); 00096 return ArrayRangeInfo.Start; 00097 } 00098 Expr *getArrayRangeEnd() const { 00099 assert(isArrayRangeDesignator() && "Invalid accessor"); 00100 return ArrayRangeInfo.End; 00101 } 00102 00103 SourceLocation getLBracketLoc() const { 00104 assert((isArrayDesignator() || isArrayRangeDesignator()) && 00105 "Invalid accessor"); 00106 if (isArrayDesignator()) 00107 return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc); 00108 else 00109 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc); 00110 } 00111 00112 SourceLocation getRBracketLoc() const { 00113 assert((isArrayDesignator() || isArrayRangeDesignator()) && 00114 "Invalid accessor"); 00115 if (isArrayDesignator()) 00116 return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc); 00117 else 00118 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc); 00119 } 00120 00121 SourceLocation getEllipsisLoc() const { 00122 assert(isArrayRangeDesignator() && "Invalid accessor"); 00123 return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); 00124 } 00125 00126 static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, 00127 SourceLocation NameLoc) { 00128 Designator D; 00129 D.Kind = FieldDesignator; 00130 D.FieldInfo.II = II; 00131 D.FieldInfo.DotLoc = DotLoc.getRawEncoding(); 00132 D.FieldInfo.NameLoc = NameLoc.getRawEncoding(); 00133 return D; 00134 } 00135 00136 static Designator getArray(Expr *Index, 00137 SourceLocation LBracketLoc) { 00138 Designator D; 00139 D.Kind = ArrayDesignator; 00140 D.ArrayInfo.Index = Index; 00141 D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 00142 D.ArrayInfo.RBracketLoc = 0; 00143 return D; 00144 } 00145 00146 static Designator getArrayRange(Expr *Start, 00147 Expr *End, 00148 SourceLocation LBracketLoc, 00149 SourceLocation EllipsisLoc) { 00150 Designator D; 00151 D.Kind = ArrayRangeDesignator; 00152 D.ArrayRangeInfo.Start = Start; 00153 D.ArrayRangeInfo.End = End; 00154 D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 00155 D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding(); 00156 D.ArrayRangeInfo.RBracketLoc = 0; 00157 return D; 00158 } 00159 00160 void setRBracketLoc(SourceLocation RBracketLoc) const { 00161 assert((isArrayDesignator() || isArrayRangeDesignator()) && 00162 "Invalid accessor"); 00163 if (isArrayDesignator()) 00164 ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 00165 else 00166 ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 00167 } 00168 00169 /// ClearExprs - Null out any expression references, which prevents 00170 /// them from being 'delete'd later. 00171 void ClearExprs(Sema &Actions) {} 00172 00173 /// FreeExprs - Release any unclaimed memory for the expressions in 00174 /// this designator. 00175 void FreeExprs(Sema &Actions) {} 00176 }; 00177 00178 00179 /// Designation - Represent a full designation, which is a sequence of 00180 /// designators. This class is mostly a helper for InitListDesignations. 00181 class Designation { 00182 /// Designators - The actual designators for this initializer. 00183 SmallVector<Designator, 2> Designators; 00184 00185 public: 00186 /// AddDesignator - Add a designator to the end of this list. 00187 void AddDesignator(Designator D) { 00188 Designators.push_back(D); 00189 } 00190 00191 bool empty() const { return Designators.empty(); } 00192 00193 unsigned getNumDesignators() const { return Designators.size(); } 00194 const Designator &getDesignator(unsigned Idx) const { 00195 assert(Idx < Designators.size()); 00196 return Designators[Idx]; 00197 } 00198 00199 /// ClearExprs - Null out any expression references, which prevents them from 00200 /// being 'delete'd later. 00201 void ClearExprs(Sema &Actions) {} 00202 00203 /// FreeExprs - Release any unclaimed memory for the expressions in this 00204 /// designation. 00205 void FreeExprs(Sema &Actions) {} 00206 }; 00207 00208 } // end namespace clang 00209 00210 #endif