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