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 
getKind()69   DesignatorKind getKind() const { return Kind; }
isFieldDesignator()70   bool isFieldDesignator() const { return Kind == FieldDesignator; }
isArrayDesignator()71   bool isArrayDesignator() const { return Kind == ArrayDesignator; }
isArrayRangeDesignator()72   bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
73 
getField()74   const IdentifierInfo *getField() const {
75     assert(isFieldDesignator() && "Invalid accessor");
76     return FieldInfo.II;
77   }
78 
getDotLoc()79   SourceLocation getDotLoc() const {
80     assert(isFieldDesignator() && "Invalid accessor");
81     return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
82   }
83 
getFieldLoc()84   SourceLocation getFieldLoc() const {
85     assert(isFieldDesignator() && "Invalid accessor");
86     return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
87   }
88 
getArrayIndex()89   Expr *getArrayIndex() const {
90     assert(isArrayDesignator() && "Invalid accessor");
91     return ArrayInfo.Index;
92   }
93 
getArrayRangeStart()94   Expr *getArrayRangeStart() const {
95     assert(isArrayRangeDesignator() && "Invalid accessor");
96     return ArrayRangeInfo.Start;
97   }
getArrayRangeEnd()98   Expr *getArrayRangeEnd() const {
99     assert(isArrayRangeDesignator() && "Invalid accessor");
100     return ArrayRangeInfo.End;
101   }
102 
getLBracketLoc()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 
getRBracketLoc()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 
getEllipsisLoc()121   SourceLocation getEllipsisLoc() const {
122     assert(isArrayRangeDesignator() && "Invalid accessor");
123     return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
124   }
125 
getField(const IdentifierInfo * II,SourceLocation DotLoc,SourceLocation NameLoc)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 
getArray(Expr * Index,SourceLocation LBracketLoc)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 
getArrayRange(Expr * Start,Expr * End,SourceLocation LBracketLoc,SourceLocation EllipsisLoc)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 
setRBracketLoc(SourceLocation RBracketLoc)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.
ClearExprs(Sema & Actions)171   void ClearExprs(Sema &Actions) {}
172 
173   /// FreeExprs - Release any unclaimed memory for the expressions in
174   /// this designator.
FreeExprs(Sema & Actions)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.
AddDesignator(Designator D)187   void AddDesignator(Designator D) {
188     Designators.push_back(D);
189   }
190 
empty()191   bool empty() const { return Designators.empty(); }
192 
getNumDesignators()193   unsigned getNumDesignators() const { return Designators.size(); }
getDesignator(unsigned Idx)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.
ClearExprs(Sema & Actions)201   void ClearExprs(Sema &Actions) {}
202 
203   /// FreeExprs - Release any unclaimed memory for the expressions in this
204   /// designation.
FreeExprs(Sema & Actions)205   void FreeExprs(Sema &Actions) {}
206 };
207 
208 } // end namespace clang
209 
210 #endif
211