/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Sema/DeclSpec.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- DeclSpec.h - Parsed declaration specifiers -------------*- 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 | | /// \file |
10 | | /// This file defines the classes used to store parsed information about |
11 | | /// declaration-specifiers and declarators. |
12 | | /// |
13 | | /// \verbatim |
14 | | /// static const int volatile x, *y, *(*(*z)[10])(const void *x); |
15 | | /// ------------------------- - -- --------------------------- |
16 | | /// declaration-specifiers \ | / |
17 | | /// declarators |
18 | | /// \endverbatim |
19 | | /// |
20 | | //===----------------------------------------------------------------------===// |
21 | | |
22 | | #ifndef LLVM_CLANG_SEMA_DECLSPEC_H |
23 | | #define LLVM_CLANG_SEMA_DECLSPEC_H |
24 | | |
25 | | #include "clang/AST/DeclCXX.h" |
26 | | #include "clang/AST/DeclObjCCommon.h" |
27 | | #include "clang/AST/NestedNameSpecifier.h" |
28 | | #include "clang/Basic/ExceptionSpecificationType.h" |
29 | | #include "clang/Basic/Lambda.h" |
30 | | #include "clang/Basic/OperatorKinds.h" |
31 | | #include "clang/Basic/Specifiers.h" |
32 | | #include "clang/Lex/Token.h" |
33 | | #include "clang/Sema/Ownership.h" |
34 | | #include "clang/Sema/ParsedAttr.h" |
35 | | #include "llvm/ADT/SmallVector.h" |
36 | | #include "llvm/Support/Compiler.h" |
37 | | #include "llvm/Support/ErrorHandling.h" |
38 | | |
39 | | namespace clang { |
40 | | class ASTContext; |
41 | | class CXXRecordDecl; |
42 | | class TypeLoc; |
43 | | class LangOptions; |
44 | | class IdentifierInfo; |
45 | | class NamespaceAliasDecl; |
46 | | class NamespaceDecl; |
47 | | class ObjCDeclSpec; |
48 | | class Sema; |
49 | | class Declarator; |
50 | | struct TemplateIdAnnotation; |
51 | | |
52 | | /// Represents a C++ nested-name-specifier or a global scope specifier. |
53 | | /// |
54 | | /// These can be in 3 states: |
55 | | /// 1) Not present, identified by isEmpty() |
56 | | /// 2) Present, identified by isNotEmpty() |
57 | | /// 2.a) Valid, identified by isValid() |
58 | | /// 2.b) Invalid, identified by isInvalid(). |
59 | | /// |
60 | | /// isSet() is deprecated because it mostly corresponded to "valid" but was |
61 | | /// often used as if it meant "present". |
62 | | /// |
63 | | /// The actual scope is described by getScopeRep(). |
64 | | class CXXScopeSpec { |
65 | | SourceRange Range; |
66 | | NestedNameSpecifierLocBuilder Builder; |
67 | | |
68 | | public: |
69 | 6.53M | SourceRange getRange() const { return Range; } |
70 | 0 | void setRange(SourceRange R) { Range = R; } |
71 | 0 | void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } |
72 | 59 | void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } |
73 | 142k | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
74 | 31.4k | SourceLocation getEndLoc() const { return Range.getEnd(); } |
75 | | |
76 | | /// Retrieve the representation of the nested-name-specifier. |
77 | 390M | NestedNameSpecifier *getScopeRep() const { |
78 | 390M | return Builder.getRepresentation(); |
79 | 390M | } |
80 | | |
81 | | /// Extend the current nested-name-specifier by another |
82 | | /// nested-name-specifier component of the form 'type::'. |
83 | | /// |
84 | | /// \param Context The AST context in which this nested-name-specifier |
85 | | /// resides. |
86 | | /// |
87 | | /// \param TemplateKWLoc The location of the 'template' keyword, if present. |
88 | | /// |
89 | | /// \param TL The TypeLoc that describes the type preceding the '::'. |
90 | | /// |
91 | | /// \param ColonColonLoc The location of the trailing '::'. |
92 | | void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, |
93 | | SourceLocation ColonColonLoc); |
94 | | |
95 | | /// Extend the current nested-name-specifier by another |
96 | | /// nested-name-specifier component of the form 'identifier::'. |
97 | | /// |
98 | | /// \param Context The AST context in which this nested-name-specifier |
99 | | /// resides. |
100 | | /// |
101 | | /// \param Identifier The identifier. |
102 | | /// |
103 | | /// \param IdentifierLoc The location of the identifier. |
104 | | /// |
105 | | /// \param ColonColonLoc The location of the trailing '::'. |
106 | | void Extend(ASTContext &Context, IdentifierInfo *Identifier, |
107 | | SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); |
108 | | |
109 | | /// Extend the current nested-name-specifier by another |
110 | | /// nested-name-specifier component of the form 'namespace::'. |
111 | | /// |
112 | | /// \param Context The AST context in which this nested-name-specifier |
113 | | /// resides. |
114 | | /// |
115 | | /// \param Namespace The namespace. |
116 | | /// |
117 | | /// \param NamespaceLoc The location of the namespace name. |
118 | | /// |
119 | | /// \param ColonColonLoc The location of the trailing '::'. |
120 | | void Extend(ASTContext &Context, NamespaceDecl *Namespace, |
121 | | SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); |
122 | | |
123 | | /// Extend the current nested-name-specifier by another |
124 | | /// nested-name-specifier component of the form 'namespace-alias::'. |
125 | | /// |
126 | | /// \param Context The AST context in which this nested-name-specifier |
127 | | /// resides. |
128 | | /// |
129 | | /// \param Alias The namespace alias. |
130 | | /// |
131 | | /// \param AliasLoc The location of the namespace alias |
132 | | /// name. |
133 | | /// |
134 | | /// \param ColonColonLoc The location of the trailing '::'. |
135 | | void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, |
136 | | SourceLocation AliasLoc, SourceLocation ColonColonLoc); |
137 | | |
138 | | /// Turn this (empty) nested-name-specifier into the global |
139 | | /// nested-name-specifier '::'. |
140 | | void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); |
141 | | |
142 | | /// Turns this (empty) nested-name-specifier into '__super' |
143 | | /// nested-name-specifier. |
144 | | /// |
145 | | /// \param Context The AST context in which this nested-name-specifier |
146 | | /// resides. |
147 | | /// |
148 | | /// \param RD The declaration of the class in which nested-name-specifier |
149 | | /// appeared. |
150 | | /// |
151 | | /// \param SuperLoc The location of the '__super' keyword. |
152 | | /// name. |
153 | | /// |
154 | | /// \param ColonColonLoc The location of the trailing '::'. |
155 | | void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, |
156 | | SourceLocation SuperLoc, SourceLocation ColonColonLoc); |
157 | | |
158 | | /// Make a new nested-name-specifier from incomplete source-location |
159 | | /// information. |
160 | | /// |
161 | | /// FIXME: This routine should be used very, very rarely, in cases where we |
162 | | /// need to synthesize a nested-name-specifier. Most code should instead use |
163 | | /// \c Adopt() with a proper \c NestedNameSpecifierLoc. |
164 | | void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, |
165 | | SourceRange R); |
166 | | |
167 | | /// Adopt an existing nested-name-specifier (with source-range |
168 | | /// information). |
169 | | void Adopt(NestedNameSpecifierLoc Other); |
170 | | |
171 | | /// Retrieve a nested-name-specifier with location information, copied |
172 | | /// into the given AST context. |
173 | | /// |
174 | | /// \param Context The context into which this nested-name-specifier will be |
175 | | /// copied. |
176 | | NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; |
177 | | |
178 | | /// Retrieve the location of the name in the last qualifier |
179 | | /// in this nested name specifier. |
180 | | /// |
181 | | /// For example, the location of \c bar |
182 | | /// in |
183 | | /// \verbatim |
184 | | /// \::foo::bar<0>:: |
185 | | /// ^~~ |
186 | | /// \endverbatim |
187 | | SourceLocation getLastQualifierNameLoc() const; |
188 | | |
189 | | /// No scope specifier. |
190 | 148M | bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr136M ; } |
191 | | /// A scope specifier is present, but may be valid or invalid. |
192 | 97.4M | bool isNotEmpty() const { return !isEmpty(); } |
193 | | |
194 | | /// An error occurred during parsing of the scope specifier. |
195 | 101M | bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr20.4M ; } |
196 | | /// A scope specifier is present, and it refers to a real scope. |
197 | 32.4M | bool isValid() const { return getScopeRep() != nullptr; } |
198 | | |
199 | | /// Indicate that this nested-name-specifier is invalid. |
200 | 1.25k | void SetInvalid(SourceRange R) { |
201 | 1.25k | assert(R.isValid() && "Must have a valid source range"); |
202 | 1.25k | if (Range.getBegin().isInvalid()) |
203 | 514 | Range.setBegin(R.getBegin()); |
204 | 1.25k | Range.setEnd(R.getEnd()); |
205 | 1.25k | Builder.Clear(); |
206 | 1.25k | } |
207 | | |
208 | | /// Deprecated. Some call sites intend isNotEmpty() while others intend |
209 | | /// isValid(). |
210 | 172M | bool isSet() const { return getScopeRep() != nullptr; } |
211 | | |
212 | 70.0M | void clear() { |
213 | 70.0M | Range = SourceRange(); |
214 | 70.0M | Builder.Clear(); |
215 | 70.0M | } |
216 | | |
217 | | /// Retrieve the data associated with the source-location information. |
218 | 5.67M | char *location_data() const { return Builder.getBuffer().first; } |
219 | | |
220 | | /// Retrieve the size of the data associated with source-location |
221 | | /// information. |
222 | 10.9M | unsigned location_size() const { return Builder.getBuffer().second; } |
223 | | }; |
224 | | |
225 | | /// Captures information about "declaration specifiers". |
226 | | /// |
227 | | /// "Declaration specifiers" encompasses storage-class-specifiers, |
228 | | /// type-specifiers, type-qualifiers, and function-specifiers. |
229 | | class DeclSpec { |
230 | | public: |
231 | | /// storage-class-specifier |
232 | | /// \note The order of these enumerators is important for diagnostics. |
233 | | enum SCS { |
234 | | SCS_unspecified = 0, |
235 | | SCS_typedef, |
236 | | SCS_extern, |
237 | | SCS_static, |
238 | | SCS_auto, |
239 | | SCS_register, |
240 | | SCS_private_extern, |
241 | | SCS_mutable |
242 | | }; |
243 | | |
244 | | // Import thread storage class specifier enumeration and constants. |
245 | | // These can be combined with SCS_extern and SCS_static. |
246 | | typedef ThreadStorageClassSpecifier TSCS; |
247 | | static const TSCS TSCS_unspecified = clang::TSCS_unspecified; |
248 | | static const TSCS TSCS___thread = clang::TSCS___thread; |
249 | | static const TSCS TSCS_thread_local = clang::TSCS_thread_local; |
250 | | static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local; |
251 | | |
252 | | enum TSC { |
253 | | TSC_unspecified, |
254 | | TSC_imaginary, |
255 | | TSC_complex |
256 | | }; |
257 | | |
258 | | // Import type specifier type enumeration and constants. |
259 | | typedef TypeSpecifierType TST; |
260 | | static const TST TST_unspecified = clang::TST_unspecified; |
261 | | static const TST TST_void = clang::TST_void; |
262 | | static const TST TST_char = clang::TST_char; |
263 | | static const TST TST_wchar = clang::TST_wchar; |
264 | | static const TST TST_char8 = clang::TST_char8; |
265 | | static const TST TST_char16 = clang::TST_char16; |
266 | | static const TST TST_char32 = clang::TST_char32; |
267 | | static const TST TST_int = clang::TST_int; |
268 | | static const TST TST_int128 = clang::TST_int128; |
269 | | static const TST TST_extint = clang::TST_extint; |
270 | | static const TST TST_half = clang::TST_half; |
271 | | static const TST TST_BFloat16 = clang::TST_BFloat16; |
272 | | static const TST TST_float = clang::TST_float; |
273 | | static const TST TST_double = clang::TST_double; |
274 | | static const TST TST_float16 = clang::TST_Float16; |
275 | | static const TST TST_accum = clang::TST_Accum; |
276 | | static const TST TST_fract = clang::TST_Fract; |
277 | | static const TST TST_float128 = clang::TST_float128; |
278 | | static const TST TST_bool = clang::TST_bool; |
279 | | static const TST TST_decimal32 = clang::TST_decimal32; |
280 | | static const TST TST_decimal64 = clang::TST_decimal64; |
281 | | static const TST TST_decimal128 = clang::TST_decimal128; |
282 | | static const TST TST_enum = clang::TST_enum; |
283 | | static const TST TST_union = clang::TST_union; |
284 | | static const TST TST_struct = clang::TST_struct; |
285 | | static const TST TST_interface = clang::TST_interface; |
286 | | static const TST TST_class = clang::TST_class; |
287 | | static const TST TST_typename = clang::TST_typename; |
288 | | static const TST TST_typeofType = clang::TST_typeofType; |
289 | | static const TST TST_typeofExpr = clang::TST_typeofExpr; |
290 | | static const TST TST_decltype = clang::TST_decltype; |
291 | | static const TST TST_decltype_auto = clang::TST_decltype_auto; |
292 | | static const TST TST_underlyingType = clang::TST_underlyingType; |
293 | | static const TST TST_auto = clang::TST_auto; |
294 | | static const TST TST_auto_type = clang::TST_auto_type; |
295 | | static const TST TST_unknown_anytype = clang::TST_unknown_anytype; |
296 | | static const TST TST_atomic = clang::TST_atomic; |
297 | | #define GENERIC_IMAGE_TYPE(ImgType, Id) \ |
298 | | static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t; |
299 | | #include "clang/Basic/OpenCLImageTypes.def" |
300 | | static const TST TST_error = clang::TST_error; |
301 | | |
302 | | // type-qualifiers |
303 | | enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. |
304 | | TQ_unspecified = 0, |
305 | | TQ_const = 1, |
306 | | TQ_restrict = 2, |
307 | | TQ_volatile = 4, |
308 | | TQ_unaligned = 8, |
309 | | // This has no corresponding Qualifiers::TQ value, because it's not treated |
310 | | // as a qualifier in our type system. |
311 | | TQ_atomic = 16 |
312 | | }; |
313 | | |
314 | | /// ParsedSpecifiers - Flags to query which specifiers were applied. This is |
315 | | /// returned by getParsedSpecifiers. |
316 | | enum ParsedSpecifiers { |
317 | | PQ_None = 0, |
318 | | PQ_StorageClassSpecifier = 1, |
319 | | PQ_TypeSpecifier = 2, |
320 | | PQ_TypeQualifier = 4, |
321 | | PQ_FunctionSpecifier = 8 |
322 | | // FIXME: Attributes should be included here. |
323 | | }; |
324 | | |
325 | | private: |
326 | | // storage-class-specifier |
327 | | /*SCS*/unsigned StorageClassSpec : 3; |
328 | | /*TSCS*/unsigned ThreadStorageClassSpec : 2; |
329 | | unsigned SCS_extern_in_linkage_spec : 1; |
330 | | |
331 | | // type-specifier |
332 | | /*TypeSpecifierWidth*/ unsigned TypeSpecWidth : 2; |
333 | | /*TSC*/unsigned TypeSpecComplex : 2; |
334 | | /*TSS*/unsigned TypeSpecSign : 2; |
335 | | /*TST*/unsigned TypeSpecType : 6; |
336 | | unsigned TypeAltiVecVector : 1; |
337 | | unsigned TypeAltiVecPixel : 1; |
338 | | unsigned TypeAltiVecBool : 1; |
339 | | unsigned TypeSpecOwned : 1; |
340 | | unsigned TypeSpecPipe : 1; |
341 | | unsigned TypeSpecSat : 1; |
342 | | unsigned ConstrainedAuto : 1; |
343 | | |
344 | | // type-qualifiers |
345 | | unsigned TypeQualifiers : 5; // Bitwise OR of TQ. |
346 | | |
347 | | // function-specifier |
348 | | unsigned FS_inline_specified : 1; |
349 | | unsigned FS_forceinline_specified: 1; |
350 | | unsigned FS_virtual_specified : 1; |
351 | | unsigned FS_noreturn_specified : 1; |
352 | | |
353 | | // friend-specifier |
354 | | unsigned Friend_specified : 1; |
355 | | |
356 | | // constexpr-specifier |
357 | | unsigned ConstexprSpecifier : 2; |
358 | | |
359 | | union { |
360 | | UnionParsedType TypeRep; |
361 | | Decl *DeclRep; |
362 | | Expr *ExprRep; |
363 | | TemplateIdAnnotation *TemplateIdRep; |
364 | | }; |
365 | | |
366 | | /// ExplicitSpecifier - Store information about explicit spicifer. |
367 | | ExplicitSpecifier FS_explicit_specifier; |
368 | | |
369 | | // attributes. |
370 | | ParsedAttributes Attrs; |
371 | | |
372 | | // Scope specifier for the type spec, if applicable. |
373 | | CXXScopeSpec TypeScope; |
374 | | |
375 | | // SourceLocation info. These are null if the item wasn't specified or if |
376 | | // the setting was synthesized. |
377 | | SourceRange Range; |
378 | | |
379 | | SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; |
380 | | SourceRange TSWRange; |
381 | | SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc, TSSatLoc; |
382 | | /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, |
383 | | /// typename, then this is the location of the named type (if present); |
384 | | /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and |
385 | | /// TSTNameLoc provides source range info for tag types. |
386 | | SourceLocation TSTNameLoc; |
387 | | SourceRange TypeofParensRange; |
388 | | SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, |
389 | | TQ_unalignedLoc; |
390 | | SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; |
391 | | SourceLocation FS_explicitCloseParenLoc; |
392 | | SourceLocation FS_forceinlineLoc; |
393 | | SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; |
394 | | SourceLocation TQ_pipeLoc; |
395 | | |
396 | | WrittenBuiltinSpecs writtenBS; |
397 | | void SaveWrittenBuiltinSpecs(); |
398 | | |
399 | | ObjCDeclSpec *ObjCQualifiers; |
400 | | |
401 | 129M | static bool isTypeRep(TST T) { |
402 | 129M | return (T == TST_typename || T == TST_typeofType7.82M || |
403 | 7.82M | T == TST_underlyingType || T == TST_atomic7.82M ); |
404 | 129M | } |
405 | 7.96M | static bool isExprRep(TST T) { |
406 | 7.96M | return (T == TST_typeofExpr || T == TST_decltype7.95M || T == TST_extint7.81M ); |
407 | 7.96M | } |
408 | 217 | static bool isTemplateIdRep(TST T) { |
409 | 217 | return (T == TST_auto || T == TST_decltype_auto18 ); |
410 | 217 | } |
411 | | |
412 | | DeclSpec(const DeclSpec &) = delete; |
413 | | void operator=(const DeclSpec &) = delete; |
414 | | public: |
415 | 45.0M | static bool isDeclRep(TST T) { |
416 | 45.0M | return (T == TST_enum || T == TST_struct38.1M || |
417 | 25.0M | T == TST_interface || T == TST_union25.0M || |
418 | 24.5M | T == TST_class); |
419 | 45.0M | } |
420 | | |
421 | | DeclSpec(AttributeFactory &attrFactory) |
422 | | : StorageClassSpec(SCS_unspecified), |
423 | | ThreadStorageClassSpec(TSCS_unspecified), |
424 | | SCS_extern_in_linkage_spec(false), |
425 | | TypeSpecWidth(static_cast<unsigned>(TypeSpecifierWidth::Unspecified)), |
426 | | TypeSpecComplex(TSC_unspecified), |
427 | | TypeSpecSign(static_cast<unsigned>(TypeSpecifierSign::Unspecified)), |
428 | | TypeSpecType(TST_unspecified), TypeAltiVecVector(false), |
429 | | TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), |
430 | | TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false), |
431 | | TypeQualifiers(TQ_unspecified), FS_inline_specified(false), |
432 | | FS_forceinline_specified(false), FS_virtual_specified(false), |
433 | | FS_noreturn_specified(false), Friend_specified(false), |
434 | | ConstexprSpecifier( |
435 | | static_cast<unsigned>(ConstexprSpecKind::Unspecified)), |
436 | | FS_explicit_specifier(), Attrs(attrFactory), writtenBS(), |
437 | 94.2M | ObjCQualifiers(nullptr) {} |
438 | | |
439 | | // storage-class-specifier |
440 | 292M | SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } |
441 | 69.6M | TSCS getThreadStorageClassSpec() const { |
442 | 69.6M | return (TSCS)ThreadStorageClassSpec; |
443 | 69.6M | } |
444 | 2.63M | bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; } |
445 | 86.2k | void setExternInLinkageSpec(bool Value) { |
446 | 86.2k | SCS_extern_in_linkage_spec = Value; |
447 | 86.2k | } |
448 | | |
449 | 946 | SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; } |
450 | 131 | SourceLocation getThreadStorageClassSpecLoc() const { |
451 | 131 | return ThreadStorageClassSpecLoc; |
452 | 131 | } |
453 | | |
454 | 389 | void ClearStorageClassSpecs() { |
455 | 389 | StorageClassSpec = DeclSpec::SCS_unspecified; |
456 | 389 | ThreadStorageClassSpec = DeclSpec::TSCS_unspecified; |
457 | 389 | SCS_extern_in_linkage_spec = false; |
458 | 389 | StorageClassSpecLoc = SourceLocation(); |
459 | 389 | ThreadStorageClassSpecLoc = SourceLocation(); |
460 | 389 | } |
461 | | |
462 | 25 | void ClearTypeSpecType() { |
463 | 25 | TypeSpecType = DeclSpec::TST_unspecified; |
464 | 25 | TypeSpecOwned = false; |
465 | 25 | TSTLoc = SourceLocation(); |
466 | 25 | } |
467 | | |
468 | | // type-specifier |
469 | 293M | TypeSpecifierWidth getTypeSpecWidth() const { |
470 | 293M | return static_cast<TypeSpecifierWidth>(TypeSpecWidth); |
471 | 293M | } |
472 | 261M | TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; } |
473 | 292M | TypeSpecifierSign getTypeSpecSign() const { |
474 | 292M | return static_cast<TypeSpecifierSign>(TypeSpecSign); |
475 | 292M | } |
476 | 842M | TST getTypeSpecType() const { return (TST)TypeSpecType; } |
477 | 107M | bool isTypeAltiVecVector() const { return TypeAltiVecVector; } |
478 | 597k | bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; } |
479 | 587k | bool isTypeAltiVecBool() const { return TypeAltiVecBool; } |
480 | 87.3M | bool isTypeSpecOwned() const { return TypeSpecOwned; } |
481 | 0 | bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } |
482 | 146M | bool isTypeSpecPipe() const { return TypeSpecPipe; } |
483 | 69.6M | bool isTypeSpecSat() const { return TypeSpecSat; } |
484 | 47.8k | bool isConstrainedAuto() const { return ConstrainedAuto; } |
485 | | |
486 | 62.2M | ParsedType getRepAsType() const { |
487 | 62.2M | assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); |
488 | 62.2M | return TypeRep; |
489 | 62.2M | } |
490 | 9.99M | Decl *getRepAsDecl() const { |
491 | 9.99M | assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl"); |
492 | 9.99M | return DeclRep; |
493 | 9.99M | } |
494 | 75.0k | Expr *getRepAsExpr() const { |
495 | 75.0k | assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); |
496 | 75.0k | return ExprRep; |
497 | 75.0k | } |
498 | 217 | TemplateIdAnnotation *getRepAsTemplateId() const { |
499 | 217 | assert(isTemplateIdRep((TST) TypeSpecType) && |
500 | 217 | "DeclSpec does not store a template id"); |
501 | 217 | return TemplateIdRep; |
502 | 217 | } |
503 | 5.74M | CXXScopeSpec &getTypeSpecScope() { return TypeScope; } |
504 | 1.31M | const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } |
505 | | |
506 | 224M | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
507 | 4.59M | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
508 | 4.69M | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
509 | | |
510 | 103k | SourceLocation getTypeSpecWidthLoc() const { return TSWRange.getBegin(); } |
511 | 805k | SourceRange getTypeSpecWidthRange() const { return TSWRange; } |
512 | 57 | SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; } |
513 | 763k | SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } |
514 | 72.7M | SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } |
515 | 0 | SourceLocation getAltiVecLoc() const { return AltiVecLoc; } |
516 | 11 | SourceLocation getTypeSpecSatLoc() const { return TSSatLoc; } |
517 | | |
518 | 3.08M | SourceLocation getTypeSpecTypeNameLoc() const { |
519 | 3.08M | assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename); |
520 | 3.08M | return TSTNameLoc; |
521 | 3.08M | } |
522 | | |
523 | 5.57k | SourceRange getTypeofParensRange() const { return TypeofParensRange; } |
524 | 5.68k | void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } |
525 | | |
526 | 28.8M | bool hasAutoTypeSpec() const { |
527 | 28.8M | return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type28.7M || |
528 | 28.7M | TypeSpecType == TST_decltype_auto); |
529 | 28.8M | } |
530 | | |
531 | | bool hasTagDefinition() const; |
532 | | |
533 | | /// Turn a type-specifier-type into a string like "_Bool" or "union". |
534 | | static const char *getSpecifierName(DeclSpec::TST T, |
535 | | const PrintingPolicy &Policy); |
536 | | static const char *getSpecifierName(DeclSpec::TQ Q); |
537 | | static const char *getSpecifierName(TypeSpecifierSign S); |
538 | | static const char *getSpecifierName(DeclSpec::TSC C); |
539 | | static const char *getSpecifierName(TypeSpecifierWidth W); |
540 | | static const char *getSpecifierName(DeclSpec::SCS S); |
541 | | static const char *getSpecifierName(DeclSpec::TSCS S); |
542 | | static const char *getSpecifierName(ConstexprSpecKind C); |
543 | | |
544 | | // type-qualifiers |
545 | | |
546 | | /// getTypeQualifiers - Return a set of TQs. |
547 | 112M | unsigned getTypeQualifiers() const { return TypeQualifiers; } |
548 | 6.78M | SourceLocation getConstSpecLoc() const { return TQ_constLoc; } |
549 | 6.78M | SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } |
550 | 6.78M | SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } |
551 | 6.78M | SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } |
552 | 6.78M | SourceLocation getUnalignedSpecLoc() const { return TQ_unalignedLoc; } |
553 | 117 | SourceLocation getPipeLoc() const { return TQ_pipeLoc; } |
554 | | |
555 | | /// Clear out all of the type qualifiers. |
556 | 2.57k | void ClearTypeQualifiers() { |
557 | 2.57k | TypeQualifiers = 0; |
558 | 2.57k | TQ_constLoc = SourceLocation(); |
559 | 2.57k | TQ_restrictLoc = SourceLocation(); |
560 | 2.57k | TQ_volatileLoc = SourceLocation(); |
561 | 2.57k | TQ_atomicLoc = SourceLocation(); |
562 | 2.57k | TQ_unalignedLoc = SourceLocation(); |
563 | 2.57k | TQ_pipeLoc = SourceLocation(); |
564 | 2.57k | } |
565 | | |
566 | | // function-specifier |
567 | 64.8M | bool isInlineSpecified() const { |
568 | 64.8M | return FS_inline_specified | FS_forceinline_specified; |
569 | 64.8M | } |
570 | 964 | SourceLocation getInlineSpecLoc() const { |
571 | 957 | return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc7 ; |
572 | 964 | } |
573 | | |
574 | 2.66M | ExplicitSpecifier getExplicitSpecifier() const { |
575 | 2.66M | return FS_explicit_specifier; |
576 | 2.66M | } |
577 | | |
578 | 48.3M | bool isVirtualSpecified() const { return FS_virtual_specified; } |
579 | 49 | SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } |
580 | | |
581 | 98.3M | bool hasExplicitSpecifier() const { |
582 | 98.3M | return FS_explicit_specifier.isSpecified(); |
583 | 98.3M | } |
584 | 4.99k | SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } |
585 | 4.98k | SourceRange getExplicitSpecRange() const { |
586 | 4.98k | return FS_explicit_specifier.getExpr() |
587 | 12 | ? SourceRange(FS_explicitLoc, FS_explicitCloseParenLoc) |
588 | 4.97k | : SourceRange(FS_explicitLoc); |
589 | 4.98k | } |
590 | | |
591 | 59.4M | bool isNoreturnSpecified() const { return FS_noreturn_specified; } |
592 | 83 | SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } |
593 | | |
594 | 6 | void ClearFunctionSpecs() { |
595 | 6 | FS_inline_specified = false; |
596 | 6 | FS_inlineLoc = SourceLocation(); |
597 | 6 | FS_forceinline_specified = false; |
598 | 6 | FS_forceinlineLoc = SourceLocation(); |
599 | 6 | FS_virtual_specified = false; |
600 | 6 | FS_virtualLoc = SourceLocation(); |
601 | 6 | FS_explicit_specifier = ExplicitSpecifier(); |
602 | 6 | FS_explicitLoc = SourceLocation(); |
603 | 6 | FS_explicitCloseParenLoc = SourceLocation(); |
604 | 6 | FS_noreturn_specified = false; |
605 | 6 | FS_noreturnLoc = SourceLocation(); |
606 | 6 | } |
607 | | |
608 | | /// This method calls the passed in handler on each CVRU qual being |
609 | | /// set. |
610 | | /// Handle - a handler to be invoked. |
611 | | void forEachCVRUQualifier( |
612 | | llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle); |
613 | | |
614 | | /// This method calls the passed in handler on each qual being |
615 | | /// set. |
616 | | /// Handle - a handler to be invoked. |
617 | | void forEachQualifier( |
618 | | llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle); |
619 | | |
620 | | /// Return true if any type-specifier has been found. |
621 | 153M | bool hasTypeSpecifier() const { |
622 | 153M | return getTypeSpecType() != DeclSpec::TST_unspecified || |
623 | 62.1M | getTypeSpecWidth() != TypeSpecifierWidth::Unspecified || |
624 | 61.5M | getTypeSpecComplex() != DeclSpec::TSC_unspecified || |
625 | 61.5M | getTypeSpecSign() != TypeSpecifierSign::Unspecified; |
626 | 153M | } |
627 | | |
628 | | /// Return a bitmask of which flavors of specifiers this |
629 | | /// DeclSpec includes. |
630 | | unsigned getParsedSpecifiers() const; |
631 | | |
632 | | /// isEmpty - Return true if this declaration specifier is completely empty: |
633 | | /// no tokens were parsed in the production of it. |
634 | 36.1M | bool isEmpty() const { |
635 | 36.1M | return getParsedSpecifiers() == DeclSpec::PQ_None; |
636 | 36.1M | } |
637 | | |
638 | 71.3M | void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); } |
639 | 170M | void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); } |
640 | | |
641 | | /// These methods set the specified attribute of the DeclSpec and |
642 | | /// return false if there was no error. If an error occurs (for |
643 | | /// example, if we tried to set "auto" on a spec with "extern" |
644 | | /// already set), they return true and set PrevSpec and DiagID |
645 | | /// such that |
646 | | /// Diag(Loc, DiagID) << PrevSpec; |
647 | | /// will yield a useful result. |
648 | | /// |
649 | | /// TODO: use a more general approach that still allows these |
650 | | /// diagnostics to be ignored when desired. |
651 | | bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, |
652 | | const char *&PrevSpec, unsigned &DiagID, |
653 | | const PrintingPolicy &Policy); |
654 | | bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, |
655 | | const char *&PrevSpec, unsigned &DiagID); |
656 | | bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, |
657 | | const char *&PrevSpec, unsigned &DiagID, |
658 | | const PrintingPolicy &Policy); |
659 | | bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, |
660 | | unsigned &DiagID); |
661 | | bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, |
662 | | const char *&PrevSpec, unsigned &DiagID); |
663 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
664 | | unsigned &DiagID, const PrintingPolicy &Policy); |
665 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
666 | | unsigned &DiagID, ParsedType Rep, |
667 | | const PrintingPolicy &Policy); |
668 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
669 | | unsigned &DiagID, TypeResult Rep, |
670 | 21.9M | const PrintingPolicy &Policy) { |
671 | 21.9M | if (Rep.isInvalid()) |
672 | 671 | return SetTypeSpecError(); |
673 | 21.9M | return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Rep.get(), Policy); |
674 | 21.9M | } |
675 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
676 | | unsigned &DiagID, Decl *Rep, bool Owned, |
677 | | const PrintingPolicy &Policy); |
678 | | bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, |
679 | | SourceLocation TagNameLoc, const char *&PrevSpec, |
680 | | unsigned &DiagID, ParsedType Rep, |
681 | | const PrintingPolicy &Policy); |
682 | | bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, |
683 | | SourceLocation TagNameLoc, const char *&PrevSpec, |
684 | | unsigned &DiagID, Decl *Rep, bool Owned, |
685 | | const PrintingPolicy &Policy); |
686 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
687 | | unsigned &DiagID, TemplateIdAnnotation *Rep, |
688 | | const PrintingPolicy &Policy); |
689 | | |
690 | | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
691 | | unsigned &DiagID, Expr *Rep, |
692 | | const PrintingPolicy &policy); |
693 | | bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, |
694 | | const char *&PrevSpec, unsigned &DiagID, |
695 | | const PrintingPolicy &Policy); |
696 | | bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, |
697 | | const char *&PrevSpec, unsigned &DiagID, |
698 | | const PrintingPolicy &Policy); |
699 | | bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, |
700 | | const char *&PrevSpec, unsigned &DiagID, |
701 | | const PrintingPolicy &Policy); |
702 | | bool SetTypePipe(bool isPipe, SourceLocation Loc, |
703 | | const char *&PrevSpec, unsigned &DiagID, |
704 | | const PrintingPolicy &Policy); |
705 | | bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth, |
706 | | const char *&PrevSpec, unsigned &DiagID, |
707 | | const PrintingPolicy &Policy); |
708 | | bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, |
709 | | unsigned &DiagID); |
710 | | bool SetTypeSpecError(); |
711 | 0 | void UpdateDeclRep(Decl *Rep) { |
712 | 0 | assert(isDeclRep((TST) TypeSpecType)); |
713 | 0 | DeclRep = Rep; |
714 | 0 | } |
715 | 133k | void UpdateTypeRep(ParsedType Rep) { |
716 | 133k | assert(isTypeRep((TST) TypeSpecType)); |
717 | 133k | TypeRep = Rep; |
718 | 133k | } |
719 | 3 | void UpdateExprRep(Expr *Rep) { |
720 | 3 | assert(isExprRep((TST) TypeSpecType)); |
721 | 3 | ExprRep = Rep; |
722 | 3 | } |
723 | | |
724 | | bool SetTypeQual(TQ T, SourceLocation Loc); |
725 | | |
726 | | bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, |
727 | | unsigned &DiagID, const LangOptions &Lang); |
728 | | |
729 | | bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, |
730 | | unsigned &DiagID); |
731 | | bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, |
732 | | unsigned &DiagID); |
733 | | bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, |
734 | | unsigned &DiagID); |
735 | | bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, |
736 | | unsigned &DiagID, ExplicitSpecifier ExplicitSpec, |
737 | | SourceLocation CloseParenLoc); |
738 | | bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, |
739 | | unsigned &DiagID); |
740 | | |
741 | | bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, |
742 | | unsigned &DiagID); |
743 | | bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, |
744 | | unsigned &DiagID); |
745 | | bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, |
746 | | const char *&PrevSpec, unsigned &DiagID); |
747 | | |
748 | 183M | bool isFriendSpecified() const { return Friend_specified; } |
749 | 4.87M | SourceLocation getFriendSpecLoc() const { return FriendLoc; } |
750 | | |
751 | 48.0M | bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } |
752 | 2.75M | SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } |
753 | | |
754 | 380M | ConstexprSpecKind getConstexprSpecifier() const { |
755 | 380M | return ConstexprSpecKind(ConstexprSpecifier); |
756 | 380M | } |
757 | | |
758 | 248 | SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } |
759 | 56.7M | bool hasConstexprSpecifier() const { |
760 | 56.7M | return getConstexprSpecifier() != ConstexprSpecKind::Unspecified; |
761 | 56.7M | } |
762 | | |
763 | 32 | void ClearConstexprSpec() { |
764 | 32 | ConstexprSpecifier = static_cast<unsigned>(ConstexprSpecKind::Unspecified); |
765 | 32 | ConstexprLoc = SourceLocation(); |
766 | 32 | } |
767 | | |
768 | 74.5M | AttributePool &getAttributePool() const { |
769 | 74.5M | return Attrs.getPool(); |
770 | 74.5M | } |
771 | | |
772 | | /// Concatenates two attribute lists. |
773 | | /// |
774 | | /// The GCC attribute syntax allows for the following: |
775 | | /// |
776 | | /// \code |
777 | | /// short __attribute__(( unused, deprecated )) |
778 | | /// int __attribute__(( may_alias, aligned(16) )) var; |
779 | | /// \endcode |
780 | | /// |
781 | | /// This declares 4 attributes using 2 lists. The following syntax is |
782 | | /// also allowed and equivalent to the previous declaration. |
783 | | /// |
784 | | /// \code |
785 | | /// short __attribute__((unused)) __attribute__((deprecated)) |
786 | | /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; |
787 | | /// \endcode |
788 | | /// |
789 | 74.1k | void addAttributes(ParsedAttributesView &AL) { |
790 | 74.1k | Attrs.addAll(AL.begin(), AL.end()); |
791 | 74.1k | } |
792 | | |
793 | 46 | bool hasAttributes() const { return !Attrs.empty(); } |
794 | | |
795 | 351M | ParsedAttributes &getAttributes() { return Attrs; } |
796 | 85.5M | const ParsedAttributes &getAttributes() const { return Attrs; } |
797 | | |
798 | 58.3M | void takeAttributesFrom(ParsedAttributes &attrs) { |
799 | 58.3M | Attrs.takeAllFrom(attrs); |
800 | 58.3M | } |
801 | | |
802 | | /// Finish - This does final analysis of the declspec, issuing diagnostics for |
803 | | /// things like "_Imaginary" (lacking an FP type). After calling this method, |
804 | | /// DeclSpec is guaranteed self-consistent, even if an error occurred. |
805 | | void Finish(Sema &S, const PrintingPolicy &Policy); |
806 | | |
807 | 3.68M | const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { |
808 | 3.68M | return writtenBS; |
809 | 3.68M | } |
810 | | |
811 | 950k | ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } |
812 | 2.11M | void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } |
813 | | |
814 | | /// Checks if this DeclSpec can stand alone, without a Declarator. |
815 | | /// |
816 | | /// Only tag declspecs can stand alone. |
817 | | bool isMissingDeclaratorOk(); |
818 | | }; |
819 | | |
820 | | /// Captures information about "declaration specifiers" specific to |
821 | | /// Objective-C. |
822 | | class ObjCDeclSpec { |
823 | | public: |
824 | | /// ObjCDeclQualifier - Qualifier used on types in method |
825 | | /// declarations. Not all combinations are sensible. Parameters |
826 | | /// can be one of { in, out, inout } with one of { bycopy, byref }. |
827 | | /// Returns can either be { oneway } or not. |
828 | | /// |
829 | | /// This should be kept in sync with Decl::ObjCDeclQualifier. |
830 | | enum ObjCDeclQualifier { |
831 | | DQ_None = 0x0, |
832 | | DQ_In = 0x1, |
833 | | DQ_Inout = 0x2, |
834 | | DQ_Out = 0x4, |
835 | | DQ_Bycopy = 0x8, |
836 | | DQ_Byref = 0x10, |
837 | | DQ_Oneway = 0x20, |
838 | | DQ_CSNullability = 0x40 |
839 | | }; |
840 | | |
841 | | ObjCDeclSpec() |
842 | | : objcDeclQualifier(DQ_None), |
843 | | PropertyAttributes(ObjCPropertyAttribute::kind_noattr), Nullability(0), |
844 | 2.57M | GetterName(nullptr), SetterName(nullptr) {} |
845 | | |
846 | 5.61M | ObjCDeclQualifier getObjCDeclQualifier() const { |
847 | 5.61M | return (ObjCDeclQualifier)objcDeclQualifier; |
848 | 5.61M | } |
849 | 1.29M | void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { |
850 | 1.29M | objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); |
851 | 1.29M | } |
852 | 0 | void clearObjCDeclQualifier(ObjCDeclQualifier DQVal) { |
853 | 0 | objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal); |
854 | 0 | } |
855 | | |
856 | 1.94M | ObjCPropertyAttribute::Kind getPropertyAttributes() const { |
857 | 1.94M | return ObjCPropertyAttribute::Kind(PropertyAttributes); |
858 | 1.94M | } |
859 | 891k | void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { |
860 | 891k | PropertyAttributes = |
861 | 891k | (ObjCPropertyAttribute::Kind)(PropertyAttributes | PRVal); |
862 | 891k | } |
863 | | |
864 | 463k | NullabilityKind getNullability() const { |
865 | 463k | assert( |
866 | 463k | ((getObjCDeclQualifier() & DQ_CSNullability) || |
867 | 463k | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && |
868 | 463k | "Objective-C declspec doesn't have nullability"); |
869 | 463k | return static_cast<NullabilityKind>(Nullability); |
870 | 463k | } |
871 | | |
872 | 463k | SourceLocation getNullabilityLoc() const { |
873 | 463k | assert( |
874 | 463k | ((getObjCDeclQualifier() & DQ_CSNullability) || |
875 | 463k | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && |
876 | 463k | "Objective-C declspec doesn't have nullability"); |
877 | 463k | return NullabilityLoc; |
878 | 463k | } |
879 | | |
880 | 463k | void setNullability(SourceLocation loc, NullabilityKind kind) { |
881 | 463k | assert( |
882 | 463k | ((getObjCDeclQualifier() & DQ_CSNullability) || |
883 | 463k | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && |
884 | 463k | "Set the nullability declspec or property attribute first"); |
885 | 463k | Nullability = static_cast<unsigned>(kind); |
886 | 463k | NullabilityLoc = loc; |
887 | 463k | } |
888 | | |
889 | 0 | const IdentifierInfo *getGetterName() const { return GetterName; } |
890 | 479k | IdentifierInfo *getGetterName() { return GetterName; } |
891 | 457k | SourceLocation getGetterNameLoc() const { return GetterNameLoc; } |
892 | 21.9k | void setGetterName(IdentifierInfo *name, SourceLocation loc) { |
893 | 21.9k | GetterName = name; |
894 | 21.9k | GetterNameLoc = loc; |
895 | 21.9k | } |
896 | | |
897 | 0 | const IdentifierInfo *getSetterName() const { return SetterName; } |
898 | 457k | IdentifierInfo *getSetterName() { return SetterName; } |
899 | 457k | SourceLocation getSetterNameLoc() const { return SetterNameLoc; } |
900 | 89 | void setSetterName(IdentifierInfo *name, SourceLocation loc) { |
901 | 89 | SetterName = name; |
902 | 89 | SetterNameLoc = loc; |
903 | 89 | } |
904 | | |
905 | | private: |
906 | | // FIXME: These two are unrelated and mutually exclusive. So perhaps |
907 | | // we can put them in a union to reflect their mutual exclusivity |
908 | | // (space saving is negligible). |
909 | | unsigned objcDeclQualifier : 7; |
910 | | |
911 | | // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttribute::Kind |
912 | | unsigned PropertyAttributes : NumObjCPropertyAttrsBits; |
913 | | |
914 | | unsigned Nullability : 2; |
915 | | |
916 | | SourceLocation NullabilityLoc; |
917 | | |
918 | | IdentifierInfo *GetterName; // getter name or NULL if no getter |
919 | | IdentifierInfo *SetterName; // setter name or NULL if no setter |
920 | | SourceLocation GetterNameLoc; // location of the getter attribute's value |
921 | | SourceLocation SetterNameLoc; // location of the setter attribute's value |
922 | | |
923 | | }; |
924 | | |
925 | | /// Describes the kind of unqualified-id parsed. |
926 | | enum class UnqualifiedIdKind { |
927 | | /// An identifier. |
928 | | IK_Identifier, |
929 | | /// An overloaded operator name, e.g., operator+. |
930 | | IK_OperatorFunctionId, |
931 | | /// A conversion function name, e.g., operator int. |
932 | | IK_ConversionFunctionId, |
933 | | /// A user-defined literal name, e.g., operator "" _i. |
934 | | IK_LiteralOperatorId, |
935 | | /// A constructor name. |
936 | | IK_ConstructorName, |
937 | | /// A constructor named via a template-id. |
938 | | IK_ConstructorTemplateId, |
939 | | /// A destructor name. |
940 | | IK_DestructorName, |
941 | | /// A template-id, e.g., f<int>. |
942 | | IK_TemplateId, |
943 | | /// An implicit 'self' parameter |
944 | | IK_ImplicitSelfParam, |
945 | | /// A deduction-guide name (a template-name) |
946 | | IK_DeductionGuideName |
947 | | }; |
948 | | |
949 | | /// Represents a C++ unqualified-id that has been parsed. |
950 | | class UnqualifiedId { |
951 | | private: |
952 | | UnqualifiedId(const UnqualifiedId &Other) = delete; |
953 | | const UnqualifiedId &operator=(const UnqualifiedId &) = delete; |
954 | | |
955 | | public: |
956 | | /// Describes the kind of unqualified-id parsed. |
957 | | UnqualifiedIdKind Kind; |
958 | | |
959 | | struct OFI { |
960 | | /// The kind of overloaded operator. |
961 | | OverloadedOperatorKind Operator; |
962 | | |
963 | | /// The source locations of the individual tokens that name |
964 | | /// the operator, e.g., the "new", "[", and "]" tokens in |
965 | | /// operator new []. |
966 | | /// |
967 | | /// Different operators have different numbers of tokens in their name, |
968 | | /// up to three. Any remaining source locations in this array will be |
969 | | /// set to an invalid value for operators with fewer than three tokens. |
970 | | SourceLocation SymbolLocations[3]; |
971 | | }; |
972 | | |
973 | | /// Anonymous union that holds extra data associated with the |
974 | | /// parsed unqualified-id. |
975 | | union { |
976 | | /// When Kind == IK_Identifier, the parsed identifier, or when |
977 | | /// Kind == IK_UserLiteralId, the identifier suffix. |
978 | | IdentifierInfo *Identifier; |
979 | | |
980 | | /// When Kind == IK_OperatorFunctionId, the overloaded operator |
981 | | /// that we parsed. |
982 | | struct OFI OperatorFunctionId; |
983 | | |
984 | | /// When Kind == IK_ConversionFunctionId, the type that the |
985 | | /// conversion function names. |
986 | | UnionParsedType ConversionFunctionId; |
987 | | |
988 | | /// When Kind == IK_ConstructorName, the class-name of the type |
989 | | /// whose constructor is being referenced. |
990 | | UnionParsedType ConstructorName; |
991 | | |
992 | | /// When Kind == IK_DestructorName, the type referred to by the |
993 | | /// class-name. |
994 | | UnionParsedType DestructorName; |
995 | | |
996 | | /// When Kind == IK_DeductionGuideName, the parsed template-name. |
997 | | UnionParsedTemplateTy TemplateName; |
998 | | |
999 | | /// When Kind == IK_TemplateId or IK_ConstructorTemplateId, |
1000 | | /// the template-id annotation that contains the template name and |
1001 | | /// template arguments. |
1002 | | TemplateIdAnnotation *TemplateId; |
1003 | | }; |
1004 | | |
1005 | | /// The location of the first token that describes this unqualified-id, |
1006 | | /// which will be the location of the identifier, "operator" keyword, |
1007 | | /// tilde (for a destructor), or the template name of a template-id. |
1008 | | SourceLocation StartLocation; |
1009 | | |
1010 | | /// The location of the last token that describes this unqualified-id. |
1011 | | SourceLocation EndLocation; |
1012 | | |
1013 | | UnqualifiedId() |
1014 | 88.7M | : Kind(UnqualifiedIdKind::IK_Identifier), Identifier(nullptr) {} |
1015 | | |
1016 | | /// Clear out this unqualified-id, setting it to default (invalid) |
1017 | | /// state. |
1018 | 70.0M | void clear() { |
1019 | 70.0M | Kind = UnqualifiedIdKind::IK_Identifier; |
1020 | 70.0M | Identifier = nullptr; |
1021 | 70.0M | StartLocation = SourceLocation(); |
1022 | 70.0M | EndLocation = SourceLocation(); |
1023 | 70.0M | } |
1024 | | |
1025 | | /// Determine whether this unqualified-id refers to a valid name. |
1026 | 84.3M | bool isValid() const { return StartLocation.isValid(); } |
1027 | | |
1028 | | /// Determine whether this unqualified-id refers to an invalid name. |
1029 | 0 | bool isInvalid() const { return !isValid(); } |
1030 | | |
1031 | | /// Determine what kind of name we have. |
1032 | 545M | UnqualifiedIdKind getKind() const { return Kind; } |
1033 | | |
1034 | | /// Specify that this unqualified-id was parsed as an identifier. |
1035 | | /// |
1036 | | /// \param Id the parsed identifier. |
1037 | | /// \param IdLoc the location of the parsed identifier. |
1038 | 87.2M | void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) { |
1039 | 87.2M | Kind = UnqualifiedIdKind::IK_Identifier; |
1040 | 87.2M | Identifier = const_cast<IdentifierInfo *>(Id); |
1041 | 87.2M | StartLocation = EndLocation = IdLoc; |
1042 | 87.2M | } |
1043 | | |
1044 | | /// Specify that this unqualified-id was parsed as an |
1045 | | /// operator-function-id. |
1046 | | /// |
1047 | | /// \param OperatorLoc the location of the 'operator' keyword. |
1048 | | /// |
1049 | | /// \param Op the overloaded operator. |
1050 | | /// |
1051 | | /// \param SymbolLocations the locations of the individual operator symbols |
1052 | | /// in the operator. |
1053 | | void setOperatorFunctionId(SourceLocation OperatorLoc, |
1054 | | OverloadedOperatorKind Op, |
1055 | | SourceLocation SymbolLocations[3]); |
1056 | | |
1057 | | /// Specify that this unqualified-id was parsed as a |
1058 | | /// conversion-function-id. |
1059 | | /// |
1060 | | /// \param OperatorLoc the location of the 'operator' keyword. |
1061 | | /// |
1062 | | /// \param Ty the type to which this conversion function is converting. |
1063 | | /// |
1064 | | /// \param EndLoc the location of the last token that makes up the type name. |
1065 | | void setConversionFunctionId(SourceLocation OperatorLoc, |
1066 | | ParsedType Ty, |
1067 | 12.9k | SourceLocation EndLoc) { |
1068 | 12.9k | Kind = UnqualifiedIdKind::IK_ConversionFunctionId; |
1069 | 12.9k | StartLocation = OperatorLoc; |
1070 | 12.9k | EndLocation = EndLoc; |
1071 | 12.9k | ConversionFunctionId = Ty; |
1072 | 12.9k | } |
1073 | | |
1074 | | /// Specific that this unqualified-id was parsed as a |
1075 | | /// literal-operator-id. |
1076 | | /// |
1077 | | /// \param Id the parsed identifier. |
1078 | | /// |
1079 | | /// \param OpLoc the location of the 'operator' keyword. |
1080 | | /// |
1081 | | /// \param IdLoc the location of the identifier. |
1082 | | void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc, |
1083 | 738 | SourceLocation IdLoc) { |
1084 | 738 | Kind = UnqualifiedIdKind::IK_LiteralOperatorId; |
1085 | 738 | Identifier = const_cast<IdentifierInfo *>(Id); |
1086 | 738 | StartLocation = OpLoc; |
1087 | 738 | EndLocation = IdLoc; |
1088 | 738 | } |
1089 | | |
1090 | | /// Specify that this unqualified-id was parsed as a constructor name. |
1091 | | /// |
1092 | | /// \param ClassType the class type referred to by the constructor name. |
1093 | | /// |
1094 | | /// \param ClassNameLoc the location of the class name. |
1095 | | /// |
1096 | | /// \param EndLoc the location of the last token that makes up the type name. |
1097 | | void setConstructorName(ParsedType ClassType, |
1098 | | SourceLocation ClassNameLoc, |
1099 | 263k | SourceLocation EndLoc) { |
1100 | 263k | Kind = UnqualifiedIdKind::IK_ConstructorName; |
1101 | 263k | StartLocation = ClassNameLoc; |
1102 | 263k | EndLocation = EndLoc; |
1103 | 263k | ConstructorName = ClassType; |
1104 | 263k | } |
1105 | | |
1106 | | /// Specify that this unqualified-id was parsed as a |
1107 | | /// template-id that names a constructor. |
1108 | | /// |
1109 | | /// \param TemplateId the template-id annotation that describes the parsed |
1110 | | /// template-id. This UnqualifiedId instance will take ownership of the |
1111 | | /// \p TemplateId and will free it on destruction. |
1112 | | void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); |
1113 | | |
1114 | | /// Specify that this unqualified-id was parsed as a destructor name. |
1115 | | /// |
1116 | | /// \param TildeLoc the location of the '~' that introduces the destructor |
1117 | | /// name. |
1118 | | /// |
1119 | | /// \param ClassType the name of the class referred to by the destructor name. |
1120 | | void setDestructorName(SourceLocation TildeLoc, |
1121 | | ParsedType ClassType, |
1122 | 41.3k | SourceLocation EndLoc) { |
1123 | 41.3k | Kind = UnqualifiedIdKind::IK_DestructorName; |
1124 | 41.3k | StartLocation = TildeLoc; |
1125 | 41.3k | EndLocation = EndLoc; |
1126 | 41.3k | DestructorName = ClassType; |
1127 | 41.3k | } |
1128 | | |
1129 | | /// Specify that this unqualified-id was parsed as a template-id. |
1130 | | /// |
1131 | | /// \param TemplateId the template-id annotation that describes the parsed |
1132 | | /// template-id. This UnqualifiedId instance will take ownership of the |
1133 | | /// \p TemplateId and will free it on destruction. |
1134 | | void setTemplateId(TemplateIdAnnotation *TemplateId); |
1135 | | |
1136 | | /// Specify that this unqualified-id was parsed as a template-name for |
1137 | | /// a deduction-guide. |
1138 | | /// |
1139 | | /// \param Template The parsed template-name. |
1140 | | /// \param TemplateLoc The location of the parsed template-name. |
1141 | | void setDeductionGuideName(ParsedTemplateTy Template, |
1142 | 427 | SourceLocation TemplateLoc) { |
1143 | 427 | Kind = UnqualifiedIdKind::IK_DeductionGuideName; |
1144 | 427 | TemplateName = Template; |
1145 | 427 | StartLocation = EndLocation = TemplateLoc; |
1146 | 427 | } |
1147 | | |
1148 | | /// Specify that this unqualified-id is an implicit 'self' |
1149 | | /// parameter. |
1150 | | /// |
1151 | | /// \param Id the identifier. |
1152 | 2.18k | void setImplicitSelfParam(const IdentifierInfo *Id) { |
1153 | 2.18k | Kind = UnqualifiedIdKind::IK_ImplicitSelfParam; |
1154 | 2.18k | Identifier = const_cast<IdentifierInfo *>(Id); |
1155 | 2.18k | StartLocation = EndLocation = SourceLocation(); |
1156 | 2.18k | } |
1157 | | |
1158 | | /// Return the source range that covers this unqualified-id. |
1159 | 11.9M | SourceRange getSourceRange() const LLVM_READONLY { |
1160 | 11.9M | return SourceRange(StartLocation, EndLocation); |
1161 | 11.9M | } |
1162 | 3.62M | SourceLocation getBeginLoc() const LLVM_READONLY { return StartLocation; } |
1163 | 376 | SourceLocation getEndLoc() const LLVM_READONLY { return EndLocation; } |
1164 | | }; |
1165 | | |
1166 | | /// A set of tokens that has been cached for later parsing. |
1167 | | typedef SmallVector<Token, 4> CachedTokens; |
1168 | | |
1169 | | /// One instance of this struct is used for each type in a |
1170 | | /// declarator that is parsed. |
1171 | | /// |
1172 | | /// This is intended to be a small value object. |
1173 | | struct DeclaratorChunk { |
1174 | 23.1M | DeclaratorChunk() {}; |
1175 | | |
1176 | | enum { |
1177 | | Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren, Pipe |
1178 | | } Kind; |
1179 | | |
1180 | | /// Loc - The place where this type was defined. |
1181 | | SourceLocation Loc; |
1182 | | /// EndLoc - If valid, the place where this chunck ends. |
1183 | | SourceLocation EndLoc; |
1184 | | |
1185 | 53 | SourceRange getSourceRange() const { |
1186 | 53 | if (EndLoc.isInvalid()) |
1187 | 13 | return SourceRange(Loc, Loc); |
1188 | 40 | return SourceRange(Loc, EndLoc); |
1189 | 40 | } |
1190 | | |
1191 | | ParsedAttributesView AttrList; |
1192 | | |
1193 | | struct PointerTypeInfo { |
1194 | | /// The type qualifiers: const/volatile/restrict/unaligned/atomic. |
1195 | | unsigned TypeQuals : 5; |
1196 | | |
1197 | | /// The location of the const-qualifier, if any. |
1198 | | SourceLocation ConstQualLoc; |
1199 | | |
1200 | | /// The location of the volatile-qualifier, if any. |
1201 | | SourceLocation VolatileQualLoc; |
1202 | | |
1203 | | /// The location of the restrict-qualifier, if any. |
1204 | | SourceLocation RestrictQualLoc; |
1205 | | |
1206 | | /// The location of the _Atomic-qualifier, if any. |
1207 | | SourceLocation AtomicQualLoc; |
1208 | | |
1209 | | /// The location of the __unaligned-qualifier, if any. |
1210 | | SourceLocation UnalignedQualLoc; |
1211 | | |
1212 | 6.78M | void destroy() { |
1213 | 6.78M | } |
1214 | | }; |
1215 | | |
1216 | | struct ReferenceTypeInfo { |
1217 | | /// The type qualifier: restrict. [GNU] C++ extension |
1218 | | bool HasRestrict : 1; |
1219 | | /// True if this is an lvalue reference, false if it's an rvalue reference. |
1220 | | bool LValueRef : 1; |
1221 | 1.08M | void destroy() { |
1222 | 1.08M | } |
1223 | | }; |
1224 | | |
1225 | | struct ArrayTypeInfo { |
1226 | | /// The type qualifiers for the array: |
1227 | | /// const/volatile/restrict/__unaligned/_Atomic. |
1228 | | unsigned TypeQuals : 5; |
1229 | | |
1230 | | /// True if this dimension included the 'static' keyword. |
1231 | | unsigned hasStatic : 1; |
1232 | | |
1233 | | /// True if this dimension was [*]. In this case, NumElts is null. |
1234 | | unsigned isStar : 1; |
1235 | | |
1236 | | /// This is the size of the array, or null if [] or [*] was specified. |
1237 | | /// Since the parser is multi-purpose, and we don't want to impose a root |
1238 | | /// expression class on all clients, NumElts is untyped. |
1239 | | Expr *NumElts; |
1240 | | |
1241 | 353k | void destroy() {} |
1242 | | }; |
1243 | | |
1244 | | /// ParamInfo - An array of paraminfo objects is allocated whenever a function |
1245 | | /// declarator is parsed. There are two interesting styles of parameters |
1246 | | /// here: |
1247 | | /// K&R-style identifier lists and parameter type lists. K&R-style identifier |
1248 | | /// lists will have information about the identifier, but no type information. |
1249 | | /// Parameter type lists will have type info (if the actions module provides |
1250 | | /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'. |
1251 | | struct ParamInfo { |
1252 | | IdentifierInfo *Ident; |
1253 | | SourceLocation IdentLoc; |
1254 | | Decl *Param; |
1255 | | |
1256 | | /// DefaultArgTokens - When the parameter's default argument |
1257 | | /// cannot be parsed immediately (because it occurs within the |
1258 | | /// declaration of a member function), it will be stored here as a |
1259 | | /// sequence of tokens to be parsed once the class definition is |
1260 | | /// complete. Non-NULL indicates that there is a default argument. |
1261 | | std::unique_ptr<CachedTokens> DefaultArgTokens; |
1262 | | |
1263 | 35.3M | ParamInfo() = default; |
1264 | | ParamInfo(IdentifierInfo *ident, SourceLocation iloc, |
1265 | | Decl *param, |
1266 | | std::unique_ptr<CachedTokens> DefArgTokens = nullptr) |
1267 | | : Ident(ident), IdentLoc(iloc), Param(param), |
1268 | 35.3M | DefaultArgTokens(std::move(DefArgTokens)) {} |
1269 | | }; |
1270 | | |
1271 | | struct TypeAndRange { |
1272 | | ParsedType Ty; |
1273 | | SourceRange Range; |
1274 | | }; |
1275 | | |
1276 | | struct FunctionTypeInfo { |
1277 | | /// hasPrototype - This is true if the function had at least one typed |
1278 | | /// parameter. If the function is () or (a,b,c), then it has no prototype, |
1279 | | /// and is treated as a K&R-style function. |
1280 | | unsigned hasPrototype : 1; |
1281 | | |
1282 | | /// isVariadic - If this function has a prototype, and if that |
1283 | | /// proto ends with ',...)', this is true. When true, EllipsisLoc |
1284 | | /// contains the location of the ellipsis. |
1285 | | unsigned isVariadic : 1; |
1286 | | |
1287 | | /// Can this declaration be a constructor-style initializer? |
1288 | | unsigned isAmbiguous : 1; |
1289 | | |
1290 | | /// Whether the ref-qualifier (if any) is an lvalue reference. |
1291 | | /// Otherwise, it's an rvalue reference. |
1292 | | unsigned RefQualifierIsLValueRef : 1; |
1293 | | |
1294 | | /// ExceptionSpecType - An ExceptionSpecificationType value. |
1295 | | unsigned ExceptionSpecType : 4; |
1296 | | |
1297 | | /// DeleteParams - If this is true, we need to delete[] Params. |
1298 | | unsigned DeleteParams : 1; |
1299 | | |
1300 | | /// HasTrailingReturnType - If this is true, a trailing return type was |
1301 | | /// specified. |
1302 | | unsigned HasTrailingReturnType : 1; |
1303 | | |
1304 | | /// The location of the left parenthesis in the source. |
1305 | | SourceLocation LParenLoc; |
1306 | | |
1307 | | /// When isVariadic is true, the location of the ellipsis in the source. |
1308 | | SourceLocation EllipsisLoc; |
1309 | | |
1310 | | /// The location of the right parenthesis in the source. |
1311 | | SourceLocation RParenLoc; |
1312 | | |
1313 | | /// NumParams - This is the number of formal parameters specified by the |
1314 | | /// declarator. |
1315 | | unsigned NumParams; |
1316 | | |
1317 | | /// NumExceptionsOrDecls - This is the number of types in the |
1318 | | /// dynamic-exception-decl, if the function has one. In C, this is the |
1319 | | /// number of declarations in the function prototype. |
1320 | | unsigned NumExceptionsOrDecls; |
1321 | | |
1322 | | /// The location of the ref-qualifier, if any. |
1323 | | /// |
1324 | | /// If this is an invalid location, there is no ref-qualifier. |
1325 | | SourceLocation RefQualifierLoc; |
1326 | | |
1327 | | /// The location of the 'mutable' qualifer in a lambda-declarator, if |
1328 | | /// any. |
1329 | | SourceLocation MutableLoc; |
1330 | | |
1331 | | /// The beginning location of the exception specification, if any. |
1332 | | SourceLocation ExceptionSpecLocBeg; |
1333 | | |
1334 | | /// The end location of the exception specification, if any. |
1335 | | SourceLocation ExceptionSpecLocEnd; |
1336 | | |
1337 | | /// Params - This is a pointer to a new[]'d array of ParamInfo objects that |
1338 | | /// describe the parameters specified by this function declarator. null if |
1339 | | /// there are no parameters specified. |
1340 | | ParamInfo *Params; |
1341 | | |
1342 | | /// DeclSpec for the function with the qualifier related info. |
1343 | | DeclSpec *MethodQualifiers; |
1344 | | |
1345 | | /// AtttibuteFactory for the MethodQualifiers. |
1346 | | AttributeFactory *QualAttrFactory; |
1347 | | |
1348 | | union { |
1349 | | /// Pointer to a new[]'d array of TypeAndRange objects that |
1350 | | /// contain the types in the function's dynamic exception specification |
1351 | | /// and their locations, if there is one. |
1352 | | TypeAndRange *Exceptions; |
1353 | | |
1354 | | /// Pointer to the expression in the noexcept-specifier of this |
1355 | | /// function, if it has one. |
1356 | | Expr *NoexceptExpr; |
1357 | | |
1358 | | /// Pointer to the cached tokens for an exception-specification |
1359 | | /// that has not yet been parsed. |
1360 | | CachedTokens *ExceptionSpecTokens; |
1361 | | |
1362 | | /// Pointer to a new[]'d array of declarations that need to be available |
1363 | | /// for lookup inside the function body, if one exists. Does not exist in |
1364 | | /// C++. |
1365 | | NamedDecl **DeclsInPrototype; |
1366 | | }; |
1367 | | |
1368 | | /// If HasTrailingReturnType is true, this is the trailing return |
1369 | | /// type specified. |
1370 | | UnionParsedType TrailingReturnType; |
1371 | | |
1372 | | /// If HasTrailingReturnType is true, this is the location of the trailing |
1373 | | /// return type. |
1374 | | SourceLocation TrailingReturnTypeLoc; |
1375 | | |
1376 | | /// Reset the parameter list to having zero parameters. |
1377 | | /// |
1378 | | /// This is used in various places for error recovery. |
1379 | 14.4M | void freeParams() { |
1380 | 49.8M | for (unsigned I = 0; I < NumParams; ++I35.3M ) |
1381 | 35.3M | Params[I].DefaultArgTokens.reset(); |
1382 | 14.4M | if (DeleteParams) { |
1383 | 4.31k | delete[] Params; |
1384 | 4.31k | DeleteParams = false; |
1385 | 4.31k | } |
1386 | 14.4M | NumParams = 0; |
1387 | 14.4M | } |
1388 | | |
1389 | 14.4M | void destroy() { |
1390 | 14.4M | freeParams(); |
1391 | 14.4M | delete QualAttrFactory; |
1392 | 14.4M | delete MethodQualifiers; |
1393 | 14.4M | switch (getExceptionSpecType()) { |
1394 | 564k | default: |
1395 | 564k | break; |
1396 | 304 | case EST_Dynamic: |
1397 | 304 | delete[] Exceptions; |
1398 | 304 | break; |
1399 | 29.6k | case EST_Unparsed: |
1400 | 29.6k | delete ExceptionSpecTokens; |
1401 | 29.6k | break; |
1402 | 13.8M | case EST_None: |
1403 | 13.8M | if (NumExceptionsOrDecls != 0) |
1404 | 706 | delete[] DeclsInPrototype; |
1405 | 13.8M | break; |
1406 | 14.4M | } |
1407 | 14.4M | } |
1408 | | |
1409 | 5.55k | DeclSpec &getOrCreateMethodQualifiers() { |
1410 | 5.55k | if (!MethodQualifiers) { |
1411 | 5.53k | QualAttrFactory = new AttributeFactory(); |
1412 | 5.53k | MethodQualifiers = new DeclSpec(*QualAttrFactory); |
1413 | 5.53k | } |
1414 | 5.55k | return *MethodQualifiers; |
1415 | 5.55k | } |
1416 | | |
1417 | | /// isKNRPrototype - Return true if this is a K&R style identifier list, |
1418 | | /// like "void foo(a,b,c)". In a function definition, this will be followed |
1419 | | /// by the parameter type definitions. |
1420 | 2.61M | bool isKNRPrototype() const { return !hasPrototype && NumParams != 015.8k ; } |
1421 | | |
1422 | 14.5M | SourceLocation getLParenLoc() const { return LParenLoc; } |
1423 | | |
1424 | 14.4M | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
1425 | | |
1426 | 14.5M | SourceLocation getRParenLoc() const { return RParenLoc; } |
1427 | | |
1428 | 14.5M | SourceLocation getExceptionSpecLocBeg() const { |
1429 | 14.5M | return ExceptionSpecLocBeg; |
1430 | 14.5M | } |
1431 | | |
1432 | 14.5M | SourceLocation getExceptionSpecLocEnd() const { |
1433 | 14.5M | return ExceptionSpecLocEnd; |
1434 | 14.5M | } |
1435 | | |
1436 | 14.5M | SourceRange getExceptionSpecRange() const { |
1437 | 14.5M | return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd()); |
1438 | 14.5M | } |
1439 | | |
1440 | | /// Retrieve the location of the ref-qualifier, if any. |
1441 | 28.9M | SourceLocation getRefQualifierLoc() const { return RefQualifierLoc; } |
1442 | | |
1443 | | /// Retrieve the location of the 'const' qualifier. |
1444 | 0 | SourceLocation getConstQualifierLoc() const { |
1445 | 0 | assert(MethodQualifiers); |
1446 | 0 | return MethodQualifiers->getConstSpecLoc(); |
1447 | 0 | } |
1448 | | |
1449 | | /// Retrieve the location of the 'volatile' qualifier. |
1450 | 0 | SourceLocation getVolatileQualifierLoc() const { |
1451 | 0 | assert(MethodQualifiers); |
1452 | 0 | return MethodQualifiers->getVolatileSpecLoc(); |
1453 | 0 | } |
1454 | | |
1455 | | /// Retrieve the location of the 'restrict' qualifier. |
1456 | 0 | SourceLocation getRestrictQualifierLoc() const { |
1457 | 0 | assert(MethodQualifiers); |
1458 | 0 | return MethodQualifiers->getRestrictSpecLoc(); |
1459 | 0 | } |
1460 | | |
1461 | | /// Retrieve the location of the 'mutable' qualifier, if any. |
1462 | 5.69k | SourceLocation getMutableLoc() const { return MutableLoc; } |
1463 | | |
1464 | | /// Determine whether this function declaration contains a |
1465 | | /// ref-qualifier. |
1466 | 28.9M | bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } |
1467 | | |
1468 | | /// Determine whether this lambda-declarator contains a 'mutable' |
1469 | | /// qualifier. |
1470 | 5.69k | bool hasMutableQualifier() const { return getMutableLoc().isValid(); } |
1471 | | |
1472 | | /// Determine whether this method has qualifiers. |
1473 | 14.8M | bool hasMethodTypeQualifiers() const { |
1474 | 14.8M | return MethodQualifiers && (309k MethodQualifiers->getTypeQualifiers()309k || |
1475 | 19 | MethodQualifiers->getAttributes().size()); |
1476 | 14.8M | } |
1477 | | |
1478 | | /// Get the type of exception specification this function has. |
1479 | 59.1M | ExceptionSpecificationType getExceptionSpecType() const { |
1480 | 59.1M | return static_cast<ExceptionSpecificationType>(ExceptionSpecType); |
1481 | 59.1M | } |
1482 | | |
1483 | | /// Get the number of dynamic exception specifications. |
1484 | 304 | unsigned getNumExceptions() const { |
1485 | 304 | assert(ExceptionSpecType != EST_None); |
1486 | 304 | return NumExceptionsOrDecls; |
1487 | 304 | } |
1488 | | |
1489 | | /// Get the non-parameter decls defined within this function |
1490 | | /// prototype. Typically these are tag declarations. |
1491 | 11.3M | ArrayRef<NamedDecl *> getDeclsInPrototype() const { |
1492 | 11.3M | assert(ExceptionSpecType == EST_None); |
1493 | 11.3M | return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls); |
1494 | 11.3M | } |
1495 | | |
1496 | | /// Determine whether this function declarator had a |
1497 | | /// trailing-return-type. |
1498 | 29.0M | bool hasTrailingReturnType() const { return HasTrailingReturnType; } |
1499 | | |
1500 | | /// Get the trailing-return-type for this function declarator. |
1501 | 32.2k | ParsedType getTrailingReturnType() const { |
1502 | 32.2k | assert(HasTrailingReturnType); |
1503 | 32.2k | return TrailingReturnType; |
1504 | 32.2k | } |
1505 | | |
1506 | | /// Get the trailing-return-type location for this function declarator. |
1507 | 10 | SourceLocation getTrailingReturnTypeLoc() const { |
1508 | 10 | assert(HasTrailingReturnType); |
1509 | 10 | return TrailingReturnTypeLoc; |
1510 | 10 | } |
1511 | | }; |
1512 | | |
1513 | | struct BlockPointerTypeInfo { |
1514 | | /// For now, sema will catch these as invalid. |
1515 | | /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. |
1516 | | unsigned TypeQuals : 5; |
1517 | | |
1518 | 77.9k | void destroy() { |
1519 | 77.9k | } |
1520 | | }; |
1521 | | |
1522 | | struct MemberPointerTypeInfo { |
1523 | | /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. |
1524 | | unsigned TypeQuals : 5; |
1525 | | /// Location of the '*' token. |
1526 | | SourceLocation StarLoc; |
1527 | | // CXXScopeSpec has a constructor, so it can't be a direct member. |
1528 | | // So we need some pointer-aligned storage and a bit of trickery. |
1529 | | alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)]; |
1530 | 62.3k | CXXScopeSpec &Scope() { |
1531 | 62.3k | return *reinterpret_cast<CXXScopeSpec *>(ScopeMem); |
1532 | 62.3k | } |
1533 | 31.1k | const CXXScopeSpec &Scope() const { |
1534 | 31.1k | return *reinterpret_cast<const CXXScopeSpec *>(ScopeMem); |
1535 | 31.1k | } |
1536 | 31.1k | void destroy() { |
1537 | 31.1k | Scope().~CXXScopeSpec(); |
1538 | 31.1k | } |
1539 | | }; |
1540 | | |
1541 | | struct PipeTypeInfo { |
1542 | | /// The access writes. |
1543 | | unsigned AccessWrites : 3; |
1544 | | |
1545 | 117 | void destroy() {} |
1546 | | }; |
1547 | | |
1548 | | union { |
1549 | | PointerTypeInfo Ptr; |
1550 | | ReferenceTypeInfo Ref; |
1551 | | ArrayTypeInfo Arr; |
1552 | | FunctionTypeInfo Fun; |
1553 | | BlockPointerTypeInfo Cls; |
1554 | | MemberPointerTypeInfo Mem; |
1555 | | PipeTypeInfo PipeInfo; |
1556 | | }; |
1557 | | |
1558 | 23.1M | void destroy() { |
1559 | 23.1M | switch (Kind) { |
1560 | 14.4M | case DeclaratorChunk::Function: return Fun.destroy(); |
1561 | 6.78M | case DeclaratorChunk::Pointer: return Ptr.destroy(); |
1562 | 77.9k | case DeclaratorChunk::BlockPointer: return Cls.destroy(); |
1563 | 1.08M | case DeclaratorChunk::Reference: return Ref.destroy(); |
1564 | 353k | case DeclaratorChunk::Array: return Arr.destroy(); |
1565 | 31.1k | case DeclaratorChunk::MemberPointer: return Mem.destroy(); |
1566 | 366k | case DeclaratorChunk::Paren: return; |
1567 | 117 | case DeclaratorChunk::Pipe: return PipeInfo.destroy(); |
1568 | 23.1M | } |
1569 | 23.1M | } |
1570 | | |
1571 | | /// If there are attributes applied to this declaratorchunk, return |
1572 | | /// them. |
1573 | 21.7M | const ParsedAttributesView &getAttrs() const { return AttrList; } |
1574 | 70.1M | ParsedAttributesView &getAttrs() { return AttrList; } |
1575 | | |
1576 | | /// Return a DeclaratorChunk for a pointer. |
1577 | | static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, |
1578 | | SourceLocation ConstQualLoc, |
1579 | | SourceLocation VolatileQualLoc, |
1580 | | SourceLocation RestrictQualLoc, |
1581 | | SourceLocation AtomicQualLoc, |
1582 | 6.78M | SourceLocation UnalignedQualLoc) { |
1583 | 6.78M | DeclaratorChunk I; |
1584 | 6.78M | I.Kind = Pointer; |
1585 | 6.78M | I.Loc = Loc; |
1586 | 6.78M | new (&I.Ptr) PointerTypeInfo; |
1587 | 6.78M | I.Ptr.TypeQuals = TypeQuals; |
1588 | 6.78M | I.Ptr.ConstQualLoc = ConstQualLoc; |
1589 | 6.78M | I.Ptr.VolatileQualLoc = VolatileQualLoc; |
1590 | 6.78M | I.Ptr.RestrictQualLoc = RestrictQualLoc; |
1591 | 6.78M | I.Ptr.AtomicQualLoc = AtomicQualLoc; |
1592 | 6.78M | I.Ptr.UnalignedQualLoc = UnalignedQualLoc; |
1593 | 6.78M | return I; |
1594 | 6.78M | } |
1595 | | |
1596 | | /// Return a DeclaratorChunk for a reference. |
1597 | | static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, |
1598 | 1.08M | bool lvalue) { |
1599 | 1.08M | DeclaratorChunk I; |
1600 | 1.08M | I.Kind = Reference; |
1601 | 1.08M | I.Loc = Loc; |
1602 | 1.08M | I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; |
1603 | 1.08M | I.Ref.LValueRef = lvalue; |
1604 | 1.08M | return I; |
1605 | 1.08M | } |
1606 | | |
1607 | | /// Return a DeclaratorChunk for an array. |
1608 | | static DeclaratorChunk getArray(unsigned TypeQuals, |
1609 | | bool isStatic, bool isStar, Expr *NumElts, |
1610 | 353k | SourceLocation LBLoc, SourceLocation RBLoc) { |
1611 | 353k | DeclaratorChunk I; |
1612 | 353k | I.Kind = Array; |
1613 | 353k | I.Loc = LBLoc; |
1614 | 353k | I.EndLoc = RBLoc; |
1615 | 353k | I.Arr.TypeQuals = TypeQuals; |
1616 | 353k | I.Arr.hasStatic = isStatic; |
1617 | 353k | I.Arr.isStar = isStar; |
1618 | 353k | I.Arr.NumElts = NumElts; |
1619 | 353k | return I; |
1620 | 353k | } |
1621 | | |
1622 | | /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. |
1623 | | /// "TheDeclarator" is the declarator that this will be added to. |
1624 | | static DeclaratorChunk getFunction(bool HasProto, |
1625 | | bool IsAmbiguous, |
1626 | | SourceLocation LParenLoc, |
1627 | | ParamInfo *Params, unsigned NumParams, |
1628 | | SourceLocation EllipsisLoc, |
1629 | | SourceLocation RParenLoc, |
1630 | | bool RefQualifierIsLvalueRef, |
1631 | | SourceLocation RefQualifierLoc, |
1632 | | SourceLocation MutableLoc, |
1633 | | ExceptionSpecificationType ESpecType, |
1634 | | SourceRange ESpecRange, |
1635 | | ParsedType *Exceptions, |
1636 | | SourceRange *ExceptionRanges, |
1637 | | unsigned NumExceptions, |
1638 | | Expr *NoexceptExpr, |
1639 | | CachedTokens *ExceptionSpecTokens, |
1640 | | ArrayRef<NamedDecl *> DeclsInPrototype, |
1641 | | SourceLocation LocalRangeBegin, |
1642 | | SourceLocation LocalRangeEnd, |
1643 | | Declarator &TheDeclarator, |
1644 | | TypeResult TrailingReturnType = |
1645 | | TypeResult(), |
1646 | | SourceLocation TrailingReturnTypeLoc = |
1647 | | SourceLocation(), |
1648 | | DeclSpec *MethodQualifiers = nullptr); |
1649 | | |
1650 | | /// Return a DeclaratorChunk for a block. |
1651 | | static DeclaratorChunk getBlockPointer(unsigned TypeQuals, |
1652 | 77.9k | SourceLocation Loc) { |
1653 | 77.9k | DeclaratorChunk I; |
1654 | 77.9k | I.Kind = BlockPointer; |
1655 | 77.9k | I.Loc = Loc; |
1656 | 77.9k | I.Cls.TypeQuals = TypeQuals; |
1657 | 77.9k | return I; |
1658 | 77.9k | } |
1659 | | |
1660 | | /// Return a DeclaratorChunk for a block. |
1661 | | static DeclaratorChunk getPipe(unsigned TypeQuals, |
1662 | 117 | SourceLocation Loc) { |
1663 | 117 | DeclaratorChunk I; |
1664 | 117 | I.Kind = Pipe; |
1665 | 117 | I.Loc = Loc; |
1666 | 117 | I.Cls.TypeQuals = TypeQuals; |
1667 | 117 | return I; |
1668 | 117 | } |
1669 | | |
1670 | | static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, |
1671 | | unsigned TypeQuals, |
1672 | | SourceLocation StarLoc, |
1673 | 31.1k | SourceLocation EndLoc) { |
1674 | 31.1k | DeclaratorChunk I; |
1675 | 31.1k | I.Kind = MemberPointer; |
1676 | 31.1k | I.Loc = SS.getBeginLoc(); |
1677 | 31.1k | I.EndLoc = EndLoc; |
1678 | 31.1k | new (&I.Mem) MemberPointerTypeInfo; |
1679 | 31.1k | I.Mem.StarLoc = StarLoc; |
1680 | 31.1k | I.Mem.TypeQuals = TypeQuals; |
1681 | 31.1k | new (I.Mem.ScopeMem) CXXScopeSpec(SS); |
1682 | 31.1k | return I; |
1683 | 31.1k | } |
1684 | | |
1685 | | /// Return a DeclaratorChunk for a paren. |
1686 | | static DeclaratorChunk getParen(SourceLocation LParenLoc, |
1687 | 366k | SourceLocation RParenLoc) { |
1688 | 366k | DeclaratorChunk I; |
1689 | 366k | I.Kind = Paren; |
1690 | 366k | I.Loc = LParenLoc; |
1691 | 366k | I.EndLoc = RParenLoc; |
1692 | 366k | return I; |
1693 | 366k | } |
1694 | | |
1695 | 253k | bool isParen() const { |
1696 | 253k | return Kind == Paren; |
1697 | 253k | } |
1698 | | }; |
1699 | | |
1700 | | /// A parsed C++17 decomposition declarator of the form |
1701 | | /// '[' identifier-list ']' |
1702 | | class DecompositionDeclarator { |
1703 | | public: |
1704 | | struct Binding { |
1705 | | IdentifierInfo *Name; |
1706 | | SourceLocation NameLoc; |
1707 | | }; |
1708 | | |
1709 | | private: |
1710 | | /// The locations of the '[' and ']' tokens. |
1711 | | SourceLocation LSquareLoc, RSquareLoc; |
1712 | | |
1713 | | /// The bindings. |
1714 | | Binding *Bindings; |
1715 | | unsigned NumBindings : 31; |
1716 | | unsigned DeleteBindings : 1; |
1717 | | |
1718 | | friend class Declarator; |
1719 | | |
1720 | | public: |
1721 | | DecompositionDeclarator() |
1722 | 69.6M | : Bindings(nullptr), NumBindings(0), DeleteBindings(false) {} |
1723 | | DecompositionDeclarator(const DecompositionDeclarator &G) = delete; |
1724 | | DecompositionDeclarator &operator=(const DecompositionDeclarator &G) = delete; |
1725 | 69.6M | ~DecompositionDeclarator() { |
1726 | 69.6M | if (DeleteBindings) |
1727 | 0 | delete[] Bindings; |
1728 | 69.6M | } |
1729 | | |
1730 | 69.8M | void clear() { |
1731 | 69.8M | LSquareLoc = RSquareLoc = SourceLocation(); |
1732 | 69.8M | if (DeleteBindings) |
1733 | 0 | delete[] Bindings; |
1734 | 69.8M | Bindings = nullptr; |
1735 | 69.8M | NumBindings = 0; |
1736 | 69.8M | DeleteBindings = false; |
1737 | 69.8M | } |
1738 | | |
1739 | 1.02k | ArrayRef<Binding> bindings() const { |
1740 | 1.02k | return llvm::makeArrayRef(Bindings, NumBindings); |
1741 | 1.02k | } |
1742 | | |
1743 | 84.9M | bool isSet() const { return LSquareLoc.isValid(); } |
1744 | | |
1745 | 719 | SourceLocation getLSquareLoc() const { return LSquareLoc; } |
1746 | 0 | SourceLocation getRSquareLoc() const { return RSquareLoc; } |
1747 | 354 | SourceRange getSourceRange() const { |
1748 | 354 | return SourceRange(LSquareLoc, RSquareLoc); |
1749 | 354 | } |
1750 | | }; |
1751 | | |
1752 | | /// Described the kind of function definition (if any) provided for |
1753 | | /// a function. |
1754 | | enum class FunctionDefinitionKind { |
1755 | | Declaration, |
1756 | | Definition, |
1757 | | Defaulted, |
1758 | | Deleted |
1759 | | }; |
1760 | | |
1761 | | enum class DeclaratorContext { |
1762 | | File, // File scope declaration. |
1763 | | Prototype, // Within a function prototype. |
1764 | | ObjCResult, // An ObjC method result type. |
1765 | | ObjCParameter, // An ObjC method parameter type. |
1766 | | KNRTypeList, // K&R type definition list for formals. |
1767 | | TypeName, // Abstract declarator for types. |
1768 | | FunctionalCast, // Type in a C++ functional cast expression. |
1769 | | Member, // Struct/Union field. |
1770 | | Block, // Declaration within a block in a function. |
1771 | | ForInit, // Declaration within first part of a for loop. |
1772 | | SelectionInit, // Declaration within optional init stmt of if/switch. |
1773 | | Condition, // Condition declaration in a C++ if/switch/while/for. |
1774 | | TemplateParam, // Within a template parameter list. |
1775 | | CXXNew, // C++ new-expression. |
1776 | | CXXCatch, // C++ catch exception-declaration |
1777 | | ObjCCatch, // Objective-C catch exception-declaration |
1778 | | BlockLiteral, // Block literal declarator. |
1779 | | LambdaExpr, // Lambda-expression declarator. |
1780 | | LambdaExprParameter, // Lambda-expression parameter declarator. |
1781 | | ConversionId, // C++ conversion-type-id. |
1782 | | TrailingReturn, // C++11 trailing-type-specifier. |
1783 | | TrailingReturnVar, // C++11 trailing-type-specifier for variable. |
1784 | | TemplateArg, // Any template argument (in template argument list). |
1785 | | TemplateTypeArg, // Template type argument (in default argument). |
1786 | | AliasDecl, // C++11 alias-declaration. |
1787 | | AliasTemplate, // C++11 alias-declaration template. |
1788 | | RequiresExpr // C++2a requires-expression. |
1789 | | }; |
1790 | | |
1791 | | /// Information about one declarator, including the parsed type |
1792 | | /// information and the identifier. |
1793 | | /// |
1794 | | /// When the declarator is fully formed, this is turned into the appropriate |
1795 | | /// Decl object. |
1796 | | /// |
1797 | | /// Declarators come in two types: normal declarators and abstract declarators. |
1798 | | /// Abstract declarators are used when parsing types, and don't have an |
1799 | | /// identifier. Normal declarators do have ID's. |
1800 | | /// |
1801 | | /// Instances of this class should be a transient object that lives on the |
1802 | | /// stack, not objects that are allocated in large quantities on the heap. |
1803 | | class Declarator { |
1804 | | |
1805 | | private: |
1806 | | const DeclSpec &DS; |
1807 | | CXXScopeSpec SS; |
1808 | | UnqualifiedId Name; |
1809 | | SourceRange Range; |
1810 | | |
1811 | | /// Where we are parsing this declarator. |
1812 | | DeclaratorContext Context; |
1813 | | |
1814 | | /// The C++17 structured binding, if any. This is an alternative to a Name. |
1815 | | DecompositionDeclarator BindingGroup; |
1816 | | |
1817 | | /// DeclTypeInfo - This holds each type that the declarator includes as it is |
1818 | | /// parsed. This is pushed from the identifier out, which means that element |
1819 | | /// #0 will be the most closely bound to the identifier, and |
1820 | | /// DeclTypeInfo.back() will be the least closely bound. |
1821 | | SmallVector<DeclaratorChunk, 8> DeclTypeInfo; |
1822 | | |
1823 | | /// InvalidType - Set by Sema::GetTypeForDeclarator(). |
1824 | | unsigned InvalidType : 1; |
1825 | | |
1826 | | /// GroupingParens - Set by Parser::ParseParenDeclarator(). |
1827 | | unsigned GroupingParens : 1; |
1828 | | |
1829 | | /// FunctionDefinition - Is this Declarator for a function or member |
1830 | | /// definition and, if so, what kind? |
1831 | | /// |
1832 | | /// Actually a FunctionDefinitionKind. |
1833 | | unsigned FunctionDefinition : 2; |
1834 | | |
1835 | | /// Is this Declarator a redeclaration? |
1836 | | unsigned Redeclaration : 1; |
1837 | | |
1838 | | /// true if the declaration is preceded by \c __extension__. |
1839 | | unsigned Extension : 1; |
1840 | | |
1841 | | /// Indicates whether this is an Objective-C instance variable. |
1842 | | unsigned ObjCIvar : 1; |
1843 | | |
1844 | | /// Indicates whether this is an Objective-C 'weak' property. |
1845 | | unsigned ObjCWeakProperty : 1; |
1846 | | |
1847 | | /// Indicates whether the InlineParams / InlineBindings storage has been used. |
1848 | | unsigned InlineStorageUsed : 1; |
1849 | | |
1850 | | /// Indicates whether this declarator has an initializer. |
1851 | | unsigned HasInitializer : 1; |
1852 | | |
1853 | | /// Attrs - Attributes. |
1854 | | ParsedAttributes Attrs; |
1855 | | |
1856 | | /// The asm label, if specified. |
1857 | | Expr *AsmLabel; |
1858 | | |
1859 | | /// \brief The constraint-expression specified by the trailing |
1860 | | /// requires-clause, or null if no such clause was specified. |
1861 | | Expr *TrailingRequiresClause; |
1862 | | |
1863 | | /// If this declarator declares a template, its template parameter lists. |
1864 | | ArrayRef<TemplateParameterList *> TemplateParameterLists; |
1865 | | |
1866 | | /// If the declarator declares an abbreviated function template, the innermost |
1867 | | /// template parameter list containing the invented and explicit template |
1868 | | /// parameters (if any). |
1869 | | TemplateParameterList *InventedTemplateParameterList; |
1870 | | |
1871 | | #ifndef _MSC_VER |
1872 | | union { |
1873 | | #endif |
1874 | | /// InlineParams - This is a local array used for the first function decl |
1875 | | /// chunk to avoid going to the heap for the common case when we have one |
1876 | | /// function chunk in the declarator. |
1877 | | DeclaratorChunk::ParamInfo InlineParams[16]; |
1878 | | DecompositionDeclarator::Binding InlineBindings[16]; |
1879 | | #ifndef _MSC_VER |
1880 | | }; |
1881 | | #endif |
1882 | | |
1883 | | /// If this is the second or subsequent declarator in this declaration, |
1884 | | /// the location of the comma before this declarator. |
1885 | | SourceLocation CommaLoc; |
1886 | | |
1887 | | /// If provided, the source location of the ellipsis used to describe |
1888 | | /// this declarator as a parameter pack. |
1889 | | SourceLocation EllipsisLoc; |
1890 | | |
1891 | | friend struct DeclaratorChunk; |
1892 | | |
1893 | | public: |
1894 | | Declarator(const DeclSpec &ds, DeclaratorContext C) |
1895 | | : DS(ds), Range(ds.getSourceRange()), Context(C), |
1896 | | InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), |
1897 | | GroupingParens(false), FunctionDefinition(static_cast<unsigned>( |
1898 | | FunctionDefinitionKind::Declaration)), |
1899 | | Redeclaration(false), Extension(false), ObjCIvar(false), |
1900 | | ObjCWeakProperty(false), InlineStorageUsed(false), |
1901 | | HasInitializer(false), Attrs(ds.getAttributePool().getFactory()), |
1902 | | AsmLabel(nullptr), TrailingRequiresClause(nullptr), |
1903 | 69.6M | InventedTemplateParameterList(nullptr) {} |
1904 | | |
1905 | 69.6M | ~Declarator() { |
1906 | 69.6M | clear(); |
1907 | 69.6M | } |
1908 | | /// getDeclSpec - Return the declaration-specifier that this declarator was |
1909 | | /// declared with. |
1910 | 885M | const DeclSpec &getDeclSpec() const { return DS; } |
1911 | | |
1912 | | /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This |
1913 | | /// should be used with extreme care: declspecs can often be shared between |
1914 | | /// multiple declarators, so mutating the DeclSpec affects all of the |
1915 | | /// Declarators. This should only be done when the declspec is known to not |
1916 | | /// be shared or when in error recovery etc. |
1917 | 79.2M | DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } |
1918 | | |
1919 | 31.6M | AttributePool &getAttributePool() const { |
1920 | 31.6M | return Attrs.getPool(); |
1921 | 31.6M | } |
1922 | | |
1923 | | /// getCXXScopeSpec - Return the C++ scope specifier (global scope or |
1924 | | /// nested-name-specifier) that is part of the declarator-id. |
1925 | 1.67M | const CXXScopeSpec &getCXXScopeSpec() const { return SS; } |
1926 | 274M | CXXScopeSpec &getCXXScopeSpec() { return SS; } |
1927 | | |
1928 | | /// Retrieve the name specified by this declarator. |
1929 | 193M | UnqualifiedId &getName() { return Name; } |
1930 | | |
1931 | 1.04k | const DecompositionDeclarator &getDecompositionDeclarator() const { |
1932 | 1.04k | return BindingGroup; |
1933 | 1.04k | } |
1934 | | |
1935 | 461M | DeclaratorContext getContext() const { return Context; } |
1936 | | |
1937 | 68.4M | bool isPrototypeContext() const { |
1938 | 68.4M | return (Context == DeclaratorContext::Prototype || |
1939 | 32.2M | Context == DeclaratorContext::ObjCParameter || |
1940 | 30.0M | Context == DeclaratorContext::ObjCResult || |
1941 | 28.9M | Context == DeclaratorContext::LambdaExprParameter); |
1942 | 68.4M | } |
1943 | | |
1944 | | /// Get the source range that spans this declarator. |
1945 | 23.6M | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
1946 | 58.6M | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
1947 | 25.3k | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
1948 | | |
1949 | 27.7k | void SetSourceRange(SourceRange R) { Range = R; } |
1950 | | /// SetRangeBegin - Set the start of the source range to Loc, unless it's |
1951 | | /// invalid. |
1952 | 1 | void SetRangeBegin(SourceLocation Loc) { |
1953 | 1 | if (!Loc.isInvalid()) |
1954 | 1 | Range.setBegin(Loc); |
1955 | 1 | } |
1956 | | /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid. |
1957 | 60.3M | void SetRangeEnd(SourceLocation Loc) { |
1958 | 60.3M | if (!Loc.isInvalid()) |
1959 | 60.3M | Range.setEnd(Loc); |
1960 | 60.3M | } |
1961 | | /// ExtendWithDeclSpec - Extend the declarator source range to include the |
1962 | | /// given declspec, unless its location is invalid. Adopts the range start if |
1963 | | /// the current range start is invalid. |
1964 | 7.97M | void ExtendWithDeclSpec(const DeclSpec &DS) { |
1965 | 7.97M | SourceRange SR = DS.getSourceRange(); |
1966 | 7.97M | if (Range.getBegin().isInvalid()) |
1967 | 798 | Range.setBegin(SR.getBegin()); |
1968 | 7.97M | if (!SR.getEnd().isInvalid()) |
1969 | 183k | Range.setEnd(SR.getEnd()); |
1970 | 7.97M | } |
1971 | | |
1972 | | /// Reset the contents of this Declarator. |
1973 | 69.8M | void clear() { |
1974 | 69.8M | SS.clear(); |
1975 | 69.8M | Name.clear(); |
1976 | 69.8M | Range = DS.getSourceRange(); |
1977 | 69.8M | BindingGroup.clear(); |
1978 | | |
1979 | 93.0M | for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i23.1M ) |
1980 | 23.1M | DeclTypeInfo[i].destroy(); |
1981 | 69.8M | DeclTypeInfo.clear(); |
1982 | 69.8M | Attrs.clear(); |
1983 | 69.8M | AsmLabel = nullptr; |
1984 | 69.8M | InlineStorageUsed = false; |
1985 | 69.8M | HasInitializer = false; |
1986 | 69.8M | ObjCIvar = false; |
1987 | 69.8M | ObjCWeakProperty = false; |
1988 | 69.8M | CommaLoc = SourceLocation(); |
1989 | 69.8M | EllipsisLoc = SourceLocation(); |
1990 | 69.8M | } |
1991 | | |
1992 | | /// mayOmitIdentifier - Return true if the identifier is either optional or |
1993 | | /// not allowed. This is true for typenames, prototypes, and template |
1994 | | /// parameter lists. |
1995 | 42.2M | bool mayOmitIdentifier() const { |
1996 | 42.2M | switch (Context) { |
1997 | 924k | case DeclaratorContext::File: |
1998 | 924k | case DeclaratorContext::KNRTypeList: |
1999 | 1.84M | case DeclaratorContext::Member: |
2000 | 1.92M | case DeclaratorContext::Block: |
2001 | 1.92M | case DeclaratorContext::ForInit: |
2002 | 1.92M | case DeclaratorContext::SelectionInit: |
2003 | 1.92M | case DeclaratorContext::Condition: |
2004 | 1.92M | return false; |
2005 | | |
2006 | 5.09M | case DeclaratorContext::TypeName: |
2007 | 5.09M | case DeclaratorContext::FunctionalCast: |
2008 | 5.12M | case DeclaratorContext::AliasDecl: |
2009 | 5.16M | case DeclaratorContext::AliasTemplate: |
2010 | 33.2M | case DeclaratorContext::Prototype: |
2011 | 33.2M | case DeclaratorContext::LambdaExprParameter: |
2012 | 35.4M | case DeclaratorContext::ObjCParameter: |
2013 | 36.5M | case DeclaratorContext::ObjCResult: |
2014 | 36.5M | case DeclaratorContext::TemplateParam: |
2015 | 36.5M | case DeclaratorContext::CXXNew: |
2016 | 36.5M | case DeclaratorContext::CXXCatch: |
2017 | 36.5M | case DeclaratorContext::ObjCCatch: |
2018 | 36.5M | case DeclaratorContext::BlockLiteral: |
2019 | 36.5M | case DeclaratorContext::LambdaExpr: |
2020 | 36.5M | case DeclaratorContext::ConversionId: |
2021 | 40.2M | case DeclaratorContext::TemplateArg: |
2022 | 40.2M | case DeclaratorContext::TemplateTypeArg: |
2023 | 40.3M | case DeclaratorContext::TrailingReturn: |
2024 | 40.3M | case DeclaratorContext::TrailingReturnVar: |
2025 | 40.3M | case DeclaratorContext::RequiresExpr: |
2026 | 40.3M | return true; |
2027 | 0 | } |
2028 | 0 | llvm_unreachable("unknown context kind!"); |
2029 | 0 | } |
2030 | | |
2031 | | /// mayHaveIdentifier - Return true if the identifier is either optional or |
2032 | | /// required. This is true for normal declarators and prototypes, but not |
2033 | | /// typenames. |
2034 | 41.1M | bool mayHaveIdentifier() const { |
2035 | 41.1M | switch (Context) { |
2036 | 16.6M | case DeclaratorContext::File: |
2037 | 16.6M | case DeclaratorContext::KNRTypeList: |
2038 | 22.0M | case DeclaratorContext::Member: |
2039 | 23.2M | case DeclaratorContext::Block: |
2040 | 23.3M | case DeclaratorContext::ForInit: |
2041 | 23.3M | case DeclaratorContext::SelectionInit: |
2042 | 23.3M | case DeclaratorContext::Condition: |
2043 | 36.1M | case DeclaratorContext::Prototype: |
2044 | 36.1M | case DeclaratorContext::LambdaExprParameter: |
2045 | 36.3M | case DeclaratorContext::TemplateParam: |
2046 | 36.3M | case DeclaratorContext::CXXCatch: |
2047 | 36.3M | case DeclaratorContext::ObjCCatch: |
2048 | 36.3M | case DeclaratorContext::RequiresExpr: |
2049 | 36.3M | return true; |
2050 | | |
2051 | 917k | case DeclaratorContext::TypeName: |
2052 | 917k | case DeclaratorContext::FunctionalCast: |
2053 | 917k | case DeclaratorContext::CXXNew: |
2054 | 947k | case DeclaratorContext::AliasDecl: |
2055 | 992k | case DeclaratorContext::AliasTemplate: |
2056 | 1.12M | case DeclaratorContext::ObjCParameter: |
2057 | 1.21M | case DeclaratorContext::ObjCResult: |
2058 | 1.21M | case DeclaratorContext::BlockLiteral: |
2059 | 1.21M | case DeclaratorContext::LambdaExpr: |
2060 | 1.21M | case DeclaratorContext::ConversionId: |
2061 | 4.68M | case DeclaratorContext::TemplateArg: |
2062 | 4.77M | case DeclaratorContext::TemplateTypeArg: |
2063 | 4.77M | case DeclaratorContext::TrailingReturn: |
2064 | 4.78M | case DeclaratorContext::TrailingReturnVar: |
2065 | 4.78M | return false; |
2066 | 0 | } |
2067 | 0 | llvm_unreachable("unknown context kind!"); |
2068 | 0 | } |
2069 | | |
2070 | | /// Return true if the context permits a C++17 decomposition declarator. |
2071 | 348 | bool mayHaveDecompositionDeclarator() const { |
2072 | 348 | switch (Context) { |
2073 | 47 | case DeclaratorContext::File: |
2074 | | // FIXME: It's not clear that the proposal meant to allow file-scope |
2075 | | // structured bindings, but it does. |
2076 | 287 | case DeclaratorContext::Block: |
2077 | 312 | case DeclaratorContext::ForInit: |
2078 | 316 | case DeclaratorContext::SelectionInit: |
2079 | 346 | case DeclaratorContext::Condition: |
2080 | 346 | return true; |
2081 | | |
2082 | 2 | case DeclaratorContext::Member: |
2083 | 2 | case DeclaratorContext::Prototype: |
2084 | 2 | case DeclaratorContext::TemplateParam: |
2085 | 2 | case DeclaratorContext::RequiresExpr: |
2086 | | // Maybe one day... |
2087 | 2 | return false; |
2088 | | |
2089 | | // These contexts don't allow any kind of non-abstract declarator. |
2090 | 0 | case DeclaratorContext::KNRTypeList: |
2091 | 0 | case DeclaratorContext::TypeName: |
2092 | 0 | case DeclaratorContext::FunctionalCast: |
2093 | 0 | case DeclaratorContext::AliasDecl: |
2094 | 0 | case DeclaratorContext::AliasTemplate: |
2095 | 0 | case DeclaratorContext::LambdaExprParameter: |
2096 | 0 | case DeclaratorContext::ObjCParameter: |
2097 | 0 | case DeclaratorContext::ObjCResult: |
2098 | 0 | case DeclaratorContext::CXXNew: |
2099 | 0 | case DeclaratorContext::CXXCatch: |
2100 | 0 | case DeclaratorContext::ObjCCatch: |
2101 | 0 | case DeclaratorContext::BlockLiteral: |
2102 | 0 | case DeclaratorContext::LambdaExpr: |
2103 | 0 | case DeclaratorContext::ConversionId: |
2104 | 0 | case DeclaratorContext::TemplateArg: |
2105 | 0 | case DeclaratorContext::TemplateTypeArg: |
2106 | 0 | case DeclaratorContext::TrailingReturn: |
2107 | 0 | case DeclaratorContext::TrailingReturnVar: |
2108 | 0 | return false; |
2109 | 0 | } |
2110 | 0 | llvm_unreachable("unknown context kind!"); |
2111 | 0 | } |
2112 | | |
2113 | | /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be |
2114 | | /// followed by a C++ direct initializer, e.g. "int x(1);". |
2115 | 3.04M | bool mayBeFollowedByCXXDirectInit() const { |
2116 | 3.04M | if (hasGroupingParens()) return false1.58k ; |
2117 | | |
2118 | 3.04M | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) |
2119 | 27.8k | return false; |
2120 | | |
2121 | 3.01M | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern && |
2122 | 187k | Context != DeclaratorContext::File) |
2123 | 409 | return false; |
2124 | | |
2125 | | // Special names can't have direct initializers. |
2126 | 3.01M | if (Name.getKind() != UnqualifiedIdKind::IK_Identifier) |
2127 | 650k | return false; |
2128 | | |
2129 | 2.36M | switch (Context) { |
2130 | 1.54M | case DeclaratorContext::File: |
2131 | 1.60M | case DeclaratorContext::Block: |
2132 | 1.60M | case DeclaratorContext::ForInit: |
2133 | 1.60M | case DeclaratorContext::SelectionInit: |
2134 | 1.60M | case DeclaratorContext::TrailingReturnVar: |
2135 | 1.60M | return true; |
2136 | | |
2137 | 10 | case DeclaratorContext::Condition: |
2138 | | // This may not be followed by a direct initializer, but it can't be a |
2139 | | // function declaration either, and we'd prefer to perform a tentative |
2140 | | // parse in order to produce the right diagnostic. |
2141 | 10 | return true; |
2142 | | |
2143 | 0 | case DeclaratorContext::KNRTypeList: |
2144 | 554k | case DeclaratorContext::Member: |
2145 | 638k | case DeclaratorContext::Prototype: |
2146 | 638k | case DeclaratorContext::LambdaExprParameter: |
2147 | 685k | case DeclaratorContext::ObjCParameter: |
2148 | 686k | case DeclaratorContext::ObjCResult: |
2149 | 686k | case DeclaratorContext::TemplateParam: |
2150 | 686k | case DeclaratorContext::CXXCatch: |
2151 | 686k | case DeclaratorContext::ObjCCatch: |
2152 | 689k | case DeclaratorContext::TypeName: |
2153 | 689k | case DeclaratorContext::FunctionalCast: // FIXME |
2154 | 689k | case DeclaratorContext::CXXNew: |
2155 | 690k | case DeclaratorContext::AliasDecl: |
2156 | 690k | case DeclaratorContext::AliasTemplate: |
2157 | 690k | case DeclaratorContext::BlockLiteral: |
2158 | 690k | case DeclaratorContext::LambdaExpr: |
2159 | 690k | case DeclaratorContext::ConversionId: |
2160 | 763k | case DeclaratorContext::TemplateArg: |
2161 | 763k | case DeclaratorContext::TemplateTypeArg: |
2162 | 763k | case DeclaratorContext::TrailingReturn: |
2163 | 763k | case DeclaratorContext::RequiresExpr: |
2164 | 763k | return false; |
2165 | 0 | } |
2166 | 0 | llvm_unreachable("unknown context kind!"); |
2167 | 0 | } |
2168 | | |
2169 | | /// isPastIdentifier - Return true if we have parsed beyond the point where |
2170 | | /// the name would appear. (This may happen even if we haven't actually parsed |
2171 | | /// a name, perhaps because this context doesn't require one.) |
2172 | 84.3M | bool isPastIdentifier() const { return Name.isValid(); } |
2173 | | |
2174 | | /// hasName - Whether this declarator has a name, which might be an |
2175 | | /// identifier (accessible via getIdentifier()) or some kind of |
2176 | | /// special C++ name (constructor, destructor, etc.), or a structured |
2177 | | /// binding (which is not exactly a name, but occupies the same position). |
2178 | 124M | bool hasName() const { |
2179 | 124M | return Name.getKind() != UnqualifiedIdKind::IK_Identifier || |
2180 | 123M | Name.Identifier || isDecompositionDeclarator()58.7M ; |
2181 | 124M | } |
2182 | | |
2183 | | /// Return whether this declarator is a decomposition declarator. |
2184 | 84.9M | bool isDecompositionDeclarator() const { |
2185 | 84.9M | return BindingGroup.isSet(); |
2186 | 84.9M | } |
2187 | | |
2188 | 193M | IdentifierInfo *getIdentifier() const { |
2189 | 193M | if (Name.getKind() == UnqualifiedIdKind::IK_Identifier) |
2190 | 193M | return Name.Identifier; |
2191 | | |
2192 | 882k | return nullptr; |
2193 | 882k | } |
2194 | 188M | SourceLocation getIdentifierLoc() const { return Name.StartLocation; } |
2195 | | |
2196 | | /// Set the name of this declarator to be the given identifier. |
2197 | 59.8M | void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) { |
2198 | 59.8M | Name.setIdentifier(Id, IdLoc); |
2199 | 59.8M | } |
2200 | | |
2201 | | /// Set the decomposition bindings for this declarator. |
2202 | | void |
2203 | | setDecompositionBindings(SourceLocation LSquareLoc, |
2204 | | ArrayRef<DecompositionDeclarator::Binding> Bindings, |
2205 | | SourceLocation RSquareLoc); |
2206 | | |
2207 | | /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to |
2208 | | /// EndLoc, which should be the last token of the chunk. |
2209 | | /// This function takes attrs by R-Value reference because it takes ownership |
2210 | | /// of those attributes from the parameter. |
2211 | | void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, |
2212 | 23.1M | SourceLocation EndLoc) { |
2213 | 23.1M | DeclTypeInfo.push_back(TI); |
2214 | 23.1M | DeclTypeInfo.back().getAttrs().addAll(attrs.begin(), attrs.end()); |
2215 | 23.1M | getAttributePool().takeAllFrom(attrs.getPool()); |
2216 | | |
2217 | 23.1M | if (!EndLoc.isInvalid()) |
2218 | 15.1M | SetRangeEnd(EndLoc); |
2219 | 23.1M | } |
2220 | | |
2221 | | /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to |
2222 | | /// EndLoc, which should be the last token of the chunk. |
2223 | 1.67k | void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) { |
2224 | 1.67k | DeclTypeInfo.push_back(TI); |
2225 | | |
2226 | 1.67k | if (!EndLoc.isInvalid()) |
2227 | 1.58k | SetRangeEnd(EndLoc); |
2228 | 1.67k | } |
2229 | | |
2230 | | /// Add a new innermost chunk to this declarator. |
2231 | 20 | void AddInnermostTypeInfo(const DeclaratorChunk &TI) { |
2232 | 20 | DeclTypeInfo.insert(DeclTypeInfo.begin(), TI); |
2233 | 20 | } |
2234 | | |
2235 | | /// Return the number of types applied to this declarator. |
2236 | 499M | unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } |
2237 | | |
2238 | | /// Return the specified TypeInfo from this declarator. TypeInfo #0 is |
2239 | | /// closest to the identifier. |
2240 | 21.8M | const DeclaratorChunk &getTypeObject(unsigned i) const { |
2241 | 21.8M | assert(i < DeclTypeInfo.size() && "Invalid type chunk"); |
2242 | 21.8M | return DeclTypeInfo[i]; |
2243 | 21.8M | } |
2244 | 104M | DeclaratorChunk &getTypeObject(unsigned i) { |
2245 | 104M | assert(i < DeclTypeInfo.size() && "Invalid type chunk"); |
2246 | 104M | return DeclTypeInfo[i]; |
2247 | 104M | } |
2248 | | |
2249 | | typedef SmallVectorImpl<DeclaratorChunk>::const_iterator type_object_iterator; |
2250 | | typedef llvm::iterator_range<type_object_iterator> type_object_range; |
2251 | | |
2252 | | /// Returns the range of type objects, from the identifier outwards. |
2253 | 52.1M | type_object_range type_objects() const { |
2254 | 52.1M | return type_object_range(DeclTypeInfo.begin(), DeclTypeInfo.end()); |
2255 | 52.1M | } |
2256 | | |
2257 | 1.19k | void DropFirstTypeObject() { |
2258 | 1.19k | assert(!DeclTypeInfo.empty() && "No type chunks to drop."); |
2259 | 1.19k | DeclTypeInfo.front().destroy(); |
2260 | 1.19k | DeclTypeInfo.erase(DeclTypeInfo.begin()); |
2261 | 1.19k | } |
2262 | | |
2263 | | /// Return the innermost (closest to the declarator) chunk of this |
2264 | | /// declarator that is not a parens chunk, or null if there are no |
2265 | | /// non-parens chunks. |
2266 | 285k | const DeclaratorChunk *getInnermostNonParenChunk() const { |
2267 | 285k | for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i0 ) { |
2268 | 253k | if (!DeclTypeInfo[i].isParen()) |
2269 | 253k | return &DeclTypeInfo[i]; |
2270 | 253k | } |
2271 | 31.8k | return nullptr; |
2272 | 285k | } |
2273 | | |
2274 | | /// Return the outermost (furthest from the declarator) chunk of |
2275 | | /// this declarator that is not a parens chunk, or null if there are |
2276 | | /// no non-parens chunks. |
2277 | 0 | const DeclaratorChunk *getOutermostNonParenChunk() const { |
2278 | 0 | for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) { |
2279 | 0 | if (!DeclTypeInfo[i-1].isParen()) |
2280 | 0 | return &DeclTypeInfo[i-1]; |
2281 | 0 | } |
2282 | 0 | return nullptr; |
2283 | 0 | } |
2284 | | |
2285 | | /// isArrayOfUnknownBound - This method returns true if the declarator |
2286 | | /// is a declarator for an array of unknown bound (looking through |
2287 | | /// parentheses). |
2288 | 2.96k | bool isArrayOfUnknownBound() const { |
2289 | 2.96k | const DeclaratorChunk *chunk = getInnermostNonParenChunk(); |
2290 | 2.96k | return (chunk && chunk->Kind == DeclaratorChunk::Array759 && |
2291 | 91 | !chunk->Arr.NumElts); |
2292 | 2.96k | } |
2293 | | |
2294 | | /// isFunctionDeclarator - This method returns true if the declarator |
2295 | | /// is a function declarator (looking through parentheses). |
2296 | | /// If true is returned, then the reference type parameter idx is |
2297 | | /// assigned with the index of the declaration chunk. |
2298 | 109M | bool isFunctionDeclarator(unsigned& idx) const { |
2299 | 109M | for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i56.1k ) { |
2300 | 97.6M | switch (DeclTypeInfo[i].Kind) { |
2301 | 95.6M | case DeclaratorChunk::Function: |
2302 | 95.6M | idx = i; |
2303 | 95.6M | return true; |
2304 | 56.1k | case DeclaratorChunk::Paren: |
2305 | 56.1k | continue; |
2306 | 1.37M | case DeclaratorChunk::Pointer: |
2307 | 1.52M | case DeclaratorChunk::Reference: |
2308 | 1.93M | case DeclaratorChunk::Array: |
2309 | 1.96M | case DeclaratorChunk::BlockPointer: |
2310 | 1.97M | case DeclaratorChunk::MemberPointer: |
2311 | 1.97M | case DeclaratorChunk::Pipe: |
2312 | 1.97M | return false; |
2313 | 0 | } |
2314 | 0 | llvm_unreachable("Invalid type chunk"); |
2315 | 0 | } |
2316 | 12.2M | return false; |
2317 | 109M | } |
2318 | | |
2319 | | /// isFunctionDeclarator - Once this declarator is fully parsed and formed, |
2320 | | /// this method returns true if the identifier is a function declarator |
2321 | | /// (looking through parentheses). |
2322 | 80.2M | bool isFunctionDeclarator() const { |
2323 | 80.2M | unsigned index; |
2324 | 80.2M | return isFunctionDeclarator(index); |
2325 | 80.2M | } |
2326 | | |
2327 | | /// getFunctionTypeInfo - Retrieves the function type info object |
2328 | | /// (looking through parentheses). |
2329 | 15.6M | DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() { |
2330 | 15.6M | assert(isFunctionDeclarator() && "Not a function declarator!"); |
2331 | 15.6M | unsigned index = 0; |
2332 | 15.6M | isFunctionDeclarator(index); |
2333 | 15.6M | return DeclTypeInfo[index].Fun; |
2334 | 15.6M | } |
2335 | | |
2336 | | /// getFunctionTypeInfo - Retrieves the function type info object |
2337 | | /// (looking through parentheses). |
2338 | 102 | const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const { |
2339 | 102 | return const_cast<Declarator*>(this)->getFunctionTypeInfo(); |
2340 | 102 | } |
2341 | | |
2342 | | /// Determine whether the declaration that will be produced from |
2343 | | /// this declaration will be a function. |
2344 | | /// |
2345 | | /// A declaration can declare a function even if the declarator itself |
2346 | | /// isn't a function declarator, if the type specifier refers to a function |
2347 | | /// type. This routine checks for both cases. |
2348 | | bool isDeclarationOfFunction() const; |
2349 | | |
2350 | | /// Return true if this declaration appears in a context where a |
2351 | | /// function declarator would be a function declaration. |
2352 | 45.8M | bool isFunctionDeclarationContext() const { |
2353 | 45.8M | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) |
2354 | 1.14M | return false; |
2355 | | |
2356 | 44.7M | switch (Context) { |
2357 | 28.1M | case DeclaratorContext::File: |
2358 | 33.4M | case DeclaratorContext::Member: |
2359 | 34.1M | case DeclaratorContext::Block: |
2360 | 34.2M | case DeclaratorContext::ForInit: |
2361 | 34.2M | case DeclaratorContext::SelectionInit: |
2362 | 34.2M | return true; |
2363 | | |
2364 | 1.01k | case DeclaratorContext::Condition: |
2365 | 1.01k | case DeclaratorContext::KNRTypeList: |
2366 | 1.02M | case DeclaratorContext::TypeName: |
2367 | 1.33M | case DeclaratorContext::FunctionalCast: |
2368 | 1.36M | case DeclaratorContext::AliasDecl: |
2369 | 1.40M | case DeclaratorContext::AliasTemplate: |
2370 | 6.27M | case DeclaratorContext::Prototype: |
2371 | 6.27M | case DeclaratorContext::LambdaExprParameter: |
2372 | 6.49M | case DeclaratorContext::ObjCParameter: |
2373 | 6.57M | case DeclaratorContext::ObjCResult: |
2374 | 6.78M | case DeclaratorContext::TemplateParam: |
2375 | 6.78M | case DeclaratorContext::CXXNew: |
2376 | 6.78M | case DeclaratorContext::CXXCatch: |
2377 | 6.78M | case DeclaratorContext::ObjCCatch: |
2378 | 6.78M | case DeclaratorContext::BlockLiteral: |
2379 | 6.79M | case DeclaratorContext::LambdaExpr: |
2380 | 6.80M | case DeclaratorContext::ConversionId: |
2381 | 10.3M | case DeclaratorContext::TemplateArg: |
2382 | 10.4M | case DeclaratorContext::TemplateTypeArg: |
2383 | 10.4M | case DeclaratorContext::TrailingReturn: |
2384 | 10.4M | case DeclaratorContext::TrailingReturnVar: |
2385 | 10.4M | case DeclaratorContext::RequiresExpr: |
2386 | 10.4M | return false; |
2387 | 0 | } |
2388 | 0 | llvm_unreachable("unknown context kind!"); |
2389 | 0 | } |
2390 | | |
2391 | | /// Determine whether this declaration appears in a context where an |
2392 | | /// expression could appear. |
2393 | 379 | bool isExpressionContext() const { |
2394 | 379 | switch (Context) { |
2395 | 114 | case DeclaratorContext::File: |
2396 | 114 | case DeclaratorContext::KNRTypeList: |
2397 | 148 | case DeclaratorContext::Member: |
2398 | | |
2399 | | // FIXME: sizeof(...) permits an expression. |
2400 | 173 | case DeclaratorContext::TypeName: |
2401 | | |
2402 | 173 | case DeclaratorContext::FunctionalCast: |
2403 | 175 | case DeclaratorContext::AliasDecl: |
2404 | 175 | case DeclaratorContext::AliasTemplate: |
2405 | 234 | case DeclaratorContext::Prototype: |
2406 | 234 | case DeclaratorContext::LambdaExprParameter: |
2407 | 238 | case DeclaratorContext::ObjCParameter: |
2408 | 238 | case DeclaratorContext::ObjCResult: |
2409 | 243 | case DeclaratorContext::TemplateParam: |
2410 | 245 | case DeclaratorContext::CXXNew: |
2411 | 245 | case DeclaratorContext::CXXCatch: |
2412 | 245 | case DeclaratorContext::ObjCCatch: |
2413 | 245 | case DeclaratorContext::BlockLiteral: |
2414 | 245 | case DeclaratorContext::LambdaExpr: |
2415 | 245 | case DeclaratorContext::ConversionId: |
2416 | 245 | case DeclaratorContext::TrailingReturn: |
2417 | 246 | case DeclaratorContext::TrailingReturnVar: |
2418 | 246 | case DeclaratorContext::TemplateTypeArg: |
2419 | 246 | case DeclaratorContext::RequiresExpr: |
2420 | 246 | return false; |
2421 | | |
2422 | 116 | case DeclaratorContext::Block: |
2423 | 116 | case DeclaratorContext::ForInit: |
2424 | 119 | case DeclaratorContext::SelectionInit: |
2425 | 129 | case DeclaratorContext::Condition: |
2426 | 133 | case DeclaratorContext::TemplateArg: |
2427 | 133 | return true; |
2428 | 0 | } |
2429 | | |
2430 | 0 | llvm_unreachable("unknown context kind!"); |
2431 | 0 | } |
2432 | | |
2433 | | /// Return true if a function declarator at this position would be a |
2434 | | /// function declaration. |
2435 | 15.5M | bool isFunctionDeclaratorAFunctionDeclaration() const { |
2436 | 15.5M | if (!isFunctionDeclarationContext()) |
2437 | 278k | return false; |
2438 | | |
2439 | 15.2M | for (unsigned I = 0, N = getNumTypeObjects(); 15.2M I != N; ++I162 ) |
2440 | 155k | if (getTypeObject(I).Kind != DeclaratorChunk::Paren) |
2441 | 155k | return false; |
2442 | | |
2443 | 15.1M | return true; |
2444 | 15.2M | } |
2445 | | |
2446 | | /// Determine whether a trailing return type was written (at any |
2447 | | /// level) within this declarator. |
2448 | 34.6k | bool hasTrailingReturnType() const { |
2449 | 34.6k | for (const auto &Chunk : type_objects()) |
2450 | 21.7k | if (Chunk.Kind == DeclaratorChunk::Function && |
2451 | 19.8k | Chunk.Fun.hasTrailingReturnType()) |
2452 | 15.6k | return true; |
2453 | 19.0k | return false; |
2454 | 34.6k | } |
2455 | | /// Get the trailing return type appearing (at any level) within this |
2456 | | /// declarator. |
2457 | 15.6k | ParsedType getTrailingReturnType() const { |
2458 | 15.6k | for (const auto &Chunk : type_objects()) |
2459 | 15.8k | if (Chunk.Kind == DeclaratorChunk::Function && |
2460 | 15.6k | Chunk.Fun.hasTrailingReturnType()) |
2461 | 15.6k | return Chunk.Fun.getTrailingReturnType(); |
2462 | 0 | return ParsedType(); |
2463 | 15.6k | } |
2464 | | |
2465 | | /// \brief Sets a trailing requires clause for this declarator. |
2466 | 120 | void setTrailingRequiresClause(Expr *TRC) { |
2467 | 120 | TrailingRequiresClause = TRC; |
2468 | | |
2469 | 120 | SetRangeEnd(TRC->getEndLoc()); |
2470 | 120 | } |
2471 | | |
2472 | | /// \brief Sets a trailing requires clause for this declarator. |
2473 | 2.67M | Expr *getTrailingRequiresClause() { |
2474 | 2.67M | return TrailingRequiresClause; |
2475 | 2.67M | } |
2476 | | |
2477 | | /// \brief Determine whether a trailing requires clause was written in this |
2478 | | /// declarator. |
2479 | 1 | bool hasTrailingRequiresClause() const { |
2480 | 1 | return TrailingRequiresClause != nullptr; |
2481 | 1 | } |
2482 | | |
2483 | | /// Sets the template parameter lists that preceded the declarator. |
2484 | 689k | void setTemplateParameterLists(ArrayRef<TemplateParameterList *> TPLs) { |
2485 | 689k | TemplateParameterLists = TPLs; |
2486 | 689k | } |
2487 | | |
2488 | | /// The template parameter lists that preceded the declarator. |
2489 | 14.0M | ArrayRef<TemplateParameterList *> getTemplateParameterLists() const { |
2490 | 14.0M | return TemplateParameterLists; |
2491 | 14.0M | } |
2492 | | |
2493 | | /// Sets the template parameter list generated from the explicit template |
2494 | | /// parameters along with any invented template parameters from |
2495 | | /// placeholder-typed parameters. |
2496 | 75 | void setInventedTemplateParameterList(TemplateParameterList *Invented) { |
2497 | 75 | InventedTemplateParameterList = Invented; |
2498 | 75 | } |
2499 | | |
2500 | | /// The template parameter list generated from the explicit template |
2501 | | /// parameters along with any invented template parameters from |
2502 | | /// placeholder-typed parameters, if there were any such parameters. |
2503 | 14.0M | TemplateParameterList * getInventedTemplateParameterList() const { |
2504 | 14.0M | return InventedTemplateParameterList; |
2505 | 14.0M | } |
2506 | | |
2507 | | /// takeAttributes - Takes attributes from the given parsed-attributes |
2508 | | /// set and add them to this declarator. |
2509 | | /// |
2510 | | /// These examples both add 3 attributes to "var": |
2511 | | /// short int var __attribute__((aligned(16),common,deprecated)); |
2512 | | /// short int x, __attribute__((aligned(16)) var |
2513 | | /// __attribute__((common,deprecated)); |
2514 | | /// |
2515 | | /// Also extends the range of the declarator. |
2516 | 2.65M | void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) { |
2517 | 2.65M | Attrs.takeAllFrom(attrs); |
2518 | | |
2519 | 2.65M | if (!lastLoc.isInvalid()) |
2520 | 2.65M | SetRangeEnd(lastLoc); |
2521 | 2.65M | } |
2522 | | |
2523 | 59.6M | const ParsedAttributes &getAttributes() const { return Attrs; } |
2524 | 159M | ParsedAttributes &getAttributes() { return Attrs; } |
2525 | | |
2526 | | /// hasAttributes - do we contain any attributes? |
2527 | 0 | bool hasAttributes() const { |
2528 | 0 | if (!getAttributes().empty() || getDeclSpec().hasAttributes()) |
2529 | 0 | return true; |
2530 | 0 | for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i) |
2531 | 0 | if (!getTypeObject(i).getAttrs().empty()) |
2532 | 0 | return true; |
2533 | 0 | return false; |
2534 | 0 | } |
2535 | | |
2536 | | /// Return a source range list of C++11 attributes associated |
2537 | | /// with the declarator. |
2538 | 21.2k | void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { |
2539 | 21.2k | for (const ParsedAttr &AL : Attrs) |
2540 | 5 | if (AL.isCXX11Attribute()) |
2541 | 4 | Ranges.push_back(AL.getRange()); |
2542 | 21.2k | } |
2543 | | |
2544 | 59.9k | void setAsmLabel(Expr *E) { AsmLabel = E; } |
2545 | 16.7M | Expr *getAsmLabel() const { return AsmLabel; } |
2546 | | |
2547 | 75.2k | void setExtension(bool Val = true) { Extension = Val; } |
2548 | 0 | bool getExtension() const { return Extension; } |
2549 | | |
2550 | 177k | void setObjCIvar(bool Val = true) { ObjCIvar = Val; } |
2551 | 42.6M | bool isObjCIvar() const { return ObjCIvar; } |
2552 | | |
2553 | 457k | void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; } |
2554 | 42.5M | bool isObjCWeakProperty() const { return ObjCWeakProperty; } |
2555 | | |
2556 | 9.78k | void setInvalidType(bool Val = true) { InvalidType = Val; } |
2557 | 292M | bool isInvalidType() const { |
2558 | 292M | return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error292M ; |
2559 | 292M | } |
2560 | | |
2561 | 733k | void setGroupingParens(bool flag) { GroupingParens = flag; } |
2562 | 3.51M | bool hasGroupingParens() const { return GroupingParens; } |
2563 | | |
2564 | 172 | bool isFirstDeclarator() const { return !CommaLoc.isValid(); } |
2565 | 45 | SourceLocation getCommaLoc() const { return CommaLoc; } |
2566 | 3.25M | void setCommaLoc(SourceLocation CL) { CommaLoc = CL; } |
2567 | | |
2568 | 104M | bool hasEllipsis() const { return EllipsisLoc.isValid(); } |
2569 | 465k | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
2570 | 464k | void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } |
2571 | | |
2572 | 19.9M | void setFunctionDefinitionKind(FunctionDefinitionKind Val) { |
2573 | 19.9M | FunctionDefinition = static_cast<unsigned>(Val); |
2574 | 19.9M | } |
2575 | | |
2576 | 29.6M | bool isFunctionDefinition() const { |
2577 | 29.6M | return getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration; |
2578 | 29.6M | } |
2579 | | |
2580 | 86.1M | FunctionDefinitionKind getFunctionDefinitionKind() const { |
2581 | 86.1M | return (FunctionDefinitionKind)FunctionDefinition; |
2582 | 86.1M | } |
2583 | | |
2584 | 688k | void setHasInitializer(bool Val = true) { HasInitializer = Val; } |
2585 | 2.68M | bool hasInitializer() const { return HasInitializer; } |
2586 | | |
2587 | | /// Returns true if this declares a real member and not a friend. |
2588 | 19.6M | bool isFirstDeclarationOfMember() { |
2589 | 19.6M | return getContext() == DeclaratorContext::Member && |
2590 | 3.04M | !getDeclSpec().isFriendSpecified(); |
2591 | 19.6M | } |
2592 | | |
2593 | | /// Returns true if this declares a static member. This cannot be called on a |
2594 | | /// declarator outside of a MemberContext because we won't know until |
2595 | | /// redeclaration time if the decl is static. |
2596 | | bool isStaticMember(); |
2597 | | |
2598 | | /// Returns true if this declares a constructor or a destructor. |
2599 | | bool isCtorOrDtor(); |
2600 | | |
2601 | 19.0M | void setRedeclaration(bool Val) { Redeclaration = Val; } |
2602 | 49.7M | bool isRedeclaration() const { return Redeclaration; } |
2603 | | }; |
2604 | | |
2605 | | /// This little struct is used to capture information about |
2606 | | /// structure field declarators, which is basically just a bitfield size. |
2607 | | struct FieldDeclarator { |
2608 | | Declarator D; |
2609 | | Expr *BitfieldSize; |
2610 | | explicit FieldDeclarator(const DeclSpec &DS) |
2611 | 3.01M | : D(DS, DeclaratorContext::Member), BitfieldSize(nullptr) {} |
2612 | | }; |
2613 | | |
2614 | | /// Represents a C++11 virt-specifier-seq. |
2615 | | class VirtSpecifiers { |
2616 | | public: |
2617 | | enum Specifier { |
2618 | | VS_None = 0, |
2619 | | VS_Override = 1, |
2620 | | VS_Final = 2, |
2621 | | VS_Sealed = 4, |
2622 | | // Represents the __final keyword, which is legal for gcc in pre-C++11 mode. |
2623 | | VS_GNU_Final = 8 |
2624 | | }; |
2625 | | |
2626 | 2.41M | VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { } |
2627 | | |
2628 | | bool SetSpecifier(Specifier VS, SourceLocation Loc, |
2629 | | const char *&PrevSpec); |
2630 | | |
2631 | 7.23M | bool isUnset() const { return Specifiers == 0; } |
2632 | | |
2633 | 2.40M | bool isOverrideSpecified() const { return Specifiers & VS_Override; } |
2634 | 442 | SourceLocation getOverrideLoc() const { return VS_overrideLoc; } |
2635 | | |
2636 | 2.40M | bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed | VS_GNU_Final); } |
2637 | 89 | bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; } |
2638 | 89 | SourceLocation getFinalLoc() const { return VS_finalLoc; } |
2639 | | |
2640 | 22.1k | void clear() { Specifiers = 0; } |
2641 | | |
2642 | | static const char *getSpecifierName(Specifier VS); |
2643 | | |
2644 | 12 | SourceLocation getFirstLocation() const { return FirstLocation; } |
2645 | 2.40M | SourceLocation getLastLocation() const { return LastLocation; } |
2646 | 12 | Specifier getLastSpecifier() const { return LastSpecifier; } |
2647 | | |
2648 | | private: |
2649 | | unsigned Specifiers; |
2650 | | Specifier LastSpecifier; |
2651 | | |
2652 | | SourceLocation VS_overrideLoc, VS_finalLoc; |
2653 | | SourceLocation FirstLocation; |
2654 | | SourceLocation LastLocation; |
2655 | | }; |
2656 | | |
2657 | | enum class LambdaCaptureInitKind { |
2658 | | NoInit, //!< [a] |
2659 | | CopyInit, //!< [a = b], [a = {b}] |
2660 | | DirectInit, //!< [a(b)] |
2661 | | ListInit //!< [a{b}] |
2662 | | }; |
2663 | | |
2664 | | /// Represents a complete lambda introducer. |
2665 | | struct LambdaIntroducer { |
2666 | | /// An individual capture in a lambda introducer. |
2667 | | struct LambdaCapture { |
2668 | | LambdaCaptureKind Kind; |
2669 | | SourceLocation Loc; |
2670 | | IdentifierInfo *Id; |
2671 | | SourceLocation EllipsisLoc; |
2672 | | LambdaCaptureInitKind InitKind; |
2673 | | ExprResult Init; |
2674 | | ParsedType InitCaptureType; |
2675 | | SourceRange ExplicitRange; |
2676 | | |
2677 | | LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, |
2678 | | IdentifierInfo *Id, SourceLocation EllipsisLoc, |
2679 | | LambdaCaptureInitKind InitKind, ExprResult Init, |
2680 | | ParsedType InitCaptureType, |
2681 | | SourceRange ExplicitRange) |
2682 | | : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), |
2683 | | InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType), |
2684 | 2.00k | ExplicitRange(ExplicitRange) {} |
2685 | | }; |
2686 | | |
2687 | | SourceRange Range; |
2688 | | SourceLocation DefaultLoc; |
2689 | | LambdaCaptureDefault Default; |
2690 | | SmallVector<LambdaCapture, 4> Captures; |
2691 | | |
2692 | | LambdaIntroducer() |
2693 | 8.59k | : Default(LCD_None) {} |
2694 | | |
2695 | | /// Append a capture in a lambda introducer. |
2696 | | void addCapture(LambdaCaptureKind Kind, |
2697 | | SourceLocation Loc, |
2698 | | IdentifierInfo* Id, |
2699 | | SourceLocation EllipsisLoc, |
2700 | | LambdaCaptureInitKind InitKind, |
2701 | | ExprResult Init, |
2702 | | ParsedType InitCaptureType, |
2703 | 2.00k | SourceRange ExplicitRange) { |
2704 | 2.00k | Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, |
2705 | 2.00k | InitCaptureType, ExplicitRange)); |
2706 | 2.00k | } |
2707 | | }; |
2708 | | |
2709 | | struct InventedTemplateParameterInfo { |
2710 | | /// The number of parameters in the template parameter list that were |
2711 | | /// explicitly specified by the user, as opposed to being invented by use |
2712 | | /// of an auto parameter. |
2713 | | unsigned NumExplicitTemplateParams = 0; |
2714 | | |
2715 | | /// If this is a generic lambda or abbreviated function template, use this |
2716 | | /// as the depth of each 'auto' parameter, during initial AST construction. |
2717 | | unsigned AutoTemplateParameterDepth = 0; |
2718 | | |
2719 | | /// Store the list of the template parameters for a generic lambda or an |
2720 | | /// abbreviated function template. |
2721 | | /// If this is a generic lambda or abbreviated function template, this holds |
2722 | | /// the explicit template parameters followed by the auto parameters |
2723 | | /// converted into TemplateTypeParmDecls. |
2724 | | /// It can be used to construct the generic lambda or abbreviated template's |
2725 | | /// template parameter list during initial AST construction. |
2726 | | SmallVector<NamedDecl*, 4> TemplateParams; |
2727 | | }; |
2728 | | |
2729 | | } // end namespace clang |
2730 | | |
2731 | | #endif // LLVM_CLANG_SEMA_DECLSPEC_H |