106f32e7eSjoerg //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file defines interfaces used to represent designators (a la 1006f32e7eSjoerg // C99 designated initializers) during parsing. 1106f32e7eSjoerg // 1206f32e7eSjoerg //===----------------------------------------------------------------------===// 1306f32e7eSjoerg 1406f32e7eSjoerg #ifndef LLVM_CLANG_SEMA_DESIGNATOR_H 1506f32e7eSjoerg #define LLVM_CLANG_SEMA_DESIGNATOR_H 1606f32e7eSjoerg 1706f32e7eSjoerg #include "clang/Basic/SourceLocation.h" 1806f32e7eSjoerg #include "llvm/ADT/SmallVector.h" 1906f32e7eSjoerg 2006f32e7eSjoerg namespace clang { 2106f32e7eSjoerg 2206f32e7eSjoerg class Expr; 2306f32e7eSjoerg class IdentifierInfo; 2406f32e7eSjoerg class Sema; 2506f32e7eSjoerg 2606f32e7eSjoerg /// Designator - A designator in a C99 designated initializer. 2706f32e7eSjoerg /// 2806f32e7eSjoerg /// This class is a discriminated union which holds the various 2906f32e7eSjoerg /// different sorts of designators possible. A Designation is an array of 3006f32e7eSjoerg /// these. An example of a designator are things like this: 3106f32e7eSjoerg /// [8] .field [47] // C99 designation: 3 designators 3206f32e7eSjoerg /// [8 ... 47] field: // GNU extensions: 2 designators 3306f32e7eSjoerg /// These occur in initializers, e.g.: 3406f32e7eSjoerg /// int a[10] = {2, 4, [8]=9, 10}; 3506f32e7eSjoerg /// 3606f32e7eSjoerg class Designator { 3706f32e7eSjoerg public: 3806f32e7eSjoerg enum DesignatorKind { 3906f32e7eSjoerg FieldDesignator, ArrayDesignator, ArrayRangeDesignator 4006f32e7eSjoerg }; 4106f32e7eSjoerg private: Designator()42*13fbcb42Sjoerg Designator() {}; 43*13fbcb42Sjoerg 4406f32e7eSjoerg DesignatorKind Kind; 4506f32e7eSjoerg 4606f32e7eSjoerg struct FieldDesignatorInfo { 4706f32e7eSjoerg const IdentifierInfo *II; 48*13fbcb42Sjoerg SourceLocation DotLoc; 49*13fbcb42Sjoerg SourceLocation NameLoc; 5006f32e7eSjoerg }; 5106f32e7eSjoerg struct ArrayDesignatorInfo { 5206f32e7eSjoerg Expr *Index; 53*13fbcb42Sjoerg SourceLocation LBracketLoc; 54*13fbcb42Sjoerg mutable SourceLocation RBracketLoc; 5506f32e7eSjoerg }; 5606f32e7eSjoerg struct ArrayRangeDesignatorInfo { 5706f32e7eSjoerg Expr *Start, *End; 58*13fbcb42Sjoerg SourceLocation LBracketLoc, EllipsisLoc; 59*13fbcb42Sjoerg mutable SourceLocation RBracketLoc; 6006f32e7eSjoerg }; 6106f32e7eSjoerg 6206f32e7eSjoerg union { 6306f32e7eSjoerg FieldDesignatorInfo FieldInfo; 6406f32e7eSjoerg ArrayDesignatorInfo ArrayInfo; 6506f32e7eSjoerg ArrayRangeDesignatorInfo ArrayRangeInfo; 6606f32e7eSjoerg }; 6706f32e7eSjoerg 6806f32e7eSjoerg public: 6906f32e7eSjoerg getKind()7006f32e7eSjoerg DesignatorKind getKind() const { return Kind; } isFieldDesignator()7106f32e7eSjoerg bool isFieldDesignator() const { return Kind == FieldDesignator; } isArrayDesignator()7206f32e7eSjoerg bool isArrayDesignator() const { return Kind == ArrayDesignator; } isArrayRangeDesignator()7306f32e7eSjoerg bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } 7406f32e7eSjoerg getField()7506f32e7eSjoerg const IdentifierInfo *getField() const { 7606f32e7eSjoerg assert(isFieldDesignator() && "Invalid accessor"); 7706f32e7eSjoerg return FieldInfo.II; 7806f32e7eSjoerg } 7906f32e7eSjoerg getDotLoc()8006f32e7eSjoerg SourceLocation getDotLoc() const { 8106f32e7eSjoerg assert(isFieldDesignator() && "Invalid accessor"); 82*13fbcb42Sjoerg return FieldInfo.DotLoc; 8306f32e7eSjoerg } 8406f32e7eSjoerg getFieldLoc()8506f32e7eSjoerg SourceLocation getFieldLoc() const { 8606f32e7eSjoerg assert(isFieldDesignator() && "Invalid accessor"); 87*13fbcb42Sjoerg return FieldInfo.NameLoc; 8806f32e7eSjoerg } 8906f32e7eSjoerg getArrayIndex()9006f32e7eSjoerg Expr *getArrayIndex() const { 9106f32e7eSjoerg assert(isArrayDesignator() && "Invalid accessor"); 9206f32e7eSjoerg return ArrayInfo.Index; 9306f32e7eSjoerg } 9406f32e7eSjoerg getArrayRangeStart()9506f32e7eSjoerg Expr *getArrayRangeStart() const { 9606f32e7eSjoerg assert(isArrayRangeDesignator() && "Invalid accessor"); 9706f32e7eSjoerg return ArrayRangeInfo.Start; 9806f32e7eSjoerg } getArrayRangeEnd()9906f32e7eSjoerg Expr *getArrayRangeEnd() const { 10006f32e7eSjoerg assert(isArrayRangeDesignator() && "Invalid accessor"); 10106f32e7eSjoerg return ArrayRangeInfo.End; 10206f32e7eSjoerg } 10306f32e7eSjoerg getLBracketLoc()10406f32e7eSjoerg SourceLocation getLBracketLoc() const { 10506f32e7eSjoerg assert((isArrayDesignator() || isArrayRangeDesignator()) && 10606f32e7eSjoerg "Invalid accessor"); 10706f32e7eSjoerg if (isArrayDesignator()) 108*13fbcb42Sjoerg return ArrayInfo.LBracketLoc; 10906f32e7eSjoerg else 110*13fbcb42Sjoerg return ArrayRangeInfo.LBracketLoc; 11106f32e7eSjoerg } 11206f32e7eSjoerg getRBracketLoc()11306f32e7eSjoerg SourceLocation getRBracketLoc() const { 11406f32e7eSjoerg assert((isArrayDesignator() || isArrayRangeDesignator()) && 11506f32e7eSjoerg "Invalid accessor"); 11606f32e7eSjoerg if (isArrayDesignator()) 117*13fbcb42Sjoerg return ArrayInfo.RBracketLoc; 11806f32e7eSjoerg else 119*13fbcb42Sjoerg return ArrayRangeInfo.RBracketLoc; 12006f32e7eSjoerg } 12106f32e7eSjoerg getEllipsisLoc()12206f32e7eSjoerg SourceLocation getEllipsisLoc() const { 12306f32e7eSjoerg assert(isArrayRangeDesignator() && "Invalid accessor"); 124*13fbcb42Sjoerg return ArrayRangeInfo.EllipsisLoc; 12506f32e7eSjoerg } 12606f32e7eSjoerg getField(const IdentifierInfo * II,SourceLocation DotLoc,SourceLocation NameLoc)12706f32e7eSjoerg static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, 12806f32e7eSjoerg SourceLocation NameLoc) { 12906f32e7eSjoerg Designator D; 13006f32e7eSjoerg D.Kind = FieldDesignator; 131*13fbcb42Sjoerg new (&D.FieldInfo) FieldDesignatorInfo; 13206f32e7eSjoerg D.FieldInfo.II = II; 133*13fbcb42Sjoerg D.FieldInfo.DotLoc = DotLoc; 134*13fbcb42Sjoerg D.FieldInfo.NameLoc = NameLoc; 13506f32e7eSjoerg return D; 13606f32e7eSjoerg } 13706f32e7eSjoerg getArray(Expr * Index,SourceLocation LBracketLoc)13806f32e7eSjoerg static Designator getArray(Expr *Index, 13906f32e7eSjoerg SourceLocation LBracketLoc) { 14006f32e7eSjoerg Designator D; 14106f32e7eSjoerg D.Kind = ArrayDesignator; 142*13fbcb42Sjoerg new (&D.ArrayInfo) ArrayDesignatorInfo; 14306f32e7eSjoerg D.ArrayInfo.Index = Index; 144*13fbcb42Sjoerg D.ArrayInfo.LBracketLoc = LBracketLoc; 145*13fbcb42Sjoerg D.ArrayInfo.RBracketLoc = SourceLocation(); 14606f32e7eSjoerg return D; 14706f32e7eSjoerg } 14806f32e7eSjoerg getArrayRange(Expr * Start,Expr * End,SourceLocation LBracketLoc,SourceLocation EllipsisLoc)14906f32e7eSjoerg static Designator getArrayRange(Expr *Start, 15006f32e7eSjoerg Expr *End, 15106f32e7eSjoerg SourceLocation LBracketLoc, 15206f32e7eSjoerg SourceLocation EllipsisLoc) { 15306f32e7eSjoerg Designator D; 15406f32e7eSjoerg D.Kind = ArrayRangeDesignator; 155*13fbcb42Sjoerg new (&D.ArrayRangeInfo) ArrayRangeDesignatorInfo; 15606f32e7eSjoerg D.ArrayRangeInfo.Start = Start; 15706f32e7eSjoerg D.ArrayRangeInfo.End = End; 158*13fbcb42Sjoerg D.ArrayRangeInfo.LBracketLoc = LBracketLoc; 159*13fbcb42Sjoerg D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc; 160*13fbcb42Sjoerg D.ArrayRangeInfo.RBracketLoc = SourceLocation(); 16106f32e7eSjoerg return D; 16206f32e7eSjoerg } 16306f32e7eSjoerg setRBracketLoc(SourceLocation RBracketLoc)16406f32e7eSjoerg void setRBracketLoc(SourceLocation RBracketLoc) const { 16506f32e7eSjoerg assert((isArrayDesignator() || isArrayRangeDesignator()) && 16606f32e7eSjoerg "Invalid accessor"); 16706f32e7eSjoerg if (isArrayDesignator()) 168*13fbcb42Sjoerg ArrayInfo.RBracketLoc = RBracketLoc; 16906f32e7eSjoerg else 170*13fbcb42Sjoerg ArrayRangeInfo.RBracketLoc = RBracketLoc; 17106f32e7eSjoerg } 17206f32e7eSjoerg 17306f32e7eSjoerg /// ClearExprs - Null out any expression references, which prevents 17406f32e7eSjoerg /// them from being 'delete'd later. ClearExprs(Sema & Actions)17506f32e7eSjoerg void ClearExprs(Sema &Actions) {} 17606f32e7eSjoerg 17706f32e7eSjoerg /// FreeExprs - Release any unclaimed memory for the expressions in 17806f32e7eSjoerg /// this designator. FreeExprs(Sema & Actions)17906f32e7eSjoerg void FreeExprs(Sema &Actions) {} 18006f32e7eSjoerg }; 18106f32e7eSjoerg 18206f32e7eSjoerg 18306f32e7eSjoerg /// Designation - Represent a full designation, which is a sequence of 18406f32e7eSjoerg /// designators. This class is mostly a helper for InitListDesignations. 18506f32e7eSjoerg class Designation { 18606f32e7eSjoerg /// Designators - The actual designators for this initializer. 18706f32e7eSjoerg SmallVector<Designator, 2> Designators; 18806f32e7eSjoerg 18906f32e7eSjoerg public: 19006f32e7eSjoerg /// AddDesignator - Add a designator to the end of this list. AddDesignator(Designator D)19106f32e7eSjoerg void AddDesignator(Designator D) { 19206f32e7eSjoerg Designators.push_back(D); 19306f32e7eSjoerg } 19406f32e7eSjoerg empty()19506f32e7eSjoerg bool empty() const { return Designators.empty(); } 19606f32e7eSjoerg getNumDesignators()19706f32e7eSjoerg unsigned getNumDesignators() const { return Designators.size(); } getDesignator(unsigned Idx)19806f32e7eSjoerg const Designator &getDesignator(unsigned Idx) const { 19906f32e7eSjoerg assert(Idx < Designators.size()); 20006f32e7eSjoerg return Designators[Idx]; 20106f32e7eSjoerg } 20206f32e7eSjoerg 20306f32e7eSjoerg /// ClearExprs - Null out any expression references, which prevents them from 20406f32e7eSjoerg /// being 'delete'd later. ClearExprs(Sema & Actions)20506f32e7eSjoerg void ClearExprs(Sema &Actions) {} 20606f32e7eSjoerg 20706f32e7eSjoerg /// FreeExprs - Release any unclaimed memory for the expressions in this 20806f32e7eSjoerg /// designation. FreeExprs(Sema & Actions)20906f32e7eSjoerg void FreeExprs(Sema &Actions) {} 21006f32e7eSjoerg }; 21106f32e7eSjoerg 21206f32e7eSjoerg } // end namespace clang 21306f32e7eSjoerg 21406f32e7eSjoerg #endif 215