clang: lib/AST/ODRDiagsEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15

16using namespace clang;

17

22}

23

28}

29

31 assert(D);

35}

36

41}

42

44

46 return M->getFullModuleName();

47

48

49 return {};

50}

51

52template

55 StringRef FirstModule,

56 StringRef SecondModule,

57 const MethodT *FirstMethod,

58 const MethodT *SecondMethod) {

59 enum DiagMethodType {

60 DiagMethod,

61 DiagConstructor,

62 DiagDestructor,

63 };

64 auto GetDiagMethodType = [](const NamedDecl *D) {

65 if (isa(D))

66 return DiagConstructor;

67 if (isa(D))

68 return DiagDestructor;

69 return DiagMethod;

70 };

71

72 enum ODRMethodParametersDifference {

73 NumberParameters,

74 ParameterType,

75 ParameterName,

76 };

77 auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,

78 FirstMethod](ODRMethodParametersDifference DiffType) {

80 DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);

81 return Diags.Report(FirstMethod->getLocation(),

82 diag::err_module_odr_violation_method_params)

83 << FirstContainer << FirstModule.empty() << FirstModule

84 << FirstMethod->getSourceRange() << DiffType << FirstMethodType

85 << FirstName;

86 };

87 auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,

88 SecondMethod](ODRMethodParametersDifference DiffType) {

90 DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);

91 return Diags.Report(SecondMethod->getLocation(),

92 diag::note_module_odr_violation_method_params)

93 << SecondModule.empty() << SecondModule

94 << SecondMethod->getSourceRange() << DiffType << SecondMethodType

95 << SecondName;

96 };

97

98 const unsigned FirstNumParameters = FirstMethod->param_size();

99 const unsigned SecondNumParameters = SecondMethod->param_size();

100 if (FirstNumParameters != SecondNumParameters) {

101 DiagError(NumberParameters) << FirstNumParameters;

102 DiagNote(NumberParameters) << SecondNumParameters;

103 return true;

104 }

105

106 for (unsigned I = 0; I < FirstNumParameters; ++I) {

107 const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);

108 const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);

109

112 if (FirstParamType != SecondParamType &&

114 if (const DecayedType *ParamDecayedType =

116 DiagError(ParameterType) << (I + 1) << FirstParamType << true

117 << ParamDecayedType->getOriginalType();

118 } else {

119 DiagError(ParameterType) << (I + 1) << FirstParamType << false;

120 }

121

122 if (const DecayedType *ParamDecayedType =

124 DiagNote(ParameterType) << (I + 1) << SecondParamType << true

125 << ParamDecayedType->getOriginalType();

126 } else {

127 DiagNote(ParameterType) << (I + 1) << SecondParamType << false;

128 }

129 return true;

130 }

131

134 if (FirstParamName != SecondParamName) {

135 DiagError(ParameterName) << (I + 1) << FirstParamName;

136 DiagNote(ParameterName) << (I + 1) << SecondParamName;

137 return true;

138 }

139 }

140

141 return false;

142}

143

144bool ODRDiagsEmitter::diagnoseSubMismatchField(

145 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,

147 enum ODRFieldDifference {

148 FieldName,

149 FieldTypeName,

150 FieldSingleBitField,

151 FieldDifferentWidthBitField,

152 FieldSingleMutable,

153 FieldSingleInitializer,

154 FieldDifferentInitializers,

155 };

156

157 auto DiagError = [FirstRecord, FirstField, FirstModule,

158 this](ODRFieldDifference DiffType) {

159 return Diag(FirstField->getLocation(), diag::err_module_odr_violation_field)

160 << FirstRecord << FirstModule.empty() << FirstModule

162 };

163 auto DiagNote = [SecondField, SecondModule,

164 this](ODRFieldDifference DiffType) {

166 diag::note_module_odr_violation_field)

167 << SecondModule.empty() << SecondModule << SecondField->getSourceRange() << DiffType;

168 };

169

173 DiagError(FieldName) << FirstII;

174 DiagNote(FieldName) << SecondII;

175 return true;

176 }

177

181 DiagError(FieldTypeName) << FirstII << FirstType;

182 DiagNote(FieldTypeName) << SecondII << SecondType;

183 return true;

184 }

185

187 (void)Context;

188

189 const bool IsFirstBitField = FirstField->isBitField();

190 const bool IsSecondBitField = SecondField->isBitField();

191 if (IsFirstBitField != IsSecondBitField) {

192 DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;

193 DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;

194 return true;

195 }

196

197 if (IsFirstBitField && IsSecondBitField) {

200 if (FirstBitWidthHash != SecondBitWidthHash) {

201 DiagError(FieldDifferentWidthBitField)

203 DiagNote(FieldDifferentWidthBitField)

205 return true;

206 }

207 }

208

209 if (!LangOpts.CPlusPlus)

210 return false;

211

212 const bool IsFirstMutable = FirstField->isMutable();

213 const bool IsSecondMutable = SecondField->isMutable();

214 if (IsFirstMutable != IsSecondMutable) {

215 DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;

216 DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;

217 return true;

218 }

219

222 if ((!FirstInitializer && SecondInitializer) ||

223 (FirstInitializer && !SecondInitializer)) {

224 DiagError(FieldSingleInitializer)

225 << FirstII << (FirstInitializer != nullptr);

226 DiagNote(FieldSingleInitializer)

227 << SecondII << (SecondInitializer != nullptr);

228 return true;

229 }

230

231 if (FirstInitializer && SecondInitializer) {

232 unsigned FirstInitHash = computeODRHash(FirstInitializer);

233 unsigned SecondInitHash = computeODRHash(SecondInitializer);

234 if (FirstInitHash != SecondInitHash) {

235 DiagError(FieldDifferentInitializers)

237 DiagNote(FieldDifferentInitializers)

239 return true;

240 }

241 }

242

243 return false;

244}

245

246bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(

247 const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,

249 bool IsTypeAlias) const {

250 enum ODRTypedefDifference {

251 TypedefName,

253 };

254

255 auto DiagError = [FirstRecord, FirstTD, FirstModule,

256 this](ODRTypedefDifference DiffType) {

257 return Diag(FirstTD->getLocation(), diag::err_module_odr_violation_typedef)

258 << FirstRecord << FirstModule.empty() << FirstModule

260 };

261 auto DiagNote = [SecondTD, SecondModule,

262 this](ODRTypedefDifference DiffType) {

264 diag::note_module_odr_violation_typedef)

265 << SecondModule << SecondTD->getSourceRange() << DiffType;

266 };

267

270 if (FirstName != SecondName) {

271 DiagError(TypedefName) << IsTypeAlias << FirstName;

272 DiagNote(TypedefName) << IsTypeAlias << SecondName;

273 return true;

274 }

275

279 DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType;

280 DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType;

281 return true;

282 }

283 return false;

284}

285

286bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord,

287 StringRef FirstModule,

288 StringRef SecondModule,

290 const VarDecl *SecondVD) const {

291 enum ODRVarDifference {

292 VarName,

293 VarType,

294 VarSingleInitializer,

295 VarDifferentInitializer,

296 VarConstexpr,

297 };

298

299 auto DiagError = [FirstRecord, FirstVD, FirstModule,

300 this](ODRVarDifference DiffType) {

301 return Diag(FirstVD->getLocation(), diag::err_module_odr_violation_variable)

302 << FirstRecord << FirstModule.empty() << FirstModule

304 };

305 auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) {

307 diag::note_module_odr_violation_variable)

308 << SecondModule << SecondVD->getSourceRange() << DiffType;

309 };

310

313 if (FirstName != SecondName) {

314 DiagError(VarName) << FirstName;

315 DiagNote(VarName) << SecondName;

316 return true;

317 }

318

322 DiagError(VarType) << FirstName << FirstType;

323 DiagNote(VarType) << SecondName << SecondType;

324 return true;

325 }

326

327 if (!LangOpts.CPlusPlus)

328 return false;

329

330 const Expr *FirstInit = FirstVD->getInit();

331 const Expr *SecondInit = SecondVD->getInit();

332 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {

333 DiagError(VarSingleInitializer)

334 << FirstName << (FirstInit == nullptr)

335 << (FirstInit ? FirstInit->getSourceRange() : SourceRange());

336 DiagNote(VarSingleInitializer)

337 << SecondName << (SecondInit == nullptr)

338 << (SecondInit ? SecondInit->getSourceRange() : SourceRange());

339 return true;

340 }

341

342 if (FirstInit && SecondInit &&

344 DiagError(VarDifferentInitializer)

345 << FirstName << FirstInit->getSourceRange();

346 DiagNote(VarDifferentInitializer)

347 << SecondName << SecondInit->getSourceRange();

348 return true;

349 }

350

351 const bool FirstIsConstexpr = FirstVD->isConstexpr();

352 const bool SecondIsConstexpr = SecondVD->isConstexpr();

353 if (FirstIsConstexpr != SecondIsConstexpr) {

354 DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;

355 DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;

356 return true;

357 }

358 return false;

359}

360

361bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(

365 const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const {

366

367 enum ODRReferencedProtocolDifference {

368 NumProtocols,

369 ProtocolType,

370 };

371 auto DiagRefProtocolError = [FirstContainer, FirstModule,

373 ODRReferencedProtocolDifference DiffType) {

374 return Diag(Loc, diag::err_module_odr_violation_referenced_protocols)

375 << FirstContainer << FirstModule.empty() << FirstModule << Range

376 << DiffType;

377 };

378 auto DiagRefProtocolNote = [SecondModule,

380 ODRReferencedProtocolDifference DiffType) {

381 return Diag(Loc, diag::note_module_odr_violation_referenced_protocols)

382 << SecondModule.empty() << SecondModule << Range << DiffType;

383 };

384 auto GetProtoListSourceRange = [](const ObjCProtocolList &PL) {

385 if (PL.empty())

387 return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end()));

388 };

389

390 if (FirstProtocols.size() != SecondProtocols.size()) {

391 DiagRefProtocolError(FirstContainer->getLocation(),

392 GetProtoListSourceRange(FirstProtocols), NumProtocols)

393 << FirstProtocols.size();

394 DiagRefProtocolNote(SecondContainer->getLocation(),

395 GetProtoListSourceRange(SecondProtocols), NumProtocols)

396 << SecondProtocols.size();

397 return true;

398 }

399

400 for (unsigned I = 0, E = FirstProtocols.size(); I != E; ++I) {

405 if (FirstProtocolName != SecondProtocolName) {

409 DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType)

410 << (I + 1) << FirstProtocolName;

411 DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType)

412 << (I + 1) << SecondProtocolName;

413 return true;

414 }

415 }

416

417 return false;

418}

419

420bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(

421 const NamedDecl *FirstObjCContainer, StringRef FirstModule,

422 StringRef SecondModule, const ObjCMethodDecl *FirstMethod,

424 enum ODRMethodDifference {

425 ReturnType,

426 InstanceOrClass,

427 ControlLevel,

428 DesignatedInitializer,

429 Directness,

430 Name,

431 };

432

433 auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,

434 this](ODRMethodDifference DiffType) {

436 diag::err_module_odr_violation_objc_method)

437 << FirstObjCContainer << FirstModule.empty() << FirstModule

439 };

440 auto DiagNote = [SecondModule, SecondMethod,

441 this](ODRMethodDifference DiffType) {

442 return Diag(SecondMethod->getLocation(),

443 diag::note_module_odr_violation_objc_method)

444 << SecondModule.empty() << SecondModule

445 << SecondMethod->getSourceRange() << DiffType;

446 };

447

450 DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType();

451 DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();

452 return true;

453 }

454

455 if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) {

456 DiagError(InstanceOrClass)

458 DiagNote(InstanceOrClass)

459 << SecondMethod << SecondMethod->isInstanceMethod();

460 return true;

461 }

463 SecondMethod->getImplementationControl()) {

464 DiagError(ControlLevel)

466 DiagNote(ControlLevel) << llvm::to_underlying(

467 SecondMethod->getImplementationControl());

468 return true;

469 }

471 SecondMethod->isThisDeclarationADesignatedInitializer()) {

472 DiagError(DesignatedInitializer)

473 << FirstMethod

475 DiagNote(DesignatedInitializer)

476 << SecondMethod

477 << SecondMethod->isThisDeclarationADesignatedInitializer();

478 return true;

479 }

480 if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {

481 DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();

482 DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();

483 return true;

484 }

486 FirstModule, SecondModule,

487 FirstMethod, SecondMethod))

488 return true;

489

490

491

492

494 DeclarationName SecondName = SecondMethod->getDeclName();

495 if (FirstName != SecondName) {

496 DiagError(Name) << FirstName;

497 DiagNote(Name) << SecondName;

498 return true;

499 }

500

501 return false;

502}

503

504bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(

505 const NamedDecl *FirstObjCContainer, StringRef FirstModule,

508 enum ODRPropertyDifference {

509 Name,

511 ControlLevel,

512 Attribute,

513 };

514

515 auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,

517 return Diag(Loc, diag::err_module_odr_violation_objc_property)

518 << FirstObjCContainer << FirstModule.empty() << FirstModule

520 };

521 auto DiagNote = [SecondModule, SecondProp,

523 return Diag(Loc, diag::note_module_odr_violation_objc_property)

524 << SecondModule.empty() << SecondModule

525 << SecondProp->getSourceRange() << DiffType;

526 };

527

529 IdentifierInfo *SecondII = SecondProp->getIdentifier();

531 DiagError(FirstProp->getLocation(), Name) << FirstII;

532 DiagNote(SecondProp->getLocation(), Name) << SecondII;

533 return true;

534 }

538 << FirstII << FirstProp->getType();

539 DiagNote(SecondProp->getLocation(), Type)

540 << SecondII << SecondProp->getType();

541 return true;

542 }

544 SecondProp->getPropertyImplementation()) {

545 DiagError(FirstProp->getLocation(), ControlLevel)

547 DiagNote(SecondProp->getLocation(), ControlLevel)

548 << SecondProp->getPropertyImplementation();

549 return true;

550 }

551

552

554 unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();

555 if (FirstAttrs != SecondAttrs) {

557 unsigned CheckedAttr = (1 << I);

558 if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))

559 continue;

560

561 bool IsFirstWritten =

563 bool IsSecondWritten =

564 (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;

565 DiagError(IsFirstWritten ? FirstProp->getLParenLoc()

567 Attribute)

568 << FirstII << (I + 1) << IsFirstWritten;

569 DiagNote(IsSecondWritten ? SecondProp->getLParenLoc()

570 : SecondProp->getLocation(),

571 Attribute)

572 << SecondII << (I + 1);

573 return true;

574 }

575 }

576

577 return false;

578}

579

580ODRDiagsEmitter::DiffResult

581ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,

582 DeclHashes &SecondHashes) {

583 auto DifferenceSelector = [](const Decl *D) {

584 assert(D && "valid Decl required");

586 default:

587 return Other;

588 case Decl::AccessSpec:

591 return PublicSpecifer;

593 return PrivateSpecifer;

595 return ProtectedSpecifer;

597 break;

598 }

599 llvm_unreachable("Invalid access specifier");

600 case Decl::StaticAssert:

601 return StaticAssert;

602 case Decl::Field:

603 return Field;

604 case Decl::CXXMethod:

605 case Decl::CXXConstructor:

606 case Decl::CXXDestructor:

607 return CXXMethod;

608 case Decl::TypeAlias:

609 return TypeAlias;

610 case Decl::Typedef:

611 return TypeDef;

612 case Decl::Var:

613 return Var;

614 case Decl::Friend:

615 return Friend;

616 case Decl::FunctionTemplate:

617 return FunctionTemplate;

618 case Decl::ObjCMethod:

619 return ObjCMethod;

620 case Decl::ObjCIvar:

621 return ObjCIvar;

622 case Decl::ObjCProperty:

623 return ObjCProperty;

624 }

625 };

626

627 DiffResult DR;

628 auto FirstIt = FirstHashes.begin();

629 auto SecondIt = SecondHashes.begin();

630 while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {

631 if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&

632 FirstIt->second == SecondIt->second) {

633 ++FirstIt;

634 ++SecondIt;

635 continue;

636 }

637

638 DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;

639 DR.SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;

640

641 DR.FirstDiffType =

642 DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;

643 DR.SecondDiffType =

644 DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;

645 return DR;

646 }

647 return DR;

648}

649

650void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(

651 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,

652 const NamedDecl *SecondRecord, StringRef SecondModule) const {

654 diag::err_module_odr_violation_different_definitions)

655 << FirstRecord << FirstModule.empty() << FirstModule;

656

657 if (DR.FirstDecl) {

658 Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)

660 }

661

663 diag::note_module_odr_violation_different_definitions)

664 << SecondModule;

665

666 if (DR.SecondDecl) {

667 Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)

668 << DR.SecondDecl->getSourceRange();

669 }

670}

671

672void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(

673 DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,

674 const NamedDecl *SecondRecord, StringRef SecondModule) const {

675 auto GetMismatchedDeclLoc = [](const NamedDecl *Container,

676 ODRMismatchDecl DiffType, const Decl *D) {

679 if (DiffType == EndOfClass) {

680 if (auto *Tag = dyn_cast(Container))

681 Loc = Tag->getBraceRange().getEnd();

682 else if (auto *IF = dyn_cast(Container))

683 Loc = IF->getAtEndRange().getBegin();

684 else

685 Loc = Container->getEndLoc();

686 } else {

689 }

690 return std::make_pair(Loc, Range);

691 };

692

693 auto FirstDiagInfo =

694 GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);

695 Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)

696 << FirstRecord << FirstModule.empty() << FirstModule

697 << FirstDiagInfo.second << DR.FirstDiffType;

698

699 auto SecondDiagInfo =

700 GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);

701 Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)

702 << SecondModule.empty() << SecondModule << SecondDiagInfo.second

703 << DR.SecondDiffType;

704}

705

708 const struct CXXRecordDecl::DefinitionData *SecondDD) const {

709

710

711 if (FirstRecord == SecondRecord)

712 return false;

713

716

717 const struct CXXRecordDecl::DefinitionData *FirstDD =

718 FirstRecord->DefinitionData;

719 assert(FirstDD && SecondDD && "Definitions without DefinitionData");

720

721

722 if (FirstDD != SecondDD) {

723

724 enum ODRDefinitionDataDifference {

725 NumBases,

726 NumVBases,

727 BaseType,

728 BaseVirtual,

729 BaseAccess,

730 };

731 auto DiagBaseError = [FirstRecord, &FirstModule,

733 ODRDefinitionDataDifference DiffType) {

734 return Diag(Loc, diag::err_module_odr_violation_definition_data)

735 << FirstRecord << FirstModule.empty() << FirstModule << Range

736 << DiffType;

737 };

738 auto DiagBaseNote = [&SecondModule,

740 ODRDefinitionDataDifference DiffType) {

741 return Diag(Loc, diag::note_module_odr_violation_definition_data)

742 << SecondModule << Range << DiffType;

743 };

744 auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {

745 unsigned NumBases = DD->NumBases;

746 if (NumBases == 0)

749 return SourceRange(bases[0].getBeginLoc(),

750 bases[NumBases - 1].getEndLoc());

751 };

752

753 unsigned FirstNumBases = FirstDD->NumBases;

754 unsigned FirstNumVBases = FirstDD->NumVBases;

755 unsigned SecondNumBases = SecondDD->NumBases;

756 unsigned SecondNumVBases = SecondDD->NumVBases;

757 if (FirstNumBases != SecondNumBases) {

758 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),

759 NumBases)

760 << FirstNumBases;

761 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),

762 NumBases)

763 << SecondNumBases;

764 return true;

765 }

766

767 if (FirstNumVBases != SecondNumVBases) {

768 DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),

769 NumVBases)

770 << FirstNumVBases;

771 DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),

772 NumVBases)

773 << SecondNumVBases;

774 return true;

775 }

776

779 for (unsigned I = 0; I < FirstNumBases; ++I) {

785 BaseType)

786 << (I + 1) << FirstBase.getType();

788 BaseType)

789 << (I + 1) << SecondBase.getType();

790 return true;

791 }

792

795 BaseVirtual)

798 BaseVirtual)

799 << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();

800 return true;

801 }

802

806 BaseAccess)

807 << (I + 1) << FirstBase.getType()

810 BaseAccess)

811 << (I + 1) << SecondBase.getType()

813 return true;

814 }

815 }

816 }

817

822

823 assert(!FirstTemplate == !SecondTemplate &&

824 "Both pointers should be null or non-null");

825

826 if (FirstTemplate && SecondTemplate) {

831 assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&

832 "Number of template parameters should be equal.");

833 for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams)) {

834 const NamedDecl *FirstDecl = std::get<0>(Pair);

835 const NamedDecl *SecondDecl = std::get<1>(Pair);

837 continue;

838

839 assert(FirstDecl->getKind() == SecondDecl->getKind() &&

840 "Parameter Decl's should be the same kind.");

841

842 enum ODRTemplateDifference {

843 ParamEmptyName,

844 ParamName,

845 ParamSingleDefaultArgument,

846 ParamDifferentDefaultArgument,

847 };

848

849 auto hasDefaultArg = [](const NamedDecl *D) {

850 if (auto *TTP = dyn_cast(D))

851 return TTP->hasDefaultArgument() &&

852 !TTP->defaultArgumentWasInherited();

853 if (auto *NTTP = dyn_cast(D))

854 return NTTP->hasDefaultArgument() &&

855 !NTTP->defaultArgumentWasInherited();

856 auto *TTP = cast(D);

857 return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();

858 };

859 bool hasFirstArg = hasDefaultArg(FirstDecl);

860 bool hasSecondArg = hasDefaultArg(SecondDecl);

861

862 ODRTemplateDifference ErrDiffType;

863 ODRTemplateDifference NoteDiffType;

864

867

868 if (FirstName != SecondName) {

869 bool FirstNameEmpty =

871 bool SecondNameEmpty =

873 ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;

874 NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;

875 } else if (hasFirstArg == hasSecondArg)

876 ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;

877 else

878 ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;

879

881 diag::err_module_odr_violation_template_parameter)

882 << FirstRecord << FirstModule.empty() << FirstModule

883 << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg

884 << FirstName;

886 diag::note_module_odr_violation_template_parameter)

887 << SecondModule << SecondDecl->getSourceRange() << NoteDiffType

888 << hasSecondArg << SecondName;

889 return true;

890 }

891 }

892

897 continue;

899 }

900 };

901

905 PopulateHashes(FirstHashes, FirstRecord, DC);

906 PopulateHashes(SecondHashes, SecondRecord, DC);

907

908 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);

909 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;

910 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;

911 const Decl *FirstDecl = DR.FirstDecl;

912 const Decl *SecondDecl = DR.SecondDecl;

913

914 if (FirstDiffType == Other || SecondDiffType == Other) {

915 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,

916 SecondModule);

917 return true;

918 }

919

920 if (FirstDiffType != SecondDiffType) {

921 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,

922 SecondRecord, SecondModule);

923 return true;

924 }

925

926

927

928 enum ODRCXXRecordDifference {

929 StaticAssertCondition,

930 StaticAssertMessage,

931 StaticAssertOnlyMessage,

932 MethodName,

933 MethodDeleted,

934 MethodDefaulted,

935 MethodVirtual,

936 MethodStatic,

937 MethodVolatile,

938 MethodConst,

939 MethodInline,

940 MethodParameterSingleDefaultArgument,

941 MethodParameterDifferentDefaultArgument,

942 MethodNoTemplateArguments,

943 MethodDifferentNumberTemplateArguments,

944 MethodDifferentTemplateArgument,

945 MethodSingleBody,

946 MethodDifferentBody,

947 FriendTypeFunction,

948 FriendType,

949 FriendFunction,

950 FunctionTemplateDifferentNumberParameters,

951 FunctionTemplateParameterDifferentKind,

952 FunctionTemplateParameterName,

953 FunctionTemplateParameterSingleDefaultArgument,

954 FunctionTemplateParameterDifferentDefaultArgument,

955 FunctionTemplateParameterDifferentType,

956 FunctionTemplatePackParameter,

957 };

958 auto DiagError = [FirstRecord, &FirstModule,

960 ODRCXXRecordDifference DiffType) {

961 return Diag(Loc, diag::err_module_odr_violation_record)

962 << FirstRecord << FirstModule.empty() << FirstModule << Range

963 << DiffType;

964 };

966 ODRCXXRecordDifference DiffType) {

967 return Diag(Loc, diag::note_module_odr_violation_record)

968 << SecondModule << Range << DiffType;

969 };

970

971 assert(FirstDiffType == SecondDiffType);

972 switch (FirstDiffType) {

974 case EndOfClass:

975 case PublicSpecifer:

976 case PrivateSpecifer:

977 case ProtectedSpecifer:

978 case ObjCMethod:

979 case ObjCIvar:

980 case ObjCProperty:

981 llvm_unreachable("Invalid diff type");

982

983 case StaticAssert: {

984 const StaticAssertDecl *FirstSA = cast(FirstDecl);

985 const StaticAssertDecl *SecondSA = cast(SecondDecl);

986

991 if (FirstODRHash != SecondODRHash) {

993 StaticAssertCondition);

995 StaticAssertCondition);

996 return true;

997 }

998

1001 assert((FirstMessage || SecondMessage) && "Both messages cannot be empty");

1002 if ((FirstMessage && !SecondMessage) || (!FirstMessage && SecondMessage)) {

1005 if (FirstMessage) {

1008 } else {

1011 }

1012 if (SecondMessage) {

1013 SecondLoc = SecondMessage->getBeginLoc();

1015 } else {

1018 }

1019 DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)

1020 << (FirstMessage == nullptr);

1021 DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)

1022 << (SecondMessage == nullptr);

1023 return true;

1024 }

1025

1026 if (FirstMessage && SecondMessage) {

1027 unsigned FirstMessageODRHash = computeODRHash(FirstMessage);

1028 unsigned SecondMessageODRHash = computeODRHash(SecondMessage);

1029 if (FirstMessageODRHash != SecondMessageODRHash) {

1031 StaticAssertMessage);

1033 StaticAssertMessage);

1034 return true;

1035 }

1036 }

1037 break;

1038 }

1039

1040 case Field: {

1041 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,

1042 cast(FirstDecl),

1043 cast(SecondDecl)))

1044 return true;

1045 break;

1046 }

1047

1048 case CXXMethod: {

1049 enum {

1050 DiagMethod,

1051 DiagConstructor,

1052 DiagDestructor,

1053 } FirstMethodType,

1054 SecondMethodType;

1055 auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {

1056 if (isa(D))

1057 return DiagConstructor;

1058 if (isa(D))

1059 return DiagDestructor;

1060 return DiagMethod;

1061 };

1062 const CXXMethodDecl *FirstMethod = cast(FirstDecl);

1063 const CXXMethodDecl *SecondMethod = cast(SecondDecl);

1064 FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);

1065 SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);

1068 auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,

1069 FirstName](ODRCXXRecordDifference DiffType) {

1070 return DiagError(FirstMethod->getLocation(),

1072 << FirstMethodType << FirstName;

1073 };

1074 auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,

1075 SecondName](ODRCXXRecordDifference DiffType) {

1076 return DiagNote(SecondMethod->getLocation(),

1078 << SecondMethodType << SecondName;

1079 };

1080

1081 if (FirstMethodType != SecondMethodType || FirstName != SecondName) {

1082 DiagMethodError(MethodName);

1083 DiagMethodNote(MethodName);

1084 return true;

1085 }

1086

1089 if (FirstDeleted != SecondDeleted) {

1090 DiagMethodError(MethodDeleted) << FirstDeleted;

1091 DiagMethodNote(MethodDeleted) << SecondDeleted;

1092 return true;

1093 }

1094

1097 if (FirstDefaulted != SecondDefaulted) {

1098 DiagMethodError(MethodDefaulted) << FirstDefaulted;

1099 DiagMethodNote(MethodDefaulted) << SecondDefaulted;

1100 return true;

1101 }

1102

1105 const bool FirstPure = FirstMethod->isPureVirtual();

1106 const bool SecondPure = SecondMethod->isPureVirtual();

1107 if ((FirstVirtual || SecondVirtual) &&

1108 (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {

1109 DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;

1110 DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;

1111 return true;

1112 }

1113

1114

1115

1116

1119 const bool FirstStatic = FirstStorage == SC_Static;

1120 const bool SecondStatic = SecondStorage == SC_Static;

1121 if (FirstStatic != SecondStatic) {

1122 DiagMethodError(MethodStatic) << FirstStatic;

1123 DiagMethodNote(MethodStatic) << SecondStatic;

1124 return true;

1125 }

1126

1127 const bool FirstVolatile = FirstMethod->isVolatile();

1128 const bool SecondVolatile = SecondMethod->isVolatile();

1129 if (FirstVolatile != SecondVolatile) {

1130 DiagMethodError(MethodVolatile) << FirstVolatile;

1131 DiagMethodNote(MethodVolatile) << SecondVolatile;

1132 return true;

1133 }

1134

1135 const bool FirstConst = FirstMethod->isConst();

1136 const bool SecondConst = SecondMethod->isConst();

1137 if (FirstConst != SecondConst) {

1138 DiagMethodError(MethodConst) << FirstConst;

1139 DiagMethodNote(MethodConst) << SecondConst;

1140 return true;

1141 }

1142

1145 if (FirstInline != SecondInline) {

1146 DiagMethodError(MethodInline) << FirstInline;

1147 DiagMethodNote(MethodInline) << SecondInline;

1148 return true;

1149 }

1150

1152 FirstModule, SecondModule,

1153 FirstMethod, SecondMethod))

1154 return true;

1155

1156 for (unsigned I = 0, N = FirstMethod->param_size(); I < N; ++I) {

1159

1160 const Expr *FirstInit = FirstParam->getInit();

1161 const Expr *SecondInit = SecondParam->getInit();

1162 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {

1163 DiagMethodError(MethodParameterSingleDefaultArgument)

1164 << (I + 1) << (FirstInit == nullptr)

1166 DiagMethodNote(MethodParameterSingleDefaultArgument)

1167 << (I + 1) << (SecondInit == nullptr)

1169 return true;

1170 }

1171

1172 if (FirstInit && SecondInit &&

1174 DiagMethodError(MethodParameterDifferentDefaultArgument)

1176 DiagMethodNote(MethodParameterDifferentDefaultArgument)

1178 return true;

1179 }

1180 }

1181

1186

1187 if ((FirstTemplateArgs && !SecondTemplateArgs) ||

1188 (!FirstTemplateArgs && SecondTemplateArgs)) {

1189 DiagMethodError(MethodNoTemplateArguments)

1190 << (FirstTemplateArgs != nullptr);

1191 DiagMethodNote(MethodNoTemplateArguments)

1192 << (SecondTemplateArgs != nullptr);

1193 return true;

1194 }

1195

1196 if (FirstTemplateArgs && SecondTemplateArgs) {

1197

1202 ExpandedList.push_back(&TA);

1203 continue;

1204 }

1205 llvm::append_range(ExpandedList,

1206 llvm::make_pointer_range(TA.getPackAsArray()));

1207 }

1208 return ExpandedList;

1209 };

1211 ExpandTemplateArgumentList(FirstTemplateArgs);

1213 ExpandTemplateArgumentList(SecondTemplateArgs);

1214

1215 if (FirstExpandedList.size() != SecondExpandedList.size()) {

1216 DiagMethodError(MethodDifferentNumberTemplateArguments)

1217 << (unsigned)FirstExpandedList.size();

1218 DiagMethodNote(MethodDifferentNumberTemplateArguments)

1219 << (unsigned)SecondExpandedList.size();

1220 return true;

1221 }

1222

1223 for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {

1225 &SecondTA = *SecondExpandedList[i];

1227 continue;

1228

1229 DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;

1230 DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;

1231 return true;

1232 }

1233 }

1234

1235

1236 auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {

1240 };

1241

1242

1243

1244

1245 const bool HasFirstBody =

1246 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();

1247 const bool HasSecondBody =

1248 ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();

1249

1250 if (HasFirstBody != HasSecondBody) {

1251 DiagMethodError(MethodSingleBody) << HasFirstBody;

1252 DiagMethodNote(MethodSingleBody) << HasSecondBody;

1253 return true;

1254 }

1255

1256 if (HasFirstBody && HasSecondBody) {

1257 DiagMethodError(MethodDifferentBody);

1258 DiagMethodNote(MethodDifferentBody);

1259 return true;

1260 }

1261

1262 break;

1263 }

1264

1265 case TypeAlias:

1266 case TypeDef: {

1267 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,

1268 cast(FirstDecl),

1269 cast(SecondDecl),

1270 FirstDiffType == TypeAlias))

1271 return true;

1272 break;

1273 }

1274 case Var: {

1275 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,

1276 cast(FirstDecl),

1277 cast(SecondDecl)))

1278 return true;

1279 break;

1280 }

1282 const FriendDecl *FirstFriend = cast(FirstDecl);

1283 const FriendDecl *SecondFriend = cast(SecondDecl);

1284

1287

1290

1291 if (FirstND && SecondND) {

1293 FriendFunction)

1294 << FirstND;

1296 FriendFunction)

1297 << SecondND;

1298 return true;

1299 }

1300

1301 if (FirstTSI && SecondTSI) {

1307 FriendType)

1308 << FirstFriendType;

1310 FriendType)

1311 << SecondFriendType;

1312 return true;

1313 }

1314

1316 FriendTypeFunction)

1317 << (FirstTSI == nullptr);

1319 FriendTypeFunction)

1320 << (SecondTSI == nullptr);

1321 return true;

1322 }

1323 case FunctionTemplate: {

1325 cast(FirstDecl);

1327 cast(SecondDecl);

1328

1331

1332 auto DiagTemplateError = [&DiagError,

1333 FirstTemplate](ODRCXXRecordDifference DiffType) {

1334 return DiagError(FirstTemplate->getLocation(),

1336 << FirstTemplate;

1337 };

1338 auto DiagTemplateNote = [&DiagNote,

1339 SecondTemplate](ODRCXXRecordDifference DiffType) {

1340 return DiagNote(SecondTemplate->getLocation(),

1342 << SecondTemplate;

1343 };

1344

1345 if (FirstTPL->size() != SecondTPL->size()) {

1346 DiagTemplateError(FunctionTemplateDifferentNumberParameters)

1347 << FirstTPL->size();

1348 DiagTemplateNote(FunctionTemplateDifferentNumberParameters)

1349 << SecondTPL->size();

1350 return true;

1351 }

1352

1353 for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {

1356

1357 if (FirstParam->getKind() != SecondParam->getKind()) {

1358 enum {

1359 TemplateTypeParameter,

1360 NonTypeTemplateParameter,

1361 TemplateTemplateParameter,

1362 };

1363 auto GetParamType = [](NamedDecl *D) {

1365 default:

1366 llvm_unreachable("Unexpected template parameter type");

1367 case Decl::TemplateTypeParm:

1368 return TemplateTypeParameter;

1369 case Decl::NonTypeTemplateParm:

1370 return NonTypeTemplateParameter;

1371 case Decl::TemplateTemplateParm:

1372 return TemplateTemplateParameter;

1373 }

1374 };

1375

1376 DiagTemplateError(FunctionTemplateParameterDifferentKind)

1377 << (i + 1) << GetParamType(FirstParam);

1378 DiagTemplateNote(FunctionTemplateParameterDifferentKind)

1379 << (i + 1) << GetParamType(SecondParam);

1380 return true;

1381 }

1382

1383 if (FirstParam->getName() != SecondParam->getName()) {

1384 DiagTemplateError(FunctionTemplateParameterName)

1385 << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;

1386 DiagTemplateNote(FunctionTemplateParameterName)

1387 << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;

1388 return true;

1389 }

1390

1391 if (isa(FirstParam) &&

1392 isa(SecondParam)) {

1394 cast(FirstParam);

1396 cast(SecondParam);

1397 bool HasFirstDefaultArgument =

1400 bool HasSecondDefaultArgument =

1403 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {

1404 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)

1405 << (i + 1) << HasFirstDefaultArgument;

1406 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)

1407 << (i + 1) << HasSecondDefaultArgument;

1408 return true;

1409 }

1410

1411 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {

1417 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)

1418 << (i + 1) << FirstTA;

1419 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)

1420 << (i + 1) << SecondTA;

1421 return true;

1422 }

1423 }

1424

1426 DiagTemplateError(FunctionTemplatePackParameter)

1428 DiagTemplateNote(FunctionTemplatePackParameter)

1430 return true;

1431 }

1432 }

1433

1434 if (isa(FirstParam) &&

1435 isa(SecondParam)) {

1437 cast(FirstParam);

1439 cast(SecondParam);

1440

1443

1444 auto ComputeTemplateParameterListODRHash =

1446 assert(TPL);

1450 };

1451

1452 if (ComputeTemplateParameterListODRHash(FirstTPL) !=

1453 ComputeTemplateParameterListODRHash(SecondTPL)) {

1454 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);

1455 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);

1456 return true;

1457 }

1458

1459 bool HasFirstDefaultArgument =

1462 bool HasSecondDefaultArgument =

1465 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {

1466 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)

1467 << (i + 1) << HasFirstDefaultArgument;

1468 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)

1469 << (i + 1) << HasSecondDefaultArgument;

1470 return true;

1471 }

1472

1473 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {

1479 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)

1480 << (i + 1) << FirstTA;

1481 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)

1482 << (i + 1) << SecondTA;

1483 return true;

1484 }

1485 }

1486

1488 DiagTemplateError(FunctionTemplatePackParameter)

1490 DiagTemplateNote(FunctionTemplatePackParameter)

1492 return true;

1493 }

1494 }

1495

1496 if (isa(FirstParam) &&

1497 isa(SecondParam)) {

1499 cast(FirstParam);

1501 cast(SecondParam);

1502

1506 DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);

1507 DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);

1508 return true;

1509 }

1510

1511 bool HasFirstDefaultArgument =

1514 bool HasSecondDefaultArgument =

1517 if (HasFirstDefaultArgument != HasSecondDefaultArgument) {

1518 DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)

1519 << (i + 1) << HasFirstDefaultArgument;

1520 DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)

1521 << (i + 1) << HasSecondDefaultArgument;

1522 return true;

1523 }

1524

1525 if (HasFirstDefaultArgument && HasSecondDefaultArgument) {

1530

1533 DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)

1534 << (i + 1) << FirstDefaultArgument;

1535 DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)

1536 << (i + 1) << SecondDefaultArgument;

1537 return true;

1538 }

1539 }

1540

1542 DiagTemplateError(FunctionTemplatePackParameter)

1544 DiagTemplateNote(FunctionTemplatePackParameter)

1546 return true;

1547 }

1548 }

1549 }

1550 break;

1551 }

1552 }

1553

1555 diag::err_module_odr_violation_mismatch_decl_unknown)

1556 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType

1559 diag::note_module_odr_violation_mismatch_decl_unknown)

1560 << SecondModule.empty() << SecondModule << FirstDiffType

1562 return true;

1563}

1564

1566 const RecordDecl *SecondRecord) const {

1567 if (FirstRecord == SecondRecord)

1568 return false;

1569

1572

1577 continue;

1579 }

1580 };

1581

1585 PopulateHashes(FirstHashes, FirstRecord, DC);

1586 PopulateHashes(SecondHashes, SecondRecord, DC);

1587

1588 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);

1589 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;

1590 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;

1591 const Decl *FirstDecl = DR.FirstDecl;

1592 const Decl *SecondDecl = DR.SecondDecl;

1593

1594 if (FirstDiffType == Other || SecondDiffType == Other) {

1595 diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,

1596 SecondModule);

1597 return true;

1598 }

1599

1600 if (FirstDiffType != SecondDiffType) {

1601 diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,

1602 SecondRecord, SecondModule);

1603 return true;

1604 }

1605

1606 assert(FirstDiffType == SecondDiffType);

1607 switch (FirstDiffType) {

1608

1609 case EndOfClass:

1611

1612 case PublicSpecifer:

1613 case PrivateSpecifer:

1614 case ProtectedSpecifer:

1615 case StaticAssert:

1616 case CXXMethod:

1617 case TypeAlias:

1619 case FunctionTemplate:

1620

1621 case ObjCMethod:

1622 case ObjCIvar:

1623 case ObjCProperty:

1624 llvm_unreachable("Invalid diff type");

1625

1626 case Field: {

1627 if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,

1628 cast(FirstDecl),

1629 cast(SecondDecl)))

1630 return true;

1631 break;

1632 }

1633 case TypeDef: {

1634 if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,

1635 cast(FirstDecl),

1636 cast(SecondDecl),

1637 false))

1638 return true;

1639 break;

1640 }

1641 case Var: {

1642 if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,

1643 cast(FirstDecl),

1644 cast(SecondDecl)))

1645 return true;

1646 break;

1647 }

1648 }

1649

1651 diag::err_module_odr_violation_mismatch_decl_unknown)

1652 << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType

1655 diag::note_module_odr_violation_mismatch_decl_unknown)

1656 << SecondModule.empty() << SecondModule << FirstDiffType

1658 return true;

1659}

1660

1664 if (FirstFunction == SecondFunction)

1665 return false;

1666

1667

1668 enum ODRFunctionDifference {

1669 ReturnType,

1670 ParameterName,

1671 ParameterType,

1672 ParameterSingleDefaultArgument,

1673 ParameterDifferentDefaultArgument,

1674 FunctionBody,

1675 };

1676

1679

1680 auto DiagError = [FirstFunction, &FirstModule,

1682 ODRFunctionDifference DiffType) {

1683 return Diag(Loc, diag::err_module_odr_violation_function)

1684 << FirstFunction << FirstModule.empty() << FirstModule << Range

1685 << DiffType;

1686 };

1688 ODRFunctionDifference DiffType) {

1689 return Diag(Loc, diag::note_module_odr_violation_function)

1690 << SecondModule << Range << DiffType;

1691 };

1692

1701 return true;

1702 }

1703

1705 "Merged functions with different number of parameters");

1706

1707 size_t ParamSize = FirstFunction->param_size();

1708 for (unsigned I = 0; I < ParamSize; ++I) {

1711

1713 "Merged function has different parameter types.");

1714

1717 ParameterName)

1720 ParameterName)

1722 return true;

1723 };

1724

1727 if (FirstParamType != SecondParamType &&

1729 if (const DecayedType *ParamDecayedType =

1732 ParameterType)

1733 << (I + 1) << FirstParamType << true

1734 << ParamDecayedType->getOriginalType();

1735 } else {

1737 ParameterType)

1738 << (I + 1) << FirstParamType << false;

1739 }

1740

1741 if (const DecayedType *ParamDecayedType =

1744 ParameterType)

1745 << (I + 1) << SecondParamType << true

1746 << ParamDecayedType->getOriginalType();

1747 } else {

1749 ParameterType)

1750 << (I + 1) << SecondParamType << false;

1751 }

1752 return true;

1753 }

1754

1755

1756 const Expr *FirstInit = FirstParam->getInit();

1757 const Expr *SecondInit = SecondParam->getInit();

1758 if ((FirstInit == nullptr) != (SecondInit == nullptr)) {

1760 ParameterSingleDefaultArgument)

1761 << (I + 1) << (FirstInit == nullptr)

1764 ParameterSingleDefaultArgument)

1765 << (I + 1) << (SecondInit == nullptr)

1767 return true;

1768 }

1769

1770 if (FirstInit && SecondInit &&

1773 ParameterDifferentDefaultArgument)

1776 ParameterDifferentDefaultArgument)

1778 return true;

1779 }

1780

1782 "Undiagnosed parameter difference.");

1783 }

1784

1785

1786

1788 FunctionBody);

1790 FunctionBody);

1791 return true;

1792}

1793

1795 const EnumDecl *SecondEnum) const {

1796 if (FirstEnum == SecondEnum)

1797 return false;

1798

1799

1800 enum ODREnumDifference {

1801 SingleScopedEnum,

1802 EnumTagKeywordMismatch,

1803 SingleSpecifiedType,

1804 DifferentSpecifiedTypes,

1805 DifferentNumberEnumConstants,

1806 EnumConstantName,

1807 EnumConstantSingleInitializer,

1808 EnumConstantDifferentInitializer,

1809 };

1810

1813

1814 auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,

1815 ODREnumDifference DiffType) {

1816 return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)

1817 << FirstEnum << FirstModule.empty() << FirstModule

1819 };

1820 auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,

1821 ODREnumDifference DiffType) {

1822 return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)

1823 << SecondModule << DiagAnchor->getSourceRange() << DiffType;

1824 };

1825

1827 DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();

1828 DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();

1829 return true;

1830 }

1831

1835 DiagError(FirstEnum, EnumTagKeywordMismatch)

1837 DiagNote(SecondEnum, EnumTagKeywordMismatch)

1839 return true;

1840 }

1841 }

1842

1843 QualType FirstUnderlyingType =

1847 QualType SecondUnderlyingType =

1851 if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {

1852 DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();

1853 DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();

1854 return true;

1855 }

1856

1857 if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {

1860 DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;

1861 DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;

1862 return true;

1863 }

1864 }

1865

1866

1870 for (const Decl *D : Enum->decls()) {

1871

1872

1874 continue;

1875 assert(isa(D) && "Unexpected Decl kind");

1876 Hashes.emplace_back(cast(D), computeODRHash(D));

1877 }

1878 };

1880 PopulateHashes(FirstHashes, FirstEnum);

1882 PopulateHashes(SecondHashes, SecondEnum);

1883

1884 if (FirstHashes.size() != SecondHashes.size()) {

1885 DiagError(FirstEnum, DifferentNumberEnumConstants)

1886 << (int)FirstHashes.size();

1887 DiagNote(SecondEnum, DifferentNumberEnumConstants)

1888 << (int)SecondHashes.size();

1889 return true;

1890 }

1891

1892 for (unsigned I = 0, N = FirstHashes.size(); I < N; ++I) {

1893 if (FirstHashes[I].second == SecondHashes[I].second)

1894 continue;

1895 const EnumConstantDecl *FirstConstant = FirstHashes[I].first;

1896 const EnumConstantDecl *SecondConstant = SecondHashes[I].first;

1897

1899 DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;

1900 DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;

1901 return true;

1902 }

1903

1906 if (!FirstInit && !SecondInit)

1907 continue;

1908

1909 if (!FirstInit || !SecondInit) {

1910 DiagError(FirstConstant, EnumConstantSingleInitializer)

1911 << I + 1 << FirstConstant << (FirstInit != nullptr);

1912 DiagNote(SecondConstant, EnumConstantSingleInitializer)

1913 << I + 1 << SecondConstant << (SecondInit != nullptr);

1914 return true;

1915 }

1916

1918 DiagError(FirstConstant, EnumConstantDifferentInitializer)

1919 << I + 1 << FirstConstant;

1920 DiagNote(SecondConstant, EnumConstantDifferentInitializer)

1921 << I + 1 << SecondConstant;

1922 return true;

1923 }

1924 }

1925 return false;

1926}

1927

1930 const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {

1931

1932

1933 if (FirstID == SecondID)

1934 return false;

1935

1938

1939

1940 enum ODRInterfaceDifference {

1941 SuperClassType,

1942 IVarAccess,

1943 };

1944

1945 auto DiagError = [FirstID, &FirstModule,

1947 ODRInterfaceDifference DiffType) {

1948 return Diag(Loc, diag::err_module_odr_violation_objc_interface)

1949 << FirstID << FirstModule.empty() << FirstModule << Range

1950 << DiffType;

1951 };

1953 ODRInterfaceDifference DiffType) {

1954 return Diag(Loc, diag::note_module_odr_violation_objc_interface)

1955 << SecondModule.empty() << SecondModule << Range << DiffType;

1956 };

1957

1958 const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();

1959 assert(FirstDD && SecondDD && "Definitions without DefinitionData");

1960 if (FirstDD != SecondDD) {

1961

1962 auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,

1964 if (!SuperInfo)

1965 return ID->getSourceRange();

1968 };

1969

1973 const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;

1974 if (SecondSuperInfo)

1975 SecondSuperClass =

1977

1978 if ((FirstSuperClass && SecondSuperClass &&

1980 (FirstSuperClass && !SecondSuperClass) ||

1981 (!FirstSuperClass && SecondSuperClass)) {

1983 if (FirstSuperInfo)

1984 FirstType = FirstSuperInfo->getType();

1985

1987 GetSuperClassSourceRange(FirstSuperInfo, FirstID),

1988 SuperClassType)

1989 << (bool)FirstSuperInfo << FirstType;

1990

1992 if (SecondSuperInfo)

1993 SecondType = SecondSuperInfo->getType();

1994

1996 GetSuperClassSourceRange(SecondSuperInfo, SecondID),

1997 SuperClassType)

1998 << (bool)SecondSuperInfo << SecondType;

1999 return true;

2000 }

2001

2002

2004 auto &SecondProtos = SecondDD->ReferencedProtocols;

2005 if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,

2006 SecondProtos, SecondID, SecondModule))

2007 return true;

2008 }

2009

2012 for (auto *D : ID->decls()) {

2014 continue;

2016 }

2017 };

2018

2021

2022

2023 PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());

2024 PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());

2025

2026 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);

2027 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;

2028 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;

2029 const Decl *FirstDecl = DR.FirstDecl;

2030 const Decl *SecondDecl = DR.SecondDecl;

2031

2032 if (FirstDiffType == Other || SecondDiffType == Other) {

2033 diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,

2034 SecondModule);

2035 return true;

2036 }

2037

2038 if (FirstDiffType != SecondDiffType) {

2039 diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,

2040 SecondModule);

2041 return true;

2042 }

2043

2044 assert(FirstDiffType == SecondDiffType);

2045 switch (FirstDiffType) {

2046

2047 case EndOfClass:

2049

2050 case Field:

2051 case TypeDef:

2052 case Var:

2053

2054 case PublicSpecifer:

2055 case PrivateSpecifer:

2056 case ProtectedSpecifer:

2057 case StaticAssert:

2058 case CXXMethod:

2059 case TypeAlias:

2061 case FunctionTemplate:

2062 llvm_unreachable("Invalid diff type");

2063

2064 case ObjCMethod: {

2065 if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,

2066 cast(FirstDecl),

2067 cast(SecondDecl)))

2068 return true;

2069 break;

2070 }

2071 case ObjCIvar: {

2072 if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,

2073 cast(FirstDecl),

2074 cast(SecondDecl)))

2075 return true;

2076

2077

2078 const ObjCIvarDecl *FirstIvar = cast(FirstDecl);

2079 const ObjCIvarDecl *SecondIvar = cast(SecondDecl);

2083 IVarAccess)

2087 IVarAccess)

2088 << SecondIvar->getName()

2090 return true;

2091 }

2092 break;

2093 }

2094 case ObjCProperty: {

2095 if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,

2096 cast(FirstDecl),

2097 cast(SecondDecl)))

2098 return true;

2099 break;

2100 }

2101 }

2102

2104 diag::err_module_odr_violation_mismatch_decl_unknown)

2105 << FirstID << FirstModule.empty() << FirstModule << FirstDiffType

2108 diag::note_module_odr_violation_mismatch_decl_unknown)

2109 << SecondModule.empty() << SecondModule << FirstDiffType

2111 return true;

2112}

2113

2117 const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {

2118 if (FirstProtocol == SecondProtocol)

2119 return false;

2120

2123

2124 const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();

2125 assert(FirstDD && SecondDD && "Definitions without DefinitionData");

2126

2127 if (FirstDD != SecondDD) {

2128

2131 const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;

2132 if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,

2133 SecondProtocols, SecondProtocol,

2134 SecondModule))

2135 return true;

2136 }

2137

2140 for (const Decl *D : ID->decls()) {

2142 continue;

2144 }

2145 };

2146

2149

2150

2151 PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());

2152 PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());

2153

2154 DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);

2155 ODRMismatchDecl FirstDiffType = DR.FirstDiffType;

2156 ODRMismatchDecl SecondDiffType = DR.SecondDiffType;

2157 const Decl *FirstDecl = DR.FirstDecl;

2158 const Decl *SecondDecl = DR.SecondDecl;

2159

2160 if (FirstDiffType == Other || SecondDiffType == Other) {

2161 diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,

2162 SecondProtocol, SecondModule);

2163 return true;

2164 }

2165

2166 if (FirstDiffType != SecondDiffType) {

2167 diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,

2168 SecondProtocol, SecondModule);

2169 return true;

2170 }

2171

2172 assert(FirstDiffType == SecondDiffType);

2173 switch (FirstDiffType) {

2174

2175 case EndOfClass:

2177

2178 case Field:

2179 case TypeDef:

2180 case Var:

2181 case ObjCIvar:

2182

2183 case PublicSpecifer:

2184 case PrivateSpecifer:

2185 case ProtectedSpecifer:

2186 case StaticAssert:

2187 case CXXMethod:

2188 case TypeAlias:

2190 case FunctionTemplate:

2191 llvm_unreachable("Invalid diff type");

2192 case ObjCMethod: {

2193 if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,

2194 cast(FirstDecl),

2195 cast(SecondDecl)))

2196 return true;

2197 break;

2198 }

2199 case ObjCProperty: {

2200 if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,

2201 SecondModule,

2202 cast(FirstDecl),

2203 cast(SecondDecl)))

2204 return true;

2205 break;

2206 }

2207 }

2208

2210 diag::err_module_odr_violation_mismatch_decl_unknown)

2211 << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType

2214 diag::note_module_odr_violation_mismatch_decl_unknown)

2215 << SecondModule.empty() << SecondModule << FirstDiffType

2217 return true;

2218}

Defines the C++ template declaration subclasses.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::Record Record

Defines the clang::Module class, which describes a module in the source code.

static unsigned computeODRHash(QualType Ty)

static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags, const NamedDecl *FirstContainer, StringRef FirstModule, StringRef SecondModule, const MethodT *FirstMethod, const MethodT *SecondMethod)

This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

Represents a base class of a C++ class.

AccessSpecifier getAccessSpecifierAsWritten() const

Retrieves the access specifier as written in the source code (which may mean that no access specifier...

bool isVirtual() const

Determines whether the base class is a virtual base class (or not).

QualType getType() const

Retrieves the type of the base class.

SourceRange getSourceRange() const LLVM_READONLY

Retrieves the source range that contains the entire base specifier.

Represents a static or instance method of a struct/union/class.

Represents a C++ struct/union/class.

ClassTemplateDecl * getDescribedClassTemplate() const

Retrieves the class template that is described by this class declaration.

Declaration of a class template.

Represents a pointer type decayed from an array or function type.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

Decl - This represents one declaration (or definition), e.g.

Module * getImportedOwningModule() const

Get the imported owning module, if this decl is from an imported (non-local) module.

SourceLocation getLocation() const

AccessSpecifier getAccess() const

SourceLocation getBeginLoc() const LLVM_READONLY

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

The name of a declaration.

IdentifierInfo * getAsIdentifierInfo() const

Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...

bool isIdentifier() const

Predicate functions for querying what type of name this is.

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

An instance of this object exists for each enum constant that is defined.

const Expr * getInitExpr() const

bool isScoped() const

Returns true if this is a C++11 scoped enumeration.

bool isScopedUsingClassTag() const

Returns true if this is a C++11 scoped enumeration.

TypeSourceInfo * getIntegerTypeSourceInfo() const

Return the type source info for the underlying integer type, if no type source info exists,...

SourceRange getSourceRange() const override LLVM_READONLY

Overrides to provide correct range when there's an enum-base specifier with forward declarations.

This represents one expression.

Represents a member of a struct/union/class.

bool isMutable() const

Determines whether this field is mutable (C++ only).

Expr * getInClassInitializer() const

Get the C++11 default member initializer for this member, or null if one has not been set.

bool isBitField() const

Determines whether this field is a bitfield.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Expr * getBitWidth() const

Returns the expression that represents the bit width, if this field is a bit field.

FriendDecl - Represents the declaration of a friend entity, which can be a function,...

SourceLocation getFriendLoc() const

Retrieves the location of the 'friend' keyword.

SourceRange getSourceRange() const override LLVM_READONLY

Retrieves the source range for the friend declaration.

NamedDecl * getFriendDecl() const

If this friend declaration doesn't name a type, return the inner declaration.

TypeSourceInfo * getFriendType() const

If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...

Represents a function declaration or definition.

const ParmVarDecl * getParamDecl(unsigned i) const

SourceRange getReturnTypeSourceRange() const

Attempt to compute an informative source range covering the function return type.

QualType getReturnType() const

bool isExplicitlyDefaulted() const

Whether this function is explicitly defaulted.

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

unsigned getODRHash()

Returns ODRHash of the function.

StorageClass getStorageClass() const

Returns the storage class as written in the source.

bool isDeletedAsWritten() const

bool isPureVirtual() const

Whether this virtual function is pure, i.e.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool isVirtualAsWritten() const

Whether this function is marked as virtual explicitly.

size_t param_size() const

bool isInlineSpecified() const

Determine whether the "inline" keyword was specified for this function.

Declaration of a template function.

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

Describes a module or submodule.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.

bool hasDefaultArgument() const

Determine whether this template parameter has a default argument.

bool defaultArgumentWasInherited() const

Determines whether the default argument was inherited from a previous declaration of this template.

const TemplateArgumentLoc & getDefaultArgument() const

Retrieve the default argument, if any.

bool isParameterPack() const

Whether this parameter is a non-type template parameter pack.

bool diagnoseMismatch(const FunctionDecl *FirstFunction, const FunctionDecl *SecondFunction) const

Diagnose ODR mismatch between 2 FunctionDecl.

static std::string getOwningModuleNameForDiagnostic(const Decl *D)

Get the best name we know for the module that owns the given declaration, or an empty string if the d...

void AddStmt(const Stmt *S)

void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)

void AddSubDecl(const Decl *D)

void AddQualType(QualType T)

void AddTemplateParameterList(const TemplateParameterList *TPL)

void AddTemplateArgument(TemplateArgument TA)

static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent)

ObjCContainerDecl - Represents a container for method declarations.

Represents an ObjC class declaration.

unsigned getODRHash()

Get precomputed ODRHash or add a new one.

const ObjCProtocolList & getReferencedProtocols() const

ObjCInterfaceDecl * getSuperClass() const

ObjCInterfaceDecl * getDefinition()

Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...

TypeSourceInfo * getSuperClassTInfo() const

ObjCIvarDecl - Represents an ObjC instance variable.

AccessControl getCanonicalAccessControl() const

ObjCMethodDecl - Represents an instance or class method declaration.

bool isDirectMethod() const

True if the method is tagged as objc_direct.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool isInstanceMethod() const

bool isThisDeclarationADesignatedInitializer() const

Returns true if this specific method declaration is marked with the designated initializer attribute.

QualType getReturnType() const

ObjCImplementationControl getImplementationControl() const

Represents a class type in Objective C.

Represents one property declaration in an Objective-C interface.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

SourceLocation getLParenLoc() const

ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const

ObjCPropertyAttribute::Kind getPropertyAttributes() const

PropertyControl getPropertyImplementation() const

Represents an Objective-C protocol declaration.

const ObjCProtocolList & getReferencedProtocols() const

ObjCProtocolDecl * getDefinition()

Retrieve the definition of this protocol, if any.

A list of Objective-C protocols, along with the source locations at which they were referenced.

loc_iterator loc_begin() const

Represents a parameter to a function.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

Represents a struct/union/class.

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Represents a C++11 static_assert declaration.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Stmt - This represents one statement.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

A template argument list.

const TemplateArgument & getArgument() const

Represents a template argument.

@ Pack

The template argument is actually a parameter pack.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

Stores a list of template parameters for a TemplateDecl and its derived classes.

NamedDecl * getParam(unsigned Idx)

ArrayRef< NamedDecl * > asArray()

TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.

const TemplateArgumentLoc & getDefaultArgument() const

Retrieve the default argument, if any.

bool isParameterPack() const

Whether this template template parameter is a template parameter pack.

bool defaultArgumentWasInherited() const

Determines whether the default argument was inherited from a previous declaration of this template.

bool hasDefaultArgument() const

Determine whether this template parameter has a default argument.

Declaration of a template type parameter.

const TemplateArgumentLoc & getDefaultArgument() const

Retrieve the default argument, if any.

bool hasDefaultArgument() const

Determine whether this template parameter has a default argument.

bool defaultArgumentWasInherited() const

Determines whether the default argument was inherited from a previous declaration of this template.

bool isParameterPack() const

Returns whether this is a parameter pack.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Base wrapper for a particular "section" of type source info.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

The base class of the type hierarchy.

const T * castAs() const

Member-template castAs.

const T * getAs() const

Member-template getAs'.

Base class for declarations which introduce a typedef-name.

QualType getUnderlyingType() const

Represents a variable declaration or definition.

bool isConstexpr() const

Whether this variable is (C++11) constexpr.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

const Expr * getInit() const

The JSON file list parser is used to communicate input to InstallAPI.

@ NumObjCPropertyAttrsBits

Number of bits fitting all the property attributes.

StorageClass

Storage classes.

@ Enum

The "enum" keyword introduces the elaborated-type-specifier.

@ Other

Other implicit parameter.