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

1

2

3

4

5

6

7

8

9

10

11

12

22#include "llvm/ADT/StringExtras.h"

23#include "llvm/Support/ConvertUTF.h"

24#include "llvm/Support/Format.h"

25#include "llvm/Support/raw_ostream.h"

26

27using namespace clang;

28

29

30

31

33 bool &ShouldAKA) {

35

36 while (true) {

38

39

40 if (const UsingType *UT = dyn_cast(Ty)) {

41 QT = UT->desugar();

42 continue;

43 }

44

45 if (const ParenType *PT = dyn_cast(Ty)) {

46 QT = PT->desugar();

47 continue;

48 }

49

50 if (const MacroQualifiedType *MDT = dyn_cast(Ty)) {

51 QT = MDT->desugar();

52 continue;

53 }

54

55 if (const SubstTemplateTypeParmType *ST =

56 dyn_cast(Ty)) {

57 QT = ST->desugar();

58 continue;

59 }

60

61 if (const AttributedType *AT = dyn_cast(Ty)) {

62 QT = AT->desugar();

63 continue;

64 }

65

66 if (const AdjustedType *AT = dyn_cast(Ty)) {

67 QT = AT->desugar();

68 continue;

69 }

70

71 if (const AutoType *AT = dyn_cast(Ty)) {

72 if (!AT->isSugared())

73 break;

74 QT = AT->desugar();

75 continue;

76 }

77

78

79

80 if (const FunctionType *FT = dyn_cast(Ty)) {

81 bool DesugarReturn = false;

82 QualType SugarRT = FT->getReturnType();

84 if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {

85 RT = Context.getAttributedType(*nullability, RT, RT);

86 }

87

88 bool DesugarArgument = false;

91 if (FPT) {

94 if (auto nullability =

95 AttributedType::stripOuterNullability(SugarPT)) {

96 PT = Context.getAttributedType(*nullability, PT, PT);

97 }

98 Args.push_back(PT);

99 }

100 }

101

102 if (DesugarReturn || DesugarArgument) {

103 ShouldAKA = true;

104 QT = FPT ? Context.getFunctionType(RT, Args, FPT->getExtProtoInfo())

105 : Context.getFunctionNoProtoType(RT, FT->getExtInfo());

106 break;

107 }

108 }

109

110

111

112 if (const TemplateSpecializationType *TST =

113 dyn_cast(Ty)) {

114 if (!TST->isTypeAlias()) {

115 bool DesugarArgument = false;

117 for (const TemplateArgument &Arg : TST->template_arguments()) {

120 DesugarArgument));

121 else

122 Args.push_back(Arg);

123 }

124

125 if (DesugarArgument) {

126 ShouldAKA = true;

127 QT = Context.getTemplateSpecializationType(

128 TST->getKeyword(), TST->getTemplateName(), Args,

129 {}, QT);

130 }

131 break;

132 }

133 }

134

135 if (const auto *AT = dyn_cast(Ty)) {

138 if (const auto *CAT = dyn_cast(AT))

139 QT = Context.getConstantArrayType(

140 ElementTy, CAT->getSize(), CAT->getSizeExpr(),

141 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());

142 else if (const auto *VAT = dyn_cast(AT))

143 QT = Context.getVariableArrayType(ElementTy, VAT->getSizeExpr(),

144 VAT->getSizeModifier(),

145 VAT->getIndexTypeCVRQualifiers());

146 else if (const auto *DSAT = dyn_cast(AT))

147 QT = Context.getDependentSizedArrayType(

148 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),

149 DSAT->getIndexTypeCVRQualifiers());

150 else if (const auto *IAT = dyn_cast(AT))

151 QT = Context.getIncompleteArrayType(ElementTy, IAT->getSizeModifier(),

152 IAT->getIndexTypeCVRQualifiers());

153 else

154 llvm_unreachable("Unhandled array type");

155 break;

156 }

157

158

159 if (QualType(Ty,0) == Context.getObjCIdType() ||

160 QualType(Ty,0) == Context.getObjCClassType() ||

161 QualType(Ty,0) == Context.getObjCSelType() ||

162 QualType(Ty,0) == Context.getObjCProtoType())

163 break;

164

165

166 if (QualType(Ty, 0) == Context.getBuiltinVaListType() ||

167 QualType(Ty, 0) == Context.getBuiltinMSVaListType())

168 break;

169

170

172 bool IsSugar = false;

174#define ABSTRACT_TYPE(Class, Base)

175#define TYPE(Class, Base) \

176case Type::Class: { \

177const Class##Type *CTy = cast<Class##Type>(Ty); \

178if (CTy->isSugared()) { \

179IsSugar = true; \

180Underlying = CTy->desugar(); \

181} \

182break; \

183}

184#include "clang/AST/TypeNodes.inc"

185 }

186

187

188 if (!IsSugar)

189 break;

190

191

192

194 break;

195

196

197 if (const TagType *UTT = Underlying->getAs())

198 if (const TypedefType *QTT = dyn_cast(QT))

199 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())

200 break;

201

202

203 ShouldAKA = true;

204 QT = Underlying;

205 }

206

207

208

210 QT = Context.getPointerType(

213 QT = Context.getObjCObjectPointerType(

216 QT = Context.getLValueReferenceType(

219 QT = Context.getRValueReferenceType(

222 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {

225 QT = Context.getObjCObjectType(

226 BaseType, Ty->getTypeArgsAsWritten(),

227 ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),

228 Ty->isKindOfTypeAsWritten());

229 }

230 }

231

232 return QC.apply(Context, QT);

233}

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259static std::string

263

264 bool ForceAKA = false;

266 std::string S = Ty.getAsString(Context.getPrintingPolicy());

267 std::string CanS = CanTy.getAsString(Context.getPrintingPolicy());

268

269 for (const intptr_t &QualTypeVal : QualTypeVals) {

272 if (CompareTy.isNull())

273 continue;

274 if (CompareTy == Ty)

275 continue;

277 if (CompareCanTy == CanTy)

278 continue;

279 std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy());

280 bool ShouldAKA = false;

283 std::string CompareDesugarStr =

284 CompareDesugar.getAsString(Context.getPrintingPolicy());

285 if (CompareS != S && CompareDesugarStr != S)

286 continue;

287

288 std::string CompareCanS =

289 CompareCanTy.getAsString(Context.getPrintingPolicy());

290

291 if (CompareCanS == CanS)

292 continue;

293

294 ForceAKA = true;

295 break;

296 }

297

298

299

300 bool Repeated = false;

301 for (const auto &PrevArg : PrevArgs) {

302

306 if (PrevTy == Ty) {

307 Repeated = true;

308 break;

309 }

310 }

311 }

312

313

314

315 if (!Repeated) {

316 bool ShouldAKA = false;

318 if (ShouldAKA || ForceAKA) {

319 if (DesugaredTy == Ty) {

321 }

322 std::string akaStr = DesugaredTy.getAsString(Context.getPrintingPolicy());

323 if (akaStr != S) {

324 S = "'" + S + "' (aka '" + akaStr + "')";

325 return S;

326 }

327 }

328

329

330

331

333 std::string DecoratedString;

334 llvm::raw_string_ostream OS(DecoratedString);

335 const char *Values = VTy->getNumElements() > 1 ? "values" : "value";

336 OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"

337 << VTy->getElementType().getAsString(Context.getPrintingPolicy())

338 << "' " << Values << ")";

339 return DecoratedString;

340 }

341 }

342

343 S = "'" + S + "'";

344 return S;

345}

346

348 QualType ToType, bool PrintTree,

349 bool PrintFromType, bool ElideType,

350 bool ShowColors, raw_ostream &OS);

351

355 StringRef Modifier,

356 StringRef Argument,

359 void *Cookie,

362

363 size_t OldEnd = Output.size();

364 llvm::raw_svector_ostream OS(Output);

365 bool NeedQuotes = true;

366

367 switch (Kind) {

368 default: llvm_unreachable("unknown ArgumentKind");

370 assert(Modifier.empty() && Argument.empty() &&

371 "Invalid modifier for Qualifiers argument");

372

374 if (S.empty()) {

375 OS << (Context.getLangOpts().OpenCL ? "default" : "generic");

376 OS << " address space";

377 } else {

378 OS << "address space";

379 OS << " '" << S << "'";

380 }

381 NeedQuotes = false;

382 break;

383 }

385 assert(Modifier.empty() && Argument.empty() &&

386 "Invalid modifier for Qualifiers argument");

387

390 if (S.empty()) {

391 OS << "unqualified";

392 NeedQuotes = false;

393 } else {

394 OS << S;

395 }

396 break;

397 }

404

410 break;

411 }

412

413

414

416 return;

417

418

419

421 Modifier = StringRef();

422 Argument = StringRef();

423

424 [[fallthrough]];

425 }

427 assert(Modifier.empty() && Argument.empty() &&

428 "Invalid modifier for QualType argument");

429

432 NeedQuotes = false;

433 break;

434 }

436 if (Modifier == "objcclass" && Argument.empty())

437 OS << '+';

438 else if (Modifier == "objcinstance" && Argument.empty())

439 OS << '-';

440 else

441 assert(Modifier.empty() && Argument.empty() &&

442 "Invalid modifier for DeclarationName argument");

443

445 break;

446 }

449 if (Modifier == "q" && Argument.empty())

451 else {

452 assert(Modifier.empty() && Argument.empty() &&

453 "Invalid modifier for NamedDecl* argument");

455 }

458 break;

459 }

462 .print(OS, Context.getPrintingPolicy(),

463 false,

464 false);

465 break;

468 assert(DC && "Should never have a null declaration context");

469 NeedQuotes = false;

470

471

473 if (Context.getLangOpts().CPlusPlus)

474 OS << "the global namespace";

475 else

476 OS << "the global scope";

478 OS << "block literal";

480 OS << "lambda expression";

481 } else if (TypeDecl *Type = dyn_cast(DC)) {

483 Context, Context.getTypeDeclType(Type), PrevArgs, QualTypeVals);

484 } else {

485 assert(isa(DC) && "Expected a NamedDecl");

488 OS << "namespace ";

490 OS << "method ";

492 OS << "function ";

493

494 OS << '\'';

496 OS << '\'';

497 }

498 break;

499 }

501 const Attr *At = reinterpret_cast<Attr *>(Val);

502 assert(At && "Received null Attr object!");

503

504 OS << '\'';

508 } else {

510 }

511 OS << '\'';

512 NeedQuotes = false;

513 break;

514 }

516 const Expr *E = reinterpret_cast<Expr *>(Val);

517 assert(E && "Received null Expr!");

518 E->printPretty(OS, nullptr, Context.getPrintingPolicy());

519 break;

520 }

523 assert(AT && "Received null AttributeCommonInfo object!");

524

525 OS << '\'';

528 } else {

530 }

531 OS << '\'';

532 NeedQuotes = false;

533 break;

534 }

535 }

536

537 if (NeedQuotes) {

538 Output.insert(Output.begin()+OldEnd, '\'');

539 Output.push_back('\'');

540 }

541}

542

543

544

545

546

547namespace {

548class TemplateDiff {

549

551

552

554

555

556 bool ElideType;

557

558

559 bool PrintTree;

560

561

562 bool ShowColor;

563

564

565

566

568

569

570

572

573

574 raw_ostream &OS;

575

576

577 bool IsBold;

578

579

580 class DiffTree {

581 public:

582

583

584

585 enum DiffKind {

586

588

590

591

593

594

595

597

598 TemplateTemplate,

599

601

603

604 FromIntegerAndToDeclaration,

605 FromDeclarationAndToInteger

606 };

607

608 private:

609

610

611

612 struct TemplateArgumentInfo {

613 QualType ArgType;

614 Qualifiers Qual;

615 llvm::APSInt Val;

616 bool IsValidInt = false;

617 Expr *ArgExpr = nullptr;

618 TemplateDecl *TD = nullptr;

619 ValueDecl *VD = nullptr;

620 bool NeedAddressOf = false;

621 bool IsNullPtr = false;

622 bool IsDefault = false;

623 };

624

625

626

627

628 struct DiffNode {

630

631

632 unsigned NextNode = 0;

633

634

635 unsigned ChildNode = 0;

636

637

638 unsigned ParentNode = 0;

639

640 TemplateArgumentInfo FromArgInfo, ToArgInfo;

641

642

643 bool Same = false;

644

645 DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}

646 };

647

648

649 SmallVector<DiffNode, 16> FlatTree;

650

651

652 unsigned CurrentNode;

653

654

655

656 unsigned NextFreeNode;

657

658

659 unsigned ReadNode;

660

661 public:

662 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) {

663 FlatTree.push_back(DiffNode());

664 }

665

666

667 void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,

668 Qualifiers FromQual, Qualifiers ToQual,

669 bool FromDefault, bool ToDefault) {

670 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

671 FlatTree[CurrentNode].Kind = Template;

672 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;

673 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;

674 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;

675 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;

676 SetDefault(FromDefault, ToDefault);

677 }

678

679 void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,

680 bool ToDefault) {

681 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

682 FlatTree[CurrentNode].Kind = Type;

683 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;

684 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;

685 SetDefault(FromDefault, ToDefault);

686 }

687

688 void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault,

689 bool ToDefault) {

690 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

691 FlatTree[CurrentNode].Kind = Expression;

692 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;

693 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;

694 SetDefault(FromDefault, ToDefault);

695 }

696

697 void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,

698 bool FromDefault, bool ToDefault) {

699 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

700 FlatTree[CurrentNode].Kind = TemplateTemplate;

701 FlatTree[CurrentNode].FromArgInfo.TD = FromTD;

702 FlatTree[CurrentNode].ToArgInfo.TD = ToTD;

703 SetDefault(FromDefault, ToDefault);

704 }

705

706 void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,

707 bool IsValidFromInt, bool IsValidToInt,

708 QualType FromIntType, QualType ToIntType,

709 Expr *FromExpr, Expr *ToExpr, bool FromDefault,

710 bool ToDefault) {

711 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

712 FlatTree[CurrentNode].Kind = Integer;

713 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;

714 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;

715 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;

716 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;

717 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;

718 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;

719 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;

720 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;

721 SetDefault(FromDefault, ToDefault);

722 }

723

724 void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,

725 bool FromAddressOf, bool ToAddressOf,

726 bool FromNullPtr, bool ToNullPtr, Expr *FromExpr,

727 Expr *ToExpr, bool FromDefault, bool ToDefault) {

728 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

729 FlatTree[CurrentNode].Kind = Declaration;

730 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;

731 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;

732 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;

733 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;

734 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;

735 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;

736 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;

737 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;

738 SetDefault(FromDefault, ToDefault);

739 }

740

741 void SetFromDeclarationAndToIntegerDiff(

742 ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr,

743 Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt,

744 QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) {

745 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

746 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;

747 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;

748 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;

749 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;

750 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;

751 FlatTree[CurrentNode].ToArgInfo.Val = ToInt;

752 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;

753 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;

754 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;

755 SetDefault(FromDefault, ToDefault);

756 }

757

758 void SetFromIntegerAndToDeclarationDiff(

759 const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType,

760 Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf,

761 bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) {

762 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");

763 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;

764 FlatTree[CurrentNode].FromArgInfo.Val = FromInt;

765 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;

766 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;

767 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;

768 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;

769 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;

770 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;

771 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;

772 SetDefault(FromDefault, ToDefault);

773 }

774

775

776 void SetDefault(bool FromDefault, bool ToDefault) {

777 assert((!FromDefault || !ToDefault) && "Both arguments cannot be default.");

778 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;

779 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;

780 }

781

782

783 void SetSame(bool Same) {

784 FlatTree[CurrentNode].Same = Same;

785 }

786

787

788 void SetKind(DiffKind Kind) {

789 FlatTree[CurrentNode].Kind = Kind;

790 }

791

792

793 void Up() {

794 assert(FlatTree[CurrentNode].Kind != Invalid &&

795 "Cannot exit node before setting node information.");

796 CurrentNode = FlatTree[CurrentNode].ParentNode;

797 }

798

799

800

801 void AddNode() {

802 assert(FlatTree[CurrentNode].Kind == Template &&

803 "Only Template nodes can have children nodes.");

804 FlatTree.push_back(DiffNode(CurrentNode));

805 DiffNode &Node = FlatTree[CurrentNode];

806 if (Node.ChildNode == 0) {

807

808 Node.ChildNode = NextFreeNode;

809 } else {

810

811

812 unsigned i;

813 for (i = Node.ChildNode; FlatTree[i].NextNode != 0;

814 i = FlatTree[i].NextNode) {

815 }

816 FlatTree[i].NextNode = NextFreeNode;

817 }

818 CurrentNode = NextFreeNode;

819 ++NextFreeNode;

820 }

821

822

823

824 void StartTraverse() {

825 ReadNode = 0;

826 CurrentNode = NextFreeNode;

827 NextFreeNode = 0;

828 }

829

830

831 void Parent() {

832 ReadNode = FlatTree[ReadNode].ParentNode;

833 }

834

835 void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,

836 Qualifiers &FromQual, Qualifiers &ToQual) {

837 assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");

838 FromTD = FlatTree[ReadNode].FromArgInfo.TD;

839 ToTD = FlatTree[ReadNode].ToArgInfo.TD;

840 FromQual = FlatTree[ReadNode].FromArgInfo.Qual;

841 ToQual = FlatTree[ReadNode].ToArgInfo.Qual;

842 }

843

844 void GetTypeDiff(QualType &FromType, QualType &ToType) {

845 assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");

846 FromType = FlatTree[ReadNode].FromArgInfo.ArgType;

847 ToType = FlatTree[ReadNode].ToArgInfo.ArgType;

848 }

849

850 void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {

851 assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");

852 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;

853 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;

854 }

855

856 void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {

857 assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");

858 FromTD = FlatTree[ReadNode].FromArgInfo.TD;

859 ToTD = FlatTree[ReadNode].ToArgInfo.TD;

860 }

861

862 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,

863 bool &IsValidFromInt, bool &IsValidToInt,

864 QualType &FromIntType, QualType &ToIntType,

865 Expr *&FromExpr, Expr *&ToExpr) {

866 assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");

867 FromInt = FlatTree[ReadNode].FromArgInfo.Val;

868 ToInt = FlatTree[ReadNode].ToArgInfo.Val;

869 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;

870 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;

871 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;

872 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;

873 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;

874 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;

875 }

876

877 void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,

878 bool &FromAddressOf, bool &ToAddressOf,

879 bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr,

880 Expr *&ToExpr) {

881 assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");

882 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;

883 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;

884 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;

885 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;

886 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;

887 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;

888 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;

889 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;

890 }

891

892 void GetFromDeclarationAndToIntegerDiff(

893 ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr,

894 Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt,

895 QualType &ToIntType, Expr *&ToExpr) {

896 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&

897 "Unexpected kind.");

898 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;

899 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;

900 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;

901 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;

902 ToInt = FlatTree[ReadNode].ToArgInfo.Val;

903 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;

904 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;

905 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;

906 }

907

908 void GetFromIntegerAndToDeclarationDiff(

909 llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType,

910 Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf,

911 bool &ToNullPtr, Expr *&ToExpr) {

912 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&

913 "Unexpected kind.");

914 FromInt = FlatTree[ReadNode].FromArgInfo.Val;

915 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;

916 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;

917 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;

918 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;

919 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;

920 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;

921 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;

922 }

923

924

925 bool FromDefault() {

926 return FlatTree[ReadNode].FromArgInfo.IsDefault;

927 }

928

929

930 bool ToDefault() {

931 return FlatTree[ReadNode].ToArgInfo.IsDefault;

932 }

933

934

935 bool NodeIsSame() {

936 return FlatTree[ReadNode].Same;

937 }

938

939

940 bool HasChildren() {

941 return FlatTree[ReadNode].ChildNode != 0;

942 }

943

944

945 void MoveToChild() {

946 ReadNode = FlatTree[ReadNode].ChildNode;

947 }

948

949

950

951 bool AdvanceSibling() {

952 if (FlatTree[ReadNode].NextNode == 0)

953 return false;

954

955 ReadNode = FlatTree[ReadNode].NextNode;

956 return true;

957 }

958

959

960 bool HasNextSibling() {

961 return FlatTree[ReadNode].NextNode != 0;

962 }

963

964

966 return GetKind() == Invalid;

967 }

968

969

970 DiffKind GetKind() {

971 return FlatTree[ReadNode].Kind;

972 }

973 };

974

975 DiffTree Tree;

976

977

978

979

980

981 class TSTiterator {

982 typedef const TemplateArgument& reference;

983 typedef const TemplateArgument* pointer;

984

985

986

987

988 struct InternalIterator {

989

990

991 const TemplateSpecializationType *TST;

992

993

994 unsigned Index;

995

996

997

999

1000

1002

1003

1004

1005 InternalIterator(const TemplateSpecializationType *TST)

1006 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {

1007 if (!TST) return;

1008

1009 if (isEnd()) return;

1010

1011

1012 TemplateArgument TA = TST->template_arguments()[0];

1014

1015

1018

1019

1020 if (CurrentTA != EndTA) return;

1021

1022

1023

1024 ++(*this);

1025 }

1026

1027

1028 bool isValid() const { return TST; }

1029

1030

1031 bool isEnd() const {

1032 assert(TST && "InternalIterator is invalid with a null TST.");

1033 return Index >= TST->template_arguments().size();

1034 }

1035

1036

1037 InternalIterator &operator++() {

1038 assert(TST && "InternalIterator is invalid with a null TST.");

1039 if (isEnd()) {

1040 return *this;

1041 }

1042

1043

1044 if (CurrentTA != EndTA) {

1045 ++CurrentTA;

1046 if (CurrentTA != EndTA)

1047 return *this;

1048 }

1049

1050

1051 while (true) {

1052

1053 if (++Index == TST->template_arguments().size())

1054 break;

1055

1056

1057 TemplateArgument TA = TST->template_arguments()[Index];

1059 break;

1060

1061

1064

1065

1066 if (CurrentTA != EndTA)

1067 break;

1068 }

1069 return *this;

1070 }

1071

1072

1074 assert(TST && "InternalIterator is invalid with a null TST.");

1075 assert(!isEnd() && "Index exceeds number of arguments.");

1076 if (CurrentTA == EndTA)

1077 return TST->template_arguments()[Index];

1078 else

1079 return *CurrentTA;

1080 }

1081

1082

1083 pointer operator->() const {

1084 assert(TST && "InternalIterator is invalid with a null TST.");

1086 }

1087 };

1088

1089 InternalIterator SugaredIterator;

1090 InternalIterator DesugaredIterator;

1091

1092 public:

1093 TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)

1094 : SugaredIterator(TST),

1095 DesugaredIterator(

1096 (TST->isSugared() && !TST->isTypeAlias())

1097 ? GetTemplateSpecializationType(Context, TST->desugar())

1099

1100

1101 TSTiterator &operator++() {

1102 ++SugaredIterator;

1103 if (DesugaredIterator.isValid())

1104 ++DesugaredIterator;

1105 return *this;

1106 }

1107

1108

1110 return *SugaredIterator;

1111 }

1112

1113

1114 pointer operator->() const {

1116 }

1117

1118

1119 bool isEnd() const {

1120 return SugaredIterator.isEnd();

1121 }

1122

1123

1124

1125 bool hasDesugaredTA() const {

1126 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd();

1127 }

1128

1129

1130 reference getDesugaredTA() const {

1131 assert(DesugaredIterator.isValid() &&

1132 "Desugared TemplateArgument should not be used.");

1133 return *DesugaredIterator;

1134 }

1135 };

1136

1137

1138

1139

1140 static const TemplateSpecializationType *

1141 GetTemplateSpecializationType(ASTContext &Context, QualType Ty) {

1142 if (const TemplateSpecializationType *TST =

1143 Ty->getAs())

1144 return TST;

1145

1146 if (const auto* SubstType = Ty->getAs())

1147 Ty = SubstType->getReplacementType();

1148

1149 const auto *RT = Ty->getAs();

1150 if (!RT)

1151 return nullptr;

1152

1153 const auto *CTSD = dyn_cast(RT->getDecl());

1154 if (!CTSD)

1155 return nullptr;

1156

1157 Ty = Context.getTemplateSpecializationType(

1158 ElaboratedTypeKeyword::None,

1159 TemplateName(CTSD->getSpecializedTemplate()),

1160 CTSD->getTemplateArgs().asArray(), {},

1162

1163 return Ty->getAs();

1164 }

1165

1166

1167 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,

1168 QualType ToType,

1169 const TemplateSpecializationType *&FromArgTST,

1170 const TemplateSpecializationType *&ToArgTST) {

1172 return true;

1173

1174 if (Context.hasSameType(FromType, ToType))

1175 return true;

1176

1177 FromArgTST = GetTemplateSpecializationType(Context, FromType);

1178 ToArgTST = GetTemplateSpecializationType(Context, ToType);

1179

1180 if (!FromArgTST || !ToArgTST)

1181 return true;

1182

1183 if (!hasSameTemplate(Context, FromArgTST, ToArgTST))

1184 return true;

1185

1186 return false;

1187 }

1188

1189

1190 void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) {

1191 QualType FromType = GetType(FromIter);

1192 QualType ToType = GetType(ToIter);

1193

1194 bool FromDefault = FromIter.isEnd() && !FromType.isNull();

1195 bool ToDefault = ToIter.isEnd() && !ToType.isNull();

1196

1197 const TemplateSpecializationType *FromArgTST = nullptr;

1198 const TemplateSpecializationType *ToArgTST = nullptr;

1199 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {

1200 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);

1201 Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&

1202 Context.hasSameType(FromType, ToType));

1203 } else {

1204 assert(FromArgTST && ToArgTST &&

1205 "Both template specializations need to be valid.");

1208 FromQual -= QualType(FromArgTST, 0).getQualifiers();

1209 ToQual -= QualType(ToArgTST, 0).getQualifiers();

1210 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),

1211 ToArgTST->getTemplateName().getAsTemplateDecl(),

1212 FromQual, ToQual, FromDefault, ToDefault);

1213 DiffTemplate(FromArgTST, ToArgTST);

1214 }

1215 }

1216

1217

1218

1219 void DiffTemplateTemplates(const TSTiterator &FromIter,

1220 const TSTiterator &ToIter) {

1221 TemplateDecl *FromDecl = GetTemplateDecl(FromIter);

1222 TemplateDecl *ToDecl = GetTemplateDecl(ToIter);

1223 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,

1224 ToIter.isEnd() && ToDecl);

1225 Tree.SetSame(FromDecl && ToDecl &&

1227 }

1228

1229

1230 static void InitializeNonTypeDiffVariables(ASTContext &Context,

1231 const TSTiterator &Iter,

1232 NonTypeTemplateParmDecl *Default,

1233 llvm::APSInt &Value, bool &HasInt,

1234 QualType &IntType, bool &IsNullPtr,

1235 Expr *&E, ValueDecl *&VD,

1236 bool &NeedAddressOf) {

1237 if (!Iter.isEnd()) {

1238 switch (Iter->getKind()) {

1240

1241

1242

1243 return;

1245 Value = Iter->getAsIntegral();

1246 HasInt = true;

1247 IntType = Iter->getIntegralType();

1248 return;

1250 VD = Iter->getAsDecl();

1251 QualType ArgType = Iter->getParamTypeForDecl();

1252 QualType VDType = VD->getType();

1254 Context.hasSameType(ArgType->getPointeeType(), VDType))

1255 NeedAddressOf = true;

1256 return;

1257 }

1259 IsNullPtr = true;

1260 return;

1262 E = Iter->getAsExpr();

1263 break;

1268 llvm_unreachable("TemplateArgument kind is not expected for NTTP");

1270 llvm_unreachable("TemplateArgument kind should be handled elsewhere");

1271 }

1272 } else if (Default->isParameterPack()) {

1273 E = Default->getDefaultArgument().getArgument().getAsExpr();

1274 }

1275

1276 if (!Iter.hasDesugaredTA())

1277 return;

1278

1279 const TemplateArgument &TA = Iter.getDesugaredTA();

1282

1283

1284 return;

1287 HasInt = true;

1289 return;

1293 QualType VDType = VD->getType();

1295 Context.hasSameType(ArgType->getPointeeType(), VDType))

1296 NeedAddressOf = true;

1297 return;

1298 }

1300 IsNullPtr = true;

1301 return;

1303

1304

1305

1306 if (!E)

1308 return;

1313 llvm_unreachable("TemplateArgument kind is not expected for NTTP");

1315 llvm_unreachable("TemplateArgument kind should be handled elsewhere");

1316 }

1317 llvm_unreachable("Unexpected TemplateArgument kind");

1318 }

1319

1320

1321

1322 void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,

1323 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl,

1324 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {

1325 Expr *FromExpr = nullptr, *ToExpr = nullptr;

1326 llvm::APSInt FromInt, ToInt;

1327 QualType FromIntType, ToIntType;

1328 ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;

1329 bool HasFromInt = false, HasToInt = false, FromNullPtr = false,

1330 ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false;

1331 InitializeNonTypeDiffVariables(

1332 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,

1333 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);

1334 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,

1335 HasToInt, ToIntType, ToNullPtr, ToExpr,

1336 ToValueDecl, NeedToAddressOf);

1337

1338 bool FromDefault = FromIter.isEnd() &&

1339 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);

1340 bool ToDefault = ToIter.isEnd() &&

1341 (ToExpr || ToValueDecl || HasToInt || ToNullPtr);

1342

1343 bool FromDeclaration = FromValueDecl || FromNullPtr;

1344 bool ToDeclaration = ToValueDecl || ToNullPtr;

1345

1346 if (FromDeclaration && HasToInt) {

1347 Tree.SetFromDeclarationAndToIntegerDiff(

1348 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,

1349 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);

1350 Tree.SetSame(false);

1351 return;

1352

1353 }

1354

1355 if (HasFromInt && ToDeclaration) {

1356 Tree.SetFromIntegerAndToDeclarationDiff(

1357 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,

1358 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);

1359 Tree.SetSame(false);

1360 return;

1361 }

1362

1363 if (HasFromInt || HasToInt) {

1364 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,

1365 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);

1366 if (HasFromInt && HasToInt) {

1367 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&

1368 FromInt == ToInt);

1369 }

1370 return;

1371 }

1372

1373 if (FromDeclaration || ToDeclaration) {

1374 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,

1375 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,

1376 ToExpr, FromDefault, ToDefault);

1377 bool BothNull = FromNullPtr && ToNullPtr;

1378 bool SameValueDecl =

1379 FromValueDecl && ToValueDecl &&

1380 NeedFromAddressOf == NeedToAddressOf &&

1382 Tree.SetSame(BothNull || SameValueDecl);

1383 return;

1384 }

1385

1386 assert((FromExpr || ToExpr) && "Both template arguments cannot be empty.");

1387 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);

1388 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));

1389 }

1390

1391

1392

1393 void DiffTemplate(const TemplateSpecializationType *FromTST,

1394 const TemplateSpecializationType *ToTST) {

1395

1396

1397

1398 TemplateParameterList *ParamsFrom =

1399 FromTST->getTemplateName()

1400 .getAsTemplateDecl(true)

1401 ->getTemplateParameters();

1402 TemplateParameterList *ParamsTo =

1403 ToTST->getTemplateName()

1404 .getAsTemplateDecl(true)

1405 ->getTemplateParameters();

1406 unsigned TotalArgs = 0;

1407 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST);

1408 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) {

1409 Tree.AddNode();

1410

1411

1412

1413

1414 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1);

1415 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1);

1416 NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex);

1417 NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex);

1418

1419 assert(FromParamND->getKind() == ToParamND->getKind() &&

1420 "Parameter Decl are not the same kind.");

1421

1423 DiffTypes(FromIter, ToIter);

1425 DiffTemplateTemplates(FromIter, ToIter);

1427 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =

1429 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =

1431 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,

1432 ToDefaultNonTypeDecl);

1433 } else {

1434 llvm_unreachable("Unexpected Decl type.");

1435 }

1436

1437 ++FromIter;

1438 ++ToIter;

1439 Tree.Up();

1440 }

1441 }

1442

1443

1444 static void makeTemplateList(

1445 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList,

1446 const TemplateSpecializationType *TST) {

1447 while (TST) {

1448 TemplateList.push_back(TST);

1449 if (!TST->isTypeAlias())

1450 return;

1451 TST = TST->getAliasedType()->getAs();

1452 }

1453 }

1454

1455

1456

1457 static bool hasSameBaseTemplate(ASTContext &Context,

1458 const TemplateSpecializationType *FromTST,

1459 const TemplateSpecializationType *ToTST) {

1460 return Context.getCanonicalTemplateName(FromTST->getTemplateName(),

1461 true) ==

1462 Context.getCanonicalTemplateName(ToTST->getTemplateName(),

1463 true);

1464 }

1465

1466

1467

1468

1469

1470 static bool hasSameTemplate(ASTContext &Context,

1471 const TemplateSpecializationType *&FromTST,

1472 const TemplateSpecializationType *&ToTST) {

1473

1474 if (hasSameBaseTemplate(Context, FromTST, ToTST))

1475 return true;

1476

1477

1478 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList,

1479 ToTemplateList;

1480

1481 makeTemplateList(FromTemplateList, FromTST);

1482 makeTemplateList(ToTemplateList, ToTST);

1483

1484 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator

1485 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(),

1486 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend();

1487

1488

1489 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))

1490 return false;

1491

1492

1493

1494

1495 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) {

1496 if (!hasSameBaseTemplate(Context, *FromIter, *ToIter))

1497 break;

1498 }

1499

1500 FromTST = FromIter[-1];

1501 ToTST = ToIter[-1];

1502

1503 return true;

1504 }

1505

1506

1507

1508 static QualType GetType(const TSTiterator &Iter) {

1509 if (!Iter.isEnd())

1510 return Iter->getAsType();

1511 if (Iter.hasDesugaredTA())

1512 return Iter.getDesugaredTA().getAsType();

1513 return QualType();

1514 }

1515

1516

1517

1518 static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) {

1519 if (!Iter.isEnd())

1520 return Iter->getAsTemplate().getAsTemplateDecl();

1521 if (Iter.hasDesugaredTA())

1522 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();

1523 return nullptr;

1524 }

1525

1526

1527

1528

1529 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {

1530 if (FromExpr == ToExpr)

1531 return true;

1532

1533 if (!FromExpr || !ToExpr)

1534 return false;

1535

1536 llvm::FoldingSetNodeID FromID, ToID;

1537 FromExpr->Profile(FromID, Context, true);

1538 ToExpr->Profile(ToID, Context, true);

1539 return FromID == ToID;

1540 }

1541

1542

1543

1544

1545

1546

1547 void TreeToString(int Indent = 1) {

1548 if (PrintTree) {

1549 OS << '\n';

1550 OS.indent(2 * Indent);

1552 }

1553

1554

1555

1556 switch (Tree.GetKind()) {

1557 case DiffTree::Invalid:

1558 llvm_unreachable("Template diffing failed with bad DiffNode");

1559 case DiffTree::Type: {

1560 QualType FromType, ToType;

1561 Tree.GetTypeDiff(FromType, ToType);

1562 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),

1563 Tree.NodeIsSame());

1564 return;

1565 }

1566 case DiffTree::Expression: {

1567 Expr *FromExpr, *ToExpr;

1568 Tree.GetExpressionDiff(FromExpr, ToExpr);

1569 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),

1570 Tree.NodeIsSame());

1571 return;

1572 }

1573 case DiffTree::TemplateTemplate: {

1574 TemplateDecl *FromTD, *ToTD;

1575 Tree.GetTemplateTemplateDiff(FromTD, ToTD);

1576 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),

1577 Tree.ToDefault(), Tree.NodeIsSame());

1578 return;

1579 }

1580 case DiffTree::Integer: {

1581 llvm::APSInt FromInt, ToInt;

1582 Expr *FromExpr, *ToExpr;

1583 bool IsValidFromInt, IsValidToInt;

1584 QualType FromIntType, ToIntType;

1585 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,

1586 FromIntType, ToIntType, FromExpr, ToExpr);

1587 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,

1588 ToIntType, FromExpr, ToExpr, Tree.FromDefault(),

1589 Tree.ToDefault(), Tree.NodeIsSame());

1590 return;

1591 }

1592 case DiffTree::Declaration: {

1593 ValueDecl *FromValueDecl, *ToValueDecl;

1594 bool FromAddressOf, ToAddressOf;

1595 bool FromNullPtr, ToNullPtr;

1596 Expr *FromExpr, *ToExpr;

1597 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,

1598 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,

1599 ToExpr);

1600 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,

1601 FromNullPtr, ToNullPtr, FromExpr, ToExpr,

1602 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());

1603 return;

1604 }

1605 case DiffTree::FromDeclarationAndToInteger: {

1606 ValueDecl *FromValueDecl;

1607 bool FromAddressOf;

1608 bool FromNullPtr;

1609 Expr *FromExpr;

1610 llvm::APSInt ToInt;

1611 bool IsValidToInt;

1612 QualType ToIntType;

1613 Expr *ToExpr;

1614 Tree.GetFromDeclarationAndToIntegerDiff(

1615 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,

1616 IsValidToInt, ToIntType, ToExpr);

1617 assert((FromValueDecl || FromNullPtr) && IsValidToInt);

1618 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,

1619 FromExpr, Tree.FromDefault(), ToInt, ToIntType,

1620 ToExpr, Tree.ToDefault());

1621 return;

1622 }

1623 case DiffTree::FromIntegerAndToDeclaration: {

1624 llvm::APSInt FromInt;

1625 bool IsValidFromInt;

1626 QualType FromIntType;

1627 Expr *FromExpr;

1628 ValueDecl *ToValueDecl;

1629 bool ToAddressOf;

1630 bool ToNullPtr;

1631 Expr *ToExpr;

1632 Tree.GetFromIntegerAndToDeclarationDiff(

1633 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,

1634 ToAddressOf, ToNullPtr, ToExpr);

1635 assert(IsValidFromInt && (ToValueDecl || ToNullPtr));

1636 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,

1637 Tree.FromDefault(), ToValueDecl, ToAddressOf,

1638 ToNullPtr, ToExpr, Tree.ToDefault());

1639 return;

1640 }

1641 case DiffTree::Template: {

1642

1643 TemplateDecl *FromTD, *ToTD;

1644 Qualifiers FromQual, ToQual;

1645 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);

1646

1647 PrintQualifiers(FromQual, ToQual);

1648

1649 if (!Tree.HasChildren()) {

1650

1651

1653 return;

1654 }

1655

1657 Tree.MoveToChild();

1658 unsigned NumElideArgs = 0;

1659 bool AllArgsElided = true;

1660 do {

1661 if (ElideType) {

1662 if (Tree.NodeIsSame()) {

1663 ++NumElideArgs;

1664 continue;

1665 }

1666 AllArgsElided = false;

1667 if (NumElideArgs > 0) {

1668 PrintElideArgs(NumElideArgs, Indent);

1669 NumElideArgs = 0;

1670 OS << ", ";

1671 }

1672 }

1673 TreeToString(Indent);

1674 if (Tree.HasNextSibling())

1675 OS << ", ";

1676 } while (Tree.AdvanceSibling());

1677 if (NumElideArgs > 0) {

1678 if (AllArgsElided)

1679 OS << "...";

1680 else

1681 PrintElideArgs(NumElideArgs, Indent);

1682 }

1683

1684 Tree.Parent();

1685 OS << ">";

1686 return;

1687 }

1688 }

1689 }

1690

1691

1692

1693

1694

1695

1696 void Bold() {

1697 assert(!IsBold && "Attempting to bold text that is already bold.");

1698 IsBold = true;

1699 if (ShowColor)

1701 }

1702

1703

1704 void Unbold() {

1705 assert(IsBold && "Attempting to remove bold from unbold text.");

1706 IsBold = false;

1707 if (ShowColor)

1709 }

1710

1711

1712

1713

1714

1715

1716 void PrintTypeNames(QualType FromType, QualType ToType,

1717 bool FromDefault, bool ToDefault, bool Same) {

1718 assert((!FromType.isNull() || !ToType.isNull()) &&

1719 "Only one template argument may be missing.");

1720

1721 if (Same) {

1723 return;

1724 }

1725

1726 if (!FromType.isNull() && !ToType.isNull() &&

1731 PrintQualifiers(FromQual, ToQual);

1733 return;

1734 }

1735

1736 std::string FromTypeStr = FromType.isNull() ? "(no argument)"

1738 std::string ToTypeStr =

1740

1741 if (FromTypeStr == ToTypeStr) {

1742

1743 std::string FromCanTypeStr =

1746 if (FromCanTypeStr != ToCanTypeStr) {

1747 FromTypeStr = FromCanTypeStr;

1748 ToTypeStr = ToCanTypeStr;

1749 }

1750 }

1751

1752 if (PrintTree)

1753 OS << '[';

1754 OS << (FromDefault ? "(default) " : "");

1756 OS << FromTypeStr;

1757 Unbold();

1758 if (PrintTree) {

1759 OS << " != " << (ToDefault ? "(default) " : "");

1761 OS << ToTypeStr;

1762 Unbold();

1763 OS << "]";

1764 }

1765 }

1766

1767

1768

1769 void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault,

1770 bool ToDefault, bool Same) {

1771 assert((FromExpr || ToExpr) &&

1772 "Only one template argument may be missing.");

1773 if (Same) {

1774 PrintExpr(FromExpr);

1775 } else if (!PrintTree) {

1776 OS << (FromDefault ? "(default) " : "");

1778 PrintExpr(FromExpr);

1779 Unbold();

1780 } else {

1781 OS << (FromDefault ? "[(default) " : "[");

1783 PrintExpr(FromExpr);

1784 Unbold();

1785 OS << " != " << (ToDefault ? "(default) " : "");

1787 PrintExpr(ToExpr);

1788 Unbold();

1789 OS << ']';

1790 }

1791 }

1792

1793

1794 void PrintExpr(const Expr *E) {

1795 if (E) {

1797 return;

1798 }

1799 OS << "(no argument)";

1800 }

1801

1802

1803

1804 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD,

1805 bool FromDefault, bool ToDefault, bool Same) {

1806 assert((FromTD || ToTD) && "Only one template argument may be missing.");

1807

1808 std::string FromName =

1809 std::string(FromTD ? FromTD->getName() : "(no argument)");

1810 std::string ToName = std::string(ToTD ? ToTD->getName() : "(no argument)");

1811 if (FromTD && ToTD && FromName == ToName) {

1814 }

1815

1816 if (Same) {

1817 OS << "template " << FromTD->getDeclName();

1818 } else if (!PrintTree) {

1819 OS << (FromDefault ? "(default) template " : "template ");

1821 OS << FromName;

1822 Unbold();

1823 } else {

1824 OS << (FromDefault ? "[(default) template " : "[template ");

1826 OS << FromName;

1827 Unbold();

1828 OS << " != " << (ToDefault ? "(default) template " : "template ");

1830 OS << ToName;

1831 Unbold();

1832 OS << ']';

1833 }

1834 }

1835

1836

1837

1838 void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt,

1839 bool IsValidFromInt, bool IsValidToInt, QualType FromIntType,

1840 QualType ToIntType, Expr *FromExpr, Expr *ToExpr,

1841 bool FromDefault, bool ToDefault, bool Same) {

1842 assert((IsValidFromInt || IsValidToInt) &&

1843 "Only one integral argument may be missing.");

1844

1845 if (Same) {

1847 OS << ((FromInt == 0) ? "false" : "true");

1848 } else {

1849 OS << toString(FromInt, 10);

1850 }

1851 return;

1852 }

1853

1854 bool PrintType = IsValidFromInt && IsValidToInt &&

1855 !Context.hasSameType(FromIntType, ToIntType);

1856

1857 if (!PrintTree) {

1858 OS << (FromDefault ? "(default) " : "");

1859 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);

1860 } else {

1861 OS << (FromDefault ? "[(default) " : "[");

1862 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);

1863 OS << " != " << (ToDefault ? "(default) " : "");

1864 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);

1865 OS << ']';

1866 }

1867 }

1868

1869

1870

1871 void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid,

1872 QualType IntType, bool PrintType) {

1875 if (HasExtraInfo(E)) {

1876 PrintExpr(E);

1877 Unbold();

1878 OS << " aka ";

1880 }

1881 if (PrintType) {

1882 Unbold();

1883 OS << "(";

1885 IntType.print(OS, Context.getPrintingPolicy());

1886 Unbold();

1887 OS << ") ";

1889 }

1891 OS << ((Val == 0) ? "false" : "true");

1892 } else {

1894 }

1895 } else if (E) {

1896 PrintExpr(E);

1897 } else {

1898 OS << "(no argument)";

1899 }

1900 Unbold();

1901 }

1902

1903

1904

1905 bool HasExtraInfo(Expr *E) {

1906 if (!E) return false;

1907

1909

1910 auto CheckIntegerLiteral = [](Expr *E) {

1911 if (auto *TemplateExpr = dyn_cast(E))

1912 E = TemplateExpr->getReplacement();

1914 };

1915

1916 if (CheckIntegerLiteral(E)) return false;

1917

1918 if (UnaryOperator *UO = dyn_cast(E))

1919 if (UO->getOpcode() == UO_Minus)

1920 if (CheckIntegerLiteral(UO->getSubExpr()))

1921 return false;

1922

1924 return false;

1925

1926 return true;

1927 }

1928

1929 void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) {

1930 if (VD) {

1931 if (AddressOf)

1932 OS << "&";

1933 else if (auto *TPO = dyn_cast(VD)) {

1934

1935

1936

1937 TPO->getType().getUnqualifiedType().print(OS, Policy);

1938 TPO->printAsInit(OS, Policy);

1939 return;

1940 }

1942 return;

1943 }

1944

1945 if (NullPtr) {

1947 PrintExpr(E);

1948 if (IsBold) {

1949 Unbold();

1950 OS << " aka ";

1952 } else {

1953 OS << " aka ";

1954 }

1955 }

1956

1957 OS << "nullptr";

1958 return;

1959 }

1960

1961 if (E) {

1962 PrintExpr(E);

1963 return;

1964 }

1965

1966 OS << "(no argument)";

1967 }

1968

1969

1970

1971 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,

1972 bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,

1973 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,

1974 bool FromDefault, bool ToDefault, bool Same) {

1975 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&

1976 "Only one Decl argument may be NULL");

1977

1978 if (Same) {

1979 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);

1980 } else if (!PrintTree) {

1981 OS << (FromDefault ? "(default) " : "");

1983 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);

1984 Unbold();

1985 } else {

1986 OS << (FromDefault ? "[(default) " : "[");

1988 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);

1989 Unbold();

1990 OS << " != " << (ToDefault ? "(default) " : "");

1992 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);

1993 Unbold();

1994 OS << ']';

1995 }

1996 }

1997

1998

1999

2000 void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf,

2001 bool IsNullPtr, Expr *VDExpr, bool DefaultDecl,

2002 const llvm::APSInt &Val, QualType IntType,

2003 Expr *IntExpr, bool DefaultInt) {

2004 if (!PrintTree) {

2005 OS << (DefaultDecl ? "(default) " : "");

2007 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);

2008 Unbold();

2009 } else {

2010 OS << (DefaultDecl ? "[(default) " : "[");

2012 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);

2013 Unbold();

2014 OS << " != " << (DefaultInt ? "(default) " : "");

2015 PrintAPSInt(Val, IntExpr, true , IntType, false );

2016 OS << ']';

2017 }

2018 }

2019

2020

2021

2022 void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType,

2023 Expr *IntExpr, bool DefaultInt, ValueDecl *VD,

2024 bool NeedAddressOf, bool IsNullPtr,

2025 Expr *VDExpr, bool DefaultDecl) {

2026 if (!PrintTree) {

2027 OS << (DefaultInt ? "(default) " : "");

2028 PrintAPSInt(Val, IntExpr, true , IntType, false );

2029 } else {

2030 OS << (DefaultInt ? "[(default) " : "[");

2031 PrintAPSInt(Val, IntExpr, true , IntType, false );

2032 OS << " != " << (DefaultDecl ? "(default) " : "");

2034 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);

2035 Unbold();

2036 OS << ']';

2037 }

2038 }

2039

2040

2041 void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) {

2042 if (PrintTree) {

2043 OS << '\n';

2044 for (unsigned i = 0; i < Indent; ++i)

2045 OS << " ";

2046 }

2047 if (NumElideArgs == 0) return;

2048 if (NumElideArgs == 1)

2049 OS << "[...]";

2050 else

2051 OS << "[" << NumElideArgs << " * ...]";

2052 }

2053

2054

2055 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) {

2056

2057 if (FromQual.empty() && ToQual.empty())

2058 return;

2059

2060

2061 if (FromQual == ToQual) {

2062 PrintQualifier(FromQual, false);

2063 return;

2064 }

2065

2066

2068 ToQual);

2069

2070

2071

2072

2073

2074

2075

2076

2077

2078

2079

2080 if (PrintTree) {

2081 OS << "[";

2082 if (CommonQual.empty() && FromQual.empty()) {

2084 OS << "(no qualifiers) ";

2085 Unbold();

2086 } else {

2087 PrintQualifier(CommonQual, false);

2088 PrintQualifier(FromQual, true);

2089 }

2090 OS << "!= ";

2091 if (CommonQual.empty() && ToQual.empty()) {

2093 OS << "(no qualifiers)";

2094 Unbold();

2095 } else {

2096 PrintQualifier(CommonQual, false,

2097 !ToQual.empty());

2098 PrintQualifier(ToQual, true,

2099 false);

2100 }

2101 OS << "] ";

2102 } else {

2103 PrintQualifier(CommonQual, false);

2104 PrintQualifier(FromQual, true);

2105 }

2106 }

2107

2108 void PrintQualifier(Qualifiers Q, bool ApplyBold,

2109 bool AppendSpaceIfNonEmpty = true) {

2110 if (Q.empty()) return;

2111 if (ApplyBold) Bold();

2112 Q.print(OS, Policy, AppendSpaceIfNonEmpty);

2113 if (ApplyBold) Unbold();

2114 }

2115

2116public:

2117

2118 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType,

2119 QualType ToType, bool PrintTree, bool PrintFromType,

2120 bool ElideType, bool ShowColor)

2121 : Context(Context),

2122 Policy(Context.getLangOpts()),

2123 ElideType(ElideType),

2124 PrintTree(PrintTree),

2125 ShowColor(ShowColor),

2126

2127 FromTemplateType(PrintFromType ? FromType : ToType),

2128 ToTemplateType(PrintFromType ? ToType : FromType),

2129 OS(OS),

2131 }

2132

2133

2134 void DiffTemplate() {

2135 Qualifiers FromQual = FromTemplateType.getQualifiers(),

2136 ToQual = ToTemplateType.getQualifiers();

2137

2138 const TemplateSpecializationType *FromOrigTST =

2139 GetTemplateSpecializationType(Context, FromTemplateType);

2140 const TemplateSpecializationType *ToOrigTST =

2141 GetTemplateSpecializationType(Context, ToTemplateType);

2142

2143

2144 if (!FromOrigTST || !ToOrigTST)

2145 return;

2146

2147

2148 if (!hasSameTemplate(Context, FromOrigTST, ToOrigTST)) {

2149 return;

2150 }

2151

2152 FromQual -= QualType(FromOrigTST, 0).getQualifiers();

2153 ToQual -= QualType(ToOrigTST, 0).getQualifiers();

2154

2155

2156 Tree.SetTemplateDiff(

2157 FromOrigTST->getTemplateName().getAsTemplateDecl(

2158 true),

2159 ToOrigTST->getTemplateName().getAsTemplateDecl(true),

2160 FromQual, ToQual, false , false );

2161

2162 DiffTemplate(FromOrigTST, ToOrigTST);

2163 }

2164

2165

2166

2167

2168 bool Emit() {

2169 Tree.StartTraverse();

2170 if (Tree.Empty())

2171 return false;

2172

2173 TreeToString();

2174 assert(!IsBold && "Bold is applied to end of string.");

2175 return true;

2176 }

2177};

2178}

2179

2180

2181

2182

2184 QualType ToType, bool PrintTree,

2185 bool PrintFromType, bool ElideType,

2186 bool ShowColors, raw_ostream &OS) {

2187 if (PrintTree)

2188 PrintFromType = true;

2189 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType,

2190 ElideType, ShowColors);

2191 TD.DiffTemplate();

2192 return TD.Emit();

2193}

2194

2196 auto IsSingleCodeUnitCP = [](unsigned Value, QualType T) {

2197 if (T->isChar8Type()) {

2198 assert(Value <= 0xFF && "not a valid UTF-8 code unit");

2199 return Value <= 0x7F;

2200 }

2201 if (T->isChar16Type()) {

2202 assert(Value <= 0xFFFF && "not a valid UTF-16 code unit");

2203 return llvm::IsSingleCodeUnitUTF16Codepoint(Value);

2204 }

2205 assert(T->isChar32Type());

2206 return llvm::IsSingleCodeUnitUTF32Codepoint(Value);

2207 };

2209 if (!IsSingleCodeUnitCP(Value, T)) {

2210 llvm::raw_svector_ostream OS(Str);

2211 OS << "<" << llvm::format_hex(Value, 1, true) << ">";

2212 return std::string(Str.begin(), Str.end());

2213 }

2214

2215 char Buffer[UNI_MAX_UTF8_BYTES_PER_CODE_POINT];

2216 char *Ptr = Buffer;

2217 [[maybe_unused]] bool Converted = llvm::ConvertCodePointToUTF8(Value, Ptr);

2218 assert(Converted && "trying to encode invalid code unit");

2220 return std::string(Str.begin(), Str.end());

2221}

Defines the clang::ASTContext interface.

static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, QualType ToType, bool PrintTree, bool PrintFromType, bool ElideType, bool ShowColors, raw_ostream &OS)

FormatTemplateTypeDiff - A helper static function to start the template diff and return the properly ...

Definition ASTDiagnostic.cpp:2183

static std::string ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, ArrayRef< DiagnosticsEngine::ArgumentValue > PrevArgs, ArrayRef< intptr_t > QualTypeVals)

Convert the given type to a string suitable for printing as part of a diagnostic.

Definition ASTDiagnostic.cpp:260

This file provides some common utility functions for processing Lambda related AST Constructs.

clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

C Language Family Type Representation.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.

Attr - This represents one attribute.

const char * getSpelling() const

std::string getNormalizedFullName() const

Gets the normalized full name, which consists of both scope and name and with surrounding underscores...

const IdentifierInfo * getScopeName() const

const IdentifierInfo * getAttrName() const

bool isStandardAttributeSyntax() const

The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...

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

bool isTranslationUnit() const

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

static DeclarationName getFromOpaqueInteger(uintptr_t P)

Get a declaration name from an opaque integer returned by getAsOpaqueInteger.

@ ak_nameddecl

NamedDecl *.

@ ak_declcontext

DeclContext *.

@ ak_addrspace

address space

@ ak_qualtype_pair

pair<QualType, QualType>

@ ak_attr_info

AttributeCommonInfo *.

@ ak_declarationname

DeclarationName.

@ ak_nestednamespec

NestedNameSpecifier *.

This represents one expression.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

Represents a prototype with parameter type info, e.g.

ExtProtoInfo getExtProtoInfo() const

ArrayRef< QualType > param_types() const

FunctionType - C99 6.7.5.3 - Function Declarators.

StringRef getName() const

Return the actual identifier string.

An lvalue reference type, per C++11 [dcl.ref].

Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.

This represents a decl that may have a name.

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.

std::string getQualifiedNameAsString() const

virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const

Appends a human-readable name for this declaration into the given stream.

virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const

Pretty-print the unqualified name of this declaration.

void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const

Print this nested name specifier to the given output stream.

static NestedNameSpecifier getFromVoidPointer(const void *Ptr)

Represents a pointer to an Objective C object.

Sugar for parentheses used when specifying types.

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

QualType getLocalUnqualifiedType() const

Return this type with all of the instance-specific qualifiers removed, but without removing any quali...

bool isNull() const

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

static QualType getFromOpaquePtr(const void *Ptr)

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

QualType getCanonicalType() const

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

Qualifiers getLocalQualifiers() const

Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...

A qualifier set is used to build a set of qualifiers.

const Type * strip(QualType type)

Collect any qualifiers on the given type and return an unqualified type.

QualType apply(const ASTContext &Context, QualType QT) const

Apply the collected qualifiers to the given type.

The collection of all-type qualifiers we support.

static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R)

Returns the common set of qualifiers while removing them from the given sets.

void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const

std::string getAsString() const

static Qualifiers fromOpaqueValue(uint64_t opaque)

static std::string getAddrSpaceAsString(LangAS AS)

An rvalue reference type, per C++11 [dcl.ref].

void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const

Produce a unique representation of the given statement.

Represents a template argument.

QualType getParamTypeForDecl() const

Expr * getAsExpr() const

Retrieve the template argument as an expression.

pack_iterator pack_end() const

Iterator referencing one past the last argument of a template argument pack.

const TemplateArgument * pack_iterator

Iterator that traverses the elements of a template argument pack.

pack_iterator pack_begin() const

Iterator referencing the first argument of a template argument pack.

llvm::APSInt getAsIntegral() const

Retrieve the template argument as an integral value.

QualType getIntegralType() const

Retrieve the type of the integral value.

ValueDecl * getAsDecl() const

Retrieve the declaration for a declaration non-type template argument.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

The template argument is a template name that was provided for a template template parameter.

@ StructuralValue

The template argument is a non-type template argument that can't be represented by the special-case D...

@ Pack

The template argument is actually a parameter pack.

@ TemplateExpansion

The template argument is a pack expansion of a template name that was provided for a template templat...

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

@ Null

Represents an empty template argument, e.g., one that has not been deduced.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

NamedDecl * getParam(unsigned Idx)

Represents a declaration of a type.

The base class of the type hierarchy.

bool isBooleanType() const

bool isPointerType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

TypeClass getTypeClass() const

const T * getAs() const

Member-template getAs'.

Represents a GCC generic vector type.

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

bool isa(CodeGen::Address addr)

QualType desugarForDiagnostic(ASTContext &Context, QualType QT, bool &ShouldAKA)

Returns a desugared version of the QualType, and marks ShouldAKA as true whenever we remove significa...

Definition ASTDiagnostic.cpp:32

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

@ TemplateName

The identifier is a template name. FIXME: Add an annotation for that.

std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)

Definition ASTDiagnostic.cpp:2195

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)

bool isLambdaCallOperator(const CXXMethodDecl *MD)

const FunctionProtoType * T

@ Template

We are parsing a template declaration.

void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl< char > &OutStr)

EscapeStringForDiagnostic - Append Str to the diagnostic buffer, escaping non-printable characters an...

LangAS

Defines the address space values used by the address space qualifier of QualType.

const char ToggleHighlight

Special character that the diagnostic printer will use to toggle the bold attribute.

void FormatASTNodeDiagnosticArgument(DiagnosticsEngine::ArgumentKind Kind, intptr_t Val, StringRef Modifier, StringRef Argument, ArrayRef< DiagnosticsEngine::ArgumentValue > PrevArgs, SmallVectorImpl< char > &Output, void *Cookie, ArrayRef< intptr_t > QualTypeVals)

DiagnosticsEngine argument formatting function for diagnostics that involve AST nodes.

Definition ASTDiagnostic.cpp:352

U cast(CodeGen::Address addr)

__INTPTR_TYPE__ intptr_t

A signed integer type with the property that any valid pointer to void can be converted to this type,...

Describes how types, statements, expressions, and declarations should be printed.

unsigned TemplateDiffUsed