clang: lib/Analysis/PathDiagnostic.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

32#include "llvm/ADT/ArrayRef.h"

33#include "llvm/ADT/FoldingSet.h"

34#include "llvm/ADT/STLExtras.h"

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

36#include "llvm/ADT/StringRef.h"

37#include "llvm/Support/ErrorHandling.h"

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

39#include

40#include

41#include

42#include

43#include

44#include

45

46using namespace clang;

47using namespace ento;

48

50

54

56 : kind(k), Hint(hint) {}

57

59

61

63

65

67

69

71

73 bool ShouldFlattenMacros) const {

74 for (auto &Piece : *this) {

75 switch (Piece->getKind()) {

79 Current.push_back(std::move(CallEnter));

80 Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);

81 if (auto callExit = Call.getCallExitEvent())

82 Current.push_back(std::move(callExit));

83 break;

84 }

87 if (ShouldFlattenMacros) {

88 Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);

89 } else {

90 Current.push_back(Piece);

92 Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);

93

94 Macro.subPieces = NewPath;

95 }

96 break;

97 }

102 Current.push_back(Piece);

103 break;

104 }

105 }

106}

107

109

111 StringRef CheckerName, const Decl *declWithIssue, StringRef bugtype,

112 StringRef verboseDesc, StringRef shortDesc, StringRef category,

114 const Decl *AnalysisEntryPoint,

115 std::unique_ptr ExecutedLines)

116 : CheckerName(CheckerName), DeclWithIssue(declWithIssue),

120 Category(StripTrailingDots(category)), UniqueingLoc(LocationToUnique),

121 UniqueingDecl(DeclToUnique), AnalysisEntryPoint(AnalysisEntryPoint),

122 ExecutedLines(std::move(ExecutedLines)), path(pathImpl) {

123 assert(AnalysisEntryPoint);

124}

125

126void PathDiagnosticConsumer::anchor() {}

127

129

131 delete &Diag;

132}

133

135 std::unique_ptr D) {

136 if (!D || D->path.empty())

137 return;

138

139

140

141

142 D->flattenLocations();

143

144

145

147

149 const SourceManager &SMgr = D->path.front()->getLocation().getManager();

151 WorkList.push_back(&D->path);

153 llvm::raw_svector_ostream warning(buf);

154 warning << "warning: Path diagnostic report is not generated. Current "

155 << "output format does not support diagnostics that cross file "

156 << "boundaries. Refer to --analyzer-output for valid output "

157 << "formats\n";

158

161

162 for (const auto &I : path) {

165

168 } else if (SMgr.getFileID(L) != FID) {

169 llvm::errs() << warning.str();

170 return;

171 }

172

173

175 for (const auto &I : Ranges) {

178 llvm::errs() << warning.str();

179 return;

180 }

183 llvm::errs() << warning.str();

184 return;

185 }

186 }

187

188 if (const auto *call = dyn_cast(piece))

189 WorkList.push_back(&call->path);

190 else if (const auto *macro = dyn_cast(piece))

191 WorkList.push_back(&macro->subPieces);

192 }

193 }

194

196 return;

197 }

198

199

200 llvm::FoldingSetNodeID profile;

201 D->Profile(profile);

202 void *InsertPos = nullptr;

203

204 if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {

205

206

207

208

209 const unsigned orig_size = orig->full_size();

210 const unsigned new_size = D->full_size();

211 if (orig_size <= new_size)

212 return;

213

214 assert(orig != D.get());

215 Diags.RemoveNode(orig);

216 delete orig;

217 }

218

219 Diags.InsertNode(D.release());

220}

221

224

225static std::optional

228 FullSourceLoc XSL = X.getStartLocation().asLocation();

230 if (XSL != YSL)

234 if (XEL != YEL)

236 return std::nullopt;

237}

238

243

248 if (X_CEL != Y_CEL)

250 FullSourceLoc X_CEWL = X.callEnterWithin.asLocation();

252 if (X_CEWL != Y_CEWL)

256 if (X_CRL != Y_CRL)

259}

260

263 if (X.getKind() != Y.getKind())

264 return X.getKind() < Y.getKind();

265

268 if (XL != YL)

270

272 return X.getString() < Y.getString();

273

274 if (X.getRanges().size() != Y.getRanges().size())

275 return X.getRanges().size() < Y.getRanges().size();

276

278

279 for (unsigned i = 0, n = X.getRanges().size(); i < n; ++i) {

282 if (XR != YR) {

285 return SM.isBeforeInTranslationUnit(XR.getEnd(), YR.getEnd());

286 }

287 }

288

289 switch (X.getKind()) {

302 return std::nullopt;

303 }

304 llvm_unreachable("all cases handled");

305}

306

309 if (X.size() != Y.size())

310 return X.size() < Y.size();

311

312 PathPieces::const_iterator X_I = X.begin(), X_end = X.end();

313 PathPieces::const_iterator Y_I = Y.begin(), Y_end = Y.end();

314

315 for (; X_I != X_end && Y_I != Y_end; ++X_I, ++Y_I)

316 if (std::optional b = comparePiece(**X_I, **Y_I))

317 return *b;

318

319 return std::nullopt;

320}

321

324 return true;

326 return false;

330 std::pair<bool, bool> InSameTU = SM.isInTheSameTranslationUnit(XOffs, YOffs);

331 if (InSameTU.first)

337 if (!XFE || !YFE)

338 return XFE && !YFE;

339 int NameCmp = XFE->getName().compare(YFE->getName());

340 if (NameCmp != 0)

341 return NameCmp < 0;

342

344}

345

349 if (XL != YL)

351 FullSourceLoc XUL = X.getUniqueingLoc().asLocation();

353 if (XUL != YUL)

363 auto CompareDecls = [&XL](const Decl *D1,

364 const Decl *D2) -> std::optional {

365 if (D1 == D2)

366 return std::nullopt;

367 if (!D1)

368 return true;

369 if (!D2)

370 return false;

373 if (D1L != D2L) {

377 }

378 return std::nullopt;

379 };

380 if (auto Result = CompareDecls(X.getDeclWithIssue(), Y.getDeclWithIssue()))

381 return *Result;

383 if (auto Result = CompareDecls(X.getUniqueingDecl(), Y.getUniqueingDecl()))

384 return *Result;

385 }

388 if (XE - XI != YE - YI)

389 return (XE - XI) < (YE - YI);

390 for ( ; XI != XE ; ++XI, ++YI) {

391 if (*XI != *YI)

392 return (*XI) < (*YI);

393 }

395}

396

400 return;

401

403

404 std::vector<const PathDiagnostic *> BatchDiags;

405 for (const auto &D : Diags)

406 BatchDiags.push_back(&D);

407

408

409

412 assert(*X != *Y && "PathDiagnostics not uniqued!");

414 return -1;

415 assert(compare(**Y, **X) && "Not a total order!");

416 return 1;

417 };

418 array_pod_sort(BatchDiags.begin(), BatchDiags.end(), Comp);

419

421

422

423 for (const auto D : BatchDiags)

424 delete D;

425

426

428}

429

431 for (auto It = Set.begin(); It != Set.end();)

433}

434

436 StringRef ConsumerName,

438 llvm::FoldingSetNodeID NodeID;

439 NodeID.Add(PD);

440 void *InsertPos;

441 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);

442 if (!Entry) {

445 Set.InsertNode(Entry, InsertPos);

446 }

447

448

449 char *FileName_cstr = (char*) Alloc.Allocate(FileName.size(), 1);

451

452 Entry->files.push_back(std::make_pair(ConsumerName,

453 StringRef(FileName_cstr,

455}

456

459 llvm::FoldingSetNodeID NodeID;

460 NodeID.Add(PD);

461 void *InsertPos;

462 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);

463 if (!Entry)

464 return nullptr;

465 return &Entry->files;

466}

467

468

469

470

471

474 SourceLocation L = UseEndOfStatement ? S->getEndLoc() : S->getBeginLoc();

475 assert(!LAC.isNull() &&

476 "A valid LocationContext or AnalysisDeclContext should be passed to "

477 "PathDiagnosticLocation upon creation.");

478

479

480

483 if (auto *LC = dyn_cast<const LocationContext *>(LAC))

484 ADC = LC->getAnalysisDeclContext();

485 else

487

489

490 const Stmt *Parent = S;

491 do {

493

494

495

496

497

498 if (!Parent) {

500 if (Body)

502 else

504 break;

505 }

506

509 }

510

511

512

513 return L;

514}

515

522

523 switch (Source.getKind()) {

528 SM, CallerCtx);

532 SM, CallerCtx);

533 }

537 SM, CallerCtx);

538 }

542 }

546 if (const Stmt *CallerBody = CallerInfo->getBody())

549 }

553 }

555

556

557

560 CallerCtx);

561 }

565 llvm_unreachable("not yet implemented!");

568 llvm_unreachable("CFGElement kind should not be on callsite!");

569 }

570

571 llvm_unreachable("Unknown CFGElement kind");

572}

573

574PathDiagnosticLocation

577 return PathDiagnosticLocation(D->getBeginLoc(), SM, SingleLocK);

578}

579

584 assert(S && "Statement cannot be null");

586 SM, SingleLocK);

587}

588

593 if (const auto *CS = dyn_cast(S))

596 SM, SingleLocK);

597}

598

602 return PathDiagnosticLocation(BO->getOperatorLoc(), SM, SingleLocK);

603}

604

609 return PathDiagnosticLocation(CO->getColonLoc(), SM, SingleLocK);

610}

611

615

617

618

619

621 return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK);

622

623 return PathDiagnosticLocation(ME->getBeginLoc(), SM, SingleLocK);

624}

625

630 return PathDiagnosticLocation(L, SM, SingleLocK);

631}

632

637 return PathDiagnosticLocation(L, SM, SingleLocK);

638}

639

643

644 if (const auto *CS = dyn_cast_or_null(LC->getDecl()->getBody()))

645 if (!CS->body_empty()) {

646 SourceLocation Loc = (*CS->body_begin())->getBeginLoc();

647 return PathDiagnosticLocation(Loc, SM, SingleLocK);

648 }

649

650 return PathDiagnosticLocation();

651}

652

657 return PathDiagnosticLocation(L, SM, SingleLocK);

658}

659

663 const Stmt* S = nullptr;

664 if (std::optional BE = P.getAs<BlockEdge>()) {

665 const CFGBlock *BSrc = BE->getSrc();

667

668

671

672 } else {

674 if (!S) {

675

676

677

678 assert(BSrc == &BSrc->getParent()->getEntry() && "CFGBlock has no "

679 "TerminatorCondition and is not the enrty block of the CFG");

682 }

683 }

684 } else if (std::optional SP = P.getAs<StmtPoint>()) {

685 S = SP->getStmt();

688 } else if (std::optional PIP = P.getAs<PostInitializer>()) {

689 return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),

690 SMng);

691 } else if (std::optional PIC = P.getAs<PreImplicitCall>()) {

692 return PathDiagnosticLocation(PIC->getLocation(), SMng);

693 } else if (std::optional PIE =

695 return PathDiagnosticLocation(PIE->getLocation(), SMng);

696 } else if (std::optional CE = P.getAs<CallEnter>()) {

698 CE->getLocationContext(),

699 SMng);

700 } else if (std::optional CEE = P.getAs<CallExitEnd>()) {

702 CEE->getLocationContext(),

703 SMng);

705 if (const ReturnStmt *RS = CEB->getReturnStmt())

707 CEB->getLocationContext());

708 return PathDiagnosticLocation(

709 CEB->getLocationContext()->getDecl()->getSourceRange().getEnd(), SMng);

710 } else if (std::optional BE = P.getAs<BlockEntrance>()) {

711 if (std::optional BlockFront = BE->getFirstElement()) {

712 if (auto StmtElt = BlockFront->getAs<CFGStmt>()) {

713 return PathDiagnosticLocation(StmtElt->getStmt()->getBeginLoc(), SMng);

714 } else if (auto NewAllocElt = BlockFront->getAs<CFGNewAllocator>()) {

715 return PathDiagnosticLocation(

716 NewAllocElt->getAllocatorExpr()->getBeginLoc(), SMng);

717 }

718 llvm_unreachable("Unexpected CFG element at front of block");

719 }

720

721 return PathDiagnosticLocation(

722 BE->getBlock()->getTerminatorStmt()->getBeginLoc(), SMng);

723 } else if (std::optional FE =

725 return PathDiagnosticLocation(FE->getStmt(), SMng,

726 FE->getLocationContext());

727 } else {

728 llvm_unreachable("Unexpected ProgramPoint");

729 }

730

732}

733

735 const PathDiagnosticLocation &PDL) {

737 return PathDiagnosticLocation(L, L.getManager(), SingleLocK);

738}

739

741 PathDiagnosticLocation::genLocation(SourceLocation L,

743 assert(isValid());

744

745

746 switch (K) {

747 case SingleLocK:

748 case RangeK:

749 break;

750 case StmtK:

751

752 if (!S)

753 break;

754 return FullSourceLoc(getValidSourceLocation(S, LAC),

756 case DeclK:

757

758 if (!D)

759 break;

761 }

762

764}

765

768 assert(isValid());

769

770

771 switch (K) {

772 case SingleLocK:

774 case RangeK:

775 break;

776 case StmtK: {

777 const Stmt *S = asStmt();

779 default:

780 break;

781 case Stmt::DeclStmtClass: {

783 if (DS->isSingleDecl()) {

784

786 DS->getSingleDecl()->getLocation());

787 }

788 break;

789 }

790

791

792 case Stmt::IfStmtClass:

793 case Stmt::WhileStmtClass:

794 case Stmt::DoStmtClass:

795 case Stmt::ForStmtClass:

796 case Stmt::ChooseExprClass:

797 case Stmt::IndirectGotoStmtClass:

798 case Stmt::SwitchStmtClass:

799 case Stmt::BinaryConditionalOperatorClass:

800 case Stmt::ConditionalOperatorClass:

801 case Stmt::ObjCForCollectionStmtClass: {

802 SourceLocation L = getValidSourceLocation(S, LAC);

803 return SourceRange(L, L);

804 }

805 }

808 return R;

809 break;

810 }

811 case DeclK:

812 if (const auto *MD = dyn_cast(D))

813 return MD->getSourceRange();

814 if (const auto *FD = dyn_cast(D)) {

815 if (Stmt *Body = FD->getBody())

816 return Body->getSourceRange();

817 }

818 else {

819 SourceLocation L = D->getLocation();

820 return PathDiagnosticRange(SourceRange(L, L), true);

821 }

822 }

823

824 return SourceRange(Loc, Loc);

825}

826

828 if (K == StmtK) {

829 K = RangeK;

830 S = nullptr;

831 D = nullptr;

832 }

833 else if (K == DeclK) {

834 K = SingleLocK;

835 S = nullptr;

836 D = nullptr;

837 }

838}

839

840

841

842

843

844std::shared_ptr

851 return std::shared_ptr(

852 new PathDiagnosticCallPiece(caller, pos));

853}

854

857 const Decl *caller) {

858 std::shared_ptr C(

859 new PathDiagnosticCallPiece(path, caller));

860 path.clear();

861 auto *R = C.get();

862 path.push_front(std::move(C));

863 return R;

864}

865

869 Callee = CalleeCtx->getDecl();

870

873

874

875

876

877

878

879

880 if (const auto *MD = dyn_cast(Callee))

881 IsCalleeAnAutosynthesizedPropertyAccessor = (

882 MD->isPropertyAccessor() &&

884}

885

889 StringRef Prefix = StringRef(),

890 StringRef Postfix = StringRef());

891

895

898 } else {

900 }

901}

902

906 StringRef Prefix, StringRef Postfix) {

907 if (TAList.empty())

908 return;

909

910 Out << Prefix;

911 for (int I = 0, Last = TAList.size() - 1; I != Last; ++I) {

913 Out << ", ";

914 }

916 Out << Postfix;

917}

918

920 StringRef Prefix = StringRef()) {

922 return;

923 Out << Prefix << '\'' << *D;

924 if (const auto T = dyn_cast(D))

926 D->getLangOpts(), "<", ">");

927

928 Out << '\'';

929}

930

932 bool ExtendedDescription,

933 StringRef Prefix = StringRef()) {

934 if (!D)

935 return false;

936

938 if (ExtendedDescription)

939 Out << Prefix << "anonymous block";

940 return ExtendedDescription;

941 }

942

943 if (const auto *MD = dyn_cast(D)) {

944 Out << Prefix;

945 if (ExtendedDescription && !MD->isUserProvided()) {

946 if (MD->isExplicitlyDefaulted())

947 Out << "defaulted ";

948 else

949 Out << "implicit ";

950 }

951

952 if (const auto *CD = dyn_cast(MD)) {

953 if (CD->isDefaultConstructor())

954 Out << "default ";

955 else if (CD->isCopyConstructor())

956 Out << "copy ";

957 else if (CD->isMoveConstructor())

958 Out << "move ";

959

960 Out << "constructor";

963 if (!MD->isUserProvided()) {

964 Out << "destructor";

966 } else {

967

968 Out << "'" << *MD << "'";

969 }

970 } else if (MD->isCopyAssignmentOperator()) {

971 Out << "copy assignment operator";

973 } else if (MD->isMoveAssignmentOperator()) {

974 Out << "move assignment operator";

976 } else {

977 if (MD->getParent()->getIdentifier())

978 Out << "'" << *MD->getParent() << "::" << *MD << "'";

979 else

980 Out << "'" << *MD << "'";

981 }

982

983 return true;

984 }

985

986 Out << Prefix << '\'' << cast(*D);

987

988

989 if (const auto FD = dyn_cast(D))

991 FD->getTemplateSpecializationArgs())

993 ">");

994

995 Out << '\'';

996 return true;

997}

998

999std::shared_ptr

1001

1002

1003

1004

1005 if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)

1006 return nullptr;

1007

1009 llvm::raw_svector_ostream Out(buf);

1010

1011 Out << "Calling ";

1012 describeCodeDecl(Out, Callee, true);

1013

1014 assert(callEnter.asLocation().isValid());

1015 return std::make_shared(callEnter, Out.str());

1016}

1017

1018std::shared_ptr

1021 return nullptr;

1022 if (Callee->isImplicit() || !Callee->hasBody())

1023 return nullptr;

1024 if (const auto *MD = dyn_cast(Callee))

1025 if (MD->isDefaulted())

1026 return nullptr;

1027

1029 llvm::raw_svector_ostream Out(buf);

1030

1031 Out << "Entered call";

1032 describeCodeDecl(Out, Caller, false, " from ");

1033

1034 return std::make_shared(callEnterWithin, Out.str());

1035}

1036

1037std::shared_ptr

1039

1040

1041

1042

1043 if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)

1044 return nullptr;

1045

1047 llvm::raw_svector_ostream Out(buf);

1048

1049 if (!CallStackMessage.empty()) {

1050 Out << CallStackMessage;

1051 } else {

1053 false,

1054 "Returning from ");

1055 if (!DidDescribe)

1056 Out << "Returning to caller";

1057 }

1058

1059 assert(callReturn.asLocation().isValid());

1060 return std::make_shared(callReturn, Out.str());

1061}

1062

1064 for (const auto &I : pieces) {

1066 if (const auto *cp = dyn_cast(piece))

1068 else

1069 ++size;

1070 }

1071}

1072

1074 unsigned size = 0;

1076 return size;

1077}

1078

1091

1092

1093

1094

1095

1097 ID.Add(Range.getBegin());

1098 ID.Add(Range.getEnd());

1100}

1101

1103 ID.AddInteger((unsigned) getKind());

1104 ID.AddString(str);

1105

1108 for (const auto &I : Ranges) {

1109 ID.Add(I.getBegin());

1110 ID.Add(I.getEnd());

1111 }

1112}

1113

1116 for (const auto &I : path)

1117 ID.Add(*I);

1118}

1119

1124

1127 for (const auto &I : *this)

1128 ID.Add(I);

1129}

1130

1136

1140

1144

1148 ID.AddString(BugType);

1149 ID.AddString(VerboseDesc);

1150 ID.AddString(Category);

1151}

1152

1155 for (const auto &I : path)

1156 ID.Add(*I);

1158 ID.AddString(*I);

1159}

1160

1162 unsigned index = 0;

1164 llvm::errs() << "[" << index++ << "] ";

1165 Piece->dump();

1166 llvm::errs() << "\n";

1167 }

1168}

1169

1171 llvm::errs() << "CALL\n--------------\n";

1172

1174 SLoc->dump();

1175 else if (const auto *ND = dyn_cast_or_null(getCallee()))

1176 llvm::errs() << *ND << "\n";

1177 else

1179}

1180

1182 llvm::errs() << "EVENT\n--------------\n";

1183 llvm::errs() << getString() << "\n";

1184 llvm::errs() << " ---- at ----\n";

1186}

1187

1189 llvm::errs() << "CONTROL\n--------------\n";

1191 llvm::errs() << " ---- to ----\n";

1193}

1194

1196 llvm::errs() << "MACRO\n--------------\n";

1197

1198}

1199

1201 llvm::errs() << "NOTE\n--------------\n";

1202 llvm::errs() << getString() << "\n";

1203 llvm::errs() << " ---- at ----\n";

1205}

1206

1208 llvm::errs() << "POP-UP\n--------------\n";

1209 llvm::errs() << getString() << "\n";

1210 llvm::errs() << " ---- at ----\n";

1212}

1213

1216 llvm::errs() << "\n";

1217 return;

1218 }

1219

1220 switch (K) {

1221 case RangeK:

1222

1223 llvm::errs() << "\n";

1224 break;

1225 case SingleLocK:

1227 llvm::errs() << "\n";

1228 break;

1229 case StmtK:

1230 if (S)

1231 S->dump();

1232 else

1233 llvm::errs() << "\n";

1234 break;

1235 case DeclK:

1236 if (const auto *ND = dyn_cast_or_null(D))

1237 llvm::errs() << *ND << "\n";

1239

1240 llvm::errs() << "\n";

1241 else if (D)

1242 llvm::errs() << "\n";

1243 else

1244 llvm::errs() << "\n";

1245 break;

1246 }

1247}

This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...

static Decl::Kind getKind(const Decl *D)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

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

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

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.

static std::optional< bool > comparePath(const PathPieces &X, const PathPieces &Y)

Definition PathDiagnostic.cpp:307

static PathDiagnosticLocation getLocationForCaller(const StackFrameContext *SFC, const LocationContext *CallerCtx, const SourceManager &SM)

Definition PathDiagnostic.cpp:517

static void describeClass(raw_ostream &Out, const CXXRecordDecl *D, StringRef Prefix=StringRef())

Definition PathDiagnostic.cpp:919

static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)

Definition PathDiagnostic.cpp:346

static bool describeCodeDecl(raw_ostream &Out, const Decl *D, bool ExtendedDescription, StringRef Prefix=StringRef())

Definition PathDiagnostic.cpp:931

static std::optional< bool > compareCall(const PathDiagnosticCallPiece &X, const PathDiagnosticCallPiece &Y)

Definition PathDiagnostic.cpp:244

static std::optional< bool > comparePiece(const PathDiagnosticPiece &X, const PathDiagnosticPiece &Y)

Definition PathDiagnostic.cpp:261

static void describeTemplateParameter(raw_ostream &Out, const TemplateArgument &TArg, const LangOptions &LO)

Definition PathDiagnostic.cpp:892

static void compute_path_size(const PathPieces &pieces, unsigned &size)

Definition PathDiagnostic.cpp:1063

static std::optional< bool > compareMacro(const PathDiagnosticMacroPiece &X, const PathDiagnosticMacroPiece &Y)

Definition PathDiagnostic.cpp:239

static std::optional< bool > compareControlFlow(const PathDiagnosticControlFlowPiece &X, const PathDiagnosticControlFlowPiece &Y)

Definition PathDiagnostic.cpp:226

static StringRef StripTrailingDots(StringRef s)

Definition PathDiagnostic.cpp:49

static void describeTemplateParameters(raw_ostream &Out, const ArrayRef< TemplateArgument > TAList, const LangOptions &LO, StringRef Prefix=StringRef(), StringRef Postfix=StringRef())

Definition PathDiagnostic.cpp:903

static bool compareCrossTUSourceLocs(FullSourceLoc XL, FullSourceLoc YL)

Definition PathDiagnostic.cpp:322

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

C Language Family Type Representation.

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

__device__ __2f16 float __ockl_bool s

SourceLocation getColonLoc() const

AnalysisDeclContext contains the context data for the function, method or block under analysis.

ParentMap & getParentMap()

const Decl * getDecl() const

bool isBodyAutosynthesized() const

A builtin binary operation expression such as "x + y" or "x <= y".

SourceLocation getOperatorLoc() const

Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...

const Stmt * getTriggerStmt() const

Represents a single basic block in a source-level CFG.

CFGTerminator getTerminator() const

Stmt * getTerminatorCondition(bool StripParens=true)

Represents C++ object destructor generated from a call to delete.

const CXXDeleteExpr * getDeleteExpr() const

Represents a top-level expression in a basic block.

T castAs() const

Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.

Represents C++ base or member initializer from constructor's initialization list.

Represents C++ allocator call.

const Stmt * getStmt() const

Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...

bool isVirtualBaseBranch() const

Represents a C++ struct/union/class.

Represents a point when we begin processing an inlined call.

const StackFrameContext * getCalleeContext() const

Represents a point when we start the call exit sequence (for inlined call).

Represents a point when we finish the call exit sequence (for inlined call).

const StackFrameContext * getCalleeContext() const

CompoundStmt - This represents a group of statements like { stmt stmt }.

SourceLocation getLBracLoc() const

SourceLocation getRBracLoc() const

ConditionalOperator - The ?

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

SourceLocation getEndLoc() const LLVM_READONLY

virtual Stmt * getBody() const

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

SourceLocation getBodyRBrace() const

getBodyRBrace - Gets the right brace of the body, if a body exists.

SourceLocation getLocation() const

StringRef getName() const

The name of this FileEntry.

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

A SourceLocation and its associated SourceManager.

FullSourceLoc getExpansionLoc() const

FullSourceLoc getSpellingLoc() const

FileIDAndOffset getDecomposedLoc() const

Decompose the specified location into a raw FileID + Offset pair.

const SourceManager & getManager() const

bool isBeforeInTranslationUnitThan(SourceLocation Loc) const

Determines the order of 2 source locations in the translation unit.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...

const Decl * getDecl() const

LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

SourceLocation getMemberLoc() const

getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.

SourceLocation getBeginLoc() const LLVM_READONLY

IdentifierInfo * getIdentifier() const

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

Stmt * getParent(Stmt *) const

Represents a program point just after an implicit call event.

Represents a point after we ran remove dead bindings AFTER processing the given statement.

Represents a program point just before an implicit call event.

std::optional< T > getAs() const

Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...

const LocationContext * getLocationContext() const

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

It represents a stack frame of the call stack (based on CallEvent).

unsigned getIndex() const

const CFGBlock * getCallSiteBlock() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

StmtClass getStmtClass() const

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.

Represents a template argument.

ArrayRef< TemplateArgument > getPackAsArray() const

Return the array of arguments in this template argument pack.

void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const

Print this template argument to the given output stream.

@ Pack

The template argument is actually a parameter pack.

ArgKind getKind() const

Return the kind of stored template argument.

~PathDiagnosticCallPiece() override

PathDiagnosticLocation getLocation() const override

void setCallee(const CallEnter &CE, const SourceManager &SM)

Definition PathDiagnostic.cpp:866

PathDiagnosticLocation callEnter

void dump() const override

Definition PathDiagnostic.cpp:1170

std::shared_ptr< PathDiagnosticEventPiece > getCallExitEvent() const

Definition PathDiagnostic.cpp:1038

static std::shared_ptr< PathDiagnosticCallPiece > construct(const CallExitEnd &CE, const SourceManager &SM)

Definition PathDiagnostic.cpp:845

PathDiagnosticLocation callReturn

std::shared_ptr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const

Definition PathDiagnostic.cpp:1019

void Profile(llvm::FoldingSetNodeID &ID) const override

Definition PathDiagnostic.cpp:1114

std::shared_ptr< PathDiagnosticEventPiece > getCallEnterEvent() const

Definition PathDiagnostic.cpp:1000

PathDiagnosticLocation callEnterWithin

PDFileEntry::ConsumerFiles * getFiles(const PathDiagnostic &PD)

Definition PathDiagnostic.cpp:458

void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName)

Definition PathDiagnostic.cpp:435

~FilesMade()

Definition PathDiagnostic.cpp:430

ConsumerFiles files

A vector of <consumer,file> pairs.

std::vector< std::pair< StringRef, StringRef > > ConsumerFiles

virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic * > &Diags, FilesMade *filesMade)=0

virtual bool supportsCrossFileDiagnostics() const

Return true if the PathDiagnosticConsumer supports individual PathDiagnostics that span multiple file...

void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)

Definition PathDiagnostic.cpp:134

llvm::FoldingSet< PathDiagnostic > Diags

virtual ~PathDiagnosticConsumer()

Definition PathDiagnostic.cpp:128

void FlushDiagnostics(FilesMade *FilesMade)

Definition PathDiagnostic.cpp:397

PathDiagnosticLocation getStartLocation() const

void dump() const override

Definition PathDiagnostic.cpp:1188

~PathDiagnosticControlFlowPiece() override

PathDiagnosticLocation getEndLocation() const

void Profile(llvm::FoldingSetNodeID &ID) const override

Definition PathDiagnostic.cpp:1125

~PathDiagnosticEventPiece() override

void dump() const override

Definition PathDiagnostic.cpp:1181

static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, const SourceManager &SM)

For member expressions, return the location of the '.

Definition PathDiagnostic.cpp:613

static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, const SourceManager &SM)

Create a location for the beginning of the enclosing declaration body.

Definition PathDiagnostic.cpp:641

void dump() const

Definition PathDiagnostic.cpp:1214

void Profile(llvm::FoldingSetNodeID &ID) const

Definition PathDiagnostic.cpp:1096

static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM)

Create the location for the operator of the binary expression.

Definition PathDiagnostic.cpp:600

static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)

Create a location for the end of the compound statement.

Definition PathDiagnostic.cpp:634

static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS, const SourceManager &SM)

Create a location for the beginning of the compound statement.

Definition PathDiagnostic.cpp:627

static SourceLocation getValidSourceLocation(const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEndOfStatement=false)

Construct a source location that corresponds to either the beginning or the end of the given statemen...

Definition PathDiagnostic.cpp:472

static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)

Create a location for the end of the statement.

Definition PathDiagnostic.cpp:590

static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)

Create a location for the beginning of the declaration.

Definition PathDiagnostic.cpp:575

FullSourceLoc asLocation() const

void flatten()

Definition PathDiagnostic.cpp:827

static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)

Create a location corresponding to the given declaration.

static PathDiagnosticLocation createConditionalColonLoc(const ConditionalOperator *CO, const SourceManager &SM)

Definition PathDiagnostic.cpp:606

static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, const SourceManager &SM)

Constructs a location for the end of the enclosing declaration body.

Definition PathDiagnostic.cpp:654

static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)

Convert the given location into a single kind location.

Definition PathDiagnostic.cpp:734

void dump() const override

Definition PathDiagnostic.cpp:1195

void Profile(llvm::FoldingSetNodeID &ID) const override

Definition PathDiagnostic.cpp:1131

~PathDiagnosticMacroPiece() override

void Profile(llvm::FoldingSetNodeID &ID) const override

Definition PathDiagnostic.cpp:1137

void dump() const override

Definition PathDiagnostic.cpp:1200

~PathDiagnosticNotePiece() override

ArrayRef< SourceRange > getRanges() const

Return the SourceRanges associated with this PathDiagnosticPiece.

virtual PathDiagnosticLocation getLocation() const =0

virtual void Profile(llvm::FoldingSetNodeID &ID) const

Definition PathDiagnostic.cpp:1102

virtual ~PathDiagnosticPiece()

PathDiagnosticPiece()=delete

DisplayHint getDisplayHint() const

getDisplayHint - Return a hint indicating where the diagnostic should be displayed by the PathDiagnos...

StringRef getString() const

void Profile(llvm::FoldingSetNodeID &ID) const override

Definition PathDiagnostic.cpp:1120

PathDiagnosticLocation getLocation() const override

PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.

StringRef getCheckerName() const

meta_iterator meta_end() const

void FullProfile(llvm::FoldingSetNodeID &ID) const

Profiles the diagnostic, including its path.

Definition PathDiagnostic.cpp:1153

PathDiagnosticLocation getUniqueingLoc() const

Get the location on which the report should be uniqued.

std::deque< std::string >::const_iterator meta_iterator

StringRef getVerboseDescription() const

const Decl * getDeclWithIssue() const

Return the semantic context where an issue occurred.

void Profile(llvm::FoldingSetNodeID &ID) const

Profiles the diagnostic, independent of the path it references.

Definition PathDiagnostic.cpp:1145

unsigned full_size()

Return the unrolled size of the path.

Definition PathDiagnostic.cpp:1073

StringRef getBugType() const

const Decl * getUniqueingDecl() const

Get the declaration containing the uniqueing location.

StringRef getCategory() const

StringRef getShortDescription() const

meta_iterator meta_begin() const

SmallString< 32 > getIssueHash(const SourceManager &SrcMgr, const LangOptions &LangOpts) const

Get a hash that identifies the issue.

Definition PathDiagnostic.cpp:1080

PathDiagnosticLocation getLocation() const

void dump() const

Definition PathDiagnostic.cpp:1161

Public enums and private classes that are part of the SourceManager implementation.

static const FunctionDecl * getCallee(const CXXConstructExpr &D)

std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef

llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext

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

bool isa(CodeGen::Address addr)

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

std::pair< FileID, unsigned > FileIDAndOffset

const FunctionProtoType * T

llvm::SmallString< 32 > getIssueHash(const FullSourceLoc &IssueLoc, llvm::StringRef CheckerName, llvm::StringRef WarningMessage, const Decl *IssueDecl, const LangOptions &LangOpts)

Returns an opaque identifier for a diagnostic.

U cast(CodeGen::Address addr)

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