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