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