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