Designator.h 6.5 KB

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