1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
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/Diagnostic.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 | |
32 | namespace clang { |
33 | |
34 | class ASTContext; |
35 | class Decl; |
36 | class Expr; |
37 | class IdentifierInfo; |
38 | class LangOptions; |
39 | |
40 | |
41 | |
42 | |
43 | struct AvailabilityChange { |
44 | |
45 | SourceLocation KeywordLoc; |
46 | |
47 | |
48 | VersionTuple Version; |
49 | |
50 | |
51 | SourceRange VersionRange; |
52 | |
53 | |
54 | bool isValid() const { return !Version.empty(); } |
55 | }; |
56 | |
57 | namespace detail { |
58 | enum AvailabilitySlot { |
59 | IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots |
60 | }; |
61 | |
62 | |
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 | : StrictLoc(Strict), Replacement(ReplaceExpr) { |
73 | Changes[IntroducedSlot] = Introduced; |
74 | Changes[DeprecatedSlot] = Deprecated; |
75 | Changes[ObsoletedSlot] = Obsoleted; |
76 | } |
77 | }; |
78 | |
79 | struct TypeTagForDatatypeData { |
80 | ParsedType MatchingCType; |
81 | unsigned LayoutCompatible : 1; |
82 | unsigned MustBeNull : 1; |
83 | }; |
84 | struct PropertyData { |
85 | IdentifierInfo *GetterId, *SetterId; |
86 | |
87 | PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId) |
88 | : GetterId(getterId), SetterId(setterId) {} |
89 | }; |
90 | |
91 | } |
92 | |
93 | |
94 | struct IdentifierLoc { |
95 | SourceLocation Loc; |
96 | IdentifierInfo *Ident; |
97 | |
98 | static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, |
99 | IdentifierInfo *Ident); |
100 | }; |
101 | |
102 | |
103 | |
104 | using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>; |
105 | using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>; |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | class ParsedAttr final |
117 | : private llvm::TrailingObjects< |
118 | ParsedAttr, ArgsUnion, detail::AvailabilityData, |
119 | detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> { |
120 | friend TrailingObjects; |
121 | |
122 | size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; } |
123 | size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const { |
124 | return IsAvailability; |
125 | } |
126 | size_t |
127 | numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const { |
128 | return IsTypeTagForDatatype; |
129 | } |
130 | size_t numTrailingObjects(OverloadToken<ParsedType>) const { |
131 | return HasParsedType; |
132 | } |
133 | size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const { |
134 | return IsProperty; |
135 | } |
136 | |
137 | public: |
138 | |
139 | enum Syntax { |
140 | |
141 | AS_GNU, |
142 | |
143 | |
144 | AS_CXX11, |
145 | |
146 | |
147 | AS_C2x, |
148 | |
149 | |
150 | AS_Declspec, |
151 | |
152 | |
153 | AS_Microsoft, |
154 | |
155 | |
156 | AS_Keyword, |
157 | |
158 | |
159 | AS_Pragma, |
160 | |
161 | |
162 | |
163 | |
164 | AS_ContextSensitiveKeyword, |
165 | }; |
166 | |
167 | private: |
168 | IdentifierInfo *AttrName; |
169 | IdentifierInfo *ScopeName; |
170 | SourceRange AttrRange; |
171 | SourceLocation ScopeLoc; |
172 | SourceLocation EllipsisLoc; |
173 | |
174 | unsigned AttrKind : 16; |
175 | |
176 | |
177 | |
178 | unsigned NumArgs : 16; |
179 | |
180 | |
181 | unsigned SyntaxUsed : 3; |
182 | |
183 | |
184 | mutable unsigned Invalid : 1; |
185 | |
186 | |
187 | mutable unsigned UsedAsTypeAttr : 1; |
188 | |
189 | |
190 | |
191 | unsigned IsAvailability : 1; |
192 | |
193 | |
194 | |
195 | unsigned IsTypeTagForDatatype : 1; |
196 | |
197 | |
198 | |
199 | unsigned IsProperty : 1; |
200 | |
201 | |
202 | unsigned HasParsedType : 1; |
203 | |
204 | |
205 | mutable unsigned HasProcessingCache : 1; |
206 | |
207 | |
208 | mutable unsigned ProcessingCache : 8; |
209 | |
210 | |
211 | mutable unsigned IsPragmaClangAttribute : 1; |
212 | |
213 | |
214 | |
215 | SourceLocation UnavailableLoc; |
216 | |
217 | const Expr *MessageExpr; |
218 | |
219 | ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); } |
220 | ArgsUnion const *getArgsBuffer() const { |
221 | return getTrailingObjects<ArgsUnion>(); |
222 | } |
223 | |
224 | detail::AvailabilityData *getAvailabilityData() { |
225 | return getTrailingObjects<detail::AvailabilityData>(); |
226 | } |
227 | const detail::AvailabilityData *getAvailabilityData() const { |
228 | return getTrailingObjects<detail::AvailabilityData>(); |
229 | } |
230 | |
231 | private: |
232 | friend class AttributeFactory; |
233 | friend class AttributePool; |
234 | |
235 | |
236 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
237 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
238 | ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed, |
239 | SourceLocation ellipsisLoc) |
240 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
241 | ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), |
242 | SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), |
243 | IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), |
244 | HasParsedType(false), HasProcessingCache(false), |
245 | IsPragmaClangAttribute(false) { |
246 | if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); |
247 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
248 | } |
249 | |
250 | |
251 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
252 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
253 | IdentifierLoc *Parm, const AvailabilityChange &introduced, |
254 | const AvailabilityChange &deprecated, |
255 | const AvailabilityChange &obsoleted, SourceLocation unavailable, |
256 | const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict, |
257 | const Expr *replacementExpr) |
258 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
259 | ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), |
260 | UsedAsTypeAttr(false), IsAvailability(true), |
261 | IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), |
262 | HasProcessingCache(false), IsPragmaClangAttribute(false), |
263 | UnavailableLoc(unavailable), MessageExpr(messageExpr) { |
264 | ArgsUnion PVal(Parm); |
265 | memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); |
266 | new (getAvailabilityData()) detail::AvailabilityData( |
267 | introduced, deprecated, obsoleted, strict, replacementExpr); |
268 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
269 | } |
270 | |
271 | |
272 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
273 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
274 | IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3, |
275 | Syntax syntaxUsed) |
276 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
277 | ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false), |
278 | UsedAsTypeAttr(false), IsAvailability(false), |
279 | IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), |
280 | HasProcessingCache(false), IsPragmaClangAttribute(false) { |
281 | ArgsUnion *Args = getArgsBuffer(); |
282 | Args[0] = Parm1; |
283 | Args[1] = Parm2; |
284 | Args[2] = Parm3; |
285 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
286 | } |
287 | |
288 | |
289 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
290 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
291 | IdentifierLoc *ArgKind, ParsedType matchingCType, |
292 | bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) |
293 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
294 | ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), |
295 | UsedAsTypeAttr(false), IsAvailability(false), |
296 | IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), |
297 | HasProcessingCache(false), IsPragmaClangAttribute(false) { |
298 | ArgsUnion PVal(ArgKind); |
299 | memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); |
300 | detail::TypeTagForDatatypeData & = getTypeTagForDatatypeDataSlot(); |
301 | new (&ExtraData.MatchingCType) ParsedType(matchingCType); |
302 | ExtraData.LayoutCompatible = layoutCompatible; |
303 | ExtraData.MustBeNull = mustBeNull; |
304 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
305 | } |
306 | |
307 | |
308 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
309 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
310 | ParsedType typeArg, Syntax syntaxUsed) |
311 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
312 | ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), |
313 | UsedAsTypeAttr(false), IsAvailability(false), |
314 | IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), |
315 | HasProcessingCache(false), IsPragmaClangAttribute(false) { |
316 | new (&getTypeBuffer()) ParsedType(typeArg); |
317 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
318 | } |
319 | |
320 | |
321 | ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, |
322 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
323 | IdentifierInfo *getterId, IdentifierInfo *setterId, |
324 | Syntax syntaxUsed) |
325 | : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), |
326 | ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), |
327 | UsedAsTypeAttr(false), IsAvailability(false), |
328 | IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), |
329 | HasProcessingCache(false), IsPragmaClangAttribute(false) { |
330 | new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId); |
331 | AttrKind = getKind(getName(), getScopeName(), syntaxUsed); |
332 | } |
333 | |
334 | |
335 | |
336 | |
337 | detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { |
338 | return *getTrailingObjects<detail::TypeTagForDatatypeData>(); |
339 | } |
340 | const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { |
341 | return *getTrailingObjects<detail::TypeTagForDatatypeData>(); |
342 | } |
343 | |
344 | |
345 | |
346 | ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); } |
347 | const ParsedType &getTypeBuffer() const { |
348 | return *getTrailingObjects<ParsedType>(); |
349 | } |
350 | |
351 | |
352 | |
353 | detail::PropertyData &getPropertyDataBuffer() { |
354 | assert(IsProperty); |
355 | return *getTrailingObjects<detail::PropertyData>(); |
356 | } |
357 | const detail::PropertyData &getPropertyDataBuffer() const { |
358 | assert(IsProperty); |
359 | return *getTrailingObjects<detail::PropertyData>(); |
360 | } |
361 | |
362 | size_t allocated_size() const; |
363 | |
364 | public: |
365 | ParsedAttr(const ParsedAttr &) = delete; |
366 | ParsedAttr(ParsedAttr &&) = delete; |
367 | ParsedAttr &operator=(const ParsedAttr &) = delete; |
368 | ParsedAttr &operator=(ParsedAttr &&) = delete; |
369 | ~ParsedAttr() = delete; |
370 | |
371 | void operator delete(void *) = delete; |
372 | |
373 | enum Kind { |
374 | #define PARSED_ATTR(NAME) AT_##NAME, |
375 | #include "clang/Sema/AttrParsedAttrList.inc" |
376 | #undef PARSED_ATTR |
377 | IgnoredAttribute, |
378 | UnknownAttribute |
379 | }; |
380 | |
381 | IdentifierInfo *getName() const { return AttrName; } |
382 | SourceLocation getLoc() const { return AttrRange.getBegin(); } |
383 | SourceRange getRange() const { return AttrRange; } |
384 | |
385 | bool hasScope() const { return ScopeName; } |
386 | IdentifierInfo *getScopeName() const { return ScopeName; } |
387 | SourceLocation getScopeLoc() const { return ScopeLoc; } |
388 | |
389 | bool isGNUScope() const { |
390 | return ScopeName && |
391 | (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__")); |
392 | } |
393 | |
394 | bool hasParsedType() const { return HasParsedType; } |
395 | |
396 | |
397 | bool isDeclspecPropertyAttribute() const { |
398 | return IsProperty; |
399 | } |
400 | |
401 | bool isAlignasAttribute() const { |
402 | |
403 | return getKind() == AT_Aligned && isKeywordAttribute(); |
404 | } |
405 | |
406 | bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } |
407 | bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } |
408 | |
409 | bool isCXX11Attribute() const { |
410 | return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); |
411 | } |
412 | |
413 | bool isC2xAttribute() const { |
414 | return SyntaxUsed == AS_C2x; |
415 | } |
416 | |
417 | bool isKeywordAttribute() const { |
418 | return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword; |
419 | } |
420 | |
421 | bool isContextSensitiveKeywordAttribute() const { |
422 | return SyntaxUsed == AS_ContextSensitiveKeyword; |
423 | } |
424 | |
425 | bool isInvalid() const { return Invalid; } |
426 | void setInvalid(bool b = true) const { Invalid = b; } |
427 | |
428 | bool hasProcessingCache() const { return HasProcessingCache; } |
429 | |
430 | unsigned getProcessingCache() const { |
431 | assert(hasProcessingCache()); |
432 | return ProcessingCache; |
433 | } |
434 | |
435 | void setProcessingCache(unsigned value) const { |
436 | ProcessingCache = value; |
437 | HasProcessingCache = true; |
438 | } |
439 | |
440 | bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } |
441 | void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } |
442 | |
443 | |
444 | bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; } |
445 | |
446 | void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; } |
447 | |
448 | bool isPackExpansion() const { return EllipsisLoc.isValid(); } |
449 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
450 | |
451 | Kind getKind() const { return Kind(AttrKind); } |
452 | static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope, |
453 | Syntax SyntaxUsed); |
454 | |
455 | |
456 | unsigned getNumArgs() const { return NumArgs; } |
457 | |
458 | |
459 | ArgsUnion getArg(unsigned Arg) const { |
460 | (0) . __assert_fail ("Arg < NumArgs && \"Arg access out of range!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 460, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Arg < NumArgs && "Arg access out of range!"); |
461 | return getArgsBuffer()[Arg]; |
462 | } |
463 | |
464 | bool isArgExpr(unsigned Arg) const { |
465 | return Arg < NumArgs && getArg(Arg).is<Expr*>(); |
466 | } |
467 | |
468 | Expr *getArgAsExpr(unsigned Arg) const { |
469 | return getArg(Arg).get<Expr*>(); |
470 | } |
471 | |
472 | bool isArgIdent(unsigned Arg) const { |
473 | return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); |
474 | } |
475 | |
476 | IdentifierLoc *getArgAsIdent(unsigned Arg) const { |
477 | return getArg(Arg).get<IdentifierLoc*>(); |
478 | } |
479 | |
480 | const AvailabilityChange &getAvailabilityIntroduced() const { |
481 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 481, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
482 | return getAvailabilityData()->Changes[detail::IntroducedSlot]; |
483 | } |
484 | |
485 | const AvailabilityChange &getAvailabilityDeprecated() const { |
486 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 486, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
487 | return getAvailabilityData()->Changes[detail::DeprecatedSlot]; |
488 | } |
489 | |
490 | const AvailabilityChange &getAvailabilityObsoleted() const { |
491 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 491, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
492 | return getAvailabilityData()->Changes[detail::ObsoletedSlot]; |
493 | } |
494 | |
495 | SourceLocation getStrictLoc() const { |
496 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 496, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
497 | return getAvailabilityData()->StrictLoc; |
498 | } |
499 | |
500 | SourceLocation getUnavailableLoc() const { |
501 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 501, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
502 | return UnavailableLoc; |
503 | } |
504 | |
505 | const Expr * getMessageExpr() const { |
506 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 506, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
507 | return MessageExpr; |
508 | } |
509 | |
510 | const Expr *getReplacementExpr() const { |
511 | (0) . __assert_fail ("getKind() == AT_Availability && \"Not an availability attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 511, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_Availability && "Not an availability attribute"); |
512 | return getAvailabilityData()->Replacement; |
513 | } |
514 | |
515 | const ParsedType &getMatchingCType() const { |
516 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 517, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_TypeTagForDatatype && |
517 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 517, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Not a type_tag_for_datatype attribute"); |
518 | return getTypeTagForDatatypeDataSlot().MatchingCType; |
519 | } |
520 | |
521 | bool getLayoutCompatible() const { |
522 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 523, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_TypeTagForDatatype && |
523 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 523, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Not a type_tag_for_datatype attribute"); |
524 | return getTypeTagForDatatypeDataSlot().LayoutCompatible; |
525 | } |
526 | |
527 | bool getMustBeNull() const { |
528 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 529, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(getKind() == AT_TypeTagForDatatype && |
529 | (0) . __assert_fail ("getKind() == AT_TypeTagForDatatype && \"Not a type_tag_for_datatype attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 529, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Not a type_tag_for_datatype attribute"); |
530 | return getTypeTagForDatatypeDataSlot().MustBeNull; |
531 | } |
532 | |
533 | const ParsedType &getTypeArg() const { |
534 | (0) . __assert_fail ("HasParsedType && \"Not a type attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 534, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(HasParsedType && "Not a type attribute"); |
535 | return getTypeBuffer(); |
536 | } |
537 | |
538 | IdentifierInfo *getPropertyDataGetter() const { |
539 | (0) . __assert_fail ("isDeclspecPropertyAttribute() && \"Not a __delcspec(property) attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 540, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isDeclspecPropertyAttribute() && |
540 | (0) . __assert_fail ("isDeclspecPropertyAttribute() && \"Not a __delcspec(property) attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 540, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Not a __delcspec(property) attribute"); |
541 | return getPropertyDataBuffer().GetterId; |
542 | } |
543 | |
544 | IdentifierInfo *getPropertyDataSetter() const { |
545 | (0) . __assert_fail ("isDeclspecPropertyAttribute() && \"Not a __delcspec(property) attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 546, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isDeclspecPropertyAttribute() && |
546 | (0) . __assert_fail ("isDeclspecPropertyAttribute() && \"Not a __delcspec(property) attribute\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 546, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Not a __delcspec(property) attribute"); |
547 | return getPropertyDataBuffer().SetterId; |
548 | } |
549 | |
550 | |
551 | |
552 | |
553 | unsigned getAttributeSpellingListIndex() const; |
554 | |
555 | bool isTargetSpecificAttr() const; |
556 | bool isTypeAttr() const; |
557 | bool isStmtAttr() const; |
558 | |
559 | bool hasCustomParsing() const; |
560 | unsigned getMinArgs() const; |
561 | unsigned getMaxArgs() const; |
562 | bool hasVariadicArg() const; |
563 | bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; |
564 | bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const; |
565 | void getMatchRules(const LangOptions &LangOpts, |
566 | SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> |
567 | &MatchRules) const; |
568 | bool diagnoseLangOpts(class Sema &S) const; |
569 | bool existsInTarget(const TargetInfo &Target) const; |
570 | bool isKnownToGCC() const; |
571 | bool isSupportedByPragmaAttribute() const; |
572 | |
573 | |
574 | |
575 | |
576 | |
577 | |
578 | unsigned getSemanticSpelling() const; |
579 | |
580 | |
581 | |
582 | LangAS asOpenCLLangAS() const { |
583 | switch (getKind()) { |
584 | case ParsedAttr::AT_OpenCLConstantAddressSpace: |
585 | return LangAS::opencl_constant; |
586 | case ParsedAttr::AT_OpenCLGlobalAddressSpace: |
587 | return LangAS::opencl_global; |
588 | case ParsedAttr::AT_OpenCLLocalAddressSpace: |
589 | return LangAS::opencl_local; |
590 | case ParsedAttr::AT_OpenCLPrivateAddressSpace: |
591 | return LangAS::opencl_private; |
592 | case ParsedAttr::AT_OpenCLGenericAddressSpace: |
593 | return LangAS::opencl_generic; |
594 | default: |
595 | return LangAS::Default; |
596 | } |
597 | } |
598 | }; |
599 | |
600 | class AttributePool; |
601 | |
602 | |
603 | |
604 | |
605 | |
606 | class AttributeFactory { |
607 | public: |
608 | enum { |
609 | AvailabilityAllocSize = |
610 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
611 | detail::TypeTagForDatatypeData, ParsedType, |
612 | detail::PropertyData>(1, 1, 0, 0, 0), |
613 | TypeTagForDatatypeAllocSize = |
614 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
615 | detail::TypeTagForDatatypeData, ParsedType, |
616 | detail::PropertyData>(1, 0, 1, 0, 0), |
617 | PropertyAllocSize = |
618 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
619 | detail::TypeTagForDatatypeData, ParsedType, |
620 | detail::PropertyData>(0, 0, 0, 0, 1), |
621 | }; |
622 | |
623 | private: |
624 | enum { |
625 | |
626 | |
627 | |
628 | |
629 | |
630 | InlineFreeListsCapacity = |
631 | 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *) |
632 | }; |
633 | |
634 | llvm::BumpPtrAllocator Alloc; |
635 | |
636 | |
637 | |
638 | SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists; |
639 | |
640 | |
641 | friend class AttributePool; |
642 | |
643 | |
644 | void *allocate(size_t size); |
645 | |
646 | void deallocate(ParsedAttr *AL); |
647 | |
648 | |
649 | |
650 | |
651 | |
652 | |
653 | void reclaimPool(AttributePool &head); |
654 | |
655 | public: |
656 | AttributeFactory(); |
657 | ~AttributeFactory(); |
658 | }; |
659 | |
660 | class AttributePool { |
661 | friend class AttributeFactory; |
662 | AttributeFactory &Factory; |
663 | llvm::TinyPtrVector<ParsedAttr *> Attrs; |
664 | |
665 | void *allocate(size_t size) { |
666 | return Factory.allocate(size); |
667 | } |
668 | |
669 | ParsedAttr *add(ParsedAttr *attr) { |
670 | Attrs.push_back(attr); |
671 | return attr; |
672 | } |
673 | |
674 | void remove(ParsedAttr *attr) { |
675 | (0) . __assert_fail ("llvm..is_contained(Attrs, attr) && \"Can't take attribute from a pool that doesn't own it!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 676, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(llvm::is_contained(Attrs, attr) && |
676 | (0) . __assert_fail ("llvm..is_contained(Attrs, attr) && \"Can't take attribute from a pool that doesn't own it!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 676, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Can't take attribute from a pool that doesn't own it!"); |
677 | Attrs.erase(llvm::find(Attrs, attr)); |
678 | } |
679 | |
680 | void takePool(AttributePool &pool); |
681 | |
682 | public: |
683 | |
684 | AttributePool(AttributeFactory &factory) : Factory(factory) {} |
685 | |
686 | AttributePool(const AttributePool &) = delete; |
687 | |
688 | ~AttributePool() { Factory.reclaimPool(*this); } |
689 | |
690 | |
691 | AttributePool(AttributePool &&pool) = default; |
692 | |
693 | AttributeFactory &getFactory() const { return Factory; } |
694 | |
695 | void clear() { |
696 | Factory.reclaimPool(*this); |
697 | Attrs.clear(); |
698 | } |
699 | |
700 | |
701 | void takeAllFrom(AttributePool &pool) { |
702 | takePool(pool); |
703 | pool.Attrs.clear(); |
704 | } |
705 | |
706 | ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, |
707 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
708 | ArgsUnion *args, unsigned numArgs, |
709 | ParsedAttr::Syntax syntax, |
710 | SourceLocation ellipsisLoc = SourceLocation()) { |
711 | size_t temp = |
712 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
713 | detail::TypeTagForDatatypeData, ParsedType, |
714 | detail::PropertyData>(numArgs, 0, 0, 0, 0); |
715 | (void)temp; |
716 | void *memory = allocate( |
717 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
718 | detail::TypeTagForDatatypeData, ParsedType, |
719 | detail::PropertyData>(numArgs, 0, 0, 0, |
720 | 0)); |
721 | return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, |
722 | args, numArgs, syntax, ellipsisLoc)); |
723 | } |
724 | |
725 | ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, |
726 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
727 | IdentifierLoc *Param, const AvailabilityChange &introduced, |
728 | const AvailabilityChange &deprecated, |
729 | const AvailabilityChange &obsoleted, |
730 | SourceLocation unavailable, const Expr *MessageExpr, |
731 | ParsedAttr::Syntax syntax, SourceLocation strict, |
732 | const Expr *ReplacementExpr) { |
733 | void *memory = allocate(AttributeFactory::AvailabilityAllocSize); |
734 | return add(new (memory) ParsedAttr( |
735 | attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, |
736 | obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr)); |
737 | } |
738 | |
739 | ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, |
740 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
741 | IdentifierLoc *Param1, IdentifierLoc *Param2, |
742 | IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { |
743 | void *memory = allocate( |
744 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
745 | detail::TypeTagForDatatypeData, ParsedType, |
746 | detail::PropertyData>(3, 0, 0, 0, 0)); |
747 | return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, |
748 | Param1, Param2, Param3, syntax)); |
749 | } |
750 | |
751 | ParsedAttr * |
752 | createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, |
753 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
754 | IdentifierLoc *argumentKind, |
755 | ParsedType matchingCType, bool layoutCompatible, |
756 | bool mustBeNull, ParsedAttr::Syntax syntax) { |
757 | void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); |
758 | return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, |
759 | argumentKind, matchingCType, |
760 | layoutCompatible, mustBeNull, syntax)); |
761 | } |
762 | |
763 | ParsedAttr *createTypeAttribute(IdentifierInfo *attrName, |
764 | SourceRange attrRange, |
765 | IdentifierInfo *scopeName, |
766 | SourceLocation scopeLoc, ParsedType typeArg, |
767 | ParsedAttr::Syntax syntaxUsed) { |
768 | void *memory = allocate( |
769 | ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, |
770 | detail::TypeTagForDatatypeData, ParsedType, |
771 | detail::PropertyData>(0, 0, 0, 1, 0)); |
772 | return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, |
773 | typeArg, syntaxUsed)); |
774 | } |
775 | |
776 | ParsedAttr * |
777 | createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, |
778 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
779 | IdentifierInfo *getterId, IdentifierInfo *setterId, |
780 | ParsedAttr::Syntax syntaxUsed) { |
781 | void *memory = allocate(AttributeFactory::PropertyAllocSize); |
782 | return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, |
783 | getterId, setterId, syntaxUsed)); |
784 | } |
785 | }; |
786 | |
787 | class ParsedAttributesView { |
788 | using VecTy = llvm::TinyPtrVector<ParsedAttr *>; |
789 | using SizeType = decltype(std::declval<VecTy>().size()); |
790 | |
791 | public: |
792 | bool empty() const { return AttrList.empty(); } |
793 | SizeType size() const { return AttrList.size(); } |
794 | ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; } |
795 | const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; } |
796 | |
797 | void addAtEnd(ParsedAttr *newAttr) { |
798 | assert(newAttr); |
799 | AttrList.push_back(newAttr); |
800 | } |
801 | |
802 | void remove(ParsedAttr *ToBeRemoved) { |
803 | (0) . __assert_fail ("is_contained(AttrList, ToBeRemoved) && \"Cannot remove attribute that isn't in the list\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 804, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(is_contained(AttrList, ToBeRemoved) && |
804 | (0) . __assert_fail ("is_contained(AttrList, ToBeRemoved) && \"Cannot remove attribute that isn't in the list\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedAttr.h", 804, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Cannot remove attribute that isn't in the list"); |
805 | AttrList.erase(llvm::find(AttrList, ToBeRemoved)); |
806 | } |
807 | |
808 | void clearListOnly() { AttrList.clear(); } |
809 | |
810 | struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator, |
811 | std::random_access_iterator_tag, |
812 | ParsedAttr> { |
813 | iterator() : iterator_adaptor_base(nullptr) {} |
814 | iterator(VecTy::iterator I) : iterator_adaptor_base(I) {} |
815 | reference operator*() { return **I; } |
816 | friend class ParsedAttributesView; |
817 | }; |
818 | struct const_iterator |
819 | : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator, |
820 | std::random_access_iterator_tag, |
821 | ParsedAttr> { |
822 | const_iterator() : iterator_adaptor_base(nullptr) {} |
823 | const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {} |
824 | |
825 | reference operator*() const { return **I; } |
826 | friend class ParsedAttributesView; |
827 | }; |
828 | |
829 | void addAll(iterator B, iterator E) { |
830 | AttrList.insert(AttrList.begin(), B.I, E.I); |
831 | } |
832 | |
833 | void addAll(const_iterator B, const_iterator E) { |
834 | AttrList.insert(AttrList.begin(), B.I, E.I); |
835 | } |
836 | |
837 | void addAllAtEnd(iterator B, iterator E) { |
838 | AttrList.insert(AttrList.end(), B.I, E.I); |
839 | } |
840 | |
841 | void addAllAtEnd(const_iterator B, const_iterator E) { |
842 | AttrList.insert(AttrList.end(), B.I, E.I); |
843 | } |
844 | |
845 | iterator begin() { return iterator(AttrList.begin()); } |
846 | const_iterator begin() const { return const_iterator(AttrList.begin()); } |
847 | iterator end() { return iterator(AttrList.end()); } |
848 | const_iterator end() const { return const_iterator(AttrList.end()); } |
849 | |
850 | ParsedAttr &front() { |
851 | assert(!empty()); |
852 | return *AttrList.front(); |
853 | } |
854 | const ParsedAttr &front() const { |
855 | assert(!empty()); |
856 | return *AttrList.front(); |
857 | } |
858 | ParsedAttr &back() { |
859 | assert(!empty()); |
860 | return *AttrList.back(); |
861 | } |
862 | const ParsedAttr &back() const { |
863 | assert(!empty()); |
864 | return *AttrList.back(); |
865 | } |
866 | |
867 | bool hasAttribute(ParsedAttr::Kind K) const { |
868 | return llvm::any_of( |
869 | AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; }); |
870 | } |
871 | |
872 | private: |
873 | VecTy AttrList; |
874 | }; |
875 | |
876 | |
877 | |
878 | |
879 | |
880 | |
881 | |
882 | class ParsedAttributes : public ParsedAttributesView { |
883 | public: |
884 | ParsedAttributes(AttributeFactory &factory) : pool(factory) {} |
885 | ParsedAttributes(const ParsedAttributes &) = delete; |
886 | |
887 | AttributePool &getPool() const { return pool; } |
888 | |
889 | void takeAllFrom(ParsedAttributes &attrs) { |
890 | addAll(attrs.begin(), attrs.end()); |
891 | attrs.clearListOnly(); |
892 | pool.takeAllFrom(attrs.pool); |
893 | } |
894 | |
895 | void clear() { |
896 | clearListOnly(); |
897 | pool.clear(); |
898 | } |
899 | |
900 | |
901 | ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, |
902 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
903 | ArgsUnion *args, unsigned numArgs, |
904 | ParsedAttr::Syntax syntax, |
905 | SourceLocation ellipsisLoc = SourceLocation()) { |
906 | ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, |
907 | args, numArgs, syntax, ellipsisLoc); |
908 | addAtEnd(attr); |
909 | return attr; |
910 | } |
911 | |
912 | |
913 | ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, |
914 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
915 | IdentifierLoc *Param, const AvailabilityChange &introduced, |
916 | const AvailabilityChange &deprecated, |
917 | const AvailabilityChange &obsoleted, |
918 | SourceLocation unavailable, const Expr *MessageExpr, |
919 | ParsedAttr::Syntax syntax, SourceLocation strict, |
920 | const Expr *ReplacementExpr) { |
921 | ParsedAttr *attr = pool.create( |
922 | attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, |
923 | obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr); |
924 | addAtEnd(attr); |
925 | return attr; |
926 | } |
927 | |
928 | |
929 | ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, |
930 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
931 | IdentifierLoc *Param1, IdentifierLoc *Param2, |
932 | IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { |
933 | ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, |
934 | Param1, Param2, Param3, syntax); |
935 | addAtEnd(attr); |
936 | return attr; |
937 | } |
938 | |
939 | |
940 | ParsedAttr * |
941 | addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, |
942 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
943 | IdentifierLoc *argumentKind, |
944 | ParsedType matchingCType, bool layoutCompatible, |
945 | bool mustBeNull, ParsedAttr::Syntax syntax) { |
946 | ParsedAttr *attr = pool.createTypeTagForDatatype( |
947 | attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType, |
948 | layoutCompatible, mustBeNull, syntax); |
949 | addAtEnd(attr); |
950 | return attr; |
951 | } |
952 | |
953 | |
954 | ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, |
955 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
956 | ParsedType typeArg, |
957 | ParsedAttr::Syntax syntaxUsed) { |
958 | ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName, |
959 | scopeLoc, typeArg, syntaxUsed); |
960 | addAtEnd(attr); |
961 | return attr; |
962 | } |
963 | |
964 | |
965 | ParsedAttr * |
966 | addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, |
967 | IdentifierInfo *scopeName, SourceLocation scopeLoc, |
968 | IdentifierInfo *getterId, IdentifierInfo *setterId, |
969 | ParsedAttr::Syntax syntaxUsed) { |
970 | ParsedAttr *attr = |
971 | pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, |
972 | getterId, setterId, syntaxUsed); |
973 | addAtEnd(attr); |
974 | return attr; |
975 | } |
976 | |
977 | private: |
978 | mutable AttributePool pool; |
979 | }; |
980 | |
981 | |
982 | |
983 | enum AttributeArgumentNType { |
984 | AANT_ArgumentIntOrBool, |
985 | AANT_ArgumentIntegerConstant, |
986 | AANT_ArgumentString, |
987 | AANT_ArgumentIdentifier |
988 | }; |
989 | |
990 | |
991 | |
992 | enum AttributeDeclKind { |
993 | ExpectedFunction, |
994 | ExpectedUnion, |
995 | ExpectedVariableOrFunction, |
996 | ExpectedFunctionOrMethod, |
997 | ExpectedFunctionMethodOrBlock, |
998 | ExpectedFunctionMethodOrParameter, |
999 | ExpectedVariable, |
1000 | ExpectedVariableOrField, |
1001 | ExpectedVariableFieldOrTag, |
1002 | ExpectedTypeOrNamespace, |
1003 | ExpectedFunctionVariableOrClass, |
1004 | ExpectedKernelFunction, |
1005 | ExpectedFunctionWithProtoType, |
1006 | }; |
1007 | |
1008 | inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, |
1009 | const ParsedAttr &At) { |
1010 | DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getName()), |
1011 | DiagnosticsEngine::ak_identifierinfo); |
1012 | return DB; |
1013 | } |
1014 | |
1015 | inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, |
1016 | const ParsedAttr &At) { |
1017 | PD.AddTaggedVal(reinterpret_cast<intptr_t>(At.getName()), |
1018 | DiagnosticsEngine::ak_identifierinfo); |
1019 | return PD; |
1020 | } |
1021 | |
1022 | inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, |
1023 | const ParsedAttr *At) { |
1024 | DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getName()), |
1025 | DiagnosticsEngine::ak_identifierinfo); |
1026 | return DB; |
1027 | } |
1028 | |
1029 | inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, |
1030 | const ParsedAttr *At) { |
1031 | PD.AddTaggedVal(reinterpret_cast<intptr_t>(At->getName()), |
1032 | DiagnosticsEngine::ak_identifierinfo); |
1033 | return PD; |
1034 | } |
1035 | |
1036 | } |
1037 | |
1038 | #endif |
1039 | |