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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

37#include "llvm/ADT/SmallVector.h"

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

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

40#include "llvm/Support/Casting.h"

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

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

43#include

44#include

45#include

46#include

47#include

48#include

49

50using namespace clang;

51using namespace ento;

52

54

58

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

61

63

65

67

69

71

73

75

77 bool ShouldFlattenMacros) const {

78 for (auto &Piece : *this) {

79 switch (Piece->getKind()) {

81 auto &Call = cast(*Piece);

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

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

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

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

87 break;

88 }

90 auto &Macro = cast(*Piece);

91 if (ShouldFlattenMacros) {

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

93 } else {

94 Current.push_back(Piece);

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

97

98 Macro.subPieces = NewPath;

99 }

100 break;

101 }

106 Current.push_back(Piece);

107 break;

108 }

109 }

110}

111

113

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

116 StringRef verboseDesc, StringRef shortDesc, StringRef category,

118 const Decl *AnalysisEntryPoint,

119 std::unique_ptr ExecutedLines)

120 : CheckerName(CheckerName), DeclWithIssue(declWithIssue),

125 UniqueingDecl(DeclToUnique), AnalysisEntryPoint(AnalysisEntryPoint),

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

127 assert(AnalysisEntryPoint);

128}

129

130void PathDiagnosticConsumer::anchor() {}

131

133

135 delete &Diag;

136}

137

139 std::unique_ptr D) {

140 if (D || D->path.empty())

141 return;

142

143

144

145

146 D->flattenLocations();

147

148

149

151

157 llvm::raw_svector_ostream warning(buf);

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

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

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

161 << "formats\n";

162

165

166 for (const auto &I : path) {

169

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

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

174 return;

175 }

176

177

179 for (const auto &I : Ranges) {

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

183 return;

184 }

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

188 return;

189 }

190 }

191

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

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

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

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

196 }

197 }

198

200 return;

201 }

202

203

204 llvm::FoldingSetNodeID profile;

205 D->Profile(profile);

206 void *InsertPos = nullptr;

207

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

209

210

211

212

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

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

215 if (orig_size <= new_size)

216 return;

217

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

219 Diags.RemoveNode(orig);

220 delete orig;

221 }

222

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

224}

225

228

229static std::optional

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

234 if (XSL != YSL)

238 if (XEL != YEL)

240 return std::nullopt;

241}

242

246}

247

252 if (X_CEL != Y_CEL)

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

256 if (X_CEWL != Y_CEWL)

260 if (X_CRL != Y_CRL)

263}

264

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

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

269

272 if (XL != YL)

274

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

277

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

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

280

282

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

286 if (XR != YR) {

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

290 }

291 }

292

293 switch (X.getKind()) {

296 cast(Y));

298 return compareMacro(cast(X),

299 cast(Y));

301 return compareCall(cast(X),

302 cast(Y));

306 return std::nullopt;

307 }

308 llvm_unreachable("all cases handled");

309}

310

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

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

315

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

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

318

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

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

321 return *b;

322

323 return std::nullopt;

324}

325

328 return true;

330 return false;

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

335 if (InSameTU.first)

341 if (!XFE || !YFE)

342 return XFE && !YFE;

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

344 if (NameCmp != 0)

345 return NameCmp < 0;

346

348}

349

353 if (XL != YL)

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

357 if (XUL != YUL)

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

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

369 if (D1 == D2)

370 return std::nullopt;

371 if (!D1)

372 return true;

373 if (!D2)

374 return false;

377 if (D1L != D2L) {

381 }

382 return std::nullopt;

383 };

389 }

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

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

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

395 if (*XI != *YI)

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

397 }

399}

400

404 return;

405

407

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

409 for (const auto &D : Diags)

410 BatchDiags.push_back(&D);

411

412

413

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

418 return -1;

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

420 return 1;

421 };

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

423

425

426

427 for (const auto D : BatchDiags)

428 delete D;

429

430

432}

433

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

437}

438

440 StringRef ConsumerName,

442 llvm::FoldingSetNodeID NodeID;

443 NodeID.Add(PD);

444 void *InsertPos;

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

446 if (!Entry) {

449 Set.InsertNode(Entry, InsertPos);

450 }

451

452

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

455

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

457 StringRef(FileName_cstr,

459}

460

463 llvm::FoldingSetNodeID NodeID;

464 NodeID.Add(PD);

465 void *InsertPos;

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

467 if (!Entry)

468 return nullptr;

469 return &Entry->files;

470}

471

472

473

474

475

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

479 assert(!LAC.isNull() &&

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

481 "PathDiagnosticLocation upon creation.");

482

483

484

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

488 ADC = LC->getAnalysisDeclContext();

489 else

490 ADC = cast<AnalysisDeclContext *>(LAC);

491

493

495 do {

497

498

499

500

501

504 if (Body)

506 else

508 break;

509 }

510

511 L = UseEndOfStatement ? Parent->getEndLoc() : Parent->getBeginLoc();

513 }

514

515

516

517 return L;

518}

519

526

527 switch (Source.getKind()) {

532 SM, CallerCtx);

536 SM, CallerCtx);

537 }

541 SM, CallerCtx);

542 }

546 }

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

553 }

557 }

559

560

561

564 CallerCtx);

565 }

569 llvm_unreachable("not yet implemented!");

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

573 }

574

575 llvm_unreachable("Unknown CFGElement kind");

576}

577

582}

583

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

590 SM, SingleLocK);

591}

592

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

598 return createEndBrace(CS, SM);

600 SM, SingleLocK);

601}

602

607}

608

614}

615

619

621

622

623

626

628}

629

635}

636

642}

643

647

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

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

652 }

653

655}

656

662}

663

667 const Stmt* S = nullptr;

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

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

671

672

674 P.getLocationContext()->getDecl(), SMng);

675

676 } else {

678 if (!S) {

679

680

681

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

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

685 P.getLocationContext()->getDecl(), SMng);

686 }

687 }

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

689 S = SP->getStmt();

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

694 SMng);

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

697 } else if (std::optional PIE =

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

702 CE->getLocationContext(),

703 SMng);

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

706 CEE->getLocationContext(),

707 SMng);

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

711 CEB->getLocationContext());

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

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

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

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

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

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

721 }

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

723 }

724

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

727 } else if (std::optional FE =

730 FE->getLocationContext());

731 } else {

732 llvm_unreachable("Unexpected ProgramPoint");

733 }

734

736}

737

742}

743

745 PathDiagnosticLocation::genLocation(SourceLocation L,

747 assert(isValid());

748

749

750 switch (K) {

751 case SingleLocK:

752 case RangeK:

753 break;

754 case StmtK:

755

756 if (!S)

757 break;

758 return FullSourceLoc(getValidSourceLocation(S, LAC),

760 case DeclK:

761

762 if (D)

763 break;

765 }

766

768}

769

772 assert(isValid());

773

774

775 switch (K) {

776 case SingleLocK:

778 case RangeK:

779 break;

780 case StmtK: {

781 const Stmt *S = asStmt();

782 switch (S->getStmtClass()) {

783 default:

784 break;

785 case Stmt::DeclStmtClass: {

786 const auto *DS = cast(S);

787 if (DS->isSingleDecl()) {

788

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

791 }

792 break;

793 }

794

795

796 case Stmt::IfStmtClass:

797 case Stmt::WhileStmtClass:

798 case Stmt::DoStmtClass:

799 case Stmt::ForStmtClass:

800 case Stmt::ChooseExprClass:

801 case Stmt::IndirectGotoStmtClass:

802 case Stmt::SwitchStmtClass:

803 case Stmt::BinaryConditionalOperatorClass:

804 case Stmt::ConditionalOperatorClass:

805 case Stmt::ObjCForCollectionStmtClass: {

808 }

809 }

812 return R;

813 break;

814 }

815 case DeclK:

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

817 return MD->getSourceRange();

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

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

820 return Body->getSourceRange();

821 }

822 else {

825 }

826 }

827

829}

830

832 if (K == StmtK) {

833 K = RangeK;

834 S = nullptr;

835 D = nullptr;

836 }

837 else if (K == DeclK) {

838 K = SingleLocK;

839 S = nullptr;

840 D = nullptr;

841 }

842}

843

844

845

846

847

848std::shared_ptr

855 return std::shared_ptr(

857}

858

861 const Decl *caller) {

862 std::shared_ptr C(

864 path.clear();

865 auto *R = C.get();

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

867 return R;

868}

869

873 Callee = CalleeCtx->getDecl();

874

877

878

879

880

881

882

883

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

885 IsCalleeAnAutosynthesizedPropertyAccessor = (

886 MD->isPropertyAccessor() &&

888}

889

893 StringRef Prefix = StringRef(),

894 StringRef Postfix = StringRef());

895

899

902 } else {

904 }

905}

906

910 StringRef Prefix, StringRef Postfix) {

911 if (TAList.empty())

912 return;

913

914 Out << Prefix;

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

917 Out << ", ";

918 }

920 Out << Postfix;

921}

922

924 StringRef Prefix = StringRef()) {

925 if (D->getIdentifier())

926 return;

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

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

931

932 Out << '\'';

933}

934

936 bool ExtendedDescription,

937 StringRef Prefix = StringRef()) {

938 if (D)

939 return false;

940

941 if (isa(D)) {

942 if (ExtendedDescription)

943 Out << Prefix << "anonymous block";

944 return ExtendedDescription;

945 }

946

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

948 Out << Prefix;

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

950 if (MD->isExplicitlyDefaulted())

951 Out << "defaulted ";

952 else

953 Out << "implicit ";

954 }

955

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

957 if (CD->isDefaultConstructor())

958 Out << "default ";

959 else if (CD->isCopyConstructor())

960 Out << "copy ";

961 else if (CD->isMoveConstructor())

962 Out << "move ";

963

964 Out << "constructor";

966 } else if (isa(MD)) {

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

968 Out << "destructor";

970 } else {

971

972 Out << "'" << *MD << "'";

973 }

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

975 Out << "copy assignment operator";

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

978 Out << "move assignment operator";

980 } else {

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

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

983 else

984 Out << "'" << *MD << "'";

985 }

986

987 return true;

988 }

989

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

991

992

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

995 FD->getTemplateSpecializationArgs())

997 ">");

998

999 Out << '\'';

1000 return true;

1001}

1002

1003std::shared_ptr

1005

1006

1007

1008

1009 if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)

1010 return nullptr;

1011

1013 llvm::raw_svector_ostream Out(buf);

1014

1015 Out << "Calling ";

1016 describeCodeDecl(Out, Callee, true);

1017

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

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

1020}

1021

1022std::shared_ptr

1024 if (!callEnterWithin.asLocation().isValid())

1025 return nullptr;

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

1027 return nullptr;

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

1029 if (MD->isDefaulted())

1030 return nullptr;

1031

1033 llvm::raw_svector_ostream Out(buf);

1034

1035 Out << "Entered call";

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

1037

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

1039}

1040

1041std::shared_ptr

1043

1044

1045

1046

1047 if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)

1048 return nullptr;

1049

1051 llvm::raw_svector_ostream Out(buf);

1052

1053 if (!CallStackMessage.empty()) {

1054 Out << CallStackMessage;

1055 } else {

1057 false,

1058 "Returning from ");

1059 if (!DidDescribe)

1060 Out << "Returning to caller";

1061 }

1062

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

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

1065}

1066

1068 for (const auto &I : pieces) {

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

1072 else

1073 ++size;

1074 }

1075}

1076

1078 unsigned size = 0;

1080 return size;

1081}

1082

1083

1084

1085

1086

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

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

1091}

1092

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

1095 ID.AddString(str);

1096

1097 ID.AddInteger((unsigned) getDisplayHint());

1099 for (const auto &I : Ranges) {

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

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

1102 }

1103}

1104

1107 for (const auto &I : path)

1108 ID.Add(*I);

1109}

1110

1113 ID.Add(Pos);

1114}

1115

1118 for (const auto &I : *this)

1119 ID.Add(I);

1120}

1121

1124 for (const auto &I : subPieces)

1125 ID.Add(*I);

1126}

1127

1130}

1131

1134}

1135

1137 ID.Add(getLocation());

1138 ID.Add(getUniqueingLoc());

1140 ID.AddString(VerboseDesc);

1142}

1143

1145 Profile(ID);

1146 for (const auto &I : path)

1147 ID.Add(*I);

1148 for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)

1149 ID.AddString(*I);

1150}

1151

1153 unsigned index = 0;

1154 for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {

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

1156 (*I)->dump();

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

1158 }

1159}

1160

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

1163

1164 if (const Stmt *SLoc = getLocation().getStmtOrNull())

1165 SLoc->dump();

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

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

1168 else

1169 getLocation().dump();

1170}

1171

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

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

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

1176 getLocation().dump();

1177}

1178

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

1181 getStartLocation().dump();

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

1183 getEndLocation().dump();

1184}

1185

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

1188

1189}

1190

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

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

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

1195 getLocation().dump();

1196}

1197

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

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

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

1202 getLocation().dump();

1203}

1204

1206 if (!isValid()) {

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

1208 return;

1209 }

1210

1211 switch (K) {

1212 case RangeK:

1213

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

1215 break;

1216 case SingleLocK:

1217 asLocation().dump();

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

1219 break;

1220 case StmtK:

1221 if (S)

1222 S->dump();

1223 else

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

1225 break;

1226 case DeclK:

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

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

1229 else if (isa(D))

1230

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

1232 else if (D)

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

1234 else

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

1236 break;

1237 }

1238}

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.

Defines the clang::FileManager interface and associated types.

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)

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

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

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

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

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

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

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

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

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

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

static StringRef StripTrailingDots(StringRef s)

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

static bool compareCrossTUSourceLocs(FullSourceLoc XL, FullSourceLoc YL)

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 ?: ternary operator.

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

SourceLocation getBeginLoc() const LLVM_READONLY

const LangOptions & getLangOpts() const LLVM_READONLY

Helper to get the language options from the ASTContext.

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

std::pair< FileID, unsigned > 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

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.

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 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

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

PathDiagnosticLocation callEnter

void dump() const override

std::shared_ptr< PathDiagnosticEventPiece > getCallExitEvent() const

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

PathDiagnosticLocation callReturn

std::shared_ptr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const

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

std::shared_ptr< PathDiagnosticEventPiece > getCallEnterEvent() const

PathDiagnosticLocation callEnterWithin

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

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

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

ConsumerFiles files

A vector of <consumer,file> pairs.

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)

llvm::FoldingSet< PathDiagnostic > Diags

virtual ~PathDiagnosticConsumer()

void FlushDiagnostics(FilesMade *FilesMade)

PathDiagnosticLocation getStartLocation() const

void dump() const override

~PathDiagnosticControlFlowPiece() override

PathDiagnosticLocation getEndLocation() const

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

~PathDiagnosticEventPiece() override

void dump() const override

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

For member expressions, return the location of the '.

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

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

void Profile(llvm::FoldingSetNodeID &ID) const

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

Create the location for the operator of the binary expression.

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

Create a location for the end of the compound statement.

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

Create a location for the beginning of the compound statement.

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...

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

Create a location for the end of the statement.

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

Create a location for the beginning of the declaration.

FullSourceLoc asLocation() const

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)

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

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

static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)

Convert the given location into a single kind location.

void dump() const override

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

~PathDiagnosticMacroPiece() override

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

void dump() const override

~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

virtual ~PathDiagnosticPiece()

PathDiagnosticPiece()=delete

StringRef getString() const

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

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

meta_iterator meta_end() const

void FullProfile(llvm::FoldingSetNodeID &ID) const

Profiles the diagnostic, including its path.

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.

unsigned full_size()

Return the unrolled size of the path.

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

PathDiagnosticLocation getLocation() const

A Range represents the closed range [from, to].

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

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

@ Result

The result type of a method or function.

const FunctionProtoType * T

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