1212795Sdim//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file defines interfaces used to represent designators (a la 11212795Sdim// C99 designated initializers) during parsing. 12212795Sdim// 13212795Sdim//===----------------------------------------------------------------------===// 14212795Sdim 15212795Sdim#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H 16212795Sdim#define LLVM_CLANG_SEMA_DESIGNATOR_H 17212795Sdim 18212795Sdim#include "clang/Basic/SourceLocation.h" 19212795Sdim#include "llvm/ADT/SmallVector.h" 20212795Sdim 21212795Sdimnamespace clang { 22212795Sdim 23212795Sdimclass Expr; 24212795Sdimclass IdentifierInfo; 25212795Sdimclass Sema; 26212795Sdim 27212795Sdim/// Designator - A designator in a C99 designated initializer. 28212795Sdim/// 29212795Sdim/// This class is a discriminated union which holds the various 30212795Sdim/// different sorts of designators possible. A Designation is an array of 31212795Sdim/// these. An example of a designator are things like this: 32212795Sdim/// [8] .field [47] // C99 designation: 3 designators 33212795Sdim/// [8 ... 47] field: // GNU extensions: 2 designators 34212795Sdim/// These occur in initializers, e.g.: 35212795Sdim/// int a[10] = {2, 4, [8]=9, 10}; 36212795Sdim/// 37212795Sdimclass Designator { 38212795Sdimpublic: 39212795Sdim enum DesignatorKind { 40212795Sdim FieldDesignator, ArrayDesignator, ArrayRangeDesignator 41212795Sdim }; 42212795Sdimprivate: 43212795Sdim DesignatorKind Kind; 44212795Sdim 45212795Sdim struct FieldDesignatorInfo { 46212795Sdim const IdentifierInfo *II; 47212795Sdim unsigned DotLoc; 48212795Sdim unsigned NameLoc; 49212795Sdim }; 50212795Sdim struct ArrayDesignatorInfo { 51212795Sdim Expr *Index; 52212795Sdim unsigned LBracketLoc; 53212795Sdim mutable unsigned RBracketLoc; 54212795Sdim }; 55212795Sdim struct ArrayRangeDesignatorInfo { 56212795Sdim Expr *Start, *End; 57212795Sdim unsigned LBracketLoc, EllipsisLoc; 58212795Sdim mutable unsigned RBracketLoc; 59212795Sdim }; 60212795Sdim 61212795Sdim union { 62212795Sdim FieldDesignatorInfo FieldInfo; 63212795Sdim ArrayDesignatorInfo ArrayInfo; 64212795Sdim ArrayRangeDesignatorInfo ArrayRangeInfo; 65212795Sdim }; 66212795Sdim 67212795Sdimpublic: 68212795Sdim 69212795Sdim DesignatorKind getKind() const { return Kind; } 70212795Sdim bool isFieldDesignator() const { return Kind == FieldDesignator; } 71212795Sdim bool isArrayDesignator() const { return Kind == ArrayDesignator; } 72212795Sdim bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 73212795Sdim 74212795Sdim const IdentifierInfo *getField() const { 75212795Sdim assert(isFieldDesignator() && "Invalid accessor"); 76212795Sdim return FieldInfo.II; 77212795Sdim } 78212795Sdim 79212795Sdim SourceLocation getDotLoc() const { 80212795Sdim assert(isFieldDesignator() && "Invalid accessor"); 81212795Sdim return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); 82212795Sdim } 83212795Sdim 84212795Sdim SourceLocation getFieldLoc() const { 85212795Sdim assert(isFieldDesignator() && "Invalid accessor"); 86212795Sdim return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); 87212795Sdim } 88212795Sdim 89212795Sdim Expr *getArrayIndex() const { 90212795Sdim assert(isArrayDesignator() && "Invalid accessor"); 91212795Sdim return ArrayInfo.Index; 92212795Sdim } 93212795Sdim 94212795Sdim Expr *getArrayRangeStart() const { 95212795Sdim assert(isArrayRangeDesignator() && "Invalid accessor"); 96212795Sdim return ArrayRangeInfo.Start; 97212795Sdim } 98212795Sdim Expr *getArrayRangeEnd() const { 99212795Sdim assert(isArrayRangeDesignator() && "Invalid accessor"); 100212795Sdim return ArrayRangeInfo.End; 101212795Sdim } 102212795Sdim 103212795Sdim SourceLocation getLBracketLoc() const { 104212795Sdim assert((isArrayDesignator() || isArrayRangeDesignator()) && 105212795Sdim "Invalid accessor"); 106212795Sdim if (isArrayDesignator()) 107212795Sdim return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc); 108212795Sdim else 109212795Sdim return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc); 110212795Sdim } 111212795Sdim 112212795Sdim SourceLocation getRBracketLoc() const { 113212795Sdim assert((isArrayDesignator() || isArrayRangeDesignator()) && 114212795Sdim "Invalid accessor"); 115212795Sdim if (isArrayDesignator()) 116212795Sdim return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc); 117212795Sdim else 118212795Sdim return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc); 119212795Sdim } 120212795Sdim 121212795Sdim SourceLocation getEllipsisLoc() const { 122212795Sdim assert(isArrayRangeDesignator() && "Invalid accessor"); 123212795Sdim return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); 124212795Sdim } 125212795Sdim 126212795Sdim static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, 127212795Sdim SourceLocation NameLoc) { 128212795Sdim Designator D; 129212795Sdim D.Kind = FieldDesignator; 130212795Sdim D.FieldInfo.II = II; 131212795Sdim D.FieldInfo.DotLoc = DotLoc.getRawEncoding(); 132212795Sdim D.FieldInfo.NameLoc = NameLoc.getRawEncoding(); 133212795Sdim return D; 134212795Sdim } 135212795Sdim 136212795Sdim static Designator getArray(Expr *Index, 137212795Sdim SourceLocation LBracketLoc) { 138212795Sdim Designator D; 139212795Sdim D.Kind = ArrayDesignator; 140212795Sdim D.ArrayInfo.Index = Index; 141212795Sdim D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 142212795Sdim D.ArrayInfo.RBracketLoc = 0; 143212795Sdim return D; 144212795Sdim } 145212795Sdim 146212795Sdim static Designator getArrayRange(Expr *Start, 147212795Sdim Expr *End, 148212795Sdim SourceLocation LBracketLoc, 149212795Sdim SourceLocation EllipsisLoc) { 150212795Sdim Designator D; 151212795Sdim D.Kind = ArrayRangeDesignator; 152212795Sdim D.ArrayRangeInfo.Start = Start; 153212795Sdim D.ArrayRangeInfo.End = End; 154212795Sdim D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding(); 155212795Sdim D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding(); 156212795Sdim D.ArrayRangeInfo.RBracketLoc = 0; 157212795Sdim return D; 158212795Sdim } 159212795Sdim 160212795Sdim void setRBracketLoc(SourceLocation RBracketLoc) const { 161212795Sdim assert((isArrayDesignator() || isArrayRangeDesignator()) && 162212795Sdim "Invalid accessor"); 163212795Sdim if (isArrayDesignator()) 164212795Sdim ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 165212795Sdim else 166212795Sdim ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding(); 167212795Sdim } 168212795Sdim 169212795Sdim /// ClearExprs - Null out any expression references, which prevents 170212795Sdim /// them from being 'delete'd later. 171212795Sdim void ClearExprs(Sema &Actions) {} 172212795Sdim 173212795Sdim /// FreeExprs - Release any unclaimed memory for the expressions in 174212795Sdim /// this designator. 175212795Sdim void FreeExprs(Sema &Actions) {} 176212795Sdim}; 177212795Sdim 178212795Sdim 179212795Sdim/// Designation - Represent a full designation, which is a sequence of 180212795Sdim/// designators. This class is mostly a helper for InitListDesignations. 181212795Sdimclass Designation { 182212795Sdim /// Designators - The actual designators for this initializer. 183226890Sdim SmallVector<Designator, 2> Designators; 184212795Sdim 185212795Sdimpublic: 186212795Sdim /// AddDesignator - Add a designator to the end of this list. 187212795Sdim void AddDesignator(Designator D) { 188212795Sdim Designators.push_back(D); 189212795Sdim } 190212795Sdim 191212795Sdim bool empty() const { return Designators.empty(); } 192212795Sdim 193212795Sdim unsigned getNumDesignators() const { return Designators.size(); } 194212795Sdim const Designator &getDesignator(unsigned Idx) const { 195212795Sdim assert(Idx < Designators.size()); 196212795Sdim return Designators[Idx]; 197212795Sdim } 198212795Sdim 199212795Sdim /// ClearExprs - Null out any expression references, which prevents them from 200212795Sdim /// being 'delete'd later. 201212795Sdim void ClearExprs(Sema &Actions) {} 202212795Sdim 203212795Sdim /// FreeExprs - Release any unclaimed memory for the expressions in this 204212795Sdim /// designation. 205212795Sdim void FreeExprs(Sema &Actions) {} 206212795Sdim}; 207212795Sdim 208212795Sdim} // end namespace clang 209212795Sdim 210212795Sdim#endif 211