Warning: That file was not part of the compilation database. It may have many parsing errors.

1//======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ParsedAttr class, which is used to collect
11// parsed attributes.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
17
18#include "clang/Basic/AttrSubjectMatchRules.h"
19#include "clang/Basic/SourceLocation.h"
20#include "clang/Basic/TargetInfo.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/VersionTuple.h"
27#include <cassert>
28#include <cstddef>
29#include <cstring>
30#include <utility>
31
32namespace clang {
33
34class ASTContext;
35class Decl;
36class Expr;
37class IdentifierInfo;
38class LangOptions;
39
40/// Represents information about a change in availability for
41/// an entity, which is part of the encoding of the 'availability'
42/// attribute.
43struct AvailabilityChange {
44 /// The location of the keyword indicating the kind of change.
45 SourceLocation KeywordLoc;
46
47 /// The version number at which the change occurred.
48 VersionTuple Version;
49
50 /// The source range covering the version number.
51 SourceRange VersionRange;
52
53 /// Determine whether this availability change is valid.
54 bool isValid() const { return !Version.empty(); }
55};
56
57namespace {
58
59enum AvailabilitySlot {
60 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
61};
62
63/// Describes the trailing object for Availability attribute in ParsedAttr.
64struct AvailabilityData {
65 AvailabilityChange Changes[NumAvailabilitySlots];
66 SourceLocation StrictLoc;
67 const Expr *Replacement;
68
69 AvailabilityData(const AvailabilityChange &Introduced,
70 const AvailabilityChange &Deprecated,
71 const AvailabilityChange &Obsoleted,
72 SourceLocation Strict, const Expr *ReplaceExpr)
73 : StrictLoc(Strict), Replacement(ReplaceExpr) {
74 Changes[IntroducedSlot] = Introduced;
75 Changes[DeprecatedSlot] = Deprecated;
76 Changes[ObsoletedSlot] = Obsoleted;
77 }
78};
79
80} // namespace
81
82/// Wraps an identifier and optional source location for the identifier.
83struct IdentifierLoc {
84 SourceLocation Loc;
85 IdentifierInfo *Ident;
86
87 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
88 IdentifierInfo *Ident);
89};
90
91/// A union of the various pointer types that can be passed to an
92/// ParsedAttr as an argument.
93using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
94using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
95
96/// ParsedAttr - Represents a syntactic attribute.
97///
98/// For a GNU attribute, there are four forms of this construct:
99///
100/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
101/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
102/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
103/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
104///
105class ParsedAttr { // TODO: This should really be called ParsedAttribute
106public:
107 /// The style used to specify an attribute.
108 enum Syntax {
109 /// __attribute__((...))
110 AS_GNU,
111
112 /// [[...]]
113 AS_CXX11,
114
115 /// [[...]]
116 AS_C2x,
117
118 /// __declspec(...)
119 AS_Declspec,
120
121 /// [uuid("...")] class Foo
122 AS_Microsoft,
123
124 /// __ptr16, alignas(...), etc.
125 AS_Keyword,
126
127 /// #pragma ...
128 AS_Pragma,
129
130 // Note TableGen depends on the order above. Do not add or change the order
131 // without adding related code to TableGen/ClangAttrEmitter.cpp.
132 /// Context-sensitive version of a keyword attribute.
133 AS_ContextSensitiveKeyword,
134 };
135
136private:
137 IdentifierInfo *AttrName;
138 IdentifierInfo *ScopeName;
139 SourceRange AttrRange;
140 SourceLocation ScopeLoc;
141 SourceLocation EllipsisLoc;
142
143 unsigned AttrKind : 16;
144
145 /// The number of expression arguments this attribute has.
146 /// The expressions themselves are stored after the object.
147 unsigned NumArgs : 16;
148
149 /// Corresponds to the Syntax enum.
150 unsigned SyntaxUsed : 3;
151
152 /// True if already diagnosed as invalid.
153 mutable unsigned Invalid : 1;
154
155 /// True if this attribute was used as a type attribute.
156 mutable unsigned UsedAsTypeAttr : 1;
157
158 /// True if this has the extra information associated with an
159 /// availability attribute.
160 unsigned IsAvailability : 1;
161
162 /// True if this has extra information associated with a
163 /// type_tag_for_datatype attribute.
164 unsigned IsTypeTagForDatatype : 1;
165
166 /// True if this has extra information associated with a
167 /// Microsoft __delcspec(property) attribute.
168 unsigned IsProperty : 1;
169
170 /// True if this has a ParsedType
171 unsigned HasParsedType : 1;
172
173 /// True if the processing cache is valid.
174 mutable unsigned HasProcessingCache : 1;
175
176 /// A cached value.
177 mutable unsigned ProcessingCache : 8;
178
179 /// The location of the 'unavailable' keyword in an
180 /// availability attribute.
181 SourceLocation UnavailableLoc;
182
183 const Expr *MessageExpr;
184
185 /// Arguments, if any, are stored immediately following the object.
186 ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
187 ArgsUnion const *getArgsBuffer() const {
188 return reinterpret_cast<ArgsUnion const *>(this + 1);
189 }
190
191 /// Availability information is stored immediately following the arguments,
192 /// if any, at the end of the object.
193 AvailabilityData *getAvailabilityData() {
194 return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
195 }
196 const AvailabilityData *getAvailabilityData() const {
197 return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
198 }
199
200public:
201 struct TypeTagForDatatypeData {
202 ParsedType *MatchingCType;
203 unsigned LayoutCompatible : 1;
204 unsigned MustBeNull : 1;
205 };
206 struct PropertyData {
207 IdentifierInfo *GetterId, *SetterId;
208
209 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
210 : GetterId(getterId), SetterId(setterId) {}
211 };
212
213private:
214 friend class AttributeFactory;
215 friend class AttributePool;
216
217 /// Constructor for attributes with expression arguments.
218 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
219 IdentifierInfo *scopeName, SourceLocation scopeLoc,
220 ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
221 SourceLocation ellipsisLoc)
222 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
223 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
224 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
225 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
226 HasParsedType(false), HasProcessingCache(false) {
227 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
228 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
229 }
230
231 /// Constructor for availability attributes.
232 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
233 IdentifierInfo *scopeName, SourceLocation scopeLoc,
234 IdentifierLoc *Parm, const AvailabilityChange &introduced,
235 const AvailabilityChange &deprecated,
236 const AvailabilityChange &obsoleted, SourceLocation unavailable,
237 const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
238 const Expr *replacementExpr)
239 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
240 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
241 UsedAsTypeAttr(false), IsAvailability(true),
242 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
243 HasProcessingCache(false), UnavailableLoc(unavailable),
244 MessageExpr(messageExpr) {
245 ArgsUnion PVal(Parm);
246 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
247 new (getAvailabilityData()) AvailabilityData(
248 introduced, deprecated, obsoleted, strict, replacementExpr);
249 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
250 }
251
252 /// Constructor for objc_bridge_related attributes.
253 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
254 IdentifierInfo *scopeName, SourceLocation scopeLoc,
255 IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
256 Syntax syntaxUsed)
257 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
258 ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
259 UsedAsTypeAttr(false), IsAvailability(false),
260 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
261 HasProcessingCache(false) {
262 ArgsUnion *Args = getArgsBuffer();
263 Args[0] = Parm1;
264 Args[1] = Parm2;
265 Args[2] = Parm3;
266 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
267 }
268
269 /// Constructor for type_tag_for_datatype attribute.
270 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
271 IdentifierInfo *scopeName, SourceLocation scopeLoc,
272 IdentifierLoc *ArgKind, ParsedType matchingCType,
273 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
274 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
275 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
276 UsedAsTypeAttr(false), IsAvailability(false),
277 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
278 HasProcessingCache(false) {
279 ArgsUnion PVal(ArgKind);
280 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
281 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
282 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
283 ExtraData.LayoutCompatible = layoutCompatible;
284 ExtraData.MustBeNull = mustBeNull;
285 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
286 }
287
288 /// Constructor for attributes with a single type argument.
289 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
290 IdentifierInfo *scopeName, SourceLocation scopeLoc,
291 ParsedType typeArg, Syntax syntaxUsed)
292 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
293 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
294 UsedAsTypeAttr(false), IsAvailability(false),
295 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
296 HasProcessingCache(false) {
297 new (&getTypeBuffer()) ParsedType(typeArg);
298 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
299 }
300
301 /// Constructor for microsoft __declspec(property) attribute.
302 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
303 IdentifierInfo *scopeName, SourceLocation scopeLoc,
304 IdentifierInfo *getterId, IdentifierInfo *setterId,
305 Syntax syntaxUsed)
306 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
307 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
308 UsedAsTypeAttr(false), IsAvailability(false),
309 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
310 HasProcessingCache(false) {
311 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
312 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
313 }
314
315 /// Type tag information is stored immediately following the arguments, if
316 /// any, at the end of the object. They are mutually exclusive with
317 /// availability slots.
318 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
319 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
320 }
321 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
322 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
323 + NumArgs);
324 }
325
326 /// The type buffer immediately follows the object and are mutually exclusive
327 /// with arguments.
328 ParsedType &getTypeBuffer() {
329 return *reinterpret_cast<ParsedType *>(this + 1);
330 }
331 const ParsedType &getTypeBuffer() const {
332 return *reinterpret_cast<const ParsedType *>(this + 1);
333 }
334
335 /// The property data immediately follows the object is is mutually exclusive
336 /// with arguments.
337 PropertyData &getPropertyDataBuffer() {
338 assert(IsProperty);
339 return *reinterpret_cast<PropertyData*>(this + 1);
340 }
341 const PropertyData &getPropertyDataBuffer() const {
342 assert(IsProperty);
343 return *reinterpret_cast<const PropertyData*>(this + 1);
344 }
345
346 size_t allocated_size() const;
347
348public:
349 ParsedAttr(const ParsedAttr &) = delete;
350 ParsedAttr &operator=(const ParsedAttr &) = delete;
351 ~ParsedAttr() = delete;
352
353 void operator delete(void *) = delete;
354
355 enum Kind {
356 #define PARSED_ATTR(NAME) AT_##NAME,
357 #include "clang/Sema/AttrParsedAttrList.inc"
358 #undef PARSED_ATTR
359 IgnoredAttribute,
360 UnknownAttribute
361 };
362
363 IdentifierInfo *getName() const { return AttrName; }
364 SourceLocation getLoc() const { return AttrRange.getBegin(); }
365 SourceRange getRange() const { return AttrRange; }
366
367 bool hasScope() const { return ScopeName; }
368 IdentifierInfo *getScopeName() const { return ScopeName; }
369 SourceLocation getScopeLoc() const { return ScopeLoc; }
370
371 bool hasParsedType() const { return HasParsedType; }
372
373 /// Is this the Microsoft __declspec(property) attribute?
374 bool isDeclspecPropertyAttribute() const {
375 return IsProperty;
376 }
377
378 bool isAlignasAttribute() const {
379 // FIXME: Use a better mechanism to determine this.
380 return getKind() == AT_Aligned && isKeywordAttribute();
381 }
382
383 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
384 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
385
386 bool isCXX11Attribute() const {
387 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
388 }
389
390 bool isC2xAttribute() const {
391 return SyntaxUsed == AS_C2x;
392 }
393
394 bool isKeywordAttribute() const {
395 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
396 }
397
398 bool isContextSensitiveKeywordAttribute() const {
399 return SyntaxUsed == AS_ContextSensitiveKeyword;
400 }
401
402 bool isInvalid() const { return Invalid; }
403 void setInvalid(bool b = true) const { Invalid = b; }
404
405 bool hasProcessingCache() const { return HasProcessingCache; }
406
407 unsigned getProcessingCache() const {
408 assert(hasProcessingCache());
409 return ProcessingCache;
410 }
411
412 void setProcessingCache(unsigned value) const {
413 ProcessingCache = value;
414 HasProcessingCache = true;
415 }
416
417 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
418 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
419
420 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
421 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
422
423 Kind getKind() const { return Kind(AttrKind); }
424 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
425 Syntax SyntaxUsed);
426
427 /// getNumArgs - Return the number of actual arguments to this attribute.
428 unsigned getNumArgs() const { return NumArgs; }
429
430 /// getArg - Return the specified argument.
431 ArgsUnion getArg(unsigned Arg) const {
432 assert(Arg < NumArgs && "Arg access out of range!");
433 return getArgsBuffer()[Arg];
434 }
435
436 bool isArgExpr(unsigned Arg) const {
437 return Arg < NumArgs && getArg(Arg).is<Expr*>();
438 }
439
440 Expr *getArgAsExpr(unsigned Arg) const {
441 return getArg(Arg).get<Expr*>();
442 }
443
444 bool isArgIdent(unsigned Arg) const {
445 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
446 }
447
448 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
449 return getArg(Arg).get<IdentifierLoc*>();
450 }
451
452 const AvailabilityChange &getAvailabilityIntroduced() const {
453 assert(getKind() == AT_Availability && "Not an availability attribute");
454 return getAvailabilityData()->Changes[IntroducedSlot];
455 }
456
457 const AvailabilityChange &getAvailabilityDeprecated() const {
458 assert(getKind() == AT_Availability && "Not an availability attribute");
459 return getAvailabilityData()->Changes[DeprecatedSlot];
460 }
461
462 const AvailabilityChange &getAvailabilityObsoleted() const {
463 assert(getKind() == AT_Availability && "Not an availability attribute");
464 return getAvailabilityData()->Changes[ObsoletedSlot];
465 }
466
467 SourceLocation getStrictLoc() const {
468 assert(getKind() == AT_Availability && "Not an availability attribute");
469 return getAvailabilityData()->StrictLoc;
470 }
471
472 SourceLocation getUnavailableLoc() const {
473 assert(getKind() == AT_Availability && "Not an availability attribute");
474 return UnavailableLoc;
475 }
476
477 const Expr * getMessageExpr() const {
478 assert(getKind() == AT_Availability && "Not an availability attribute");
479 return MessageExpr;
480 }
481
482 const Expr *getReplacementExpr() const {
483 assert(getKind() == AT_Availability && "Not an availability attribute");
484 return getAvailabilityData()->Replacement;
485 }
486
487 const ParsedType &getMatchingCType() const {
488 assert(getKind() == AT_TypeTagForDatatype &&
489 "Not a type_tag_for_datatype attribute");
490 return *getTypeTagForDatatypeDataSlot().MatchingCType;
491 }
492
493 bool getLayoutCompatible() const {
494 assert(getKind() == AT_TypeTagForDatatype &&
495 "Not a type_tag_for_datatype attribute");
496 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
497 }
498
499 bool getMustBeNull() const {
500 assert(getKind() == AT_TypeTagForDatatype &&
501 "Not a type_tag_for_datatype attribute");
502 return getTypeTagForDatatypeDataSlot().MustBeNull;
503 }
504
505 const ParsedType &getTypeArg() const {
506 assert(HasParsedType && "Not a type attribute");
507 return getTypeBuffer();
508 }
509
510 const PropertyData &getPropertyData() const {
511 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
512 return getPropertyDataBuffer();
513 }
514
515 /// Get an index into the attribute spelling list
516 /// defined in Attr.td. This index is used by an attribute
517 /// to pretty print itself.
518 unsigned getAttributeSpellingListIndex() const;
519
520 bool isTargetSpecificAttr() const;
521 bool isTypeAttr() const;
522 bool isStmtAttr() const;
523
524 bool hasCustomParsing() const;
525 unsigned getMinArgs() const;
526 unsigned getMaxArgs() const;
527 bool hasVariadicArg() const;
528 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
529 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
530 void getMatchRules(const LangOptions &LangOpts,
531 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
532 &MatchRules) const;
533 bool diagnoseLangOpts(class Sema &S) const;
534 bool existsInTarget(const TargetInfo &Target) const;
535 bool isKnownToGCC() const;
536 bool isSupportedByPragmaAttribute() const;
537
538 /// If the parsed attribute has a semantic equivalent, and it would
539 /// have a semantic Spelling enumeration (due to having semantically-distinct
540 /// spelling variations), return the value of that semantic spelling. If the
541 /// parsed attribute does not have a semantic equivalent, or would not have
542 /// a Spelling enumeration, the value UINT_MAX is returned.
543 unsigned getSemanticSpelling() const;
544};
545
546class AttributePool;
547/// A factory, from which one makes pools, from which one creates
548/// individual attributes which are deallocated with the pool.
549///
550/// Note that it's tolerably cheap to create and destroy one of
551/// these as long as you don't actually allocate anything in it.
552class AttributeFactory {
553public:
554 enum {
555 /// The required allocation size of an availability attribute,
556 /// which we want to ensure is a multiple of sizeof(void*).
557 AvailabilityAllocSize =
558 sizeof(ParsedAttr) +
559 ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
560 sizeof(void *) * sizeof(void *)),
561 TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
562 (sizeof(ParsedAttr::TypeTagForDatatypeData) +
563 sizeof(void *) + sizeof(ArgsUnion) - 1) /
564 sizeof(void *) * sizeof(void *),
565 PropertyAllocSize =
566 sizeof(ParsedAttr) +
567 (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
568 sizeof(void *) * sizeof(void *)
569 };
570
571private:
572 enum {
573 /// The number of free lists we want to be sure to support
574 /// inline. This is just enough that availability attributes
575 /// don't surpass it. It's actually very unlikely we'll see an
576 /// attribute that needs more than that; on x86-64 you'd need 10
577 /// expression arguments, and on i386 you'd need 19.
578 InlineFreeListsCapacity =
579 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
580 };
581
582 llvm::BumpPtrAllocator Alloc;
583
584 /// Free lists. The index is determined by the following formula:
585 /// (size - sizeof(ParsedAttr)) / sizeof(void*)
586 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
587
588 // The following are the private interface used by AttributePool.
589 friend class AttributePool;
590
591 /// Allocate an attribute of the given size.
592 void *allocate(size_t size);
593
594 void deallocate(ParsedAttr *AL);
595
596 /// Reclaim all the attributes in the given pool chain, which is
597 /// non-empty. Note that the current implementation is safe
598 /// against reclaiming things which were not actually allocated
599 /// with the allocator, although of course it's important to make
600 /// sure that their allocator lives at least as long as this one.
601 void reclaimPool(AttributePool &head);
602
603public:
604 AttributeFactory();
605 ~AttributeFactory();
606};
607
608class AttributePool {
609 friend class AttributeFactory;
610 AttributeFactory &Factory;
611 llvm::TinyPtrVector<ParsedAttr *> Attrs;
612
613 void *allocate(size_t size) {
614 return Factory.allocate(size);
615 }
616
617 ParsedAttr *add(ParsedAttr *attr) {
618 Attrs.push_back(attr);
619 return attr;
620 }
621
622 void remove(ParsedAttr *attr) {
623 assert(llvm::is_contained(Attrs, attr) &&
624 "Can't take attribute from a pool that doesn't own it!");
625 Attrs.erase(llvm::find(Attrs, attr));
626 }
627
628 void takePool(AttributePool &pool);
629
630public:
631 /// Create a new pool for a factory.
632 AttributePool(AttributeFactory &factory) : Factory(factory) {}
633
634 AttributePool(const AttributePool &) = delete;
635
636 ~AttributePool() { Factory.reclaimPool(*this); }
637
638 /// Move the given pool's allocations to this pool.
639 AttributePool(AttributePool &&pool) = default;
640
641 AttributeFactory &getFactory() const { return Factory; }
642
643 void clear() {
644 Factory.reclaimPool(*this);
645 Attrs.clear();
646 }
647
648 /// Take the given pool's allocations and add them to this pool.
649 void takeAllFrom(AttributePool &pool) {
650 takePool(pool);
651 pool.Attrs.clear();
652 }
653
654 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
655 IdentifierInfo *scopeName, SourceLocation scopeLoc,
656 ArgsUnion *args, unsigned numArgs,
657 ParsedAttr::Syntax syntax,
658 SourceLocation ellipsisLoc = SourceLocation()) {
659 void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
660 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
661 args, numArgs, syntax, ellipsisLoc));
662 }
663
664 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
665 IdentifierInfo *scopeName, SourceLocation scopeLoc,
666 IdentifierLoc *Param, const AvailabilityChange &introduced,
667 const AvailabilityChange &deprecated,
668 const AvailabilityChange &obsoleted,
669 SourceLocation unavailable, const Expr *MessageExpr,
670 ParsedAttr::Syntax syntax, SourceLocation strict,
671 const Expr *ReplacementExpr) {
672 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
673 return add(new (memory) ParsedAttr(
674 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
675 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
676 }
677
678 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
679 IdentifierInfo *scopeName, SourceLocation scopeLoc,
680 IdentifierLoc *Param1, IdentifierLoc *Param2,
681 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
682 size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
683 void *memory = allocate(size);
684 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
685 Param1, Param2, Param3, syntax));
686 }
687
688 ParsedAttr *
689 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
690 IdentifierInfo *scopeName, SourceLocation scopeLoc,
691 IdentifierLoc *argumentKind,
692 ParsedType matchingCType, bool layoutCompatible,
693 bool mustBeNull, ParsedAttr::Syntax syntax) {
694 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
695 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
696 argumentKind, matchingCType,
697 layoutCompatible, mustBeNull, syntax));
698 }
699
700 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
701 SourceRange attrRange,
702 IdentifierInfo *scopeName,
703 SourceLocation scopeLoc, ParsedType typeArg,
704 ParsedAttr::Syntax syntaxUsed) {
705 void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
706 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
707 typeArg, syntaxUsed));
708 }
709
710 ParsedAttr *
711 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
712 IdentifierInfo *scopeName, SourceLocation scopeLoc,
713 IdentifierInfo *getterId, IdentifierInfo *setterId,
714 ParsedAttr::Syntax syntaxUsed) {
715 void *memory = allocate(AttributeFactory::PropertyAllocSize);
716 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
717 getterId, setterId, syntaxUsed));
718 }
719};
720
721class ParsedAttributesView {
722 using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
723 using SizeType = decltype(std::declval<VecTy>().size());
724
725public:
726 bool empty() const { return AttrList.empty(); }
727 SizeType size() const { return AttrList.size(); }
728 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
729 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
730
731 void addAtStart(ParsedAttr *newAttr) {
732 assert(newAttr);
733 AttrList.insert(AttrList.begin(), newAttr);
734 }
735 void addAtEnd(ParsedAttr *newAttr) {
736 assert(newAttr);
737 AttrList.push_back(newAttr);
738 }
739
740 void remove(ParsedAttr *ToBeRemoved) {
741 assert(is_contained(AttrList, ToBeRemoved) &&
742 "Cannot remove attribute that isn't in the list");
743 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
744 }
745
746 void clearListOnly() { AttrList.clear(); }
747
748 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
749 std::random_access_iterator_tag,
750 ParsedAttr> {
751 iterator() : iterator_adaptor_base(nullptr) {}
752 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
753 reference operator*() { return **I; }
754 friend class ParsedAttributesView;
755 };
756 struct const_iterator
757 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
758 std::random_access_iterator_tag,
759 ParsedAttr> {
760 const_iterator() : iterator_adaptor_base(nullptr) {}
761 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
762
763 reference operator*() const { return **I; }
764 friend class ParsedAttributesView;
765 };
766
767 void addAll(iterator B, iterator E) {
768 AttrList.insert(AttrList.begin(), B.I, E.I);
769 }
770
771 void addAll(const_iterator B, const_iterator E) {
772 AttrList.insert(AttrList.begin(), B.I, E.I);
773 }
774
775 void addAllAtEnd(iterator B, iterator E) {
776 AttrList.insert(AttrList.end(), B.I, E.I);
777 }
778
779 void addAllAtEnd(const_iterator B, const_iterator E) {
780 AttrList.insert(AttrList.end(), B.I, E.I);
781 }
782
783 iterator begin() { return iterator(AttrList.begin()); }
784 const_iterator begin() const { return const_iterator(AttrList.begin()); }
785 iterator end() { return iterator(AttrList.end()); }
786 const_iterator end() const { return const_iterator(AttrList.end()); }
787
788 bool hasAttribute(ParsedAttr::Kind K) const {
789 return llvm::any_of(
790 AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
791 }
792
793private:
794 VecTy AttrList;
795};
796
797/// ParsedAttributes - A collection of parsed attributes. Currently
798/// we don't differentiate between the various attribute syntaxes,
799/// which is basically silly.
800///
801/// Right now this is a very lightweight container, but the expectation
802/// is that this will become significantly more serious.
803class ParsedAttributes : public ParsedAttributesView {
804public:
805 ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
806 ParsedAttributes(const ParsedAttributes &) = delete;
807
808 AttributePool &getPool() const { return pool; }
809
810 void takeAllFrom(ParsedAttributes &attrs) {
811 addAll(attrs.begin(), attrs.end());
812 attrs.clearListOnly();
813 pool.takeAllFrom(attrs.pool);
814 }
815
816 void clear() {
817 clearListOnly();
818 pool.clear();
819 }
820
821 /// Add attribute with expression arguments.
822 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
823 IdentifierInfo *scopeName, SourceLocation scopeLoc,
824 ArgsUnion *args, unsigned numArgs,
825 ParsedAttr::Syntax syntax,
826 SourceLocation ellipsisLoc = SourceLocation()) {
827 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
828 args, numArgs, syntax, ellipsisLoc);
829 addAtStart(attr);
830 return attr;
831 }
832
833 /// Add availability attribute.
834 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
835 IdentifierInfo *scopeName, SourceLocation scopeLoc,
836 IdentifierLoc *Param, const AvailabilityChange &introduced,
837 const AvailabilityChange &deprecated,
838 const AvailabilityChange &obsoleted,
839 SourceLocation unavailable, const Expr *MessageExpr,
840 ParsedAttr::Syntax syntax, SourceLocation strict,
841 const Expr *ReplacementExpr) {
842 ParsedAttr *attr = pool.create(
843 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
844 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
845 addAtStart(attr);
846 return attr;
847 }
848
849 /// Add objc_bridge_related attribute.
850 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
851 IdentifierInfo *scopeName, SourceLocation scopeLoc,
852 IdentifierLoc *Param1, IdentifierLoc *Param2,
853 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
854 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
855 Param1, Param2, Param3, syntax);
856 addAtStart(attr);
857 return attr;
858 }
859
860 /// Add type_tag_for_datatype attribute.
861 ParsedAttr *
862 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
863 IdentifierInfo *scopeName, SourceLocation scopeLoc,
864 IdentifierLoc *argumentKind,
865 ParsedType matchingCType, bool layoutCompatible,
866 bool mustBeNull, ParsedAttr::Syntax syntax) {
867 ParsedAttr *attr = pool.createTypeTagForDatatype(
868 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
869 layoutCompatible, mustBeNull, syntax);
870 addAtStart(attr);
871 return attr;
872 }
873
874 /// Add an attribute with a single type argument.
875 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
876 IdentifierInfo *scopeName, SourceLocation scopeLoc,
877 ParsedType typeArg,
878 ParsedAttr::Syntax syntaxUsed) {
879 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
880 scopeLoc, typeArg, syntaxUsed);
881 addAtStart(attr);
882 return attr;
883 }
884
885 /// Add microsoft __delspec(property) attribute.
886 ParsedAttr *
887 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
888 IdentifierInfo *scopeName, SourceLocation scopeLoc,
889 IdentifierInfo *getterId, IdentifierInfo *setterId,
890 ParsedAttr::Syntax syntaxUsed) {
891 ParsedAttr *attr =
892 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
893 getterId, setterId, syntaxUsed);
894 addAtStart(attr);
895 return attr;
896 }
897
898private:
899 mutable AttributePool pool;
900};
901
902/// These constants match the enumerated choices of
903/// err_attribute_argument_n_type and err_attribute_argument_type.
904enum AttributeArgumentNType {
905 AANT_ArgumentIntOrBool,
906 AANT_ArgumentIntegerConstant,
907 AANT_ArgumentString,
908 AANT_ArgumentIdentifier
909};
910
911/// These constants match the enumerated choices of
912/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
913enum AttributeDeclKind {
914 ExpectedFunction,
915 ExpectedUnion,
916 ExpectedVariableOrFunction,
917 ExpectedFunctionOrMethod,
918 ExpectedFunctionMethodOrBlock,
919 ExpectedFunctionMethodOrParameter,
920 ExpectedVariable,
921 ExpectedVariableOrField,
922 ExpectedVariableFieldOrTag,
923 ExpectedTypeOrNamespace,
924 ExpectedFunctionVariableOrClass,
925 ExpectedKernelFunction,
926 ExpectedFunctionWithProtoType,
927};
928
929} // namespace clang
930
931#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
932

Warning: That file was not part of the compilation database. It may have many parsing errors.