Coverage Report

Created: 2020-02-18 08:44

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