Coverage Report

Created: 2023-05-31 04:38

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Sema/Designator.h
Line
Count
Source
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
25
/// Designator - A designator in a C99 designated initializer.
26
///
27
/// This class is a discriminated union which holds the various
28
/// different sorts of designators possible. A Designation is an array of
29
/// these.  An example of a designator are things like this:
30
///
31
///      [8] .field [47]        // C99 designation: 3 designators
32
///      [8 ... 47]  field:     // GNU extensions: 2 designators
33
///
34
/// These occur in initializers, e.g.:
35
///
36
///      int a[10] = {2, 4, [8]=9, 10};
37
///
38
class Designator {
39
  /// A field designator, e.g., ".x = 42".
40
  struct FieldDesignatorInfo {
41
    /// Refers to the field being initialized.
42
    const IdentifierInfo *FieldName;
43
44
    /// The location of the '.' in the designated initializer.
45
    SourceLocation DotLoc;
46
47
    /// The location of the field name in the designated initializer.
48
    SourceLocation FieldLoc;
49
50
    FieldDesignatorInfo(const IdentifierInfo *FieldName, SourceLocation DotLoc,
51
                        SourceLocation FieldLoc)
52
2.22k
        : FieldName(FieldName), DotLoc(DotLoc), FieldLoc(FieldLoc) {}
53
  };
54
55
  /// An array designator, e.g., "[42] = 0".
56
  struct ArrayDesignatorInfo {
57
    Expr *Index;
58
59
    // The location of the '[' in the designated initializer.
60
    SourceLocation LBracketLoc;
61
62
    // The location of the ']' in the designated initializer.
63
    mutable SourceLocation RBracketLoc;
64
65
    ArrayDesignatorInfo(Expr *Index, SourceLocation LBracketLoc)
66
428
        : Index(Index), LBracketLoc(LBracketLoc) {}
67
  };
68
69
  /// An array range designator, e.g. "[42 ... 50] = 1".
70
  struct ArrayRangeDesignatorInfo {
71
    Expr *Start;
72
    Expr *End;
73
74
    // The location of the '[' in the designated initializer.
75
    SourceLocation LBracketLoc;
76
77
    // The location of the '...' in the designated initializer.
78
    SourceLocation EllipsisLoc;
79
80
    // The location of the ']' in the designated initializer.
81
    mutable SourceLocation RBracketLoc;
82
83
    ArrayRangeDesignatorInfo(Expr *Start, Expr *End, SourceLocation LBracketLoc,
84
                             SourceLocation EllipsisLoc)
85
        : Start(Start), End(End), LBracketLoc(LBracketLoc),
86
28
          EllipsisLoc(EllipsisLoc) {}
87
  };
88
89
  /// The kind of designator this describes.
90
  enum DesignatorKind {
91
    FieldDesignator,
92
    ArrayDesignator,
93
    ArrayRangeDesignator
94
  };
95
96
  DesignatorKind Kind;
97
98
  union {
99
    FieldDesignatorInfo FieldInfo;
100
    ArrayDesignatorInfo ArrayInfo;
101
    ArrayRangeDesignatorInfo ArrayRangeInfo;
102
  };
103
104
2.68k
  Designator(DesignatorKind Kind) : Kind(Kind) {}
105
106
public:
107
9.45k
  bool isFieldDesignator() const { return Kind == FieldDesignator; }
108
3.54k
  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
109
261
  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
110
111
  //===--------------------------------------------------------------------===//
112
  // FieldDesignatorInfo
113
114
  /// Creates a field designator.
115
  static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
116
                                          SourceLocation DotLoc,
117
2.22k
                                          SourceLocation FieldLoc) {
118
2.22k
    Designator D(FieldDesignator);
119
2.22k
    new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
120
2.22k
    return D;
121
2.22k
  }
122
123
2.28k
  const IdentifierInfo *getFieldDecl() const {
124
2.28k
    assert(isFieldDesignator() && "Invalid accessor");
125
2.28k
    return FieldInfo.FieldName;
126
2.28k
  }
127
128
2.21k
  SourceLocation getDotLoc() const {
129
2.21k
    assert(isFieldDesignator() && "Invalid accessor");
130
2.21k
    return FieldInfo.DotLoc;
131
2.21k
  }
132
133
2.21k
  SourceLocation getFieldLoc() const {
134
2.21k
    assert(isFieldDesignator() && "Invalid accessor");
135
2.21k
    return FieldInfo.FieldLoc;
136
2.21k
  }
137
138
  //===--------------------------------------------------------------------===//
139
  // ArrayDesignatorInfo:
140
141
  /// Creates an array designator.
142
  static Designator CreateArrayDesignator(Expr *Index,
143
428
                                          SourceLocation LBracketLoc) {
144
428
    Designator D(ArrayDesignator);
145
428
    new (&D.ArrayInfo) ArrayDesignatorInfo(Index, LBracketLoc);
146
428
    return D;
147
428
  }
148
149
418
  Expr *getArrayIndex() const {
150
418
    assert(isArrayDesignator() && "Invalid accessor");
151
418
    return ArrayInfo.Index;
152
418
  }
153
154
435
  SourceLocation getLBracketLoc() const {
155
435
    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
156
435
           "Invalid accessor");
157
435
    return isArrayDesignator() ? 
ArrayInfo.LBracketLoc408
158
435
                               : 
ArrayRangeInfo.LBracketLoc27
;
159
435
  }
160
161
435
  SourceLocation getRBracketLoc() const {
162
435
    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
163
435
           "Invalid accessor");
164
435
    return isArrayDesignator() ? 
ArrayInfo.RBracketLoc408
165
435
                               : 
ArrayRangeInfo.RBracketLoc27
;
166
435
  }
167
168
  //===--------------------------------------------------------------------===//
169
  // ArrayRangeDesignatorInfo:
170
171
  /// Creates a GNU array-range designator.
172
  static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End,
173
                                               SourceLocation LBracketLoc,
174
28
                                               SourceLocation EllipsisLoc) {
175
28
    Designator D(ArrayRangeDesignator);
176
28
    new (&D.ArrayRangeInfo)
177
28
        ArrayRangeDesignatorInfo(Start, End, LBracketLoc, EllipsisLoc);
178
28
    return D;
179
28
  }
180
181
28
  Expr *getArrayRangeStart() const {
182
28
    assert(isArrayRangeDesignator() && "Invalid accessor");
183
28
    return ArrayRangeInfo.Start;
184
28
  }
185
186
28
  Expr *getArrayRangeEnd() const {
187
28
    assert(isArrayRangeDesignator() && "Invalid accessor");
188
28
    return ArrayRangeInfo.End;
189
28
  }
190
191
28
  SourceLocation getEllipsisLoc() const {
192
28
    assert(isArrayRangeDesignator() && "Invalid accessor");
193
28
    return ArrayRangeInfo.EllipsisLoc;
194
28
  }
195
196
424
  void setRBracketLoc(SourceLocation RBracketLoc) const {
197
424
    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
198
424
           "Invalid accessor");
199
424
    if (isArrayDesignator())
200
404
      ArrayInfo.RBracketLoc = RBracketLoc;
201
20
    else
202
20
      ArrayRangeInfo.RBracketLoc = RBracketLoc;
203
424
  }
204
};
205
206
/// Designation - Represent a full designation, which is a sequence of
207
/// designators.  This class is mostly a helper for InitListDesignations.
208
class Designation {
209
  /// Designators - The actual designators for this initializer.
210
  SmallVector<Designator, 2> Designators;
211
212
public:
213
  /// AddDesignator - Add a designator to the end of this list.
214
2.68k
  void AddDesignator(Designator D) { Designators.push_back(D); }
215
216
2.06k
  bool empty() const { return Designators.empty(); }
217
218
5.68k
  unsigned getNumDesignators() const { return Designators.size(); }
219
3.18k
  const Designator &getDesignator(unsigned Idx) const {
220
3.18k
    assert(Idx < Designators.size());
221
3.18k
    return Designators[Idx];
222
3.18k
  }
223
};
224
225
} // end namespace clang
226
227
#endif