1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_SEMA_OVERLOAD_H |
15 | #define LLVM_CLANG_SEMA_OVERLOAD_H |
16 | |
17 | #include "clang/AST/Decl.h" |
18 | #include "clang/AST/DeclAccessPair.h" |
19 | #include "clang/AST/DeclBase.h" |
20 | #include "clang/AST/DeclCXX.h" |
21 | #include "clang/AST/DeclTemplate.h" |
22 | #include "clang/AST/Expr.h" |
23 | #include "clang/AST/Type.h" |
24 | #include "clang/Basic/LLVM.h" |
25 | #include "clang/Basic/SourceLocation.h" |
26 | #include "clang/Sema/SemaFixItUtils.h" |
27 | #include "clang/Sema/TemplateDeduction.h" |
28 | #include "llvm/ADT/ArrayRef.h" |
29 | #include "llvm/ADT/None.h" |
30 | #include "llvm/ADT/STLExtras.h" |
31 | #include "llvm/ADT/SmallPtrSet.h" |
32 | #include "llvm/ADT/SmallVector.h" |
33 | #include "llvm/ADT/StringRef.h" |
34 | #include "llvm/Support/AlignOf.h" |
35 | #include "llvm/Support/Allocator.h" |
36 | #include "llvm/Support/Casting.h" |
37 | #include "llvm/Support/ErrorHandling.h" |
38 | #include <cassert> |
39 | #include <cstddef> |
40 | #include <cstdint> |
41 | #include <utility> |
42 | |
43 | namespace clang { |
44 | |
45 | class APValue; |
46 | class ASTContext; |
47 | class Sema; |
48 | |
49 | |
50 | |
51 | enum OverloadingResult { |
52 | |
53 | OR_Success, |
54 | |
55 | |
56 | OR_No_Viable_Function, |
57 | |
58 | |
59 | OR_Ambiguous, |
60 | |
61 | |
62 | OR_Deleted |
63 | }; |
64 | |
65 | enum OverloadCandidateDisplayKind { |
66 | |
67 | |
68 | OCD_AllCandidates, |
69 | |
70 | |
71 | OCD_ViableCandidates |
72 | }; |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | enum ImplicitConversionKind { |
79 | |
80 | ICK_Identity = 0, |
81 | |
82 | |
83 | ICK_Lvalue_To_Rvalue, |
84 | |
85 | |
86 | ICK_Array_To_Pointer, |
87 | |
88 | |
89 | ICK_Function_To_Pointer, |
90 | |
91 | |
92 | ICK_Function_Conversion, |
93 | |
94 | |
95 | ICK_Qualification, |
96 | |
97 | |
98 | ICK_Integral_Promotion, |
99 | |
100 | |
101 | ICK_Floating_Promotion, |
102 | |
103 | |
104 | ICK_Complex_Promotion, |
105 | |
106 | |
107 | ICK_Integral_Conversion, |
108 | |
109 | |
110 | ICK_Floating_Conversion, |
111 | |
112 | |
113 | ICK_Complex_Conversion, |
114 | |
115 | |
116 | ICK_Floating_Integral, |
117 | |
118 | |
119 | ICK_Pointer_Conversion, |
120 | |
121 | |
122 | ICK_Pointer_Member, |
123 | |
124 | |
125 | ICK_Boolean_Conversion, |
126 | |
127 | |
128 | ICK_Compatible_Conversion, |
129 | |
130 | |
131 | ICK_Derived_To_Base, |
132 | |
133 | |
134 | ICK_Vector_Conversion, |
135 | |
136 | |
137 | ICK_Vector_Splat, |
138 | |
139 | |
140 | ICK_Complex_Real, |
141 | |
142 | |
143 | ICK_Block_Pointer_Conversion, |
144 | |
145 | |
146 | ICK_TransparentUnionConversion, |
147 | |
148 | |
149 | ICK_Writeback_Conversion, |
150 | |
151 | |
152 | ICK_Zero_Event_Conversion, |
153 | |
154 | |
155 | ICK_Zero_Queue_Conversion, |
156 | |
157 | |
158 | ICK_C_Only_Conversion, |
159 | |
160 | |
161 | ICK_Incompatible_Pointer_Conversion, |
162 | |
163 | |
164 | ICK_Num_Conversion_Kinds, |
165 | }; |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | enum ImplicitConversionRank { |
172 | |
173 | ICR_Exact_Match = 0, |
174 | |
175 | |
176 | ICR_Promotion, |
177 | |
178 | |
179 | ICR_Conversion, |
180 | |
181 | |
182 | ICR_OCL_Scalar_Widening, |
183 | |
184 | |
185 | ICR_Complex_Real_Conversion, |
186 | |
187 | |
188 | ICR_Writeback_Conversion, |
189 | |
190 | |
191 | ICR_C_Conversion, |
192 | |
193 | |
194 | |
195 | ICR_C_Conversion_Extension |
196 | }; |
197 | |
198 | ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind); |
199 | |
200 | |
201 | |
202 | enum NarrowingKind { |
203 | |
204 | NK_Not_Narrowing, |
205 | |
206 | |
207 | NK_Type_Narrowing, |
208 | |
209 | |
210 | NK_Constant_Narrowing, |
211 | |
212 | |
213 | |
214 | NK_Variable_Narrowing, |
215 | |
216 | |
217 | |
218 | NK_Dependent_Narrowing, |
219 | }; |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | class StandardConversionSequence { |
230 | public: |
231 | |
232 | |
233 | |
234 | ImplicitConversionKind First : 8; |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | ImplicitConversionKind Second : 8; |
241 | |
242 | |
243 | |
244 | ImplicitConversionKind Third : 8; |
245 | |
246 | |
247 | |
248 | |
249 | unsigned DeprecatedStringLiteralToCharPtr : 1; |
250 | |
251 | |
252 | |
253 | unsigned QualificationIncludesObjCLifetime : 1; |
254 | |
255 | |
256 | |
257 | unsigned IncompatibleObjC : 1; |
258 | |
259 | |
260 | |
261 | unsigned ReferenceBinding : 1; |
262 | |
263 | |
264 | |
265 | unsigned DirectBinding : 1; |
266 | |
267 | |
268 | |
269 | unsigned IsLvalueReference : 1; |
270 | |
271 | |
272 | unsigned BindsToFunctionLvalue : 1; |
273 | |
274 | |
275 | unsigned BindsToRvalue : 1; |
276 | |
277 | |
278 | |
279 | unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1; |
280 | |
281 | |
282 | |
283 | unsigned ObjCLifetimeConversionBinding : 1; |
284 | |
285 | |
286 | |
287 | |
288 | void *FromTypePtr; |
289 | |
290 | |
291 | |
292 | |
293 | void *ToTypePtrs[3]; |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | CXXConstructorDecl *CopyConstructor; |
301 | DeclAccessPair FoundCopyConstructor; |
302 | |
303 | void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } |
304 | |
305 | void setToType(unsigned Idx, QualType T) { |
306 | (0) . __assert_fail ("Idx < 3 && \"To type index is out of range\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 306, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Idx < 3 && "To type index is out of range"); |
307 | ToTypePtrs[Idx] = T.getAsOpaquePtr(); |
308 | } |
309 | |
310 | void setAllToTypes(QualType T) { |
311 | ToTypePtrs[0] = T.getAsOpaquePtr(); |
312 | ToTypePtrs[1] = ToTypePtrs[0]; |
313 | ToTypePtrs[2] = ToTypePtrs[0]; |
314 | } |
315 | |
316 | QualType getFromType() const { |
317 | return QualType::getFromOpaquePtr(FromTypePtr); |
318 | } |
319 | |
320 | QualType getToType(unsigned Idx) const { |
321 | (0) . __assert_fail ("Idx < 3 && \"To type index is out of range\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 321, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Idx < 3 && "To type index is out of range"); |
322 | return QualType::getFromOpaquePtr(ToTypePtrs[Idx]); |
323 | } |
324 | |
325 | void setAsIdentityConversion(); |
326 | |
327 | bool isIdentityConversion() const { |
328 | return Second == ICK_Identity && Third == ICK_Identity; |
329 | } |
330 | |
331 | ImplicitConversionRank getRank() const; |
332 | NarrowingKind |
333 | getNarrowingKind(ASTContext &Context, const Expr *Converted, |
334 | APValue &ConstantValue, QualType &ConstantType, |
335 | bool IgnoreFloatToIntegralConversion = false) const; |
336 | bool isPointerConversionToBool() const; |
337 | bool isPointerConversionToVoidPointer(ASTContext& Context) const; |
338 | void dump() const; |
339 | }; |
340 | |
341 | |
342 | |
343 | struct UserDefinedConversionSequence { |
344 | |
345 | |
346 | |
347 | |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | StandardConversionSequence Before; |
356 | |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | |
363 | bool EllipsisConversion : 1; |
364 | |
365 | |
366 | |
367 | |
368 | bool HadMultipleCandidates : 1; |
369 | |
370 | |
371 | |
372 | StandardConversionSequence After; |
373 | |
374 | |
375 | |
376 | |
377 | FunctionDecl* ConversionFunction; |
378 | |
379 | |
380 | |
381 | |
382 | DeclAccessPair FoundConversionFunction; |
383 | |
384 | void dump() const; |
385 | }; |
386 | |
387 | |
388 | struct AmbiguousConversionSequence { |
389 | using ConversionSet = |
390 | SmallVector<std::pair<NamedDecl *, FunctionDecl *>, 4>; |
391 | |
392 | void *FromTypePtr; |
393 | void *ToTypePtr; |
394 | char Buffer[sizeof(ConversionSet)]; |
395 | |
396 | QualType getFromType() const { |
397 | return QualType::getFromOpaquePtr(FromTypePtr); |
398 | } |
399 | |
400 | QualType getToType() const { |
401 | return QualType::getFromOpaquePtr(ToTypePtr); |
402 | } |
403 | |
404 | void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } |
405 | void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); } |
406 | |
407 | ConversionSet &conversions() { |
408 | return *reinterpret_cast<ConversionSet*>(Buffer); |
409 | } |
410 | |
411 | const ConversionSet &conversions() const { |
412 | return *reinterpret_cast<const ConversionSet*>(Buffer); |
413 | } |
414 | |
415 | void addConversion(NamedDecl *Found, FunctionDecl *D) { |
416 | conversions().push_back(std::make_pair(Found, D)); |
417 | } |
418 | |
419 | using iterator = ConversionSet::iterator; |
420 | |
421 | iterator begin() { return conversions().begin(); } |
422 | iterator end() { return conversions().end(); } |
423 | |
424 | using const_iterator = ConversionSet::const_iterator; |
425 | |
426 | const_iterator begin() const { return conversions().begin(); } |
427 | const_iterator end() const { return conversions().end(); } |
428 | |
429 | void construct(); |
430 | void destruct(); |
431 | void copyFrom(const AmbiguousConversionSequence &); |
432 | }; |
433 | |
434 | |
435 | |
436 | struct BadConversionSequence { |
437 | enum FailureKind { |
438 | no_conversion, |
439 | unrelated_class, |
440 | bad_qualifiers, |
441 | lvalue_ref_to_rvalue, |
442 | rvalue_ref_to_lvalue |
443 | }; |
444 | |
445 | |
446 | Expr *FromExpr; |
447 | |
448 | FailureKind Kind; |
449 | |
450 | private: |
451 | |
452 | void *FromTy; |
453 | |
454 | |
455 | void *ToTy; |
456 | |
457 | public: |
458 | void init(FailureKind K, Expr *From, QualType To) { |
459 | init(K, From->getType(), To); |
460 | FromExpr = From; |
461 | } |
462 | |
463 | void init(FailureKind K, QualType From, QualType To) { |
464 | Kind = K; |
465 | FromExpr = nullptr; |
466 | setFromType(From); |
467 | setToType(To); |
468 | } |
469 | |
470 | QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); } |
471 | QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); } |
472 | |
473 | void setFromExpr(Expr *E) { |
474 | FromExpr = E; |
475 | setFromType(E->getType()); |
476 | } |
477 | |
478 | void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); } |
479 | void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); } |
480 | }; |
481 | |
482 | |
483 | |
484 | |
485 | |
486 | class ImplicitConversionSequence { |
487 | public: |
488 | |
489 | |
490 | |
491 | |
492 | enum Kind { |
493 | StandardConversion = 0, |
494 | UserDefinedConversion, |
495 | AmbiguousConversion, |
496 | EllipsisConversion, |
497 | BadConversion |
498 | }; |
499 | |
500 | private: |
501 | enum { |
502 | Uninitialized = BadConversion + 1 |
503 | }; |
504 | |
505 | |
506 | unsigned ConversionKind : 30; |
507 | |
508 | |
509 | |
510 | unsigned StdInitializerListElement : 1; |
511 | |
512 | void setKind(Kind K) { |
513 | destruct(); |
514 | ConversionKind = K; |
515 | } |
516 | |
517 | void destruct() { |
518 | if (ConversionKind == AmbiguousConversion) Ambiguous.destruct(); |
519 | } |
520 | |
521 | public: |
522 | union { |
523 | |
524 | |
525 | StandardConversionSequence Standard; |
526 | |
527 | |
528 | |
529 | UserDefinedConversionSequence UserDefined; |
530 | |
531 | |
532 | |
533 | AmbiguousConversionSequence Ambiguous; |
534 | |
535 | |
536 | |
537 | BadConversionSequence Bad; |
538 | }; |
539 | |
540 | ImplicitConversionSequence() |
541 | : ConversionKind(Uninitialized), StdInitializerListElement(false) { |
542 | Standard.setAsIdentityConversion(); |
543 | } |
544 | |
545 | ImplicitConversionSequence(const ImplicitConversionSequence &Other) |
546 | : ConversionKind(Other.ConversionKind), |
547 | StdInitializerListElement(Other.StdInitializerListElement) { |
548 | switch (ConversionKind) { |
549 | case Uninitialized: break; |
550 | case StandardConversion: Standard = Other.Standard; break; |
551 | case UserDefinedConversion: UserDefined = Other.UserDefined; break; |
552 | case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break; |
553 | case EllipsisConversion: break; |
554 | case BadConversion: Bad = Other.Bad; break; |
555 | } |
556 | } |
557 | |
558 | ImplicitConversionSequence & |
559 | operator=(const ImplicitConversionSequence &Other) { |
560 | destruct(); |
561 | new (this) ImplicitConversionSequence(Other); |
562 | return *this; |
563 | } |
564 | |
565 | ~ImplicitConversionSequence() { |
566 | destruct(); |
567 | } |
568 | |
569 | Kind getKind() const { |
570 | (0) . __assert_fail ("isInitialized() && \"querying uninitialized conversion\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 570, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isInitialized() && "querying uninitialized conversion"); |
571 | return Kind(ConversionKind); |
572 | } |
573 | |
574 | |
575 | |
576 | |
577 | |
578 | |
579 | |
580 | |
581 | unsigned getKindRank() const { |
582 | switch (getKind()) { |
583 | case StandardConversion: |
584 | return 0; |
585 | |
586 | case UserDefinedConversion: |
587 | case AmbiguousConversion: |
588 | return 1; |
589 | |
590 | case EllipsisConversion: |
591 | return 2; |
592 | |
593 | case BadConversion: |
594 | return 3; |
595 | } |
596 | |
597 | llvm_unreachable("Invalid ImplicitConversionSequence::Kind!"); |
598 | } |
599 | |
600 | bool isBad() const { return getKind() == BadConversion; } |
601 | bool isStandard() const { return getKind() == StandardConversion; } |
602 | bool isEllipsis() const { return getKind() == EllipsisConversion; } |
603 | bool isAmbiguous() const { return getKind() == AmbiguousConversion; } |
604 | bool isUserDefined() const { return getKind() == UserDefinedConversion; } |
605 | bool isFailure() const { return isBad() || isAmbiguous(); } |
606 | |
607 | |
608 | |
609 | |
610 | bool isInitialized() const { return ConversionKind != Uninitialized; } |
611 | |
612 | |
613 | void setBad(BadConversionSequence::FailureKind Failure, |
614 | Expr *FromExpr, QualType ToType) { |
615 | setKind(BadConversion); |
616 | Bad.init(Failure, FromExpr, ToType); |
617 | } |
618 | |
619 | |
620 | void setBad(BadConversionSequence::FailureKind Failure, |
621 | QualType FromType, QualType ToType) { |
622 | setKind(BadConversion); |
623 | Bad.init(Failure, FromType, ToType); |
624 | } |
625 | |
626 | void setStandard() { setKind(StandardConversion); } |
627 | void setEllipsis() { setKind(EllipsisConversion); } |
628 | void setUserDefined() { setKind(UserDefinedConversion); } |
629 | |
630 | void setAmbiguous() { |
631 | if (ConversionKind == AmbiguousConversion) return; |
632 | ConversionKind = AmbiguousConversion; |
633 | Ambiguous.construct(); |
634 | } |
635 | |
636 | void setAsIdentityConversion(QualType T) { |
637 | setStandard(); |
638 | Standard.setAsIdentityConversion(); |
639 | Standard.setFromType(T); |
640 | Standard.setAllToTypes(T); |
641 | } |
642 | |
643 | |
644 | |
645 | bool isStdInitializerListElement() const { |
646 | return StdInitializerListElement; |
647 | } |
648 | |
649 | void setStdInitializerListElement(bool V = true) { |
650 | StdInitializerListElement = V; |
651 | } |
652 | |
653 | |
654 | |
655 | |
656 | enum CompareKind { |
657 | Better = -1, |
658 | Indistinguishable = 0, |
659 | Worse = 1 |
660 | }; |
661 | |
662 | void DiagnoseAmbiguousConversion(Sema &S, |
663 | SourceLocation CaretLoc, |
664 | const PartialDiagnostic &PDiag) const; |
665 | |
666 | void dump() const; |
667 | }; |
668 | |
669 | enum OverloadFailureKind { |
670 | ovl_fail_too_many_arguments, |
671 | ovl_fail_too_few_arguments, |
672 | ovl_fail_bad_conversion, |
673 | ovl_fail_bad_deduction, |
674 | |
675 | |
676 | |
677 | |
678 | ovl_fail_trivial_conversion, |
679 | |
680 | |
681 | |
682 | |
683 | |
684 | |
685 | |
686 | |
687 | |
688 | |
689 | ovl_fail_illegal_constructor, |
690 | |
691 | |
692 | |
693 | ovl_fail_bad_final_conversion, |
694 | |
695 | |
696 | |
697 | ovl_fail_final_conversion_not_exact, |
698 | |
699 | |
700 | |
701 | |
702 | ovl_fail_bad_target, |
703 | |
704 | |
705 | |
706 | ovl_fail_enable_if, |
707 | |
708 | |
709 | ovl_fail_addr_not_available, |
710 | |
711 | |
712 | ovl_fail_ext_disabled, |
713 | |
714 | |
715 | |
716 | ovl_fail_inhctor_slice, |
717 | |
718 | |
719 | |
720 | ovl_non_default_multiversion_function, |
721 | }; |
722 | |
723 | |
724 | |
725 | using ConversionSequenceList = |
726 | llvm::MutableArrayRef<ImplicitConversionSequence>; |
727 | |
728 | |
729 | struct OverloadCandidate { |
730 | |
731 | |
732 | |
733 | |
734 | FunctionDecl *Function; |
735 | |
736 | |
737 | |
738 | |
739 | DeclAccessPair FoundDecl; |
740 | |
741 | |
742 | |
743 | QualType BuiltinParamTypes[3]; |
744 | |
745 | |
746 | |
747 | CXXConversionDecl *Surrogate; |
748 | |
749 | |
750 | |
751 | ConversionSequenceList Conversions; |
752 | |
753 | |
754 | ConversionFixItGenerator Fix; |
755 | |
756 | |
757 | bool Viable : 1; |
758 | |
759 | |
760 | |
761 | |
762 | bool IsSurrogate : 1; |
763 | |
764 | |
765 | |
766 | |
767 | |
768 | |
769 | |
770 | |
771 | bool IgnoreObjectArgument : 1; |
772 | |
773 | |
774 | CallExpr::ADLCallKind IsADLCandidate : 1; |
775 | |
776 | |
777 | |
778 | unsigned char FailureKind; |
779 | |
780 | |
781 | |
782 | unsigned ExplicitCallArguments; |
783 | |
784 | union { |
785 | DeductionFailureInfo DeductionFailure; |
786 | |
787 | |
788 | |
789 | |
790 | |
791 | StandardConversionSequence FinalConversion; |
792 | }; |
793 | |
794 | |
795 | |
796 | bool hasAmbiguousConversion() const { |
797 | for (auto &C : Conversions) { |
798 | if (!C.isInitialized()) return false; |
799 | if (C.isAmbiguous()) return true; |
800 | } |
801 | return false; |
802 | } |
803 | |
804 | bool TryToFixBadConversion(unsigned Idx, Sema &S) { |
805 | bool CanFix = Fix.tryToFixConversion( |
806 | Conversions[Idx].Bad.FromExpr, |
807 | Conversions[Idx].Bad.getFromType(), |
808 | Conversions[Idx].Bad.getToType(), S); |
809 | |
810 | |
811 | if (!CanFix) |
812 | Fix.clear(); |
813 | |
814 | return CanFix; |
815 | } |
816 | |
817 | unsigned getNumParams() const { |
818 | if (IsSurrogate) { |
819 | auto STy = Surrogate->getConversionType(); |
820 | while (STy->isPointerType() || STy->isReferenceType()) |
821 | STy = STy->getPointeeType(); |
822 | return STy->getAs<FunctionProtoType>()->getNumParams(); |
823 | } |
824 | if (Function) |
825 | return Function->getNumParams(); |
826 | return ExplicitCallArguments; |
827 | } |
828 | |
829 | private: |
830 | friend class OverloadCandidateSet; |
831 | OverloadCandidate() : IsADLCandidate(CallExpr::NotADL) {} |
832 | }; |
833 | |
834 | |
835 | |
836 | class OverloadCandidateSet { |
837 | public: |
838 | enum CandidateSetKind { |
839 | |
840 | CSK_Normal, |
841 | |
842 | |
843 | |
844 | |
845 | |
846 | |
847 | CSK_Operator, |
848 | |
849 | |
850 | |
851 | |
852 | CSK_InitByUserDefinedConversion, |
853 | |
854 | |
855 | |
856 | |
857 | CSK_InitByConstructor, |
858 | }; |
859 | |
860 | private: |
861 | SmallVector<OverloadCandidate, 16> Candidates; |
862 | llvm::SmallPtrSet<Decl *, 16> Functions; |
863 | |
864 | |
865 | |
866 | llvm::BumpPtrAllocator SlabAllocator; |
867 | |
868 | SourceLocation Loc; |
869 | CandidateSetKind Kind; |
870 | |
871 | constexpr static unsigned NumInlineBytes = |
872 | 24 * sizeof(ImplicitConversionSequence); |
873 | unsigned NumInlineBytesUsed = 0; |
874 | llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace; |
875 | |
876 | |
877 | |
878 | |
879 | |
880 | |
881 | |
882 | template <typename T> |
883 | T *slabAllocate(unsigned N) { |
884 | |
885 | static_assert(alignof(T) == alignof(void *), |
886 | "Only works for pointer-aligned types."); |
887 | static_assert(std::is_trivial<T>::value || |
888 | std::is_same<ImplicitConversionSequence, T>::value, |
889 | "Add destruction logic to OverloadCandidateSet::clear()."); |
890 | |
891 | unsigned NBytes = sizeof(T) * N; |
892 | if (NBytes > NumInlineBytes - NumInlineBytesUsed) |
893 | return SlabAllocator.Allocate<T>(N); |
894 | char *FreeSpaceStart = InlineSpace.buffer + NumInlineBytesUsed; |
895 | (0) . __assert_fail ("uintptr_t(FreeSpaceStart) % alignof(void *) == 0 && \"Misaligned storage!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 896, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(uintptr_t(FreeSpaceStart) % alignof(void *) == 0 && |
896 | (0) . __assert_fail ("uintptr_t(FreeSpaceStart) % alignof(void *) == 0 && \"Misaligned storage!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 896, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Misaligned storage!"); |
897 | |
898 | NumInlineBytesUsed += NBytes; |
899 | return reinterpret_cast<T *>(FreeSpaceStart); |
900 | } |
901 | |
902 | void destroyCandidates(); |
903 | |
904 | public: |
905 | OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK) |
906 | : Loc(Loc), Kind(CSK) {} |
907 | OverloadCandidateSet(const OverloadCandidateSet &) = delete; |
908 | OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete; |
909 | ~OverloadCandidateSet() { destroyCandidates(); } |
910 | |
911 | SourceLocation getLocation() const { return Loc; } |
912 | CandidateSetKind getKind() const { return Kind; } |
913 | |
914 | |
915 | |
916 | bool isNewCandidate(Decl *F) { |
917 | return Functions.insert(F->getCanonicalDecl()).second; |
918 | } |
919 | |
920 | |
921 | void clear(CandidateSetKind CSK); |
922 | |
923 | using iterator = SmallVectorImpl<OverloadCandidate>::iterator; |
924 | |
925 | iterator begin() { return Candidates.begin(); } |
926 | iterator end() { return Candidates.end(); } |
927 | |
928 | size_t size() const { return Candidates.size(); } |
929 | bool empty() const { return Candidates.empty(); } |
930 | |
931 | |
932 | |
933 | ConversionSequenceList |
934 | allocateConversionSequences(unsigned NumConversions) { |
935 | ImplicitConversionSequence *Conversions = |
936 | slabAllocate<ImplicitConversionSequence>(NumConversions); |
937 | |
938 | |
939 | for (unsigned I = 0; I != NumConversions; ++I) |
940 | new (&Conversions[I]) ImplicitConversionSequence(); |
941 | |
942 | return ConversionSequenceList(Conversions, NumConversions); |
943 | } |
944 | |
945 | |
946 | |
947 | OverloadCandidate &addCandidate(unsigned NumConversions = 0, |
948 | ConversionSequenceList Conversions = None) { |
949 | (0) . __assert_fail ("(Conversions.empty() || Conversions.size() == NumConversions) && \"preallocated conversion sequence has wrong length\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 950, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert((Conversions.empty() || Conversions.size() == NumConversions) && |
950 | (0) . __assert_fail ("(Conversions.empty() || Conversions.size() == NumConversions) && \"preallocated conversion sequence has wrong length\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/Overload.h", 950, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "preallocated conversion sequence has wrong length"); |
951 | |
952 | Candidates.push_back(OverloadCandidate()); |
953 | OverloadCandidate &C = Candidates.back(); |
954 | C.Conversions = Conversions.empty() |
955 | ? allocateConversionSequences(NumConversions) |
956 | : Conversions; |
957 | return C; |
958 | } |
959 | |
960 | |
961 | OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, |
962 | OverloadCandidateSet::iterator& Best); |
963 | |
964 | void NoteCandidates(Sema &S, |
965 | OverloadCandidateDisplayKind OCD, |
966 | ArrayRef<Expr *> Args, |
967 | StringRef Opc = "", |
968 | SourceLocation Loc = SourceLocation(), |
969 | llvm::function_ref<bool(OverloadCandidate&)> Filter = |
970 | [](OverloadCandidate&) { return true; }); |
971 | }; |
972 | |
973 | bool isBetterOverloadCandidate(Sema &S, |
974 | const OverloadCandidate &Cand1, |
975 | const OverloadCandidate &Cand2, |
976 | SourceLocation Loc, |
977 | OverloadCandidateSet::CandidateSetKind Kind); |
978 | |
979 | struct ConstructorInfo { |
980 | DeclAccessPair FoundDecl; |
981 | CXXConstructorDecl *Constructor; |
982 | FunctionTemplateDecl *ConstructorTmpl; |
983 | |
984 | explicit operator bool() const { return Constructor; } |
985 | }; |
986 | |
987 | |
988 | |
989 | inline ConstructorInfo getConstructorInfo(NamedDecl *ND) { |
990 | if (isa<UsingDecl>(ND)) |
991 | return ConstructorInfo{}; |
992 | |
993 | |
994 | |
995 | auto *D = ND->getUnderlyingDecl(); |
996 | ConstructorInfo Info = {DeclAccessPair::make(ND, D->getAccess()), nullptr, |
997 | nullptr}; |
998 | Info.ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D); |
999 | if (Info.ConstructorTmpl) |
1000 | D = Info.ConstructorTmpl->getTemplatedDecl(); |
1001 | Info.Constructor = dyn_cast<CXXConstructorDecl>(D); |
1002 | return Info; |
1003 | } |
1004 | |
1005 | } |
1006 | |
1007 | #endif |
1008 | |