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