1//======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ParsedAttr class, which is used to collect
10// parsed attributes.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
15#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16
17#include "clang/Basic/AttrSubjectMatchRules.h"
18#include "clang/Basic/AttributeCommonInfo.h"
19#include "clang/Basic/Diagnostic.h"
20#include "clang/Basic/SourceLocation.h"
21#include "clang/Sema/Ownership.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/TinyPtrVector.h"
25#include "llvm/Support/Allocator.h"
26#include "llvm/Support/Registry.h"
27#include "llvm/Support/VersionTuple.h"
28#include <cassert>
29#include <cstddef>
30#include <cstring>
31#include <utility>
32
33namespace clang {
34
35class ASTContext;
36class Decl;
37class Expr;
38class IdentifierInfo;
39class LangOptions;
40class ParsedAttr;
41class Sema;
42class Stmt;
43class TargetInfo;
44
45struct ParsedAttrInfo {
46 /// Corresponds to the Kind enum.
47 unsigned AttrKind : 16;
48 /// The number of required arguments of this attribute.
49 unsigned NumArgs : 4;
50 /// The number of optional arguments of this attributes.
51 unsigned OptArgs : 4;
52 /// True if the parsing does not match the semantic content.
53 unsigned HasCustomParsing : 1;
54 /// True if this attribute is only available for certain targets.
55 unsigned IsTargetSpecific : 1;
56 /// True if this attribute applies to types.
57 unsigned IsType : 1;
58 /// True if this attribute applies to statements.
59 unsigned IsStmt : 1;
60 /// True if this attribute has any spellings that are known to gcc.
61 unsigned IsKnownToGCC : 1;
62 /// True if this attribute is supported by #pragma clang attribute.
63 unsigned IsSupportedByPragmaAttribute : 1;
64 /// The syntaxes supported by this attribute and how they're spelled.
65 struct Spelling {
66 AttributeCommonInfo::Syntax Syntax;
67 const char *NormalizedFullName;
68 };
69 ArrayRef<Spelling> Spellings;
70
71 ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
72 AttributeCommonInfo::NoSemaHandlerAttribute)
73 : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0),
74 IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0),
75 IsSupportedByPragmaAttribute(0) {}
76
77 virtual ~ParsedAttrInfo() = default;
78
79 /// Check if this attribute appertains to D, and issue a diagnostic if not.
80 virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
81 const Decl *D) const {
82 return true;
83 }
84 /// Check if this attribute appertains to St, and issue a diagnostic if not.
85 virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
86 const Stmt *St) const {
87 return true;
88 }
89 /// Check if the given attribute is mutually exclusive with other attributes
90 /// already applied to the given declaration.
91 virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
92 const Decl *D) const {
93 return true;
94 }
95 /// Check if this attribute is allowed by the language we are compiling, and
96 /// issue a diagnostic if not.
97 virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const {
98 return true;
99 }
100 /// Check if this attribute is allowed when compiling for the given target.
101 virtual bool existsInTarget(const TargetInfo &Target) const {
102 return true;
103 }
104 /// Convert the spelling index of Attr to a semantic spelling enum value.
105 virtual unsigned
106 spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
107 return UINT_MAX;
108 }
109 /// Populate Rules with the match rules of this attribute.
110 virtual void getPragmaAttributeMatchRules(
111 llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
112 const LangOptions &LangOpts) const {
113 }
114 enum AttrHandling {
115 NotHandled,
116 AttributeApplied,
117 AttributeNotApplied
118 };
119 /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
120 /// Decl then do so and return either AttributeApplied if it was applied or
121 /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
122 virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
123 const ParsedAttr &Attr) const {
124 return NotHandled;
125 }
126
127 static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
128};
129
130typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
131
132/// Represents information about a change in availability for
133/// an entity, which is part of the encoding of the 'availability'
134/// attribute.
135struct AvailabilityChange {
136 /// The location of the keyword indicating the kind of change.
137 SourceLocation KeywordLoc;
138
139 /// The version number at which the change occurred.
140 VersionTuple Version;
141
142 /// The source range covering the version number.
143 SourceRange VersionRange;
144
145 /// Determine whether this availability change is valid.
146 bool isValid() const { return !Version.empty(); }
147};
148
149namespace detail {
150enum AvailabilitySlot {
151 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
152};
153
154/// Describes the trailing object for Availability attribute in ParsedAttr.
155struct AvailabilityData {
156 AvailabilityChange Changes[NumAvailabilitySlots];
157 SourceLocation StrictLoc;
158 const Expr *Replacement;
159
160 AvailabilityData(const AvailabilityChange &Introduced,
161 const AvailabilityChange &Deprecated,
162 const AvailabilityChange &Obsoleted,
163 SourceLocation Strict, const Expr *ReplaceExpr)
164 : StrictLoc(Strict), Replacement(ReplaceExpr) {
165 Changes[IntroducedSlot] = Introduced;
166 Changes[DeprecatedSlot] = Deprecated;
167 Changes[ObsoletedSlot] = Obsoleted;
168 }
169};
170
171struct TypeTagForDatatypeData {
172 ParsedType MatchingCType;
173 unsigned LayoutCompatible : 1;
174 unsigned MustBeNull : 1;
175};
176struct PropertyData {
177 IdentifierInfo *GetterId, *SetterId;
178
179 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
180 : GetterId(getterId), SetterId(setterId) {}
181};
182
183} // namespace
184
185/// Wraps an identifier and optional source location for the identifier.
186struct IdentifierLoc {
187 SourceLocation Loc;
188 IdentifierInfo *Ident;
189
190 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
191 IdentifierInfo *Ident);
192};
193
194/// A union of the various pointer types that can be passed to an
195/// ParsedAttr as an argument.
196using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
197using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
198
199/// ParsedAttr - Represents a syntactic attribute.
200///
201/// For a GNU attribute, there are four forms of this construct:
202///
203/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
204/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
205/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
206/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
207///
208class ParsedAttr final
209 : public AttributeCommonInfo,
210 private llvm::TrailingObjects<
211 ParsedAttr, ArgsUnion, detail::AvailabilityData,
212 detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
213 friend TrailingObjects;
214
215 size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
216 size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
217 return IsAvailability;
218 }
219 size_t
220 numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
221 return IsTypeTagForDatatype;
222 }
223 size_t numTrailingObjects(OverloadToken<ParsedType>) const {
224 return HasParsedType;
225 }
226 size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
227 return IsProperty;
228 }
229
230private:
231 IdentifierInfo *MacroII = nullptr;
232 SourceLocation MacroExpansionLoc;
233 SourceLocation EllipsisLoc;
234
235 /// The number of expression arguments this attribute has.
236 /// The expressions themselves are stored after the object.
237 unsigned NumArgs : 16;
238
239 /// True if already diagnosed as invalid.
240 mutable unsigned Invalid : 1;
241
242 /// True if this attribute was used as a type attribute.
243 mutable unsigned UsedAsTypeAttr : 1;
244
245 /// True if this has the extra information associated with an
246 /// availability attribute.
247 unsigned IsAvailability : 1;
248
249 /// True if this has extra information associated with a
250 /// type_tag_for_datatype attribute.
251 unsigned IsTypeTagForDatatype : 1;
252
253 /// True if this has extra information associated with a
254 /// Microsoft __delcspec(property) attribute.
255 unsigned IsProperty : 1;
256
257 /// True if this has a ParsedType
258 unsigned HasParsedType : 1;
259
260 /// True if the processing cache is valid.
261 mutable unsigned HasProcessingCache : 1;
262
263 /// A cached value.
264 mutable unsigned ProcessingCache : 8;
265
266 /// True if the attribute is specified using '#pragma clang attribute'.
267 mutable unsigned IsPragmaClangAttribute : 1;
268
269 /// The location of the 'unavailable' keyword in an
270 /// availability attribute.
271 SourceLocation UnavailableLoc;
272
273 const Expr *MessageExpr;
274
275 const ParsedAttrInfo &Info;
276
277 ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
278 ArgsUnion const *getArgsBuffer() const {
279 return getTrailingObjects<ArgsUnion>();
280 }
281
282 detail::AvailabilityData *getAvailabilityData() {
283 return getTrailingObjects<detail::AvailabilityData>();
284 }
285 const detail::AvailabilityData *getAvailabilityData() const {
286 return getTrailingObjects<detail::AvailabilityData>();
287 }
288
289private:
290 friend class AttributeFactory;
291 friend class AttributePool;
292
293 /// Constructor for attributes with expression arguments.
294 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
295 IdentifierInfo *scopeName, SourceLocation scopeLoc,
296 ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
297 SourceLocation ellipsisLoc)
298 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
299 syntaxUsed),
300 EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
301 UsedAsTypeAttr(false), IsAvailability(false),
302 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
303 HasProcessingCache(false), IsPragmaClangAttribute(false),
304 Info(ParsedAttrInfo::get(*this)) {
305 if (numArgs)
306 memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
307 }
308
309 /// Constructor for availability attributes.
310 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
311 IdentifierInfo *scopeName, SourceLocation scopeLoc,
312 IdentifierLoc *Parm, const AvailabilityChange &introduced,
313 const AvailabilityChange &deprecated,
314 const AvailabilityChange &obsoleted, SourceLocation unavailable,
315 const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
316 const Expr *replacementExpr)
317 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
318 syntaxUsed),
319 NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
320 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
321 HasProcessingCache(false), IsPragmaClangAttribute(false),
322 UnavailableLoc(unavailable), MessageExpr(messageExpr),
323 Info(ParsedAttrInfo::get(*this)) {
324 ArgsUnion PVal(Parm);
325 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
326 new (getAvailabilityData()) detail::AvailabilityData(
327 introduced, deprecated, obsoleted, strict, replacementExpr);
328 }
329
330 /// Constructor for objc_bridge_related attributes.
331 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
332 IdentifierInfo *scopeName, SourceLocation scopeLoc,
333 IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
334 Syntax syntaxUsed)
335 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
336 syntaxUsed),
337 NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
338 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
339 HasParsedType(false), HasProcessingCache(false),
340 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
341 ArgsUnion *Args = getArgsBuffer();
342 Args[0] = Parm1;
343 Args[1] = Parm2;
344 Args[2] = Parm3;
345 }
346
347 /// Constructor for type_tag_for_datatype attribute.
348 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
349 IdentifierInfo *scopeName, SourceLocation scopeLoc,
350 IdentifierLoc *ArgKind, ParsedType matchingCType,
351 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
352 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
353 syntaxUsed),
354 NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
355 IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
356 HasParsedType(false), HasProcessingCache(false),
357 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
358 ArgsUnion PVal(ArgKind);
359 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
360 detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
361 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
362 ExtraData.LayoutCompatible = layoutCompatible;
363 ExtraData.MustBeNull = mustBeNull;
364 }
365
366 /// Constructor for attributes with a single type argument.
367 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
368 IdentifierInfo *scopeName, SourceLocation scopeLoc,
369 ParsedType typeArg, Syntax syntaxUsed)
370 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
371 syntaxUsed),
372 NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
373 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
374 HasParsedType(true), HasProcessingCache(false),
375 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
376 new (&getTypeBuffer()) ParsedType(typeArg);
377 }
378
379 /// Constructor for microsoft __declspec(property) attribute.
380 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
381 IdentifierInfo *scopeName, SourceLocation scopeLoc,
382 IdentifierInfo *getterId, IdentifierInfo *setterId,
383 Syntax syntaxUsed)
384 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
385 syntaxUsed),
386 NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
387 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
388 HasParsedType(false), HasProcessingCache(false),
389 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
390 new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
391 }
392
393 /// Type tag information is stored immediately following the arguments, if
394 /// any, at the end of the object. They are mutually exclusive with
395 /// availability slots.
396 detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
397 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
398 }
399 const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
400 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
401 }
402
403 /// The type buffer immediately follows the object and are mutually exclusive
404 /// with arguments.
405 ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
406 const ParsedType &getTypeBuffer() const {
407 return *getTrailingObjects<ParsedType>();
408 }
409
410 /// The property data immediately follows the object is is mutually exclusive
411 /// with arguments.
412 detail::PropertyData &getPropertyDataBuffer() {
413 assert(IsProperty);
414 return *getTrailingObjects<detail::PropertyData>();
415 }
416 const detail::PropertyData &getPropertyDataBuffer() const {
417 assert(IsProperty);
418 return *getTrailingObjects<detail::PropertyData>();
419 }
420
421 size_t allocated_size() const;
422
423public:
424 ParsedAttr(const ParsedAttr &) = delete;
425 ParsedAttr(ParsedAttr &&) = delete;
426 ParsedAttr &operator=(const ParsedAttr &) = delete;
427 ParsedAttr &operator=(ParsedAttr &&) = delete;
428 ~ParsedAttr() = delete;
429
430 void operator delete(void *) = delete;
431
432 bool hasParsedType() const { return HasParsedType; }
433
434 /// Is this the Microsoft __declspec(property) attribute?
435 bool isDeclspecPropertyAttribute() const {
436 return IsProperty;
437 }
438
439 bool isInvalid() const { return Invalid; }
440 void setInvalid(bool b = true) const { Invalid = b; }
441
442 bool hasProcessingCache() const { return HasProcessingCache; }
443
444 unsigned getProcessingCache() const {
445 assert(hasProcessingCache());
446 return ProcessingCache;
447 }
448
449 void setProcessingCache(unsigned value) const {
450 ProcessingCache = value;
451 HasProcessingCache = true;
452 }
453
454 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
455 void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; }
456
457 /// True if the attribute is specified using '#pragma clang attribute'.
458 bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; }
459
460 void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; }
461
462 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
463 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
464
465 /// getNumArgs - Return the number of actual arguments to this attribute.
466 unsigned getNumArgs() const { return NumArgs; }
467
468 /// getArg - Return the specified argument.
469 ArgsUnion getArg(unsigned Arg) const {
470 assert(Arg < NumArgs && "Arg access out of range!");
471 return getArgsBuffer()[Arg];
472 }
473
474 bool isArgExpr(unsigned Arg) const {
475 return Arg < NumArgs && getArg(Arg).is<Expr*>();
476 }
477
478 Expr *getArgAsExpr(unsigned Arg) const {
479 return getArg(Arg).get<Expr*>();
480 }
481
482 bool isArgIdent(unsigned Arg) const {
483 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
484 }
485
486 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
487 return getArg(Arg).get<IdentifierLoc*>();
488 }
489
490 const AvailabilityChange &getAvailabilityIntroduced() const {
491 assert(getParsedKind() == AT_Availability &&
492 "Not an availability attribute");
493 return getAvailabilityData()->Changes[detail::IntroducedSlot];
494 }
495
496 const AvailabilityChange &getAvailabilityDeprecated() const {
497 assert(getParsedKind() == AT_Availability &&
498 "Not an availability attribute");
499 return getAvailabilityData()->Changes[detail::DeprecatedSlot];
500 }
501
502 const AvailabilityChange &getAvailabilityObsoleted() const {
503 assert(getParsedKind() == AT_Availability &&
504 "Not an availability attribute");
505 return getAvailabilityData()->Changes[detail::ObsoletedSlot];
506 }
507
508 SourceLocation getStrictLoc() const {
509 assert(getParsedKind() == AT_Availability &&
510 "Not an availability attribute");
511 return getAvailabilityData()->StrictLoc;
512 }
513
514 SourceLocation getUnavailableLoc() const {
515 assert(getParsedKind() == AT_Availability &&
516 "Not an availability attribute");
517 return UnavailableLoc;
518 }
519
520 const Expr * getMessageExpr() const {
521 assert(getParsedKind() == AT_Availability &&
522 "Not an availability attribute");
523 return MessageExpr;
524 }
525
526 const Expr *getReplacementExpr() const {
527 assert(getParsedKind() == AT_Availability &&
528 "Not an availability attribute");
529 return getAvailabilityData()->Replacement;
530 }
531
532 const ParsedType &getMatchingCType() const {
533 assert(getParsedKind() == AT_TypeTagForDatatype &&
534 "Not a type_tag_for_datatype attribute");
535 return getTypeTagForDatatypeDataSlot().MatchingCType;
536 }
537
538 bool getLayoutCompatible() const {
539 assert(getParsedKind() == AT_TypeTagForDatatype &&
540 "Not a type_tag_for_datatype attribute");
541 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
542 }
543
544 bool getMustBeNull() const {
545 assert(getParsedKind() == AT_TypeTagForDatatype &&
546 "Not a type_tag_for_datatype attribute");
547 return getTypeTagForDatatypeDataSlot().MustBeNull;
548 }
549
550 const ParsedType &getTypeArg() const {
551 assert(HasParsedType && "Not a type attribute");
552 return getTypeBuffer();
553 }
554
555 IdentifierInfo *getPropertyDataGetter() const {
556 assert(isDeclspecPropertyAttribute() &&
557 "Not a __delcspec(property) attribute");
558 return getPropertyDataBuffer().GetterId;
559 }
560
561 IdentifierInfo *getPropertyDataSetter() const {
562 assert(isDeclspecPropertyAttribute() &&
563 "Not a __delcspec(property) attribute");
564 return getPropertyDataBuffer().SetterId;
565 }
566
567 /// Set the macro identifier info object that this parsed attribute was
568 /// declared in if it was declared in a macro. Also set the expansion location
569 /// of the macro.
570 void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) {
571 MacroII = MacroName;
572 MacroExpansionLoc = Loc;
573 }
574
575 /// Returns true if this attribute was declared in a macro.
576 bool hasMacroIdentifier() const { return MacroII != nullptr; }
577
578 /// Return the macro identifier if this attribute was declared in a macro.
579 /// nullptr is returned if it was not declared in a macro.
580 IdentifierInfo *getMacroIdentifier() const { return MacroII; }
581
582 SourceLocation getMacroExpansionLoc() const {
583 assert(hasMacroIdentifier() && "Can only get the macro expansion location "
584 "if this attribute has a macro identifier.");
585 return MacroExpansionLoc;
586 }
587
588 /// Check if the attribute has exactly as many args as Num. May output an
589 /// error. Returns false if a diagnostic is produced.
590 bool checkExactlyNumArgs(class Sema &S, unsigned Num) const;
591 /// Check if the attribute has at least as many args as Num. May output an
592 /// error. Returns false if a diagnostic is produced.
593 bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const;
594 /// Check if the attribute has at most as many args as Num. May output an
595 /// error. Returns false if a diagnostic is produced.
596 bool checkAtMostNumArgs(class Sema &S, unsigned Num) const;
597
598 bool isTargetSpecificAttr() const;
599 bool isTypeAttr() const;
600 bool isStmtAttr() const;
601
602 bool hasCustomParsing() const;
603 unsigned getMinArgs() const;
604 unsigned getMaxArgs() const;
605 bool hasVariadicArg() const;
606 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
607 bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const;
608 bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const;
609 // This function stub exists for parity with the declaration checking code so
610 // that checkCommonAttributeFeatures() can work generically on declarations
611 // or statements.
612 bool diagnoseMutualExclusion(class Sema &S, const Stmt *St) const {
613 return true;
614 }
615 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
616 void getMatchRules(const LangOptions &LangOpts,
617 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
618 &MatchRules) const;
619 bool diagnoseLangOpts(class Sema &S) const;
620 bool existsInTarget(const TargetInfo &Target) const;
621 bool isKnownToGCC() const;
622 bool isSupportedByPragmaAttribute() const;
623
624 /// If the parsed attribute has a semantic equivalent, and it would
625 /// have a semantic Spelling enumeration (due to having semantically-distinct
626 /// spelling variations), return the value of that semantic spelling. If the
627 /// parsed attribute does not have a semantic equivalent, or would not have
628 /// a Spelling enumeration, the value UINT_MAX is returned.
629 unsigned getSemanticSpelling() const;
630
631 /// If this is an OpenCL address space attribute returns its representation
632 /// in LangAS, otherwise returns default address space.
633 LangAS asOpenCLLangAS() const {
634 switch (getParsedKind()) {
635 case ParsedAttr::AT_OpenCLConstantAddressSpace:
636 return LangAS::opencl_constant;
637 case ParsedAttr::AT_OpenCLGlobalAddressSpace:
638 return LangAS::opencl_global;
639 case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
640 return LangAS::opencl_global_device;
641 case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
642 return LangAS::opencl_global_host;
643 case ParsedAttr::AT_OpenCLLocalAddressSpace:
644 return LangAS::opencl_local;
645 case ParsedAttr::AT_OpenCLPrivateAddressSpace:
646 return LangAS::opencl_private;
647 case ParsedAttr::AT_OpenCLGenericAddressSpace:
648 return LangAS::opencl_generic;
649 default:
650 return LangAS::Default;
651 }
652 }
653
654 /// If this is an OpenCL address space attribute returns its SYCL
655 /// representation in LangAS, otherwise returns default address space.
656 LangAS asSYCLLangAS() const {
657 switch (getKind()) {
658 case ParsedAttr::AT_OpenCLGlobalAddressSpace:
659 return LangAS::sycl_global;
660 case ParsedAttr::AT_OpenCLLocalAddressSpace:
661 return LangAS::sycl_local;
662 case ParsedAttr::AT_OpenCLPrivateAddressSpace:
663 return LangAS::sycl_private;
664 case ParsedAttr::AT_OpenCLGenericAddressSpace:
665 default:
666 return LangAS::Default;
667 }
668 }
669
670 AttributeCommonInfo::Kind getKind() const {
671 return AttributeCommonInfo::Kind(Info.AttrKind);
672 }
673 const ParsedAttrInfo &getInfo() const { return Info; }
674};
675
676class AttributePool;
677/// A factory, from which one makes pools, from which one creates
678/// individual attributes which are deallocated with the pool.
679///
680/// Note that it's tolerably cheap to create and destroy one of
681/// these as long as you don't actually allocate anything in it.
682class AttributeFactory {
683public:
684 enum {
685 AvailabilityAllocSize =
686 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
687 detail::TypeTagForDatatypeData, ParsedType,
688 detail::PropertyData>(1, 1, 0, 0, 0),
689 TypeTagForDatatypeAllocSize =
690 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
691 detail::TypeTagForDatatypeData, ParsedType,
692 detail::PropertyData>(1, 0, 1, 0, 0),
693 PropertyAllocSize =
694 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
695 detail::TypeTagForDatatypeData, ParsedType,
696 detail::PropertyData>(0, 0, 0, 0, 1),
697 };
698
699private:
700 enum {
701 /// The number of free lists we want to be sure to support
702 /// inline. This is just enough that availability attributes
703 /// don't surpass it. It's actually very unlikely we'll see an
704 /// attribute that needs more than that; on x86-64 you'd need 10
705 /// expression arguments, and on i386 you'd need 19.
706 InlineFreeListsCapacity =
707 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
708 };
709
710 llvm::BumpPtrAllocator Alloc;
711
712 /// Free lists. The index is determined by the following formula:
713 /// (size - sizeof(ParsedAttr)) / sizeof(void*)
714 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
715
716 // The following are the private interface used by AttributePool.
717 friend class AttributePool;
718
719 /// Allocate an attribute of the given size.
720 void *allocate(size_t size);
721
722 void deallocate(ParsedAttr *AL);
723
724 /// Reclaim all the attributes in the given pool chain, which is
725 /// non-empty. Note that the current implementation is safe
726 /// against reclaiming things which were not actually allocated
727 /// with the allocator, although of course it's important to make
728 /// sure that their allocator lives at least as long as this one.
729 void reclaimPool(AttributePool &head);
730
731public:
732 AttributeFactory();
733 ~AttributeFactory();
734};
735
736class AttributePool {
737 friend class AttributeFactory;
738 friend class ParsedAttributes;
739 AttributeFactory &Factory;
740 llvm::TinyPtrVector<ParsedAttr *> Attrs;
741
742 void *allocate(size_t size) {
743 return Factory.allocate(size);
744 }
745
746 ParsedAttr *add(ParsedAttr *attr) {
747 Attrs.push_back(attr);
748 return attr;
749 }
750
751 void remove(ParsedAttr *attr) {
752 assert(llvm::is_contained(Attrs, attr) &&
753 "Can't take attribute from a pool that doesn't own it!");
754 Attrs.erase(llvm::find(Attrs, attr));
755 }
756
757 void takePool(AttributePool &pool);
758
759public:
760 /// Create a new pool for a factory.
761 AttributePool(AttributeFactory &factory) : Factory(factory) {}
762
763 AttributePool(const AttributePool &) = delete;
764
765 ~AttributePool() { Factory.reclaimPool(*this); }
766
767 /// Move the given pool's allocations to this pool.
768 AttributePool(AttributePool &&pool) = default;
769
770 AttributeFactory &getFactory() const { return Factory; }
771
772 void clear() {
773 Factory.reclaimPool(*this);
774 Attrs.clear();
775 }
776
777 /// Take the given pool's allocations and add them to this pool.
778 void takeAllFrom(AttributePool &pool) {
779 takePool(pool);
780 pool.Attrs.clear();
781 }
782
783 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
784 IdentifierInfo *scopeName, SourceLocation scopeLoc,
785 ArgsUnion *args, unsigned numArgs,
786 ParsedAttr::Syntax syntax,
787 SourceLocation ellipsisLoc = SourceLocation()) {
788 size_t temp =
789 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
790 detail::TypeTagForDatatypeData, ParsedType,
791 detail::PropertyData>(numArgs, 0, 0, 0, 0);
792 (void)temp;
793 void *memory = allocate(
794 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
795 detail::TypeTagForDatatypeData, ParsedType,
796 detail::PropertyData>(numArgs, 0, 0, 0,
797 0));
798 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
799 args, numArgs, syntax, ellipsisLoc));
800 }
801
802 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
803 IdentifierInfo *scopeName, SourceLocation scopeLoc,
804 IdentifierLoc *Param, const AvailabilityChange &introduced,
805 const AvailabilityChange &deprecated,
806 const AvailabilityChange &obsoleted,
807 SourceLocation unavailable, const Expr *MessageExpr,
808 ParsedAttr::Syntax syntax, SourceLocation strict,
809 const Expr *ReplacementExpr) {
810 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
811 return add(new (memory) ParsedAttr(
812 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
813 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
814 }
815
816 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
817 IdentifierInfo *scopeName, SourceLocation scopeLoc,
818 IdentifierLoc *Param1, IdentifierLoc *Param2,
819 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
820 void *memory = allocate(
821 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
822 detail::TypeTagForDatatypeData, ParsedType,
823 detail::PropertyData>(3, 0, 0, 0, 0));
824 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
825 Param1, Param2, Param3, syntax));
826 }
827
828 ParsedAttr *
829 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
830 IdentifierInfo *scopeName, SourceLocation scopeLoc,
831 IdentifierLoc *argumentKind,
832 ParsedType matchingCType, bool layoutCompatible,
833 bool mustBeNull, ParsedAttr::Syntax syntax) {
834 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
835 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
836 argumentKind, matchingCType,
837 layoutCompatible, mustBeNull, syntax));
838 }
839
840 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
841 SourceRange attrRange,
842 IdentifierInfo *scopeName,
843 SourceLocation scopeLoc, ParsedType typeArg,
844 ParsedAttr::Syntax syntaxUsed) {
845 void *memory = allocate(
846 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
847 detail::TypeTagForDatatypeData, ParsedType,
848 detail::PropertyData>(0, 0, 0, 1, 0));
849 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
850 typeArg, syntaxUsed));
851 }
852
853 ParsedAttr *
854 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
855 IdentifierInfo *scopeName, SourceLocation scopeLoc,
856 IdentifierInfo *getterId, IdentifierInfo *setterId,
857 ParsedAttr::Syntax syntaxUsed) {
858 void *memory = allocate(AttributeFactory::PropertyAllocSize);
859 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
860 getterId, setterId, syntaxUsed));
861 }
862};
863
864class ParsedAttributesView {
865 using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
866 using SizeType = decltype(std::declval<VecTy>().size());
867
868public:
869 bool empty() const { return AttrList.empty(); }
870 SizeType size() const { return AttrList.size(); }
871 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
872 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
873
874 void addAtEnd(ParsedAttr *newAttr) {
875 assert(newAttr);
876 AttrList.push_back(newAttr);
877 }
878
879 void remove(ParsedAttr *ToBeRemoved) {
880 assert(is_contained(AttrList, ToBeRemoved) &&
881 "Cannot remove attribute that isn't in the list");
882 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
883 }
884
885 void clearListOnly() { AttrList.clear(); }
886
887 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
888 std::random_access_iterator_tag,
889 ParsedAttr> {
890 iterator() : iterator_adaptor_base(nullptr) {}
891 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
892 reference operator*() { return **I; }
893 friend class ParsedAttributesView;
894 };
895 struct const_iterator
896 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
897 std::random_access_iterator_tag,
898 ParsedAttr> {
899 const_iterator() : iterator_adaptor_base(nullptr) {}
900 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
901
902 reference operator*() const { return **I; }
903 friend class ParsedAttributesView;
904 };
905
906 void addAll(iterator B, iterator E) {
907 AttrList.insert(AttrList.begin(), B.I, E.I);
908 }
909
910 void addAll(const_iterator B, const_iterator E) {
911 AttrList.insert(AttrList.begin(), B.I, E.I);
912 }
913
914 void addAllAtEnd(iterator B, iterator E) {
915 AttrList.insert(AttrList.end(), B.I, E.I);
916 }
917
918 void addAllAtEnd(const_iterator B, const_iterator E) {
919 AttrList.insert(AttrList.end(), B.I, E.I);
920 }
921
922 iterator begin() { return iterator(AttrList.begin()); }
923 const_iterator begin() const { return const_iterator(AttrList.begin()); }
924 iterator end() { return iterator(AttrList.end()); }
925 const_iterator end() const { return const_iterator(AttrList.end()); }
926
927 ParsedAttr &front() {
928 assert(!empty());
929 return *AttrList.front();
930 }
931 const ParsedAttr &front() const {
932 assert(!empty());
933 return *AttrList.front();
934 }
935 ParsedAttr &back() {
936 assert(!empty());
937 return *AttrList.back();
938 }
939 const ParsedAttr &back() const {
940 assert(!empty());
941 return *AttrList.back();
942 }
943
944 bool hasAttribute(ParsedAttr::Kind K) const {
945 return llvm::any_of(AttrList, [K](const ParsedAttr *AL) {
946 return AL->getParsedKind() == K;
947 });
948 }
949
950private:
951 VecTy AttrList;
952};
953
954/// ParsedAttributes - A collection of parsed attributes. Currently
955/// we don't differentiate between the various attribute syntaxes,
956/// which is basically silly.
957///
958/// Right now this is a very lightweight container, but the expectation
959/// is that this will become significantly more serious.
960class ParsedAttributes : public ParsedAttributesView {
961public:
962 ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
963 ParsedAttributes(const ParsedAttributes &) = delete;
964
965 AttributePool &getPool() const { return pool; }
966
967 void takeAllFrom(ParsedAttributes &attrs) {
968 addAll(attrs.begin(), attrs.end());
969 attrs.clearListOnly();
970 pool.takeAllFrom(attrs.pool);
971 }
972
973 void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) {
974 Attrs.getPool().remove(PA);
975 Attrs.remove(PA);
976 getPool().add(PA);
977 addAtEnd(PA);
978 }
979
980 void clear() {
981 clearListOnly();
982 pool.clear();
983 }
984
985 /// Add attribute with expression arguments.
986 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
987 IdentifierInfo *scopeName, SourceLocation scopeLoc,
988 ArgsUnion *args, unsigned numArgs,
989 ParsedAttr::Syntax syntax,
990 SourceLocation ellipsisLoc = SourceLocation()) {
991 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
992 args, numArgs, syntax, ellipsisLoc);
993 addAtEnd(attr);
994 return attr;
995 }
996
997 /// Add availability attribute.
998 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
999 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1000 IdentifierLoc *Param, const AvailabilityChange &introduced,
1001 const AvailabilityChange &deprecated,
1002 const AvailabilityChange &obsoleted,
1003 SourceLocation unavailable, const Expr *MessageExpr,
1004 ParsedAttr::Syntax syntax, SourceLocation strict,
1005 const Expr *ReplacementExpr) {
1006 ParsedAttr *attr = pool.create(
1007 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
1008 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
1009 addAtEnd(attr);
1010 return attr;
1011 }
1012
1013 /// Add objc_bridge_related attribute.
1014 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
1015 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1016 IdentifierLoc *Param1, IdentifierLoc *Param2,
1017 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
1018 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
1019 Param1, Param2, Param3, syntax);
1020 addAtEnd(attr);
1021 return attr;
1022 }
1023
1024 /// Add type_tag_for_datatype attribute.
1025 ParsedAttr *
1026 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
1027 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1028 IdentifierLoc *argumentKind,
1029 ParsedType matchingCType, bool layoutCompatible,
1030 bool mustBeNull, ParsedAttr::Syntax syntax) {
1031 ParsedAttr *attr = pool.createTypeTagForDatatype(
1032 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
1033 layoutCompatible, mustBeNull, syntax);
1034 addAtEnd(attr);
1035 return attr;
1036 }
1037
1038 /// Add an attribute with a single type argument.
1039 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
1040 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1041 ParsedType typeArg,
1042 ParsedAttr::Syntax syntaxUsed) {
1043 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
1044 scopeLoc, typeArg, syntaxUsed);
1045 addAtEnd(attr);
1046 return attr;
1047 }
1048
1049 /// Add microsoft __delspec(property) attribute.
1050 ParsedAttr *
1051 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
1052 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1053 IdentifierInfo *getterId, IdentifierInfo *setterId,
1054 ParsedAttr::Syntax syntaxUsed) {
1055 ParsedAttr *attr =
1056 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
1057 getterId, setterId, syntaxUsed);
1058 addAtEnd(attr);
1059 return attr;
1060 }
1061
1062private:
1063 mutable AttributePool pool;
1064};
1065
1066struct ParsedAttributesWithRange : ParsedAttributes {
1067 ParsedAttributesWithRange(AttributeFactory &factory)
1068 : ParsedAttributes(factory) {}
1069
1070 void clear() {
1071 ParsedAttributes::clear();
1072 Range = SourceRange();
1073 }
1074
1075 SourceRange Range;
1076};
1077struct ParsedAttributesViewWithRange : ParsedAttributesView {
1078 ParsedAttributesViewWithRange() : ParsedAttributesView() {}
1079 void clearListOnly() {
1080 ParsedAttributesView::clearListOnly();
1081 Range = SourceRange();
1082 }
1083
1084 SourceRange Range;
1085};
1086
1087/// These constants match the enumerated choices of
1088/// err_attribute_argument_n_type and err_attribute_argument_type.
1089enum AttributeArgumentNType {
1090 AANT_ArgumentIntOrBool,
1091 AANT_ArgumentIntegerConstant,
1092 AANT_ArgumentString,
1093 AANT_ArgumentIdentifier,
1094 AANT_ArgumentConstantExpr,
1095};
1096
1097/// These constants match the enumerated choices of
1098/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
1099enum AttributeDeclKind {
1100 ExpectedFunction,
1101 ExpectedUnion,
1102 ExpectedVariableOrFunction,
1103 ExpectedFunctionOrMethod,
1104 ExpectedFunctionMethodOrBlock,
1105 ExpectedFunctionMethodOrParameter,
1106 ExpectedVariable,
1107 ExpectedVariableOrField,
1108 ExpectedVariableFieldOrTag,
1109 ExpectedTypeOrNamespace,
1110 ExpectedFunctionVariableOrClass,
1111 ExpectedKernelFunction,
1112 ExpectedFunctionWithProtoType,
1113};
1114
1115inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1116 const ParsedAttr &At) {
1117 DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
1118 DiagnosticsEngine::ak_identifierinfo);
1119 return DB;
1120}
1121
1122inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1123 const ParsedAttr *At) {
1124 DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
1125 DiagnosticsEngine::ak_identifierinfo);
1126 return DB;
1127}
1128
1129/// AttributeCommonInfo has a non-explicit constructor which takes an
1130/// SourceRange as its only argument, this constructor has many uses so making
1131/// it explicit is hard. This constructor causes ambiguity with
1132/// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R).
1133/// We use SFINAE to disable any conversion and remove any ambiguity.
1134template <typename ACI,
1135 typename std::enable_if_t<
1136 std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1137inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1138 const ACI &CI) {
1139 DB.AddTaggedVal(reinterpret_cast<intptr_t>(CI.getAttrName()),
1140 DiagnosticsEngine::ak_identifierinfo);
1141 return DB;
1142}
1143
1144template <typename ACI,
1145 typename std::enable_if_t<
1146 std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1147inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1148 const ACI* CI) {
1149 DB.AddTaggedVal(reinterpret_cast<intptr_t>(CI->getAttrName()),
1150 DiagnosticsEngine::ak_identifierinfo);
1151 return DB;
1152}
1153
1154} // namespace clang
1155
1156#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
1157