Coverage Report

Created: 2018-07-12 09:57

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