clang: lib/AST/ODRDiagsEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
15
16using namespace clang;
17
22}
23
28}
29
31 assert(D);
35}
36
41}
42
44
46 return M->getFullModuleName();
47
48
49 return {};
50}
51
52template
55 StringRef FirstModule,
56 StringRef SecondModule,
57 const MethodT *FirstMethod,
58 const MethodT *SecondMethod) {
59 enum DiagMethodType {
60 DiagMethod,
61 DiagConstructor,
62 DiagDestructor,
63 };
64 auto GetDiagMethodType = [](const NamedDecl *D) {
65 if (isa(D))
66 return DiagConstructor;
67 if (isa(D))
68 return DiagDestructor;
69 return DiagMethod;
70 };
71
72 enum ODRMethodParametersDifference {
73 NumberParameters,
74 ParameterType,
75 ParameterName,
76 };
77 auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78 FirstMethod](ODRMethodParametersDifference DiffType) {
80 DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81 return Diags.Report(FirstMethod->getLocation(),
82 diag::err_module_odr_violation_method_params)
83 << FirstContainer << FirstModule.empty() << FirstModule
84 << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85 << FirstName;
86 };
87 auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88 SecondMethod](ODRMethodParametersDifference DiffType) {
90 DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91 return Diags.Report(SecondMethod->getLocation(),
92 diag::note_module_odr_violation_method_params)
93 << SecondModule.empty() << SecondModule
94 << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95 << SecondName;
96 };
97
98 const unsigned FirstNumParameters = FirstMethod->param_size();
99 const unsigned SecondNumParameters = SecondMethod->param_size();
100 if (FirstNumParameters != SecondNumParameters) {
101 DiagError(NumberParameters) << FirstNumParameters;
102 DiagNote(NumberParameters) << SecondNumParameters;
103 return true;
104 }
105
106 for (unsigned I = 0; I < FirstNumParameters; ++I) {
107 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
109
112 if (FirstParamType != SecondParamType &&
114 if (const DecayedType *ParamDecayedType =
116 DiagError(ParameterType) << (I + 1) << FirstParamType << true
117 << ParamDecayedType->getOriginalType();
118 } else {
119 DiagError(ParameterType) << (I + 1) << FirstParamType << false;
120 }
121
122 if (const DecayedType *ParamDecayedType =
124 DiagNote(ParameterType) << (I + 1) << SecondParamType << true
125 << ParamDecayedType->getOriginalType();
126 } else {
127 DiagNote(ParameterType) << (I + 1) << SecondParamType << false;
128 }
129 return true;
130 }
131
134 if (FirstParamName != SecondParamName) {
135 DiagError(ParameterName) << (I + 1) << FirstParamName;
136 DiagNote(ParameterName) << (I + 1) << SecondParamName;
137 return true;
138 }
139 }
140
141 return false;
142}
143
144bool ODRDiagsEmitter::diagnoseSubMismatchField(
145 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
147 enum ODRFieldDifference {
148 FieldName,
149 FieldTypeName,
150 FieldSingleBitField,
151 FieldDifferentWidthBitField,
152 FieldSingleMutable,
153 FieldSingleInitializer,
154 FieldDifferentInitializers,
155 };
156
157 auto DiagError = [FirstRecord, FirstField, FirstModule,
158 this](ODRFieldDifference DiffType) {
159 return Diag(FirstField->getLocation(), diag::err_module_odr_violation_field)
160 << FirstRecord << FirstModule.empty() << FirstModule
162 };
163 auto DiagNote = [SecondField, SecondModule,
164 this](ODRFieldDifference DiffType) {
166 diag::note_module_odr_violation_field)
167 << SecondModule.empty() << SecondModule << SecondField->getSourceRange() << DiffType;
168 };
169
173 DiagError(FieldName) << FirstII;
174 DiagNote(FieldName) << SecondII;
175 return true;
176 }
177
181 DiagError(FieldTypeName) << FirstII << FirstType;
182 DiagNote(FieldTypeName) << SecondII << SecondType;
183 return true;
184 }
185
187 (void)Context;
188
189 const bool IsFirstBitField = FirstField->isBitField();
190 const bool IsSecondBitField = SecondField->isBitField();
191 if (IsFirstBitField != IsSecondBitField) {
192 DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;
193 DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;
194 return true;
195 }
196
197 if (IsFirstBitField && IsSecondBitField) {
200 if (FirstBitWidthHash != SecondBitWidthHash) {
201 DiagError(FieldDifferentWidthBitField)
203 DiagNote(FieldDifferentWidthBitField)
205 return true;
206 }
207 }
208
209 if (!LangOpts.CPlusPlus)
210 return false;
211
212 const bool IsFirstMutable = FirstField->isMutable();
213 const bool IsSecondMutable = SecondField->isMutable();
214 if (IsFirstMutable != IsSecondMutable) {
215 DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;
216 DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;
217 return true;
218 }
219
222 if ((!FirstInitializer && SecondInitializer) ||
223 (FirstInitializer && !SecondInitializer)) {
224 DiagError(FieldSingleInitializer)
225 << FirstII << (FirstInitializer != nullptr);
226 DiagNote(FieldSingleInitializer)
227 << SecondII << (SecondInitializer != nullptr);
228 return true;
229 }
230
231 if (FirstInitializer && SecondInitializer) {
232 unsigned FirstInitHash = computeODRHash(FirstInitializer);
233 unsigned SecondInitHash = computeODRHash(SecondInitializer);
234 if (FirstInitHash != SecondInitHash) {
235 DiagError(FieldDifferentInitializers)
237 DiagNote(FieldDifferentInitializers)
239 return true;
240 }
241 }
242
243 return false;
244}
245
246bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
249 bool IsTypeAlias) const {
250 enum ODRTypedefDifference {
251 TypedefName,
253 };
254
255 auto DiagError = [FirstRecord, FirstTD, FirstModule,
256 this](ODRTypedefDifference DiffType) {
257 return Diag(FirstTD->getLocation(), diag::err_module_odr_violation_typedef)
258 << FirstRecord << FirstModule.empty() << FirstModule
260 };
261 auto DiagNote = [SecondTD, SecondModule,
262 this](ODRTypedefDifference DiffType) {
264 diag::note_module_odr_violation_typedef)
265 << SecondModule << SecondTD->getSourceRange() << DiffType;
266 };
267
270 if (FirstName != SecondName) {
271 DiagError(TypedefName) << IsTypeAlias << FirstName;
272 DiagNote(TypedefName) << IsTypeAlias << SecondName;
273 return true;
274 }
275
279 DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType;
280 DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType;
281 return true;
282 }
283 return false;
284}
285
286bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
287 StringRef FirstModule,
288 StringRef SecondModule,
290 const VarDecl *SecondVD) const {
291 enum ODRVarDifference {
292 VarName,
293 VarType,
294 VarSingleInitializer,
295 VarDifferentInitializer,
296 VarConstexpr,
297 };
298
299 auto DiagError = [FirstRecord, FirstVD, FirstModule,
300 this](ODRVarDifference DiffType) {
301 return Diag(FirstVD->getLocation(), diag::err_module_odr_violation_variable)
302 << FirstRecord << FirstModule.empty() << FirstModule
304 };
305 auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) {
307 diag::note_module_odr_violation_variable)
308 << SecondModule << SecondVD->getSourceRange() << DiffType;
309 };
310
313 if (FirstName != SecondName) {
314 DiagError(VarName) << FirstName;
315 DiagNote(VarName) << SecondName;
316 return true;
317 }
318
322 DiagError(VarType) << FirstName << FirstType;
323 DiagNote(VarType) << SecondName << SecondType;
324 return true;
325 }
326
327 if (!LangOpts.CPlusPlus)
328 return false;
329
330 const Expr *FirstInit = FirstVD->getInit();
331 const Expr *SecondInit = SecondVD->getInit();
332 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
333 DiagError(VarSingleInitializer)
334 << FirstName << (FirstInit == nullptr)
335 << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
336 DiagNote(VarSingleInitializer)
337 << SecondName << (SecondInit == nullptr)
338 << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
339 return true;
340 }
341
342 if (FirstInit && SecondInit &&
344 DiagError(VarDifferentInitializer)
345 << FirstName << FirstInit->getSourceRange();
346 DiagNote(VarDifferentInitializer)
347 << SecondName << SecondInit->getSourceRange();
348 return true;
349 }
350
351 const bool FirstIsConstexpr = FirstVD->isConstexpr();
352 const bool SecondIsConstexpr = SecondVD->isConstexpr();
353 if (FirstIsConstexpr != SecondIsConstexpr) {
354 DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;
355 DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;
356 return true;
357 }
358 return false;
359}
360
361bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(
365 const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const {
366
367 enum ODRReferencedProtocolDifference {
368 NumProtocols,
369 ProtocolType,
370 };
371 auto DiagRefProtocolError = [FirstContainer, FirstModule,
373 ODRReferencedProtocolDifference DiffType) {
374 return Diag(Loc, diag::err_module_odr_violation_referenced_protocols)
375 << FirstContainer << FirstModule.empty() << FirstModule << Range
376 << DiffType;
377 };
378 auto DiagRefProtocolNote = [SecondModule,
380 ODRReferencedProtocolDifference DiffType) {
381 return Diag(Loc, diag::note_module_odr_violation_referenced_protocols)
382 << SecondModule.empty() << SecondModule << Range << DiffType;
383 };
384 auto GetProtoListSourceRange = [](const ObjCProtocolList &PL) {
385 if (PL.empty())
387 return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end()));
388 };
389
390 if (FirstProtocols.size() != SecondProtocols.size()) {
391 DiagRefProtocolError(FirstContainer->getLocation(),
392 GetProtoListSourceRange(FirstProtocols), NumProtocols)
393 << FirstProtocols.size();
394 DiagRefProtocolNote(SecondContainer->getLocation(),
395 GetProtoListSourceRange(SecondProtocols), NumProtocols)
396 << SecondProtocols.size();
397 return true;
398 }
399
400 for (unsigned I = 0, E = FirstProtocols.size(); I != E; ++I) {
405 if (FirstProtocolName != SecondProtocolName) {
409 DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType)
410 << (I + 1) << FirstProtocolName;
411 DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType)
412 << (I + 1) << SecondProtocolName;
413 return true;
414 }
415 }
416
417 return false;
418}
419
420bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
422 StringRef SecondModule, const ObjCMethodDecl *FirstMethod,
424 enum ODRMethodDifference {
425 ReturnType,
426 InstanceOrClass,
427 ControlLevel,
428 DesignatedInitializer,
429 Directness,
430 Name,
431 };
432
433 auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434 this](ODRMethodDifference DiffType) {
436 diag::err_module_odr_violation_objc_method)
437 << FirstObjCContainer << FirstModule.empty() << FirstModule
439 };
440 auto DiagNote = [SecondModule, SecondMethod,
441 this](ODRMethodDifference DiffType) {
442 return Diag(SecondMethod->getLocation(),
443 diag::note_module_odr_violation_objc_method)
444 << SecondModule.empty() << SecondModule
445 << SecondMethod->getSourceRange() << DiffType;
446 };
447
450 DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType();
451 DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
452 return true;
453 }
454
455 if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) {
456 DiagError(InstanceOrClass)
458 DiagNote(InstanceOrClass)
459 << SecondMethod << SecondMethod->isInstanceMethod();
460 return true;
461 }
463 SecondMethod->getImplementationControl()) {
464 DiagError(ControlLevel)
466 DiagNote(ControlLevel) << llvm::to_underlying(
467 SecondMethod->getImplementationControl());
468 return true;
469 }
471 SecondMethod->isThisDeclarationADesignatedInitializer()) {
472 DiagError(DesignatedInitializer)
473 << FirstMethod
475 DiagNote(DesignatedInitializer)
476 << SecondMethod
477 << SecondMethod->isThisDeclarationADesignatedInitializer();
478 return true;
479 }
480 if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {
481 DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();
482 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
483 return true;
484 }
486 FirstModule, SecondModule,
487 FirstMethod, SecondMethod))
488 return true;
489
490
491
492
494 DeclarationName SecondName = SecondMethod->getDeclName();
495 if (FirstName != SecondName) {
496 DiagError(Name) << FirstName;
497 DiagNote(Name) << SecondName;
498 return true;
499 }
500
501 return false;
502}
503
504bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
505 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
508 enum ODRPropertyDifference {
509 Name,
511 ControlLevel,
512 Attribute,
513 };
514
515 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
517 return Diag(Loc, diag::err_module_odr_violation_objc_property)
518 << FirstObjCContainer << FirstModule.empty() << FirstModule
520 };
521 auto DiagNote = [SecondModule, SecondProp,
523 return Diag(Loc, diag::note_module_odr_violation_objc_property)
524 << SecondModule.empty() << SecondModule
525 << SecondProp->getSourceRange() << DiffType;
526 };
527
529 IdentifierInfo *SecondII = SecondProp->getIdentifier();
531 DiagError(FirstProp->getLocation(), Name) << FirstII;
532 DiagNote(SecondProp->getLocation(), Name) << SecondII;
533 return true;
534 }
538 << FirstII << FirstProp->getType();
539 DiagNote(SecondProp->getLocation(), Type)
540 << SecondII << SecondProp->getType();
541 return true;
542 }
544 SecondProp->getPropertyImplementation()) {
545 DiagError(FirstProp->getLocation(), ControlLevel)
547 DiagNote(SecondProp->getLocation(), ControlLevel)
548 << SecondProp->getPropertyImplementation();
549 return true;
550 }
551
552
554 unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();
555 if (FirstAttrs != SecondAttrs) {
557 unsigned CheckedAttr = (1 << I);
558 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
559 continue;
560
561 bool IsFirstWritten =
563 bool IsSecondWritten =
564 (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
565 DiagError(IsFirstWritten ? FirstProp->getLParenLoc()
567 Attribute)
568 << FirstII << (I + 1) << IsFirstWritten;
569 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
570 : SecondProp->getLocation(),
571 Attribute)
572 << SecondII << (I + 1);
573 return true;
574 }
575 }
576
577 return false;
578}
579
580ODRDiagsEmitter::DiffResult
581ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
582 DeclHashes &SecondHashes) {
583 auto DifferenceSelector = [](const Decl *D) {
584 assert(D && "valid Decl required");
586 default:
587 return Other;
588 case Decl::AccessSpec:
591 return PublicSpecifer;
593 return PrivateSpecifer;
595 return ProtectedSpecifer;
597 break;
598 }
599 llvm_unreachable("Invalid access specifier");
600 case Decl::StaticAssert:
601 return StaticAssert;
602 case Decl::Field:
603 return Field;
604 case Decl::CXXMethod:
605 case Decl::CXXConstructor:
606 case Decl::CXXDestructor:
607 return CXXMethod;
608 case Decl::TypeAlias:
609 return TypeAlias;
610 case Decl::Typedef:
611 return TypeDef;
612 case Decl::Var:
613 return Var;
614 case Decl::Friend:
615 return Friend;
616 case Decl::FunctionTemplate:
617 return FunctionTemplate;
618 case Decl::ObjCMethod:
619 return ObjCMethod;
620 case Decl::ObjCIvar:
621 return ObjCIvar;
622 case Decl::ObjCProperty:
623 return ObjCProperty;
624 }
625 };
626
627 DiffResult DR;
628 auto FirstIt = FirstHashes.begin();
629 auto SecondIt = SecondHashes.begin();
630 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
631 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
632 FirstIt->second == SecondIt->second) {
633 ++FirstIt;
634 ++SecondIt;
635 continue;
636 }
637
638 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
639 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
640
641 DR.FirstDiffType =
642 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
643 DR.SecondDiffType =
644 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
645 return DR;
646 }
647 return DR;
648}
649
650void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
651 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
652 const NamedDecl *SecondRecord, StringRef SecondModule) const {
654 diag::err_module_odr_violation_different_definitions)
655 << FirstRecord << FirstModule.empty() << FirstModule;
656
657 if (DR.FirstDecl) {
658 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
660 }
661
663 diag::note_module_odr_violation_different_definitions)
664 << SecondModule;
665
666 if (DR.SecondDecl) {
667 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
668 << DR.SecondDecl->getSourceRange();
669 }
670}
671
672void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
673 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
674 const NamedDecl *SecondRecord, StringRef SecondModule) const {
675 auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
676 ODRMismatchDecl DiffType, const Decl *D) {
679 if (DiffType == EndOfClass) {
680 if (auto *Tag = dyn_cast(Container))
681 Loc = Tag->getBraceRange().getEnd();
682 else if (auto *IF = dyn_cast(Container))
683 Loc = IF->getAtEndRange().getBegin();
684 else
685 Loc = Container->getEndLoc();
686 } else {
689 }
690 return std::make_pair(Loc, Range);
691 };
692
693 auto FirstDiagInfo =
694 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
695 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
696 << FirstRecord << FirstModule.empty() << FirstModule
697 << FirstDiagInfo.second << DR.FirstDiffType;
698
699 auto SecondDiagInfo =
700 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
701 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
702 << SecondModule.empty() << SecondModule << SecondDiagInfo.second
703 << DR.SecondDiffType;
704}
705
708 const struct CXXRecordDecl::DefinitionData *SecondDD) const {
709
710
711 if (FirstRecord == SecondRecord)
712 return false;
713
716
717 const struct CXXRecordDecl::DefinitionData *FirstDD =
718 FirstRecord->DefinitionData;
719 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
720
721
722 if (FirstDD != SecondDD) {
723
724 enum ODRDefinitionDataDifference {
725 NumBases,
726 NumVBases,
727 BaseType,
728 BaseVirtual,
729 BaseAccess,
730 };
731 auto DiagBaseError = [FirstRecord, &FirstModule,
733 ODRDefinitionDataDifference DiffType) {
734 return Diag(Loc, diag::err_module_odr_violation_definition_data)
735 << FirstRecord << FirstModule.empty() << FirstModule << Range
736 << DiffType;
737 };
738 auto DiagBaseNote = [&SecondModule,
740 ODRDefinitionDataDifference DiffType) {
741 return Diag(Loc, diag::note_module_odr_violation_definition_data)
742 << SecondModule << Range << DiffType;
743 };
744 auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {
745 unsigned NumBases = DD->NumBases;
746 if (NumBases == 0)
749 return SourceRange(bases[0].getBeginLoc(),
750 bases[NumBases - 1].getEndLoc());
751 };
752
753 unsigned FirstNumBases = FirstDD->NumBases;
754 unsigned FirstNumVBases = FirstDD->NumVBases;
755 unsigned SecondNumBases = SecondDD->NumBases;
756 unsigned SecondNumVBases = SecondDD->NumVBases;
757 if (FirstNumBases != SecondNumBases) {
758 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
759 NumBases)
760 << FirstNumBases;
761 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
762 NumBases)
763 << SecondNumBases;
764 return true;
765 }
766
767 if (FirstNumVBases != SecondNumVBases) {
768 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
769 NumVBases)
770 << FirstNumVBases;
771 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
772 NumVBases)
773 << SecondNumVBases;
774 return true;
775 }
776
779 for (unsigned I = 0; I < FirstNumBases; ++I) {
785 BaseType)
786 << (I + 1) << FirstBase.getType();
788 BaseType)
789 << (I + 1) << SecondBase.getType();
790 return true;
791 }
792
795 BaseVirtual)
798 BaseVirtual)
799 << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
800 return true;
801 }
802
806 BaseAccess)
807 << (I + 1) << FirstBase.getType()
810 BaseAccess)
811 << (I + 1) << SecondBase.getType()
813 return true;
814 }
815 }
816 }
817
822
823 assert(!FirstTemplate == !SecondTemplate &&
824 "Both pointers should be null or non-null");
825
826 if (FirstTemplate && SecondTemplate) {
831 assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
832 "Number of template parameters should be equal.");
833 for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {
834 const NamedDecl *FirstDecl = std::get<0>(Pair);
835 const NamedDecl *SecondDecl = std::get<1>(Pair);
837 continue;
838
839 assert(FirstDecl->getKind() == SecondDecl->getKind() &&
840 "Parameter Decl's should be the same kind.");
841
842 enum ODRTemplateDifference {
843 ParamEmptyName,
844 ParamName,
845 ParamSingleDefaultArgument,
846 ParamDifferentDefaultArgument,
847 };
848
849 auto hasDefaultArg = [](const NamedDecl *D) {
850 if (auto *TTP = dyn_cast(D))
851 return TTP->hasDefaultArgument() &&
852 !TTP->defaultArgumentWasInherited();
853 if (auto *NTTP = dyn_cast(D))
854 return NTTP->hasDefaultArgument() &&
855 !NTTP->defaultArgumentWasInherited();
856 auto *TTP = cast(D);
857 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
858 };
859 bool hasFirstArg = hasDefaultArg(FirstDecl);
860 bool hasSecondArg = hasDefaultArg(SecondDecl);
861
862 ODRTemplateDifference ErrDiffType;
863 ODRTemplateDifference NoteDiffType;
864
867
868 if (FirstName != SecondName) {
869 bool FirstNameEmpty =
871 bool SecondNameEmpty =
873 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
874 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
875 } else if (hasFirstArg == hasSecondArg)
876 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
877 else
878 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
879
881 diag::err_module_odr_violation_template_parameter)
882 << FirstRecord << FirstModule.empty() << FirstModule
883 << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
884 << FirstName;
886 diag::note_module_odr_violation_template_parameter)
887 << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
888 << hasSecondArg << SecondName;
889 return true;
890 }
891 }
892
897 continue;
899 }
900 };
901
905 PopulateHashes(FirstHashes, FirstRecord, DC);
906 PopulateHashes(SecondHashes, SecondRecord, DC);
907
908 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
909 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
910 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
911 const Decl *FirstDecl = DR.FirstDecl;
912 const Decl *SecondDecl = DR.SecondDecl;
913
914 if (FirstDiffType == Other || SecondDiffType == Other) {
915 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
916 SecondModule);
917 return true;
918 }
919
920 if (FirstDiffType != SecondDiffType) {
921 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
922 SecondRecord, SecondModule);
923 return true;
924 }
925
926
927
928 enum ODRCXXRecordDifference {
929 StaticAssertCondition,
930 StaticAssertMessage,
931 StaticAssertOnlyMessage,
932 MethodName,
933 MethodDeleted,
934 MethodDefaulted,
935 MethodVirtual,
936 MethodStatic,
937 MethodVolatile,
938 MethodConst,
939 MethodInline,
940 MethodParameterSingleDefaultArgument,
941 MethodParameterDifferentDefaultArgument,
942 MethodNoTemplateArguments,
943 MethodDifferentNumberTemplateArguments,
944 MethodDifferentTemplateArgument,
945 MethodSingleBody,
946 MethodDifferentBody,
947 FriendTypeFunction,
948 FriendType,
949 FriendFunction,
950 FunctionTemplateDifferentNumberParameters,
951 FunctionTemplateParameterDifferentKind,
952 FunctionTemplateParameterName,
953 FunctionTemplateParameterSingleDefaultArgument,
954 FunctionTemplateParameterDifferentDefaultArgument,
955 FunctionTemplateParameterDifferentType,
956 FunctionTemplatePackParameter,
957 };
958 auto DiagError = [FirstRecord, &FirstModule,
960 ODRCXXRecordDifference DiffType) {
961 return Diag(Loc, diag::err_module_odr_violation_record)
962 << FirstRecord << FirstModule.empty() << FirstModule << Range
963 << DiffType;
964 };
966 ODRCXXRecordDifference DiffType) {
967 return Diag(Loc, diag::note_module_odr_violation_record)
968 << SecondModule << Range << DiffType;
969 };
970
971 assert(FirstDiffType == SecondDiffType);
972 switch (FirstDiffType) {
974 case EndOfClass:
975 case PublicSpecifer:
976 case PrivateSpecifer:
977 case ProtectedSpecifer:
978 case ObjCMethod:
979 case ObjCIvar:
980 case ObjCProperty:
981 llvm_unreachable("Invalid diff type");
982
983 case StaticAssert: {
984 const StaticAssertDecl *FirstSA = cast(FirstDecl);
985 const StaticAssertDecl *SecondSA = cast(SecondDecl);
986
991 if (FirstODRHash != SecondODRHash) {
993 StaticAssertCondition);
995 StaticAssertCondition);
996 return true;
997 }
998
1001 assert((FirstMessage || SecondMessage) && "Both messages cannot be empty");
1002 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1005 if (FirstMessage) {
1008 } else {
1011 }
1012 if (SecondMessage) {
1013 SecondLoc = SecondMessage->getBeginLoc();
1015 } else {
1018 }
1019 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1020 << (FirstMessage == nullptr);
1021 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1022 << (SecondMessage == nullptr);
1023 return true;
1024 }
1025
1026 if (FirstMessage && SecondMessage) {
1027 unsigned FirstMessageODRHash = computeODRHash(FirstMessage);
1028 unsigned SecondMessageODRHash = computeODRHash(SecondMessage);
1029 if (FirstMessageODRHash != SecondMessageODRHash) {
1031 StaticAssertMessage);
1033 StaticAssertMessage);
1034 return true;
1035 }
1036 }
1037 break;
1038 }
1039
1040 case Field: {
1041 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1042 cast(FirstDecl),
1043 cast(SecondDecl)))
1044 return true;
1045 break;
1046 }
1047
1048 case CXXMethod: {
1049 enum {
1050 DiagMethod,
1051 DiagConstructor,
1052 DiagDestructor,
1053 } FirstMethodType,
1054 SecondMethodType;
1055 auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {
1056 if (isa(D))
1057 return DiagConstructor;
1058 if (isa(D))
1059 return DiagDestructor;
1060 return DiagMethod;
1061 };
1062 const CXXMethodDecl *FirstMethod = cast(FirstDecl);
1063 const CXXMethodDecl *SecondMethod = cast(SecondDecl);
1064 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1065 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1068 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1069 FirstName](ODRCXXRecordDifference DiffType) {
1070 return DiagError(FirstMethod->getLocation(),
1072 << FirstMethodType << FirstName;
1073 };
1074 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1075 SecondName](ODRCXXRecordDifference DiffType) {
1076 return DiagNote(SecondMethod->getLocation(),
1078 << SecondMethodType << SecondName;
1079 };
1080
1081 if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1082 DiagMethodError(MethodName);
1083 DiagMethodNote(MethodName);
1084 return true;
1085 }
1086
1089 if (FirstDeleted != SecondDeleted) {
1090 DiagMethodError(MethodDeleted) << FirstDeleted;
1091 DiagMethodNote(MethodDeleted) << SecondDeleted;
1092 return true;
1093 }
1094
1097 if (FirstDefaulted != SecondDefaulted) {
1098 DiagMethodError(MethodDefaulted) << FirstDefaulted;
1099 DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1100 return true;
1101 }
1102
1105 const bool FirstPure = FirstMethod->isPureVirtual();
1106 const bool SecondPure = SecondMethod->isPureVirtual();
1107 if ((FirstVirtual || SecondVirtual) &&
1108 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1109 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1110 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1111 return true;
1112 }
1113
1114
1115
1116
1119 const bool FirstStatic = FirstStorage == SC_Static;
1120 const bool SecondStatic = SecondStorage == SC_Static;
1121 if (FirstStatic != SecondStatic) {
1122 DiagMethodError(MethodStatic) << FirstStatic;
1123 DiagMethodNote(MethodStatic) << SecondStatic;
1124 return true;
1125 }
1126
1127 const bool FirstVolatile = FirstMethod->isVolatile();
1128 const bool SecondVolatile = SecondMethod->isVolatile();
1129 if (FirstVolatile != SecondVolatile) {
1130 DiagMethodError(MethodVolatile) << FirstVolatile;
1131 DiagMethodNote(MethodVolatile) << SecondVolatile;
1132 return true;
1133 }
1134
1135 const bool FirstConst = FirstMethod->isConst();
1136 const bool SecondConst = SecondMethod->isConst();
1137 if (FirstConst != SecondConst) {
1138 DiagMethodError(MethodConst) << FirstConst;
1139 DiagMethodNote(MethodConst) << SecondConst;
1140 return true;
1141 }
1142
1145 if (FirstInline != SecondInline) {
1146 DiagMethodError(MethodInline) << FirstInline;
1147 DiagMethodNote(MethodInline) << SecondInline;
1148 return true;
1149 }
1150
1152 FirstModule, SecondModule,
1153 FirstMethod, SecondMethod))
1154 return true;
1155
1156 for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) {
1159
1160 const Expr *FirstInit = FirstParam->getInit();
1161 const Expr *SecondInit = SecondParam->getInit();
1162 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1163 DiagMethodError(MethodParameterSingleDefaultArgument)
1164 << (I + 1) << (FirstInit == nullptr)
1166 DiagMethodNote(MethodParameterSingleDefaultArgument)
1167 << (I + 1) << (SecondInit == nullptr)
1169 return true;
1170 }
1171
1172 if (FirstInit && SecondInit &&
1174 DiagMethodError(MethodParameterDifferentDefaultArgument)
1176 DiagMethodNote(MethodParameterDifferentDefaultArgument)
1178 return true;
1179 }
1180 }
1181
1186
1187 if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1188 (!FirstTemplateArgs && SecondTemplateArgs)) {
1189 DiagMethodError(MethodNoTemplateArguments)
1190 << (FirstTemplateArgs != nullptr);
1191 DiagMethodNote(MethodNoTemplateArguments)
1192 << (SecondTemplateArgs != nullptr);
1193 return true;
1194 }
1195
1196 if (FirstTemplateArgs && SecondTemplateArgs) {
1197
1202 ExpandedList.push_back(&TA);
1203 continue;
1204 }
1205 llvm::append_range(ExpandedList,
1206 llvm::make_pointer_range(TA.getPackAsArray()));
1207 }
1208 return ExpandedList;
1209 };
1211 ExpandTemplateArgumentList(FirstTemplateArgs);
1213 ExpandTemplateArgumentList(SecondTemplateArgs);
1214
1215 if (FirstExpandedList.size() != SecondExpandedList.size()) {
1216 DiagMethodError(MethodDifferentNumberTemplateArguments)
1217 << (unsigned)FirstExpandedList.size();
1218 DiagMethodNote(MethodDifferentNumberTemplateArguments)
1219 << (unsigned)SecondExpandedList.size();
1220 return true;
1221 }
1222
1223 for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1225 &SecondTA = *SecondExpandedList[i];
1227 continue;
1228
1229 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1230 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1231 return true;
1232 }
1233 }
1234
1235
1236 auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
1240 };
1241
1242
1243
1244
1245 const bool HasFirstBody =
1246 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
1247 const bool HasSecondBody =
1248 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
1249
1250 if (HasFirstBody != HasSecondBody) {
1251 DiagMethodError(MethodSingleBody) << HasFirstBody;
1252 DiagMethodNote(MethodSingleBody) << HasSecondBody;
1253 return true;
1254 }
1255
1256 if (HasFirstBody && HasSecondBody) {
1257 DiagMethodError(MethodDifferentBody);
1258 DiagMethodNote(MethodDifferentBody);
1259 return true;
1260 }
1261
1262 break;
1263 }
1264
1265 case TypeAlias:
1266 case TypeDef: {
1267 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1268 cast(FirstDecl),
1269 cast(SecondDecl),
1270 FirstDiffType == TypeAlias))
1271 return true;
1272 break;
1273 }
1274 case Var: {
1275 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1276 cast(FirstDecl),
1277 cast(SecondDecl)))
1278 return true;
1279 break;
1280 }
1282 const FriendDecl *FirstFriend = cast(FirstDecl);
1283 const FriendDecl *SecondFriend = cast(SecondDecl);
1284
1287
1290
1291 if (FirstND && SecondND) {
1293 FriendFunction)
1294 << FirstND;
1296 FriendFunction)
1297 << SecondND;
1298 return true;
1299 }
1300
1301 if (FirstTSI && SecondTSI) {
1307 FriendType)
1308 << FirstFriendType;
1310 FriendType)
1311 << SecondFriendType;
1312 return true;
1313 }
1314
1316 FriendTypeFunction)
1317 << (FirstTSI == nullptr);
1319 FriendTypeFunction)
1320 << (SecondTSI == nullptr);
1321 return true;
1322 }
1323 case FunctionTemplate: {
1325 cast(FirstDecl);
1327 cast(SecondDecl);
1328
1331
1332 auto DiagTemplateError = [&DiagError,
1333 FirstTemplate](ODRCXXRecordDifference DiffType) {
1334 return DiagError(FirstTemplate->getLocation(),
1336 << FirstTemplate;
1337 };
1338 auto DiagTemplateNote = [&DiagNote,
1339 SecondTemplate](ODRCXXRecordDifference DiffType) {
1340 return DiagNote(SecondTemplate->getLocation(),
1342 << SecondTemplate;
1343 };
1344
1345 if (FirstTPL->size() != SecondTPL->size()) {
1346 DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1347 << FirstTPL->size();
1348 DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1349 << SecondTPL->size();
1350 return true;
1351 }
1352
1353 for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
1356
1357 if (FirstParam->getKind() != SecondParam->getKind()) {
1358 enum {
1359 TemplateTypeParameter,
1360 NonTypeTemplateParameter,
1361 TemplateTemplateParameter,
1362 };
1363 auto GetParamType = [](NamedDecl *D) {
1365 default:
1366 llvm_unreachable("Unexpected template parameter type");
1367 case Decl::TemplateTypeParm:
1368 return TemplateTypeParameter;
1369 case Decl::NonTypeTemplateParm:
1370 return NonTypeTemplateParameter;
1371 case Decl::TemplateTemplateParm:
1372 return TemplateTemplateParameter;
1373 }
1374 };
1375
1376 DiagTemplateError(FunctionTemplateParameterDifferentKind)
1377 << (i + 1) << GetParamType(FirstParam);
1378 DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1379 << (i + 1) << GetParamType(SecondParam);
1380 return true;
1381 }
1382
1383 if (FirstParam->getName() != SecondParam->getName()) {
1384 DiagTemplateError(FunctionTemplateParameterName)
1385 << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
1386 DiagTemplateNote(FunctionTemplateParameterName)
1387 << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
1388 return true;
1389 }
1390
1391 if (isa(FirstParam) &&
1392 isa(SecondParam)) {
1394 cast(FirstParam);
1396 cast(SecondParam);
1397 bool HasFirstDefaultArgument =
1400 bool HasSecondDefaultArgument =
1403 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1404 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1405 << (i + 1) << HasFirstDefaultArgument;
1406 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1407 << (i + 1) << HasSecondDefaultArgument;
1408 return true;
1409 }
1410
1411 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1417 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1418 << (i + 1) << FirstTA;
1419 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1420 << (i + 1) << SecondTA;
1421 return true;
1422 }
1423 }
1424
1426 DiagTemplateError(FunctionTemplatePackParameter)
1428 DiagTemplateNote(FunctionTemplatePackParameter)
1430 return true;
1431 }
1432 }
1433
1434 if (isa(FirstParam) &&
1435 isa(SecondParam)) {
1437 cast(FirstParam);
1439 cast(SecondParam);
1440
1443
1444 auto ComputeTemplateParameterListODRHash =
1446 assert(TPL);
1450 };
1451
1452 if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1453 ComputeTemplateParameterListODRHash(SecondTPL)) {
1454 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1455 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1456 return true;
1457 }
1458
1459 bool HasFirstDefaultArgument =
1462 bool HasSecondDefaultArgument =
1465 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1466 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1467 << (i + 1) << HasFirstDefaultArgument;
1468 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1469 << (i + 1) << HasSecondDefaultArgument;
1470 return true;
1471 }
1472
1473 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1479 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1480 << (i + 1) << FirstTA;
1481 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1482 << (i + 1) << SecondTA;
1483 return true;
1484 }
1485 }
1486
1488 DiagTemplateError(FunctionTemplatePackParameter)
1490 DiagTemplateNote(FunctionTemplatePackParameter)
1492 return true;
1493 }
1494 }
1495
1496 if (isa(FirstParam) &&
1497 isa(SecondParam)) {
1499 cast(FirstParam);
1501 cast(SecondParam);
1502
1506 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1507 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1508 return true;
1509 }
1510
1511 bool HasFirstDefaultArgument =
1514 bool HasSecondDefaultArgument =
1517 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1518 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1519 << (i + 1) << HasFirstDefaultArgument;
1520 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1521 << (i + 1) << HasSecondDefaultArgument;
1522 return true;
1523 }
1524
1525 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1530
1533 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1534 << (i + 1) << FirstDefaultArgument;
1535 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1536 << (i + 1) << SecondDefaultArgument;
1537 return true;
1538 }
1539 }
1540
1542 DiagTemplateError(FunctionTemplatePackParameter)
1544 DiagTemplateNote(FunctionTemplatePackParameter)
1546 return true;
1547 }
1548 }
1549 }
1550 break;
1551 }
1552 }
1553
1555 diag::err_module_odr_violation_mismatch_decl_unknown)
1556 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1559 diag::note_module_odr_violation_mismatch_decl_unknown)
1560 << SecondModule.empty() << SecondModule << FirstDiffType
1562 return true;
1563}
1564
1566 const RecordDecl *SecondRecord) const {
1567 if (FirstRecord == SecondRecord)
1568 return false;
1569
1572
1577 continue;
1579 }
1580 };
1581
1585 PopulateHashes(FirstHashes, FirstRecord, DC);
1586 PopulateHashes(SecondHashes, SecondRecord, DC);
1587
1588 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1589 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1590 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1591 const Decl *FirstDecl = DR.FirstDecl;
1592 const Decl *SecondDecl = DR.SecondDecl;
1593
1594 if (FirstDiffType == Other || SecondDiffType == Other) {
1595 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1596 SecondModule);
1597 return true;
1598 }
1599
1600 if (FirstDiffType != SecondDiffType) {
1601 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1602 SecondRecord, SecondModule);
1603 return true;
1604 }
1605
1606 assert(FirstDiffType == SecondDiffType);
1607 switch (FirstDiffType) {
1608
1609 case EndOfClass:
1611
1612 case PublicSpecifer:
1613 case PrivateSpecifer:
1614 case ProtectedSpecifer:
1615 case StaticAssert:
1616 case CXXMethod:
1617 case TypeAlias:
1619 case FunctionTemplate:
1620
1621 case ObjCMethod:
1622 case ObjCIvar:
1623 case ObjCProperty:
1624 llvm_unreachable("Invalid diff type");
1625
1626 case Field: {
1627 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1628 cast(FirstDecl),
1629 cast(SecondDecl)))
1630 return true;
1631 break;
1632 }
1633 case TypeDef: {
1634 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1635 cast(FirstDecl),
1636 cast(SecondDecl),
1637 false))
1638 return true;
1639 break;
1640 }
1641 case Var: {
1642 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1643 cast(FirstDecl),
1644 cast(SecondDecl)))
1645 return true;
1646 break;
1647 }
1648 }
1649
1651 diag::err_module_odr_violation_mismatch_decl_unknown)
1652 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1655 diag::note_module_odr_violation_mismatch_decl_unknown)
1656 << SecondModule.empty() << SecondModule << FirstDiffType
1658 return true;
1659}
1660
1664 if (FirstFunction == SecondFunction)
1665 return false;
1666
1667
1668 enum ODRFunctionDifference {
1669 ReturnType,
1670 ParameterName,
1671 ParameterType,
1672 ParameterSingleDefaultArgument,
1673 ParameterDifferentDefaultArgument,
1674 FunctionBody,
1675 };
1676
1679
1680 auto DiagError = [FirstFunction, &FirstModule,
1682 ODRFunctionDifference DiffType) {
1683 return Diag(Loc, diag::err_module_odr_violation_function)
1684 << FirstFunction << FirstModule.empty() << FirstModule << Range
1685 << DiffType;
1686 };
1688 ODRFunctionDifference DiffType) {
1689 return Diag(Loc, diag::note_module_odr_violation_function)
1690 << SecondModule << Range << DiffType;
1691 };
1692
1701 return true;
1702 }
1703
1705 "Merged functions with different number of parameters");
1706
1707 size_t ParamSize = FirstFunction->param_size();
1708 for (unsigned I = 0; I < ParamSize; ++I) {
1711
1713 "Merged function has different parameter types.");
1714
1717 ParameterName)
1720 ParameterName)
1722 return true;
1723 };
1724
1727 if (FirstParamType != SecondParamType &&
1729 if (const DecayedType *ParamDecayedType =
1732 ParameterType)
1733 << (I + 1) << FirstParamType << true
1734 << ParamDecayedType->getOriginalType();
1735 } else {
1737 ParameterType)
1738 << (I + 1) << FirstParamType << false;
1739 }
1740
1741 if (const DecayedType *ParamDecayedType =
1744 ParameterType)
1745 << (I + 1) << SecondParamType << true
1746 << ParamDecayedType->getOriginalType();
1747 } else {
1749 ParameterType)
1750 << (I + 1) << SecondParamType << false;
1751 }
1752 return true;
1753 }
1754
1755
1756 const Expr *FirstInit = FirstParam->getInit();
1757 const Expr *SecondInit = SecondParam->getInit();
1758 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1760 ParameterSingleDefaultArgument)
1761 << (I + 1) << (FirstInit == nullptr)
1764 ParameterSingleDefaultArgument)
1765 << (I + 1) << (SecondInit == nullptr)
1767 return true;
1768 }
1769
1770 if (FirstInit && SecondInit &&
1773 ParameterDifferentDefaultArgument)
1776 ParameterDifferentDefaultArgument)
1778 return true;
1779 }
1780
1782 "Undiagnosed parameter difference.");
1783 }
1784
1785
1786
1788 FunctionBody);
1790 FunctionBody);
1791 return true;
1792}
1793
1795 const EnumDecl *SecondEnum) const {
1796 if (FirstEnum == SecondEnum)
1797 return false;
1798
1799
1800 enum ODREnumDifference {
1801 SingleScopedEnum,
1802 EnumTagKeywordMismatch,
1803 SingleSpecifiedType,
1804 DifferentSpecifiedTypes,
1805 DifferentNumberEnumConstants,
1806 EnumConstantName,
1807 EnumConstantSingleInitializer,
1808 EnumConstantDifferentInitializer,
1809 };
1810
1813
1814 auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1815 ODREnumDifference DiffType) {
1816 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1817 << FirstEnum << FirstModule.empty() << FirstModule
1819 };
1820 auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1821 ODREnumDifference DiffType) {
1822 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1823 << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1824 };
1825
1827 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1828 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1829 return true;
1830 }
1831
1835 DiagError(FirstEnum, EnumTagKeywordMismatch)
1837 DiagNote(SecondEnum, EnumTagKeywordMismatch)
1839 return true;
1840 }
1841 }
1842
1843 QualType FirstUnderlyingType =
1847 QualType SecondUnderlyingType =
1851 if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1852 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1853 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1854 return true;
1855 }
1856
1857 if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
1860 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1861 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1862 return true;
1863 }
1864 }
1865
1866
1870 for (const Decl *D : Enum->decls()) {
1871
1872
1874 continue;
1875 assert(isa(D) && "Unexpected Decl kind");
1876 Hashes.emplace_back(cast(D), computeODRHash(D));
1877 }
1878 };
1880 PopulateHashes(FirstHashes, FirstEnum);
1882 PopulateHashes(SecondHashes, SecondEnum);
1883
1884 if (FirstHashes.size() != SecondHashes.size()) {
1885 DiagError(FirstEnum, DifferentNumberEnumConstants)
1886 << (int)FirstHashes.size();
1887 DiagNote(SecondEnum, DifferentNumberEnumConstants)
1888 << (int)SecondHashes.size();
1889 return true;
1890 }
1891
1892 for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1893 if (FirstHashes[I].second == SecondHashes[I].second)
1894 continue;
1895 const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1896 const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1897
1899 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1900 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1901 return true;
1902 }
1903
1906 if (!FirstInit && !SecondInit)
1907 continue;
1908
1909 if (!FirstInit || !SecondInit) {
1910 DiagError(FirstConstant, EnumConstantSingleInitializer)
1911 << I + 1 << FirstConstant << (FirstInit != nullptr);
1912 DiagNote(SecondConstant, EnumConstantSingleInitializer)
1913 << I + 1 << SecondConstant << (SecondInit != nullptr);
1914 return true;
1915 }
1916
1918 DiagError(FirstConstant, EnumConstantDifferentInitializer)
1919 << I + 1 << FirstConstant;
1920 DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1921 << I + 1 << SecondConstant;
1922 return true;
1923 }
1924 }
1925 return false;
1926}
1927
1930 const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {
1931
1932
1933 if (FirstID == SecondID)
1934 return false;
1935
1938
1939
1940 enum ODRInterfaceDifference {
1941 SuperClassType,
1942 IVarAccess,
1943 };
1944
1945 auto DiagError = [FirstID, &FirstModule,
1947 ODRInterfaceDifference DiffType) {
1948 return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1949 << FirstID << FirstModule.empty() << FirstModule << Range
1950 << DiffType;
1951 };
1953 ODRInterfaceDifference DiffType) {
1954 return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1955 << SecondModule.empty() << SecondModule << Range << DiffType;
1956 };
1957
1958 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1959 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1960 if (FirstDD != SecondDD) {
1961
1962 auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,
1964 if (!SuperInfo)
1965 return ID->getSourceRange();
1968 };
1969
1973 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1974 if (SecondSuperInfo)
1975 SecondSuperClass =
1977
1978 if ((FirstSuperClass && SecondSuperClass &&
1980 (FirstSuperClass && !SecondSuperClass) ||
1981 (!FirstSuperClass && SecondSuperClass)) {
1983 if (FirstSuperInfo)
1984 FirstType = FirstSuperInfo->getType();
1985
1987 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1988 SuperClassType)
1989 << (bool)FirstSuperInfo << FirstType;
1990
1992 if (SecondSuperInfo)
1993 SecondType = SecondSuperInfo->getType();
1994
1996 GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1997 SuperClassType)
1998 << (bool)SecondSuperInfo << SecondType;
1999 return true;
2000 }
2001
2002
2004 auto &SecondProtos = SecondDD->ReferencedProtocols;
2005 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2006 SecondProtos, SecondID, SecondModule))
2007 return true;
2008 }
2009
2012 for (auto *D : ID->decls()) {
2014 continue;
2016 }
2017 };
2018
2021
2022
2023 PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());
2024 PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());
2025
2026 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2027 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2028 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2029 const Decl *FirstDecl = DR.FirstDecl;
2030 const Decl *SecondDecl = DR.SecondDecl;
2031
2032 if (FirstDiffType == Other || SecondDiffType == Other) {
2033 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2034 SecondModule);
2035 return true;
2036 }
2037
2038 if (FirstDiffType != SecondDiffType) {
2039 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2040 SecondModule);
2041 return true;
2042 }
2043
2044 assert(FirstDiffType == SecondDiffType);
2045 switch (FirstDiffType) {
2046
2047 case EndOfClass:
2049
2050 case Field:
2051 case TypeDef:
2052 case Var:
2053
2054 case PublicSpecifer:
2055 case PrivateSpecifer:
2056 case ProtectedSpecifer:
2057 case StaticAssert:
2058 case CXXMethod:
2059 case TypeAlias:
2061 case FunctionTemplate:
2062 llvm_unreachable("Invalid diff type");
2063
2064 case ObjCMethod: {
2065 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2066 cast(FirstDecl),
2067 cast(SecondDecl)))
2068 return true;
2069 break;
2070 }
2071 case ObjCIvar: {
2072 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2073 cast(FirstDecl),
2074 cast(SecondDecl)))
2075 return true;
2076
2077
2078 const ObjCIvarDecl *FirstIvar = cast(FirstDecl);
2079 const ObjCIvarDecl *SecondIvar = cast(SecondDecl);
2083 IVarAccess)
2087 IVarAccess)
2088 << SecondIvar->getName()
2090 return true;
2091 }
2092 break;
2093 }
2094 case ObjCProperty: {
2095 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2096 cast(FirstDecl),
2097 cast(SecondDecl)))
2098 return true;
2099 break;
2100 }
2101 }
2102
2104 diag::err_module_odr_violation_mismatch_decl_unknown)
2105 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2108 diag::note_module_odr_violation_mismatch_decl_unknown)
2109 << SecondModule.empty() << SecondModule << FirstDiffType
2111 return true;
2112}
2113
2117 const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
2118 if (FirstProtocol == SecondProtocol)
2119 return false;
2120
2123
2124 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2125 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
2126
2127 if (FirstDD != SecondDD) {
2128
2131 const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
2132 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2133 SecondProtocols, SecondProtocol,
2134 SecondModule))
2135 return true;
2136 }
2137
2140 for (const Decl *D : ID->decls()) {
2142 continue;
2144 }
2145 };
2146
2149
2150
2151 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
2152 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
2153
2154 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2155 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2156 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2157 const Decl *FirstDecl = DR.FirstDecl;
2158 const Decl *SecondDecl = DR.SecondDecl;
2159
2160 if (FirstDiffType == Other || SecondDiffType == Other) {
2161 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2162 SecondProtocol, SecondModule);
2163 return true;
2164 }
2165
2166 if (FirstDiffType != SecondDiffType) {
2167 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2168 SecondProtocol, SecondModule);
2169 return true;
2170 }
2171
2172 assert(FirstDiffType == SecondDiffType);
2173 switch (FirstDiffType) {
2174
2175 case EndOfClass:
2177
2178 case Field:
2179 case TypeDef:
2180 case Var:
2181 case ObjCIvar:
2182
2183 case PublicSpecifer:
2184 case PrivateSpecifer:
2185 case ProtectedSpecifer:
2186 case StaticAssert:
2187 case CXXMethod:
2188 case TypeAlias:
2190 case FunctionTemplate:
2191 llvm_unreachable("Invalid diff type");
2192 case ObjCMethod: {
2193 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2194 cast(FirstDecl),
2195 cast(SecondDecl)))
2196 return true;
2197 break;
2198 }
2199 case ObjCProperty: {
2200 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2201 SecondModule,
2202 cast(FirstDecl),
2203 cast(SecondDecl)))
2204 return true;
2205 break;
2206 }
2207 }
2208
2210 diag::err_module_odr_violation_mismatch_decl_unknown)
2211 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2214 diag::note_module_odr_violation_mismatch_decl_unknown)
2215 << SecondModule.empty() << SecondModule << FirstDiffType
2217 return true;
2218}
Defines the C++ template declaration subclasses.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Defines the clang::Module class, which describes a module in the source code.
static unsigned computeODRHash(QualType Ty)
static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags, const NamedDecl *FirstContainer, StringRef FirstModule, StringRef SecondModule, const MethodT *FirstMethod, const MethodT *SecondMethod)
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Represents a base class of a C++ class.
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
Declaration of a class template.
Represents a pointer type decayed from an array or function type.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
SourceLocation getLocation() const
AccessSpecifier getAccess() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
An instance of this object exists for each enum constant that is defined.
const Expr * getInitExpr() const
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
SourceRange getSourceRange() const override LLVM_READONLY
Overrides to provide correct range when there's an enum-base specifier with forward declarations.
This represents one expression.
Represents a member of a struct/union/class.
bool isMutable() const
Determines whether this field is mutable (C++ only).
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
bool isBitField() const
Determines whether this field is a bitfield.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
SourceRange getSourceRange() const override LLVM_READONLY
Retrieves the source range for the friend declaration.
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
QualType getReturnType() const
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
unsigned getODRHash()
Returns ODRHash of the function.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isDeletedAsWritten() const
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
size_t param_size() const
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Declaration of a template function.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Describes a module or submodule.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
bool diagnoseMismatch(const FunctionDecl *FirstFunction, const FunctionDecl *SecondFunction) const
Diagnose ODR mismatch between 2 FunctionDecl.
static std::string getOwningModuleNameForDiagnostic(const Decl *D)
Get the best name we know for the module that owns the given declaration, or an empty string if the d...
void AddStmt(const Stmt *S)
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
void AddSubDecl(const Decl *D)
void AddQualType(QualType T)
void AddTemplateParameterList(const TemplateParameterList *TPL)
void AddTemplateArgument(TemplateArgument TA)
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
ObjCContainerDecl - Represents a container for method declarations.
Represents an ObjC class declaration.
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
const ObjCProtocolList & getReferencedProtocols() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
TypeSourceInfo * getSuperClassTInfo() const
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getCanonicalAccessControl() const
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isInstanceMethod() const
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
QualType getReturnType() const
ObjCImplementationControl getImplementationControl() const
Represents a class type in Objective C.
Represents one property declaration in an Objective-C interface.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getLParenLoc() const
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
PropertyControl getPropertyImplementation() const
Represents an Objective-C protocol declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
A list of Objective-C protocols, along with the source locations at which they were referenced.
loc_iterator loc_begin() const
Represents a parameter to a function.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Represents a struct/union/class.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Represents a C++11 static_assert declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
A template argument list.
const TemplateArgument & getArgument() const
Represents a template argument.
@ Pack
The template argument is actually a parameter pack.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< NamedDecl * > asArray()
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Base wrapper for a particular "section" of type source info.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
const T * castAs() const
Member-template castAs.
const T * getAs() const
Member-template getAs'.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const Expr * getInit() const
The JSON file list parser is used to communicate input to InstallAPI.
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
StorageClass
Storage classes.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.