clang 24.0.0git
ODRDiagsEmitter.cpp
Go to the documentation of this file.
1//===-- ODRDiagsEmitter.cpp - Diagnostics for ODR mismatches ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "clang/AST/ODRHash.h"
14#include "clang/Basic/Module.h"
15
16using namespace clang;
17
18static unsigned computeODRHash(QualType Ty) {
19 ODRHash Hasher;
20 Hasher.AddQualType(Ty);
21 return Hasher.CalculateHash();
22}
23
24static unsigned computeODRHash(const Stmt *S) {
25 ODRHash Hasher;
26 Hasher.AddStmt(S);
27 return Hasher.CalculateHash();
28}
29
30static unsigned computeODRHash(const Decl *D) {
31 assert(D);
32 ODRHash Hasher;
33 Hasher.AddSubDecl(D);
34 return Hasher.CalculateHash();
35}
36
37static unsigned computeODRHash(const TemplateArgument &TA) {
38 ODRHash Hasher;
39 Hasher.AddTemplateArgument(TA);
40 return Hasher.CalculateHash();
41}
42
44 // If we know the owning module, use it.
45 if (Module *M = D->getImportedOwningModule())
46 return M->getFullModuleName();
47
48 // Not from a module.
49 return {};
50}
51
52template <typename MethodT>
54 const NamedDecl *FirstContainer,
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) {
66 return DiagConstructor;
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) {
79 DeclarationName FirstName = FirstMethod->getDeclName();
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) {
89 DeclarationName SecondName = SecondMethod->getDeclName();
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
110 QualType FirstParamType = FirstParam->getType();
111 QualType SecondParamType = SecondParam->getType();
112 if (FirstParamType != SecondParamType &&
113 computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
114 if (const DecayedType *ParamDecayedType =
115 FirstParamType->getAs<DecayedType>()) {
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 =
123 SecondParamType->getAs<DecayedType>()) {
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
132 DeclarationName FirstParamName = FirstParam->getDeclName();
133 DeclarationName SecondParamName = SecondParam->getDeclName();
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,
146 const FieldDecl *FirstField, const FieldDecl *SecondField) const {
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
161 << FirstField->getSourceRange() << DiffType;
162 };
163 auto DiagNote = [SecondField, SecondModule,
164 this](ODRFieldDifference DiffType) {
165 return Diag(SecondField->getLocation(),
166 diag::note_module_odr_violation_field)
167 << SecondModule.empty() << SecondModule << SecondField->getSourceRange() << DiffType;
168 };
169
170 IdentifierInfo *FirstII = FirstField->getIdentifier();
171 IdentifierInfo *SecondII = SecondField->getIdentifier();
172 if (FirstII->getName() != SecondII->getName()) {
173 DiagError(FieldName) << FirstII;
174 DiagNote(FieldName) << SecondII;
175 return true;
176 }
177
178 QualType FirstType = FirstField->getType();
179 QualType SecondType = SecondField->getType();
180 if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
181 DiagError(FieldTypeName) << FirstII << FirstType;
182 DiagNote(FieldTypeName) << SecondII << SecondType;
183 return true;
184 }
185
186 assert(Context.hasSameType(FirstField->getType(), SecondField->getType()));
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) {
198 unsigned FirstBitWidthHash = computeODRHash(FirstField->getBitWidth());
199 unsigned SecondBitWidthHash = computeODRHash(SecondField->getBitWidth());
200 if (FirstBitWidthHash != SecondBitWidthHash) {
201 DiagError(FieldDifferentWidthBitField)
202 << FirstII << FirstField->getBitWidth()->getSourceRange();
203 DiagNote(FieldDifferentWidthBitField)
204 << SecondII << SecondField->getBitWidth()->getSourceRange();
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
220 const Expr *FirstInitializer = FirstField->getInClassInitializer();
221 const Expr *SecondInitializer = SecondField->getInClassInitializer();
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)
236 << FirstII << FirstInitializer->getSourceRange();
237 DiagNote(FieldDifferentInitializers)
238 << SecondII << SecondInitializer->getSourceRange();
239 return true;
240 }
241 }
242
243 return false;
244}
245
246bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
248 const TypedefNameDecl *FirstTD, const TypedefNameDecl *SecondTD,
249 bool IsTypeAlias) const {
250 enum ODRTypedefDifference {
251 TypedefName,
252 TypedefType,
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
259 << FirstTD->getSourceRange() << DiffType;
260 };
261 auto DiagNote = [SecondTD, SecondModule,
262 this](ODRTypedefDifference DiffType) {
263 return Diag(SecondTD->getLocation(),
264 diag::note_module_odr_violation_typedef)
265 << SecondModule << SecondTD->getSourceRange() << DiffType;
266 };
267
268 DeclarationName FirstName = FirstTD->getDeclName();
269 DeclarationName SecondName = SecondTD->getDeclName();
270 if (FirstName != SecondName) {
271 DiagError(TypedefName) << IsTypeAlias << FirstName;
272 DiagNote(TypedefName) << IsTypeAlias << SecondName;
273 return true;
274 }
275
276 QualType FirstType = FirstTD->getUnderlyingType();
277 QualType SecondType = SecondTD->getUnderlyingType();
278 if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
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,
289 const VarDecl *FirstVD,
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
303 << FirstVD->getSourceRange() << DiffType;
304 };
305 auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) {
306 return Diag(SecondVD->getLocation(),
307 diag::note_module_odr_violation_variable)
308 << SecondModule << SecondVD->getSourceRange() << DiffType;
309 };
310
311 DeclarationName FirstName = FirstVD->getDeclName();
312 DeclarationName SecondName = SecondVD->getDeclName();
313 if (FirstName != SecondName) {
314 DiagError(VarName) << FirstName;
315 DiagNote(VarName) << SecondName;
316 return true;
317 }
318
319 QualType FirstType = FirstVD->getType();
320 QualType SecondType = SecondVD->getType();
321 if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
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 &&
343 computeODRHash(FirstInit) != computeODRHash(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(
362 const ObjCProtocolList &FirstProtocols,
363 const ObjCContainerDecl *FirstContainer, StringRef FirstModule,
364 const ObjCProtocolList &SecondProtocols,
365 const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const {
366 // Keep in sync with err_module_odr_violation_referenced_protocols.
367 enum ODRReferencedProtocolDifference {
368 NumProtocols,
369 ProtocolType,
370 };
371 auto DiagRefProtocolError = [FirstContainer, FirstModule,
372 this](SourceLocation Loc, SourceRange Range,
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,
379 this](SourceLocation Loc, SourceRange Range,
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())
386 return SourceRange();
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) {
401 const ObjCProtocolDecl *FirstProtocol = FirstProtocols[I];
402 const ObjCProtocolDecl *SecondProtocol = SecondProtocols[I];
403 DeclarationName FirstProtocolName = FirstProtocol->getDeclName();
404 DeclarationName SecondProtocolName = SecondProtocol->getDeclName();
405 if (FirstProtocolName != SecondProtocolName) {
406 SourceLocation FirstLoc = *(FirstProtocols.loc_begin() + I);
407 SourceLocation SecondLoc = *(SecondProtocols.loc_begin() + I);
408 SourceRange EmptyRange;
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,
423 const ObjCMethodDecl *SecondMethod) const {
424 enum ODRMethodDifference {
425 ReturnType,
426 InstanceOrClass,
427 ControlLevel, // optional/required
428 DesignatedInitializer,
429 Directness,
430 Name,
431 };
432
433 auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434 this](ODRMethodDifference DiffType) {
435 return Diag(FirstMethod->getLocation(),
436 diag::err_module_odr_violation_objc_method)
437 << FirstObjCContainer << FirstModule.empty() << FirstModule
438 << FirstMethod->getSourceRange() << DiffType;
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
448 if (computeODRHash(FirstMethod->getReturnType()) !=
449 computeODRHash(SecondMethod->getReturnType())) {
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)
457 << FirstMethod << FirstMethod->isInstanceMethod();
458 DiagNote(InstanceOrClass)
459 << SecondMethod << SecondMethod->isInstanceMethod();
460 return true;
461 }
462 if (FirstMethod->getImplementationControl() !=
463 SecondMethod->getImplementationControl()) {
464 DiagError(ControlLevel) << FirstMethod->getImplementationControl();
465 DiagNote(ControlLevel) << SecondMethod->getImplementationControl();
466 return true;
467 }
468 if (FirstMethod->isThisDeclarationADesignatedInitializer() !=
469 SecondMethod->isThisDeclarationADesignatedInitializer()) {
470 DiagError(DesignatedInitializer)
471 << FirstMethod
473 DiagNote(DesignatedInitializer)
474 << SecondMethod
475 << SecondMethod->isThisDeclarationADesignatedInitializer();
476 return true;
477 }
478 if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {
479 DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();
480 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
481 return true;
482 }
483 if (diagnoseSubMismatchMethodParameters(Diags, FirstObjCContainer,
484 FirstModule, SecondModule,
485 FirstMethod, SecondMethod))
486 return true;
487
488 // Check method name *after* looking at the parameters otherwise we get a
489 // less ideal diagnostics: a ObjCMethodName mismatch given that selectors
490 // for different parameters are likely to be different.
491 DeclarationName FirstName = FirstMethod->getDeclName();
492 DeclarationName SecondName = SecondMethod->getDeclName();
493 if (FirstName != SecondName) {
494 DiagError(Name) << FirstName;
495 DiagNote(Name) << SecondName;
496 return true;
497 }
498
499 return false;
500}
501
502bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
503 const NamedDecl *FirstObjCContainer, StringRef FirstModule,
504 StringRef SecondModule, const ObjCPropertyDecl *FirstProp,
505 const ObjCPropertyDecl *SecondProp) const {
506 enum ODRPropertyDifference {
507 Name,
508 Type,
509 ControlLevel, // optional/required
510 Attribute,
511 };
512
513 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
514 this](SourceLocation Loc, ODRPropertyDifference DiffType) {
515 return Diag(Loc, diag::err_module_odr_violation_objc_property)
516 << FirstObjCContainer << FirstModule.empty() << FirstModule
517 << FirstProp->getSourceRange() << DiffType;
518 };
519 auto DiagNote = [SecondModule, SecondProp,
520 this](SourceLocation Loc, ODRPropertyDifference DiffType) {
521 return Diag(Loc, diag::note_module_odr_violation_objc_property)
522 << SecondModule.empty() << SecondModule
523 << SecondProp->getSourceRange() << DiffType;
524 };
525
526 IdentifierInfo *FirstII = FirstProp->getIdentifier();
527 IdentifierInfo *SecondII = SecondProp->getIdentifier();
528 if (FirstII->getName() != SecondII->getName()) {
529 DiagError(FirstProp->getLocation(), Name) << FirstII;
530 DiagNote(SecondProp->getLocation(), Name) << SecondII;
531 return true;
532 }
533 if (computeODRHash(FirstProp->getType()) !=
534 computeODRHash(SecondProp->getType())) {
535 DiagError(FirstProp->getLocation(), Type)
536 << FirstII << FirstProp->getType();
537 DiagNote(SecondProp->getLocation(), Type)
538 << SecondII << SecondProp->getType();
539 return true;
540 }
541 if (FirstProp->getPropertyImplementation() !=
542 SecondProp->getPropertyImplementation()) {
543 DiagError(FirstProp->getLocation(), ControlLevel)
544 << FirstProp->getPropertyImplementation();
545 DiagNote(SecondProp->getLocation(), ControlLevel)
546 << SecondProp->getPropertyImplementation();
547 return true;
548 }
549
550 // Go over the property attributes and stop at the first mismatch.
551 unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes();
552 unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();
553 if (FirstAttrs != SecondAttrs) {
554 for (unsigned I = 0; I < NumObjCPropertyAttrsBits; ++I) {
555 unsigned CheckedAttr = (1 << I);
556 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
557 continue;
558
559 bool IsFirstWritten =
560 (unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr;
561 bool IsSecondWritten =
562 (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
563 DiagError(IsFirstWritten ? FirstProp->getLParenLoc()
564 : FirstProp->getLocation(),
565 Attribute)
566 << FirstII << (I + 1) << IsFirstWritten;
567 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()
568 : SecondProp->getLocation(),
569 Attribute)
570 << SecondII << (I + 1);
571 return true;
572 }
573 }
574
575 return false;
576}
577
578ODRDiagsEmitter::DiffResult
579ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
580 DeclHashes &SecondHashes) {
581 auto DifferenceSelector = [](const Decl *D) {
582 assert(D && "valid Decl required");
583 switch (D->getKind()) {
584 default:
585 return Other;
586 case Decl::AccessSpec:
587 switch (D->getAccess()) {
588 case AS_public:
589 return PublicSpecifer;
590 case AS_private:
591 return PrivateSpecifer;
592 case AS_protected:
593 return ProtectedSpecifer;
594 case AS_none:
595 break;
596 }
597 llvm_unreachable("Invalid access specifier");
598 case Decl::StaticAssert:
599 return StaticAssert;
600 case Decl::Field:
601 return Field;
602 case Decl::CXXMethod:
603 case Decl::CXXConstructor:
604 case Decl::CXXDestructor:
605 return CXXMethod;
606 case Decl::TypeAlias:
607 return TypeAlias;
608 case Decl::Typedef:
609 return TypeDef;
610 case Decl::Var:
611 return Var;
612 case Decl::Friend:
613 return Friend;
614 case Decl::FunctionTemplate:
615 return FunctionTemplate;
616 case Decl::ObjCMethod:
617 return ObjCMethod;
618 case Decl::ObjCIvar:
619 return ObjCIvar;
620 case Decl::ObjCProperty:
621 return ObjCProperty;
622 }
623 };
624
625 DiffResult DR;
626 auto FirstIt = FirstHashes.begin();
627 auto SecondIt = SecondHashes.begin();
628 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
629 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
630 FirstIt->second == SecondIt->second) {
631 ++FirstIt;
632 ++SecondIt;
633 continue;
634 }
635
636 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
637 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
638
639 DR.FirstDiffType =
640 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
641 DR.SecondDiffType =
642 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
643 return DR;
644 }
645 return DR;
646}
647
648void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
649 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
650 const NamedDecl *SecondRecord, StringRef SecondModule) const {
651 Diag(FirstRecord->getLocation(),
652 diag::err_module_odr_violation_different_definitions)
653 << FirstRecord << FirstModule.empty() << FirstModule;
654
655 if (DR.FirstDecl) {
656 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
657 << FirstRecord << DR.FirstDecl->getSourceRange();
658 }
659
660 Diag(SecondRecord->getLocation(),
661 diag::note_module_odr_violation_different_definitions)
662 << SecondModule;
663
664 if (DR.SecondDecl) {
665 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
666 << DR.SecondDecl->getSourceRange();
667 }
668}
669
670void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
671 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
672 const NamedDecl *SecondRecord, StringRef SecondModule) const {
673 auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
674 ODRMismatchDecl DiffType, const Decl *D) {
675 SourceLocation Loc;
676 SourceRange Range;
677 if (DiffType == EndOfClass) {
678 if (auto *Tag = dyn_cast<TagDecl>(Container))
679 Loc = Tag->getBraceRange().getEnd();
680 else if (auto *IF = dyn_cast<ObjCInterfaceDecl>(Container))
681 Loc = IF->getAtEndRange().getBegin();
682 else
683 Loc = Container->getEndLoc();
684 } else {
685 Loc = D->getLocation();
686 Range = D->getSourceRange();
687 }
688 return std::make_pair(Loc, Range);
689 };
690
691 auto FirstDiagInfo =
692 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
693 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
694 << FirstRecord << FirstModule.empty() << FirstModule
695 << FirstDiagInfo.second << DR.FirstDiffType;
696
697 auto SecondDiagInfo =
698 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
699 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
700 << SecondModule.empty() << SecondModule << SecondDiagInfo.second
701 << DR.SecondDiffType;
702}
703
705 const CXXRecordDecl *FirstRecord, const CXXRecordDecl *SecondRecord,
706 const struct CXXRecordDecl::DefinitionData *SecondDD) const {
707 // Multiple different declarations got merged together; tell the user
708 // where they came from.
709 if (FirstRecord == SecondRecord)
710 return false;
711
712 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
713 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
714
715 const struct CXXRecordDecl::DefinitionData *FirstDD =
716 FirstRecord->DefinitionData;
717 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
718
719 // Diagnostics from DefinitionData are emitted here.
720 if (FirstDD != SecondDD) {
721 // Keep in sync with err_module_odr_violation_definition_data.
722 enum ODRDefinitionDataDifference {
723 NumBases,
724 NumVBases,
725 BaseType,
726 BaseVirtual,
727 BaseAccess,
728 };
729 auto DiagBaseError = [FirstRecord, &FirstModule,
730 this](SourceLocation Loc, SourceRange Range,
731 ODRDefinitionDataDifference DiffType) {
732 return Diag(Loc, diag::err_module_odr_violation_definition_data)
733 << FirstRecord << FirstModule.empty() << FirstModule << Range
734 << DiffType;
735 };
736 auto DiagBaseNote = [&SecondModule,
737 this](SourceLocation Loc, SourceRange Range,
738 ODRDefinitionDataDifference DiffType) {
739 return Diag(Loc, diag::note_module_odr_violation_definition_data)
740 << SecondModule << Range << DiffType;
741 };
742 auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {
743 unsigned NumBases = DD->NumBases;
744 if (NumBases == 0)
745 return SourceRange();
746 ArrayRef<CXXBaseSpecifier> bases = DD->bases();
747 return SourceRange(bases[0].getBeginLoc(),
748 bases[NumBases - 1].getEndLoc());
749 };
750
751 unsigned FirstNumBases = FirstDD->NumBases;
752 unsigned FirstNumVBases = FirstDD->NumVBases;
753 unsigned SecondNumBases = SecondDD->NumBases;
754 unsigned SecondNumVBases = SecondDD->NumVBases;
755 if (FirstNumBases != SecondNumBases) {
756 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
757 NumBases)
758 << FirstNumBases;
759 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
760 NumBases)
761 << SecondNumBases;
762 return true;
763 }
764
765 if (FirstNumVBases != SecondNumVBases) {
766 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
767 NumVBases)
768 << FirstNumVBases;
769 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
770 NumVBases)
771 << SecondNumVBases;
772 return true;
773 }
774
775 ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
776 ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
777 for (unsigned I = 0; I < FirstNumBases; ++I) {
778 const CXXBaseSpecifier FirstBase = FirstBases[I];
779 const CXXBaseSpecifier SecondBase = SecondBases[I];
780 if (computeODRHash(FirstBase.getType()) !=
781 computeODRHash(SecondBase.getType())) {
782 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
783 BaseType)
784 << (I + 1) << FirstBase.getType();
785 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
786 BaseType)
787 << (I + 1) << SecondBase.getType();
788 return true;
789 }
790
791 if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
792 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
793 BaseVirtual)
794 << (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
795 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
796 BaseVirtual)
797 << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
798 return true;
799 }
800
801 if (FirstBase.getAccessSpecifierAsWritten() !=
802 SecondBase.getAccessSpecifierAsWritten()) {
803 DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
804 BaseAccess)
805 << (I + 1) << FirstBase.getType()
806 << (int)FirstBase.getAccessSpecifierAsWritten();
807 DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
808 BaseAccess)
809 << (I + 1) << SecondBase.getType()
810 << (int)SecondBase.getAccessSpecifierAsWritten();
811 return true;
812 }
813 }
814 }
815
816 const ClassTemplateDecl *FirstTemplate =
817 FirstRecord->getDescribedClassTemplate();
818 const ClassTemplateDecl *SecondTemplate =
819 SecondRecord->getDescribedClassTemplate();
820
821 assert(!FirstTemplate == !SecondTemplate &&
822 "Both pointers should be null or non-null");
823
824 if (FirstTemplate && SecondTemplate) {
825 ArrayRef<const NamedDecl *> FirstTemplateParams =
826 FirstTemplate->getTemplateParameters()->asArray();
827 ArrayRef<const NamedDecl *> SecondTemplateParams =
828 SecondTemplate->getTemplateParameters()->asArray();
829 assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
830 "Number of template parameters should be equal.");
831 for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {
832 const NamedDecl *FirstDecl = std::get<0>(Pair);
833 const NamedDecl *SecondDecl = std::get<1>(Pair);
834 if (computeODRHash(FirstDecl) == computeODRHash(SecondDecl))
835 continue;
836
837 assert(FirstDecl->getKind() == SecondDecl->getKind() &&
838 "Parameter Decl's should be the same kind.");
839
840 enum ODRTemplateDifference {
841 ParamEmptyName,
842 ParamName,
843 ParamSingleDefaultArgument,
844 ParamDifferentDefaultArgument,
845 };
846
847 auto hasDefaultArg = [](const NamedDecl *D) {
848 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
849 return TTP->hasDefaultArgument() &&
850 !TTP->defaultArgumentWasInherited();
851 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
852 return NTTP->hasDefaultArgument() &&
853 !NTTP->defaultArgumentWasInherited();
854 auto *TTP = cast<TemplateTemplateParmDecl>(D);
855 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
856 };
857 bool hasFirstArg = hasDefaultArg(FirstDecl);
858 bool hasSecondArg = hasDefaultArg(SecondDecl);
859
860 ODRTemplateDifference ErrDiffType;
861 ODRTemplateDifference NoteDiffType;
862
863 DeclarationName FirstName = FirstDecl->getDeclName();
864 DeclarationName SecondName = SecondDecl->getDeclName();
865
866 if (FirstName != SecondName) {
867 bool FirstNameEmpty =
868 FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
869 bool SecondNameEmpty =
870 SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
871 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
872 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
873 } else if (hasFirstArg == hasSecondArg)
874 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
875 else
876 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
877
878 Diag(FirstDecl->getLocation(),
879 diag::err_module_odr_violation_template_parameter)
880 << FirstRecord << FirstModule.empty() << FirstModule
881 << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
882 << FirstName;
883 Diag(SecondDecl->getLocation(),
884 diag::note_module_odr_violation_template_parameter)
885 << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
886 << hasSecondArg << SecondName;
887 return true;
888 }
889 }
890
891 auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
892 const DeclContext *DC) {
893 for (const Decl *D : Record->decls()) {
895 continue;
896 Hashes.emplace_back(D, computeODRHash(D));
897 }
898 };
899
900 DeclHashes FirstHashes;
901 DeclHashes SecondHashes;
902 const DeclContext *DC = FirstRecord;
903 PopulateHashes(FirstHashes, FirstRecord, DC);
904 PopulateHashes(SecondHashes, SecondRecord, DC);
905
906 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
907 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
908 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
909 const Decl *FirstDecl = DR.FirstDecl;
910 const Decl *SecondDecl = DR.SecondDecl;
911
912 if (FirstDiffType == Other || SecondDiffType == Other) {
913 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
914 SecondModule);
915 return true;
916 }
917
918 if (FirstDiffType != SecondDiffType) {
919 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
920 SecondRecord, SecondModule);
921 return true;
922 }
923
924 // Used with err_module_odr_violation_record and
925 // note_module_odr_violation_record
926 enum ODRCXXRecordDifference {
927 StaticAssertCondition,
928 StaticAssertMessage,
929 StaticAssertOnlyMessage,
930 MethodName,
931 MethodDeleted,
932 MethodDefaulted,
933 MethodVirtual,
934 MethodStatic,
935 MethodVolatile,
936 MethodConst,
937 MethodInline,
938 MethodParameterSingleDefaultArgument,
939 MethodParameterDifferentDefaultArgument,
940 MethodNoTemplateArguments,
941 MethodDifferentNumberTemplateArguments,
942 MethodDifferentTemplateArgument,
943 MethodSingleBody,
944 MethodDifferentBody,
945 FriendTypeFunction,
946 FriendType,
947 FriendFunction,
948 FunctionTemplateDifferentNumberParameters,
949 FunctionTemplateParameterDifferentKind,
950 FunctionTemplateParameterName,
951 FunctionTemplateParameterSingleDefaultArgument,
952 FunctionTemplateParameterDifferentDefaultArgument,
953 FunctionTemplateParameterDifferentType,
954 FunctionTemplatePackParameter,
955 };
956 auto DiagError = [FirstRecord, &FirstModule,
957 this](SourceLocation Loc, SourceRange Range,
958 ODRCXXRecordDifference DiffType) {
959 return Diag(Loc, diag::err_module_odr_violation_record)
960 << FirstRecord << FirstModule.empty() << FirstModule << Range
961 << DiffType;
962 };
963 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
964 ODRCXXRecordDifference DiffType) {
965 return Diag(Loc, diag::note_module_odr_violation_record)
966 << SecondModule << Range << DiffType;
967 };
968
969 assert(FirstDiffType == SecondDiffType);
970 switch (FirstDiffType) {
971 case Other:
972 case EndOfClass:
973 case PublicSpecifer:
974 case PrivateSpecifer:
975 case ProtectedSpecifer:
976 case ObjCMethod:
977 case ObjCIvar:
978 case ObjCProperty:
979 llvm_unreachable("Invalid diff type");
980
981 case StaticAssert: {
982 const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
983 const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
984
985 const Expr *FirstExpr = FirstSA->getAssertExpr();
986 const Expr *SecondExpr = SecondSA->getAssertExpr();
987 unsigned FirstODRHash = computeODRHash(FirstExpr);
988 unsigned SecondODRHash = computeODRHash(SecondExpr);
989 if (FirstODRHash != SecondODRHash) {
990 DiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(),
991 StaticAssertCondition);
992 DiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(),
993 StaticAssertCondition);
994 return true;
995 }
996
997 const Expr *FirstMessage = FirstSA->getMessage();
998 const Expr *SecondMessage = SecondSA->getMessage();
999 assert((FirstMessage || SecondMessage) && "Both messages cannot be empty");
1000 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {
1001 SourceLocation FirstLoc, SecondLoc;
1002 SourceRange FirstRange, SecondRange;
1003 if (FirstMessage) {
1004 FirstLoc = FirstMessage->getBeginLoc();
1005 FirstRange = FirstMessage->getSourceRange();
1006 } else {
1007 FirstLoc = FirstSA->getBeginLoc();
1008 FirstRange = FirstSA->getSourceRange();
1009 }
1010 if (SecondMessage) {
1011 SecondLoc = SecondMessage->getBeginLoc();
1012 SecondRange = SecondMessage->getSourceRange();
1013 } else {
1014 SecondLoc = SecondSA->getBeginLoc();
1015 SecondRange = SecondSA->getSourceRange();
1016 }
1017 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1018 << (FirstMessage == nullptr);
1019 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1020 << (SecondMessage == nullptr);
1021 return true;
1022 }
1023
1024 if (FirstMessage && SecondMessage) {
1025 unsigned FirstMessageODRHash = computeODRHash(FirstMessage);
1026 unsigned SecondMessageODRHash = computeODRHash(SecondMessage);
1027 if (FirstMessageODRHash != SecondMessageODRHash) {
1028 DiagError(FirstMessage->getBeginLoc(), FirstMessage->getSourceRange(),
1029 StaticAssertMessage);
1030 DiagNote(SecondMessage->getBeginLoc(), SecondMessage->getSourceRange(),
1031 StaticAssertMessage);
1032 return true;
1033 }
1034 }
1035 break;
1036 }
1037
1038 case Field: {
1039 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1040 cast<FieldDecl>(FirstDecl),
1041 cast<FieldDecl>(SecondDecl)))
1042 return true;
1043 break;
1044 }
1045
1046 case CXXMethod: {
1047 enum {
1048 DiagMethod,
1049 DiagConstructor,
1050 DiagDestructor,
1051 } FirstMethodType,
1052 SecondMethodType;
1053 auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {
1055 return DiagConstructor;
1057 return DiagDestructor;
1058 return DiagMethod;
1059 };
1060 const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1061 const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1062 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1063 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1064 DeclarationName FirstName = FirstMethod->getDeclName();
1065 DeclarationName SecondName = SecondMethod->getDeclName();
1066 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1067 FirstName](ODRCXXRecordDifference DiffType) {
1068 return DiagError(FirstMethod->getLocation(),
1069 FirstMethod->getSourceRange(), DiffType)
1070 << FirstMethodType << FirstName;
1071 };
1072 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1073 SecondName](ODRCXXRecordDifference DiffType) {
1074 return DiagNote(SecondMethod->getLocation(),
1075 SecondMethod->getSourceRange(), DiffType)
1076 << SecondMethodType << SecondName;
1077 };
1078
1079 if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
1080 DiagMethodError(MethodName);
1081 DiagMethodNote(MethodName);
1082 return true;
1083 }
1084
1085 const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
1086 const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
1087 if (FirstDeleted != SecondDeleted) {
1088 DiagMethodError(MethodDeleted) << FirstDeleted;
1089 DiagMethodNote(MethodDeleted) << SecondDeleted;
1090 return true;
1091 }
1092
1093 const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
1094 const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
1095 if (FirstDefaulted != SecondDefaulted) {
1096 DiagMethodError(MethodDefaulted) << FirstDefaulted;
1097 DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1098 return true;
1099 }
1100
1101 const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
1102 const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
1103 const bool FirstPure = FirstMethod->isPureVirtual();
1104 const bool SecondPure = SecondMethod->isPureVirtual();
1105 if ((FirstVirtual || SecondVirtual) &&
1106 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
1107 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1108 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1109 return true;
1110 }
1111
1112 // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
1113 // FirstDecl is the canonical Decl of SecondDecl, so the storage
1114 // class needs to be checked instead.
1115 StorageClass FirstStorage = FirstMethod->getStorageClass();
1116 StorageClass SecondStorage = SecondMethod->getStorageClass();
1117 const bool FirstStatic = FirstStorage == SC_Static;
1118 const bool SecondStatic = SecondStorage == SC_Static;
1119 if (FirstStatic != SecondStatic) {
1120 DiagMethodError(MethodStatic) << FirstStatic;
1121 DiagMethodNote(MethodStatic) << SecondStatic;
1122 return true;
1123 }
1124
1125 const bool FirstVolatile = FirstMethod->isVolatile();
1126 const bool SecondVolatile = SecondMethod->isVolatile();
1127 if (FirstVolatile != SecondVolatile) {
1128 DiagMethodError(MethodVolatile) << FirstVolatile;
1129 DiagMethodNote(MethodVolatile) << SecondVolatile;
1130 return true;
1131 }
1132
1133 const bool FirstConst = FirstMethod->isConst();
1134 const bool SecondConst = SecondMethod->isConst();
1135 if (FirstConst != SecondConst) {
1136 DiagMethodError(MethodConst) << FirstConst;
1137 DiagMethodNote(MethodConst) << SecondConst;
1138 return true;
1139 }
1140
1141 const bool FirstInline = FirstMethod->isInlineSpecified();
1142 const bool SecondInline = SecondMethod->isInlineSpecified();
1143 if (FirstInline != SecondInline) {
1144 DiagMethodError(MethodInline) << FirstInline;
1145 DiagMethodNote(MethodInline) << SecondInline;
1146 return true;
1147 }
1148
1149 if (diagnoseSubMismatchMethodParameters(Diags, FirstRecord,
1150 FirstModule, SecondModule,
1151 FirstMethod, SecondMethod))
1152 return true;
1153
1154 for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) {
1155 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
1156 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
1157
1158 const Expr *FirstInit = FirstParam->getInit();
1159 const Expr *SecondInit = SecondParam->getInit();
1160 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1161 DiagMethodError(MethodParameterSingleDefaultArgument)
1162 << (I + 1) << (FirstInit == nullptr)
1163 << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1164 DiagMethodNote(MethodParameterSingleDefaultArgument)
1165 << (I + 1) << (SecondInit == nullptr)
1166 << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1167 return true;
1168 }
1169
1170 if (FirstInit && SecondInit &&
1171 computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1172 DiagMethodError(MethodParameterDifferentDefaultArgument)
1173 << (I + 1) << FirstInit->getSourceRange();
1174 DiagMethodNote(MethodParameterDifferentDefaultArgument)
1175 << (I + 1) << SecondInit->getSourceRange();
1176 return true;
1177 }
1178 }
1179
1180 const TemplateArgumentList *FirstTemplateArgs =
1181 FirstMethod->getTemplateSpecializationArgs();
1182 const TemplateArgumentList *SecondTemplateArgs =
1183 SecondMethod->getTemplateSpecializationArgs();
1184
1185 if ((FirstTemplateArgs && !SecondTemplateArgs) ||
1186 (!FirstTemplateArgs && SecondTemplateArgs)) {
1187 DiagMethodError(MethodNoTemplateArguments)
1188 << (FirstTemplateArgs != nullptr);
1189 DiagMethodNote(MethodNoTemplateArguments)
1190 << (SecondTemplateArgs != nullptr);
1191 return true;
1192 }
1193
1194 if (FirstTemplateArgs && SecondTemplateArgs) {
1195 // Remove pack expansions from argument list.
1196 auto ExpandTemplateArgumentList = [](const TemplateArgumentList *TAL) {
1198 for (const TemplateArgument &TA : TAL->asArray()) {
1199 if (TA.getKind() != TemplateArgument::Pack) {
1200 ExpandedList.push_back(&TA);
1201 continue;
1202 }
1203 llvm::append_range(ExpandedList,
1204 llvm::make_pointer_range(TA.getPackAsArray()));
1205 }
1206 return ExpandedList;
1207 };
1209 ExpandTemplateArgumentList(FirstTemplateArgs);
1211 ExpandTemplateArgumentList(SecondTemplateArgs);
1212
1213 if (FirstExpandedList.size() != SecondExpandedList.size()) {
1214 DiagMethodError(MethodDifferentNumberTemplateArguments)
1215 << (unsigned)FirstExpandedList.size();
1216 DiagMethodNote(MethodDifferentNumberTemplateArguments)
1217 << (unsigned)SecondExpandedList.size();
1218 return true;
1219 }
1220
1221 for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
1222 const TemplateArgument &FirstTA = *FirstExpandedList[i],
1223 &SecondTA = *SecondExpandedList[i];
1224 if (computeODRHash(FirstTA) == computeODRHash(SecondTA))
1225 continue;
1226
1227 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1228 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1229 return true;
1230 }
1231 }
1232
1233 // Compute the hash of the method as if it has no body.
1234 auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
1235 ODRHash Hasher;
1236 Hasher.AddFunctionDecl(D, true /*SkipBody*/);
1237 return Hasher.CalculateHash();
1238 };
1239
1240 // Compare the hash generated to the hash stored. A difference means
1241 // that a body was present in the original source. Due to merging,
1242 // the standard way of detecting a body will not work.
1243 const bool HasFirstBody =
1244 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
1245 const bool HasSecondBody =
1246 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
1247
1248 if (HasFirstBody != HasSecondBody) {
1249 DiagMethodError(MethodSingleBody) << HasFirstBody;
1250 DiagMethodNote(MethodSingleBody) << HasSecondBody;
1251 return true;
1252 }
1253
1254 if (HasFirstBody && HasSecondBody) {
1255 DiagMethodError(MethodDifferentBody);
1256 DiagMethodNote(MethodDifferentBody);
1257 return true;
1258 }
1259
1260 break;
1261 }
1262
1263 case TypeAlias:
1264 case TypeDef: {
1265 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1266 cast<TypedefNameDecl>(FirstDecl),
1267 cast<TypedefNameDecl>(SecondDecl),
1268 FirstDiffType == TypeAlias))
1269 return true;
1270 break;
1271 }
1272 case Var: {
1273 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1274 cast<VarDecl>(FirstDecl),
1275 cast<VarDecl>(SecondDecl)))
1276 return true;
1277 break;
1278 }
1279 case Friend: {
1280 const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1281 const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1282
1283 const NamedDecl *FirstND = FirstFriend->getFriendDecl();
1284 const NamedDecl *SecondND = SecondFriend->getFriendDecl();
1285
1286 TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
1287 TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
1288
1289 if (FirstND && SecondND) {
1290 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1291 FriendFunction)
1292 << FirstND;
1293 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1294 FriendFunction)
1295 << SecondND;
1296 return true;
1297 }
1298
1299 if (FirstTSI && SecondTSI) {
1300 QualType FirstFriendType = FirstTSI->getType();
1301 QualType SecondFriendType = SecondTSI->getType();
1302 assert(computeODRHash(FirstFriendType) !=
1303 computeODRHash(SecondFriendType));
1304 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1305 FriendType)
1306 << FirstFriendType;
1307 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1308 FriendType)
1309 << SecondFriendType;
1310 return true;
1311 }
1312
1313 DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1314 FriendTypeFunction)
1315 << (FirstTSI == nullptr);
1316 DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1317 FriendTypeFunction)
1318 << (SecondTSI == nullptr);
1319 return true;
1320 }
1321 case FunctionTemplate: {
1322 const FunctionTemplateDecl *FirstTemplate =
1323 cast<FunctionTemplateDecl>(FirstDecl);
1324 const FunctionTemplateDecl *SecondTemplate =
1325 cast<FunctionTemplateDecl>(SecondDecl);
1326
1327 TemplateParameterList *FirstTPL = FirstTemplate->getTemplateParameters();
1328 TemplateParameterList *SecondTPL = SecondTemplate->getTemplateParameters();
1329
1330 auto DiagTemplateError = [&DiagError,
1331 FirstTemplate](ODRCXXRecordDifference DiffType) {
1332 return DiagError(FirstTemplate->getLocation(),
1333 FirstTemplate->getSourceRange(), DiffType)
1334 << FirstTemplate;
1335 };
1336 auto DiagTemplateNote = [&DiagNote,
1337 SecondTemplate](ODRCXXRecordDifference DiffType) {
1338 return DiagNote(SecondTemplate->getLocation(),
1339 SecondTemplate->getSourceRange(), DiffType)
1340 << SecondTemplate;
1341 };
1342
1343 if (FirstTPL->size() != SecondTPL->size()) {
1344 DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1345 << FirstTPL->size();
1346 DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1347 << SecondTPL->size();
1348 return true;
1349 }
1350
1351 for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
1352 NamedDecl *FirstParam = FirstTPL->getParam(i);
1353 NamedDecl *SecondParam = SecondTPL->getParam(i);
1354
1355 if (FirstParam->getKind() != SecondParam->getKind()) {
1356 enum {
1357 TemplateTypeParameter,
1358 NonTypeTemplateParameter,
1359 TemplateTemplateParameter,
1360 };
1361 auto GetParamType = [](NamedDecl *D) {
1362 switch (D->getKind()) {
1363 default:
1364 llvm_unreachable("Unexpected template parameter type");
1365 case Decl::TemplateTypeParm:
1366 return TemplateTypeParameter;
1367 case Decl::NonTypeTemplateParm:
1368 return NonTypeTemplateParameter;
1369 case Decl::TemplateTemplateParm:
1370 return TemplateTemplateParameter;
1371 }
1372 };
1373
1374 DiagTemplateError(FunctionTemplateParameterDifferentKind)
1375 << (i + 1) << GetParamType(FirstParam);
1376 DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1377 << (i + 1) << GetParamType(SecondParam);
1378 return true;
1379 }
1380
1381 if (FirstParam->getName() != SecondParam->getName()) {
1382 DiagTemplateError(FunctionTemplateParameterName)
1383 << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
1384 DiagTemplateNote(FunctionTemplateParameterName)
1385 << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
1386 return true;
1387 }
1388
1389 if (isa<TemplateTypeParmDecl>(FirstParam) &&
1390 isa<TemplateTypeParmDecl>(SecondParam)) {
1391 TemplateTypeParmDecl *FirstTTPD =
1392 cast<TemplateTypeParmDecl>(FirstParam);
1393 TemplateTypeParmDecl *SecondTTPD =
1394 cast<TemplateTypeParmDecl>(SecondParam);
1395 bool HasFirstDefaultArgument =
1396 FirstTTPD->hasDefaultArgument() &&
1397 !FirstTTPD->defaultArgumentWasInherited();
1398 bool HasSecondDefaultArgument =
1399 SecondTTPD->hasDefaultArgument() &&
1400 !SecondTTPD->defaultArgumentWasInherited();
1401 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1402 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1403 << (i + 1) << HasFirstDefaultArgument;
1404 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1405 << (i + 1) << HasSecondDefaultArgument;
1406 return true;
1407 }
1408
1409 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1410 TemplateArgument FirstTA =
1411 FirstTTPD->getDefaultArgument().getArgument();
1412 TemplateArgument SecondTA =
1413 SecondTTPD->getDefaultArgument().getArgument();
1414 if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1415 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1416 << (i + 1) << FirstTA;
1417 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1418 << (i + 1) << SecondTA;
1419 return true;
1420 }
1421 }
1422
1423 if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1424 DiagTemplateError(FunctionTemplatePackParameter)
1425 << (i + 1) << FirstTTPD->isParameterPack();
1426 DiagTemplateNote(FunctionTemplatePackParameter)
1427 << (i + 1) << SecondTTPD->isParameterPack();
1428 return true;
1429 }
1430 }
1431
1432 if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1433 isa<TemplateTemplateParmDecl>(SecondParam)) {
1434 TemplateTemplateParmDecl *FirstTTPD =
1436 TemplateTemplateParmDecl *SecondTTPD =
1437 cast<TemplateTemplateParmDecl>(SecondParam);
1438
1439 TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();
1440 TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();
1441
1442 auto ComputeTemplateParameterListODRHash =
1443 [](const TemplateParameterList *TPL) {
1444 assert(TPL);
1445 ODRHash Hasher;
1446 Hasher.AddTemplateParameterList(TPL);
1447 return Hasher.CalculateHash();
1448 };
1449
1450 if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1451 ComputeTemplateParameterListODRHash(SecondTPL)) {
1452 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1453 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1454 return true;
1455 }
1456
1457 bool HasFirstDefaultArgument =
1458 FirstTTPD->hasDefaultArgument() &&
1459 !FirstTTPD->defaultArgumentWasInherited();
1460 bool HasSecondDefaultArgument =
1461 SecondTTPD->hasDefaultArgument() &&
1462 !SecondTTPD->defaultArgumentWasInherited();
1463 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1464 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1465 << (i + 1) << HasFirstDefaultArgument;
1466 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1467 << (i + 1) << HasSecondDefaultArgument;
1468 return true;
1469 }
1470
1471 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1472 TemplateArgument FirstTA =
1473 FirstTTPD->getDefaultArgument().getArgument();
1474 TemplateArgument SecondTA =
1475 SecondTTPD->getDefaultArgument().getArgument();
1476 if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1477 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1478 << (i + 1) << FirstTA;
1479 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1480 << (i + 1) << SecondTA;
1481 return true;
1482 }
1483 }
1484
1485 if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1486 DiagTemplateError(FunctionTemplatePackParameter)
1487 << (i + 1) << FirstTTPD->isParameterPack();
1488 DiagTemplateNote(FunctionTemplatePackParameter)
1489 << (i + 1) << SecondTTPD->isParameterPack();
1490 return true;
1491 }
1492 }
1493
1494 if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1495 isa<NonTypeTemplateParmDecl>(SecondParam)) {
1496 NonTypeTemplateParmDecl *FirstNTTPD =
1498 NonTypeTemplateParmDecl *SecondNTTPD =
1499 cast<NonTypeTemplateParmDecl>(SecondParam);
1500
1501 QualType FirstType = FirstNTTPD->getType();
1502 QualType SecondType = SecondNTTPD->getType();
1503 if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1504 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1505 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1506 return true;
1507 }
1508
1509 bool HasFirstDefaultArgument =
1510 FirstNTTPD->hasDefaultArgument() &&
1511 !FirstNTTPD->defaultArgumentWasInherited();
1512 bool HasSecondDefaultArgument =
1513 SecondNTTPD->hasDefaultArgument() &&
1514 !SecondNTTPD->defaultArgumentWasInherited();
1515 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1516 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1517 << (i + 1) << HasFirstDefaultArgument;
1518 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1519 << (i + 1) << HasSecondDefaultArgument;
1520 return true;
1521 }
1522
1523 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
1524 TemplateArgument FirstDefaultArgument =
1525 FirstNTTPD->getDefaultArgument().getArgument();
1526 TemplateArgument SecondDefaultArgument =
1527 SecondNTTPD->getDefaultArgument().getArgument();
1528
1529 if (computeODRHash(FirstDefaultArgument) !=
1530 computeODRHash(SecondDefaultArgument)) {
1531 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1532 << (i + 1) << FirstDefaultArgument;
1533 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1534 << (i + 1) << SecondDefaultArgument;
1535 return true;
1536 }
1537 }
1538
1539 if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {
1540 DiagTemplateError(FunctionTemplatePackParameter)
1541 << (i + 1) << FirstNTTPD->isParameterPack();
1542 DiagTemplateNote(FunctionTemplatePackParameter)
1543 << (i + 1) << SecondNTTPD->isParameterPack();
1544 return true;
1545 }
1546 }
1547 }
1548 break;
1549 }
1550 }
1551
1552 Diag(FirstDecl->getLocation(),
1553 diag::err_module_odr_violation_mismatch_decl_unknown)
1554 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1555 << FirstDecl->getSourceRange();
1556 Diag(SecondDecl->getLocation(),
1557 diag::note_module_odr_violation_mismatch_decl_unknown)
1558 << SecondModule.empty() << SecondModule << FirstDiffType
1559 << SecondDecl->getSourceRange();
1560 return true;
1561}
1562
1564 const RecordDecl *SecondRecord) const {
1565 if (FirstRecord == SecondRecord)
1566 return false;
1567
1568 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
1569 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
1570
1571 auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
1572 const DeclContext *DC) {
1573 for (const Decl *D : Record->decls()) {
1575 continue;
1576 Hashes.emplace_back(D, computeODRHash(D));
1577 }
1578 };
1579
1580 DeclHashes FirstHashes;
1581 DeclHashes SecondHashes;
1582 const DeclContext *DC = FirstRecord;
1583 PopulateHashes(FirstHashes, FirstRecord, DC);
1584 PopulateHashes(SecondHashes, SecondRecord, DC);
1585
1586 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1587 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1588 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1589 const Decl *FirstDecl = DR.FirstDecl;
1590 const Decl *SecondDecl = DR.SecondDecl;
1591
1592 if (FirstDiffType == Other || SecondDiffType == Other) {
1593 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1594 SecondModule);
1595 return true;
1596 }
1597
1598 if (FirstDiffType != SecondDiffType) {
1599 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1600 SecondRecord, SecondModule);
1601 return true;
1602 }
1603
1604 assert(FirstDiffType == SecondDiffType);
1605 switch (FirstDiffType) {
1606 // Already handled.
1607 case EndOfClass:
1608 case Other:
1609 // C++ only, invalid in this context.
1610 case PublicSpecifer:
1611 case PrivateSpecifer:
1612 case ProtectedSpecifer:
1613 case StaticAssert:
1614 case CXXMethod:
1615 case TypeAlias:
1616 case Friend:
1617 case FunctionTemplate:
1618 // Cannot be contained by RecordDecl, invalid in this context.
1619 case ObjCMethod:
1620 case ObjCIvar:
1621 case ObjCProperty:
1622 llvm_unreachable("Invalid diff type");
1623
1624 case Field: {
1625 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1626 cast<FieldDecl>(FirstDecl),
1627 cast<FieldDecl>(SecondDecl)))
1628 return true;
1629 break;
1630 }
1631 case TypeDef: {
1632 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1633 cast<TypedefNameDecl>(FirstDecl),
1634 cast<TypedefNameDecl>(SecondDecl),
1635 /*IsTypeAlias=*/false))
1636 return true;
1637 break;
1638 }
1639 case Var: {
1640 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1641 cast<VarDecl>(FirstDecl),
1642 cast<VarDecl>(SecondDecl)))
1643 return true;
1644 break;
1645 }
1646 }
1647
1648 Diag(FirstDecl->getLocation(),
1649 diag::err_module_odr_violation_mismatch_decl_unknown)
1650 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1651 << FirstDecl->getSourceRange();
1652 Diag(SecondDecl->getLocation(),
1653 diag::note_module_odr_violation_mismatch_decl_unknown)
1654 << SecondModule.empty() << SecondModule << FirstDiffType
1655 << SecondDecl->getSourceRange();
1656 return true;
1657}
1658
1660 const FunctionDecl *FirstFunction,
1661 const FunctionDecl *SecondFunction) const {
1662 if (FirstFunction == SecondFunction)
1663 return false;
1664
1665 // Keep in sync with select options in err_module_odr_violation_function.
1666 enum ODRFunctionDifference {
1667 ReturnType,
1668 ParameterName,
1669 ParameterType,
1670 ParameterSingleDefaultArgument,
1671 ParameterDifferentDefaultArgument,
1672 FunctionBody,
1673 };
1674
1675 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
1676 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);
1677
1678 auto DiagError = [FirstFunction, &FirstModule,
1679 this](SourceLocation Loc, SourceRange Range,
1680 ODRFunctionDifference DiffType) {
1681 return Diag(Loc, diag::err_module_odr_violation_function)
1682 << FirstFunction << FirstModule.empty() << FirstModule << Range
1683 << DiffType;
1684 };
1685 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1686 ODRFunctionDifference DiffType) {
1687 return Diag(Loc, diag::note_module_odr_violation_function)
1688 << SecondModule << Range << DiffType;
1689 };
1690
1691 if (computeODRHash(FirstFunction->getReturnType()) !=
1692 computeODRHash(SecondFunction->getReturnType())) {
1693 DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
1694 FirstFunction->getReturnTypeSourceRange(), ReturnType)
1695 << FirstFunction->getReturnType();
1696 DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
1697 SecondFunction->getReturnTypeSourceRange(), ReturnType)
1698 << SecondFunction->getReturnType();
1699 return true;
1700 }
1701
1702 assert(FirstFunction->param_size() == SecondFunction->param_size() &&
1703 "Merged functions with different number of parameters");
1704
1705 size_t ParamSize = FirstFunction->param_size();
1706 for (unsigned I = 0; I < ParamSize; ++I) {
1707 const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
1708 const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
1709
1710 assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&
1711 "Merged function has different parameter types.");
1712
1713 if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
1714 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1715 ParameterName)
1716 << I + 1 << FirstParam->getDeclName();
1717 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1718 ParameterName)
1719 << I + 1 << SecondParam->getDeclName();
1720 return true;
1721 };
1722
1723 QualType FirstParamType = FirstParam->getType();
1724 QualType SecondParamType = SecondParam->getType();
1725 if (FirstParamType != SecondParamType &&
1726 computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
1727 if (const DecayedType *ParamDecayedType =
1728 FirstParamType->getAs<DecayedType>()) {
1729 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1730 ParameterType)
1731 << (I + 1) << FirstParamType << true
1732 << ParamDecayedType->getOriginalType();
1733 } else {
1734 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1735 ParameterType)
1736 << (I + 1) << FirstParamType << false;
1737 }
1738
1739 if (const DecayedType *ParamDecayedType =
1740 SecondParamType->getAs<DecayedType>()) {
1741 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1742 ParameterType)
1743 << (I + 1) << SecondParamType << true
1744 << ParamDecayedType->getOriginalType();
1745 } else {
1746 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1747 ParameterType)
1748 << (I + 1) << SecondParamType << false;
1749 }
1750 return true;
1751 }
1752
1753 // Note, these calls can trigger deserialization.
1754 const Expr *FirstInit = FirstParam->getInit();
1755 const Expr *SecondInit = SecondParam->getInit();
1756 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1757 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1758 ParameterSingleDefaultArgument)
1759 << (I + 1) << (FirstInit == nullptr)
1760 << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
1761 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1762 ParameterSingleDefaultArgument)
1763 << (I + 1) << (SecondInit == nullptr)
1764 << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
1765 return true;
1766 }
1767
1768 if (FirstInit && SecondInit &&
1769 computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1770 DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1771 ParameterDifferentDefaultArgument)
1772 << (I + 1) << FirstInit->getSourceRange();
1773 DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1774 ParameterDifferentDefaultArgument)
1775 << (I + 1) << SecondInit->getSourceRange();
1776 return true;
1777 }
1778
1779 assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
1780 "Undiagnosed parameter difference.");
1781 }
1782
1783 // If no error has been generated before now, assume the problem is in
1784 // the body and generate a message.
1785 DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),
1786 FunctionBody);
1787 DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),
1788 FunctionBody);
1789 return true;
1790}
1791
1793 const EnumDecl *SecondEnum) const {
1794 if (FirstEnum == SecondEnum)
1795 return false;
1796
1797 // Keep in sync with select options in err_module_odr_violation_enum.
1798 enum ODREnumDifference {
1799 SingleScopedEnum,
1800 EnumTagKeywordMismatch,
1801 SingleSpecifiedType,
1802 DifferentSpecifiedTypes,
1803 DifferentNumberEnumConstants,
1804 EnumConstantName,
1805 EnumConstantSingleInitializer,
1806 EnumConstantDifferentInitializer,
1807 };
1808
1809 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
1810 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);
1811
1812 auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1813 ODREnumDifference DiffType) {
1814 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1815 << FirstEnum << FirstModule.empty() << FirstModule
1816 << DiagAnchor->getSourceRange() << DiffType;
1817 };
1818 auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1819 ODREnumDifference DiffType) {
1820 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1821 << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1822 };
1823
1824 if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
1825 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1826 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1827 return true;
1828 }
1829
1830 if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
1831 if (FirstEnum->isScopedUsingClassTag() !=
1832 SecondEnum->isScopedUsingClassTag()) {
1833 DiagError(FirstEnum, EnumTagKeywordMismatch)
1834 << FirstEnum->isScopedUsingClassTag();
1835 DiagNote(SecondEnum, EnumTagKeywordMismatch)
1836 << SecondEnum->isScopedUsingClassTag();
1837 return true;
1838 }
1839 }
1840
1841 QualType FirstUnderlyingType =
1842 FirstEnum->getIntegerTypeSourceInfo()
1843 ? FirstEnum->getIntegerTypeSourceInfo()->getType()
1844 : QualType();
1845 QualType SecondUnderlyingType =
1846 SecondEnum->getIntegerTypeSourceInfo()
1847 ? SecondEnum->getIntegerTypeSourceInfo()->getType()
1848 : QualType();
1849 if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1850 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1851 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1852 return true;
1853 }
1854
1855 if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
1856 // Match AddEnumDecl, which hashes the canonical underlying type.
1857 if (!Context.hasSameType(FirstEnum->getIntegerType(),
1858 SecondEnum->getIntegerType())) {
1859 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1860 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1861 return true;
1862 }
1863 }
1864
1865 // Compare enum constants.
1866 using DeclHashes =
1868 auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {
1869 for (const Decl *D : Enum->decls()) {
1870 // Due to decl merging, the first EnumDecl is the parent of
1871 // Decls in both records.
1872 if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
1873 continue;
1874 assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
1875 Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
1876 }
1877 };
1878 DeclHashes FirstHashes;
1879 PopulateHashes(FirstHashes, FirstEnum);
1880 DeclHashes SecondHashes;
1881 PopulateHashes(SecondHashes, SecondEnum);
1882
1883 if (FirstHashes.size() != SecondHashes.size()) {
1884 DiagError(FirstEnum, DifferentNumberEnumConstants)
1885 << (int)FirstHashes.size();
1886 DiagNote(SecondEnum, DifferentNumberEnumConstants)
1887 << (int)SecondHashes.size();
1888 return true;
1889 }
1890
1891 for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {
1892 if (FirstHashes[I].second == SecondHashes[I].second)
1893 continue;
1894 const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1895 const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1896
1897 if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
1898 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1899 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1900 return true;
1901 }
1902
1903 const Expr *FirstInit = FirstConstant->getInitExpr();
1904 const Expr *SecondInit = SecondConstant->getInitExpr();
1905 if (!FirstInit && !SecondInit)
1906 continue;
1907
1908 if (!FirstInit || !SecondInit) {
1909 DiagError(FirstConstant, EnumConstantSingleInitializer)
1910 << I + 1 << FirstConstant << (FirstInit != nullptr);
1911 DiagNote(SecondConstant, EnumConstantSingleInitializer)
1912 << I + 1 << SecondConstant << (SecondInit != nullptr);
1913 return true;
1914 }
1915
1916 if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1917 DiagError(FirstConstant, EnumConstantDifferentInitializer)
1918 << I + 1 << FirstConstant;
1919 DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1920 << I + 1 << SecondConstant;
1921 return true;
1922 }
1923 }
1924 return false;
1925}
1926
1928 const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
1929 const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {
1930 // Multiple different declarations got merged together; tell the user
1931 // where they came from.
1932 if (FirstID == SecondID)
1933 return false;
1934
1935 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID);
1936 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID);
1937
1938 // Keep in sync with err_module_odr_violation_objc_interface.
1939 enum ODRInterfaceDifference {
1940 SuperClassType,
1941 IVarAccess,
1942 };
1943
1944 auto DiagError = [FirstID, &FirstModule,
1945 this](SourceLocation Loc, SourceRange Range,
1946 ODRInterfaceDifference DiffType) {
1947 return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1948 << FirstID << FirstModule.empty() << FirstModule << Range
1949 << DiffType;
1950 };
1951 auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1952 ODRInterfaceDifference DiffType) {
1953 return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1954 << SecondModule.empty() << SecondModule << Range << DiffType;
1955 };
1956
1957 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1958 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1959 if (FirstDD != SecondDD) {
1960 // Check for matching super class.
1961 auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,
1962 const ObjCInterfaceDecl *ID) {
1963 if (!SuperInfo)
1964 return ID->getSourceRange();
1965 TypeLoc Loc = SuperInfo->getTypeLoc();
1966 return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc());
1967 };
1968
1969 ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass();
1970 ObjCInterfaceDecl *SecondSuperClass = nullptr;
1971 const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo();
1972 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1973 if (SecondSuperInfo)
1974 SecondSuperClass =
1975 SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface();
1976
1977 if ((FirstSuperClass && SecondSuperClass &&
1978 FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()) ||
1979 (FirstSuperClass && !SecondSuperClass) ||
1980 (!FirstSuperClass && SecondSuperClass)) {
1981 QualType FirstType;
1982 if (FirstSuperInfo)
1983 FirstType = FirstSuperInfo->getType();
1984
1985 DiagError(FirstID->getLocation(),
1986 GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1987 SuperClassType)
1988 << (bool)FirstSuperInfo << FirstType;
1989
1990 QualType SecondType;
1991 if (SecondSuperInfo)
1992 SecondType = SecondSuperInfo->getType();
1993
1994 DiagNote(SecondID->getLocation(),
1995 GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1996 SuperClassType)
1997 << (bool)SecondSuperInfo << SecondType;
1998 return true;
1999 }
2000
2001 // Check both interfaces reference the same protocols.
2002 auto &FirstProtos = FirstID->getReferencedProtocols();
2003 auto &SecondProtos = SecondDD->ReferencedProtocols;
2004 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
2005 SecondProtos, SecondID, SecondModule))
2006 return true;
2007 }
2008
2009 auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID,
2010 const DeclContext *DC) {
2011 for (auto *D : ID->decls()) {
2013 continue;
2014 Hashes.emplace_back(D, computeODRHash(D));
2015 }
2016 };
2017
2018 DeclHashes FirstHashes;
2019 DeclHashes SecondHashes;
2020 // Use definition as DeclContext because definitions are merged when
2021 // DeclContexts are merged and separate when DeclContexts are separate.
2022 PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());
2023 PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());
2024
2025 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2026 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2027 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2028 const Decl *FirstDecl = DR.FirstDecl;
2029 const Decl *SecondDecl = DR.SecondDecl;
2030
2031 if (FirstDiffType == Other || SecondDiffType == Other) {
2032 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2033 SecondModule);
2034 return true;
2035 }
2036
2037 if (FirstDiffType != SecondDiffType) {
2038 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2039 SecondModule);
2040 return true;
2041 }
2042
2043 assert(FirstDiffType == SecondDiffType);
2044 switch (FirstDiffType) {
2045 // Already handled.
2046 case EndOfClass:
2047 case Other:
2048 // Cannot be contained by ObjCInterfaceDecl, invalid in this context.
2049 case Field:
2050 case TypeDef:
2051 case Var:
2052 // C++ only, invalid in this context.
2053 case PublicSpecifer:
2054 case PrivateSpecifer:
2055 case ProtectedSpecifer:
2056 case StaticAssert:
2057 case CXXMethod:
2058 case TypeAlias:
2059 case Friend:
2060 case FunctionTemplate:
2061 llvm_unreachable("Invalid diff type");
2062
2063 case ObjCMethod: {
2064 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2065 cast<ObjCMethodDecl>(FirstDecl),
2066 cast<ObjCMethodDecl>(SecondDecl)))
2067 return true;
2068 break;
2069 }
2070 case ObjCIvar: {
2071 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2072 cast<FieldDecl>(FirstDecl),
2073 cast<FieldDecl>(SecondDecl)))
2074 return true;
2075
2076 // Check if the access match.
2077 const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2078 const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2079 if (FirstIvar->getCanonicalAccessControl() !=
2080 SecondIvar->getCanonicalAccessControl()) {
2081 DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(),
2082 IVarAccess)
2083 << FirstIvar->getName()
2084 << (int)FirstIvar->getCanonicalAccessControl();
2085 DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(),
2086 IVarAccess)
2087 << SecondIvar->getName()
2088 << (int)SecondIvar->getCanonicalAccessControl();
2089 return true;
2090 }
2091 break;
2092 }
2093 case ObjCProperty: {
2094 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2095 cast<ObjCPropertyDecl>(FirstDecl),
2096 cast<ObjCPropertyDecl>(SecondDecl)))
2097 return true;
2098 break;
2099 }
2100 }
2101
2102 Diag(FirstDecl->getLocation(),
2103 diag::err_module_odr_violation_mismatch_decl_unknown)
2104 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2105 << FirstDecl->getSourceRange();
2106 Diag(SecondDecl->getLocation(),
2107 diag::note_module_odr_violation_mismatch_decl_unknown)
2108 << SecondModule.empty() << SecondModule << FirstDiffType
2109 << SecondDecl->getSourceRange();
2110 return true;
2111}
2112
2114 const ObjCProtocolDecl *FirstProtocol,
2115 const ObjCProtocolDecl *SecondProtocol,
2116 const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
2117 if (FirstProtocol == SecondProtocol)
2118 return false;
2119
2120 std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);
2121 std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);
2122
2123 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2124 assert(FirstDD && SecondDD && "Definitions without DefinitionData");
2125 // Diagnostics from ObjCProtocol DefinitionData are emitted here.
2126 if (FirstDD != SecondDD) {
2127 // Check both protocols reference the same protocols.
2128 const ObjCProtocolList &FirstProtocols =
2129 FirstProtocol->getReferencedProtocols();
2130 const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
2131 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2132 SecondProtocols, SecondProtocol,
2133 SecondModule))
2134 return true;
2135 }
2136
2137 auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,
2138 const DeclContext *DC) {
2139 for (const Decl *D : ID->decls()) {
2141 continue;
2142 Hashes.emplace_back(D, computeODRHash(D));
2143 }
2144 };
2145
2146 DeclHashes FirstHashes;
2147 DeclHashes SecondHashes;
2148 // Use definition as DeclContext because definitions are merged when
2149 // DeclContexts are merged and separate when DeclContexts are separate.
2150 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
2151 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
2152
2153 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2154 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2155 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2156 const Decl *FirstDecl = DR.FirstDecl;
2157 const Decl *SecondDecl = DR.SecondDecl;
2158
2159 if (FirstDiffType == Other || SecondDiffType == Other) {
2160 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2161 SecondProtocol, SecondModule);
2162 return true;
2163 }
2164
2165 if (FirstDiffType != SecondDiffType) {
2166 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2167 SecondProtocol, SecondModule);
2168 return true;
2169 }
2170
2171 assert(FirstDiffType == SecondDiffType);
2172 switch (FirstDiffType) {
2173 // Already handled.
2174 case EndOfClass:
2175 case Other:
2176 // Cannot be contained by ObjCProtocolDecl, invalid in this context.
2177 case Field:
2178 case TypeDef:
2179 case Var:
2180 case ObjCIvar:
2181 // C++ only, invalid in this context.
2182 case PublicSpecifer:
2183 case PrivateSpecifer:
2184 case ProtectedSpecifer:
2185 case StaticAssert:
2186 case CXXMethod:
2187 case TypeAlias:
2188 case Friend:
2189 case FunctionTemplate:
2190 llvm_unreachable("Invalid diff type");
2191 case ObjCMethod: {
2192 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2193 cast<ObjCMethodDecl>(FirstDecl),
2194 cast<ObjCMethodDecl>(SecondDecl)))
2195 return true;
2196 break;
2197 }
2198 case ObjCProperty: {
2199 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2200 SecondModule,
2201 cast<ObjCPropertyDecl>(FirstDecl),
2202 cast<ObjCPropertyDecl>(SecondDecl)))
2203 return true;
2204 break;
2205 }
2206 }
2207
2208 Diag(FirstDecl->getLocation(),
2209 diag::err_module_odr_violation_mismatch_decl_unknown)
2210 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2211 << FirstDecl->getSourceRange();
2212 Diag(SecondDecl->getLocation(),
2213 diag::note_module_odr_violation_mismatch_decl_unknown)
2214 << SecondModule.empty() << SecondModule << FirstDiffType
2215 << SecondDecl->getSourceRange();
2216 return true;
2217}
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
Definition MachO.h:31
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,...
Represents a base class of a C++ class.
Definition DeclCXX.h:146
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
Definition DeclCXX.h:242
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
Definition DeclCXX.h:203
QualType getType() const
Retrieves the type of the base class.
Definition DeclCXX.h:249
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Definition DeclCXX.h:193
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2149
bool isVolatile() const
Definition DeclCXX.h:2202
bool isConst() const
Definition DeclCXX.h:2201
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
Definition DeclCXX.cpp:2054
Declaration of a class template.
Represents a pointer type decayed from an array or function type.
Definition TypeBase.h:3621
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclBase.h:443
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition DeclBase.h:824
SourceLocation getLocation() const
Definition DeclBase.h:447
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:439
Kind getKind() const
Definition DeclBase.h:450
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition DeclBase.h:435
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.
Definition Diagnostic.h:234
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.
Definition Decl.h:3558
const Expr * getInitExpr() const
Definition Decl.h:3576
Represents an enum.
Definition Decl.h:4146
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
Definition Decl.h:4364
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
Definition Decl.h:4367
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
Definition Decl.h:4335
SourceRange getSourceRange() const override LLVM_READONLY
Overrides to provide correct range when there's an enum-base specifier with forward declarations.
Definition Decl.cpp:5242
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition Decl.h:4319
This represents one expression.
Definition Expr.h:113
Represents a member of a struct/union/class.
Definition Decl.h:3295
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition Decl.h:3395
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition Decl.cpp:4789
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3398
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4890
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Definition Decl.h:3411
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:46
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getFriendLoc() const
Definition DeclFriend.h:109
virtual NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition DeclFriend.h:102
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
Represents a function declaration or definition.
Definition Decl.h:2059
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
Definition Decl.cpp:4068
QualType getReturnType() const
Definition Decl.h:2976
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
Definition Decl.h:2516
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4370
unsigned getODRHash()
Returns ODRHash of the function.
Definition Decl.cpp:4743
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition Decl.h:3019
bool isDeletedAsWritten() const
Definition Decl.h:2671
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Definition Decl.h:2480
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4610
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
Definition Decl.h:2471
size_t param_size() const
Definition Decl.h:2921
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition Decl.h:3030
Declaration of a template function.
StringRef getName() const
Return the actual identifier string.
Describes a module or submodule.
Definition Module.h:340
This represents a decl that may have a name.
Definition Decl.h:275
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
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)
Definition ODRHash.cpp:23
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition ODRHash.cpp:704
void AddSubDecl(const Decl *D)
Definition ODRHash.cpp:606
void AddQualType(QualType T)
Definition ODRHash.cpp:1288
void AddTemplateParameterList(const TemplateParameterList *TPL)
Definition ODRHash.cpp:224
void AddTemplateArgument(TemplateArgument TA)
Definition ODRHash.cpp:182
unsigned CalculateHash()
Definition ODRHash.cpp:244
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)
Definition ODRHash.cpp:579
ObjCContainerDecl - Represents a container for method declarations.
Definition DeclObjC.h:954
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition DeclObjC.cpp:788
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:1339
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Definition DeclObjC.h:1548
TypeSourceInfo * getSuperClassTInfo() const
Definition DeclObjC.h:1579
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1958
AccessControl getCanonicalAccessControl() const
Definition DeclObjC.h:2008
unsigned size() const
Definition DeclObjC.h:70
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition DeclObjC.cpp:889
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition DeclObjC.h:287
bool isInstanceMethod() const
Definition DeclObjC.h:429
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
Definition DeclObjC.cpp:894
QualType getReturnType() const
Definition DeclObjC.h:332
ObjCImplementationControl getImplementationControl() const
Definition DeclObjC.h:503
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:734
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition DeclObjC.h:934
QualType getType() const
Definition DeclObjC.h:810
SourceLocation getLParenLoc() const
Definition DeclObjC.h:805
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
Definition DeclObjC.h:833
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition DeclObjC.h:821
PropertyControl getPropertyImplementation() const
Definition DeclObjC.h:918
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:2159
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition DeclObjC.h:2256
A list of Objective-C protocols, along with the source locations at which they were referenced.
Definition DeclObjC.h:101
loc_iterator loc_begin() const
Definition DeclObjC.h:111
Represents a parameter to a function.
Definition Decl.h:1820
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2968
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
Represents a struct/union/class.
Definition Decl.h:4460
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.
Definition DeclCXX.h:4165
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition DeclCXX.h:4198
Stmt - This represents one statement.
Definition Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
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.
Definition Decl.h:3684
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
SourceLocation getEndLoc() const
Get the end source location.
Definition TypeLoc.cpp:227
SourceLocation getBeginLoc() const
Get the begin source location.
Definition TypeLoc.cpp:193
A container of type source information.
Definition TypeBase.h:8429
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8440
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9361
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9294
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3697
QualType getUnderlyingType() const
Definition Decl.h:3752
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1594
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2172
const Expr * getInit() const
Definition Decl.h:1392
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ AS_public
Definition Specifiers.h:125
@ AS_protected
Definition Specifiers.h:126
@ AS_none
Definition Specifiers.h:128
@ AS_private
Definition Specifiers.h:127
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:249
@ SC_Static
Definition Specifiers.h:253
@ Type
The name was classified as a type.
Definition Sema.h:558
@ NumObjCPropertyAttrsBits
Number of bits fitting all the property attributes.
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6002