Skip to content

Commit 27ec210

Browse files
author
George Karpenkov
committed
[analyzer] [NFC] Move the code for dumping the program point to ProgramPoint
So we can dump them outside of viewing the exploded grpah. Differential Revision: https://reviews.llvm.org/D52583 llvm-svn: 343160
1 parent 4b9bb7c commit 27ec210

File tree

3 files changed

+178
-179
lines changed

3 files changed

+178
-179
lines changed

clang/include/clang/Analysis/ProgramPoint.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ class ProgramPoint {
215215
ID.AddPointer(getTag());
216216
}
217217

218+
void print(StringRef CR, llvm::raw_ostream &Out) const;
219+
220+
LLVM_DUMP_METHOD void dump() const {
221+
return print(/*CR=*/"\n", llvm::errs());
222+
}
223+
218224
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
219225
const LocationContext *LC,
220226
const ProgramPointTag *tag);

clang/lib/Analysis/ProgramPoint.cpp

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,177 @@ ProgramPoint ProgramPoint::getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
4343
}
4444
}
4545

46+
static void printLocation(raw_ostream &Out, SourceLocation SLoc,
47+
const SourceManager &SM,
48+
StringRef CR,
49+
StringRef Postfix) {
50+
if (SLoc.isFileID()) {
51+
Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)
52+
<< " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;
53+
}
54+
}
55+
56+
void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {
57+
const ASTContext &Context =
58+
getLocationContext()->getAnalysisDeclContext()->getASTContext();
59+
const SourceManager &SM = Context.getSourceManager();
60+
switch (getKind()) {
61+
case ProgramPoint::BlockEntranceKind:
62+
Out << "Block Entrance: B"
63+
<< castAs<BlockEntrance>().getBlock()->getBlockID();
64+
break;
65+
66+
case ProgramPoint::FunctionExitKind: {
67+
auto FEP = getAs<FunctionExitPoint>();
68+
Out << "Function Exit: B" << FEP->getBlock()->getBlockID();
69+
if (const ReturnStmt *RS = FEP->getStmt()) {
70+
Out << CR << " Return: S" << RS->getID(Context) << CR;
71+
RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
72+
/*Indentation=*/2, /*NewlineSymbol=*/CR);
73+
}
74+
break;
75+
}
76+
case ProgramPoint::BlockExitKind:
77+
assert(false);
78+
break;
79+
80+
case ProgramPoint::CallEnterKind:
81+
Out << "CallEnter";
82+
break;
83+
84+
case ProgramPoint::CallExitBeginKind:
85+
Out << "CallExitBegin";
86+
break;
87+
88+
case ProgramPoint::CallExitEndKind:
89+
Out << "CallExitEnd";
90+
break;
91+
92+
case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
93+
Out << "PostStmtPurgeDeadSymbols";
94+
break;
95+
96+
case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
97+
Out << "PreStmtPurgeDeadSymbols";
98+
break;
99+
100+
case ProgramPoint::EpsilonKind:
101+
Out << "Epsilon Point";
102+
break;
103+
104+
case ProgramPoint::LoopExitKind: {
105+
LoopExit LE = castAs<LoopExit>();
106+
Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
107+
break;
108+
}
109+
110+
case ProgramPoint::PreImplicitCallKind: {
111+
ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
112+
Out << "PreCall: ";
113+
PC.getDecl()->print(Out, Context.getLangOpts());
114+
printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
115+
break;
116+
}
117+
118+
case ProgramPoint::PostImplicitCallKind: {
119+
ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
120+
Out << "PostCall: ";
121+
PC.getDecl()->print(Out, Context.getLangOpts());
122+
printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
123+
break;
124+
}
125+
126+
case ProgramPoint::PostInitializerKind: {
127+
Out << "PostInitializer: ";
128+
const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();
129+
if (const FieldDecl *FD = Init->getAnyMember())
130+
Out << *FD;
131+
else {
132+
QualType Ty = Init->getTypeSourceInfo()->getType();
133+
Ty = Ty.getLocalUnqualifiedType();
134+
Ty.print(Out, Context.getLangOpts());
135+
}
136+
break;
137+
}
138+
139+
case ProgramPoint::BlockEdgeKind: {
140+
const BlockEdge &E = castAs<BlockEdge>();
141+
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
142+
<< E.getDst()->getBlockID() << ')';
143+
144+
if (const Stmt *T = E.getSrc()->getTerminator()) {
145+
SourceLocation SLoc = T->getBeginLoc();
146+
147+
Out << "\\|Terminator: ";
148+
E.getSrc()->printTerminator(Out, Context.getLangOpts());
149+
printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");
150+
151+
if (isa<SwitchStmt>(T)) {
152+
const Stmt *Label = E.getDst()->getLabel();
153+
154+
if (Label) {
155+
if (const auto *C = dyn_cast<CaseStmt>(Label)) {
156+
Out << CR << "case ";
157+
if (C->getLHS())
158+
C->getLHS()->printPretty(
159+
Out, nullptr, Context.getPrintingPolicy(),
160+
/*Indentation=*/0, /*NewlineSymbol=*/CR);
161+
162+
if (const Stmt *RHS = C->getRHS()) {
163+
Out << " .. ";
164+
RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
165+
/*Indetation=*/0, /*NewlineSymbol=*/CR);
166+
}
167+
168+
Out << ":";
169+
} else {
170+
assert(isa<DefaultStmt>(Label));
171+
Out << CR << "default:";
172+
}
173+
} else
174+
Out << CR << "(implicit) default:";
175+
} else if (isa<IndirectGotoStmt>(T)) {
176+
// FIXME
177+
} else {
178+
Out << CR << "Condition: ";
179+
if (*E.getSrc()->succ_begin() == E.getDst())
180+
Out << "true";
181+
else
182+
Out << "false";
183+
}
184+
185+
Out << CR;
186+
}
187+
188+
break;
189+
}
190+
191+
default: {
192+
const Stmt *S = castAs<StmtPoint>().getStmt();
193+
assert(S != nullptr && "Expecting non-null Stmt");
194+
195+
Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"
196+
<< (const void *)S << "> ";
197+
S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
198+
/*Indentation=*/2, /*NewlineSymbol=*/CR);
199+
printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");
200+
201+
if (getAs<PreStmt>())
202+
Out << CR << "PreStmt" << CR;
203+
else if (getAs<PostLoad>())
204+
Out << CR << "PostLoad" << CR;
205+
else if (getAs<PostStore>())
206+
Out << CR << "PostStore" << CR;
207+
else if (getAs<PostLValue>())
208+
Out << CR << "PostLValue" << CR;
209+
else if (getAs<PostAllocatorCall>())
210+
Out << CR << "PostAllocatorCall" << CR;
211+
212+
break;
213+
}
214+
}
215+
}
216+
46217
SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider,
47218
StringRef Msg)
48219
: Desc((MsgProvider + " : " + Msg).str()) {}

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 1 addition & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,183 +2962,6 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
29622962
return {};
29632963
}
29642964

2965-
// De-duplicate some source location pretty-printing.
2966-
static void printLocation(raw_ostream &Out,
2967-
SourceLocation SLoc,
2968-
const SourceManager &SM,
2969-
StringRef Postfix="\\l") {
2970-
if (SLoc.isFileID()) {
2971-
Out << "\\lline="
2972-
<< SM.getExpansionLineNumber(SLoc)
2973-
<< " col="
2974-
<< SM.getExpansionColumnNumber(SLoc)
2975-
<< Postfix;
2976-
}
2977-
}
2978-
2979-
static void dumpProgramPoint(ProgramPoint Loc,
2980-
const ASTContext &Context,
2981-
llvm::raw_string_ostream &Out) {
2982-
const SourceManager &SM = Context.getSourceManager();
2983-
switch (Loc.getKind()) {
2984-
case ProgramPoint::BlockEntranceKind:
2985-
Out << "Block Entrance: B"
2986-
<< Loc.castAs<BlockEntrance>().getBlock()->getBlockID();
2987-
break;
2988-
2989-
case ProgramPoint::FunctionExitKind: {
2990-
auto FEP = Loc.getAs<FunctionExitPoint>();
2991-
Out << "Function Exit: B"
2992-
<< FEP->getBlock()->getBlockID();
2993-
if (const ReturnStmt *RS = FEP->getStmt()) {
2994-
Out << "\\l Return: S" << RS->getID(Context) << "\\l";
2995-
RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
2996-
/*Indentation=*/2, /*NewlineSymbol=*/"\\l");
2997-
}
2998-
break;
2999-
}
3000-
case ProgramPoint::BlockExitKind:
3001-
assert(false);
3002-
break;
3003-
3004-
case ProgramPoint::CallEnterKind:
3005-
Out << "CallEnter";
3006-
break;
3007-
3008-
case ProgramPoint::CallExitBeginKind:
3009-
Out << "CallExitBegin";
3010-
break;
3011-
3012-
case ProgramPoint::CallExitEndKind:
3013-
Out << "CallExitEnd";
3014-
break;
3015-
3016-
case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
3017-
Out << "PostStmtPurgeDeadSymbols";
3018-
break;
3019-
3020-
case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
3021-
Out << "PreStmtPurgeDeadSymbols";
3022-
break;
3023-
3024-
case ProgramPoint::EpsilonKind:
3025-
Out << "Epsilon Point";
3026-
break;
3027-
3028-
case ProgramPoint::LoopExitKind: {
3029-
LoopExit LE = Loc.castAs<LoopExit>();
3030-
Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
3031-
break;
3032-
}
3033-
3034-
case ProgramPoint::PreImplicitCallKind: {
3035-
ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
3036-
Out << "PreCall: ";
3037-
PC.getDecl()->print(Out, Context.getLangOpts());
3038-
printLocation(Out, PC.getLocation(), SM);
3039-
break;
3040-
}
3041-
3042-
case ProgramPoint::PostImplicitCallKind: {
3043-
ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
3044-
Out << "PostCall: ";
3045-
PC.getDecl()->print(Out, Context.getLangOpts());
3046-
printLocation(Out, PC.getLocation(), SM);
3047-
break;
3048-
}
3049-
3050-
case ProgramPoint::PostInitializerKind: {
3051-
Out << "PostInitializer: ";
3052-
const CXXCtorInitializer *Init =
3053-
Loc.castAs<PostInitializer>().getInitializer();
3054-
if (const FieldDecl *FD = Init->getAnyMember())
3055-
Out << *FD;
3056-
else {
3057-
QualType Ty = Init->getTypeSourceInfo()->getType();
3058-
Ty = Ty.getLocalUnqualifiedType();
3059-
Ty.print(Out, Context.getLangOpts());
3060-
}
3061-
break;
3062-
}
3063-
3064-
case ProgramPoint::BlockEdgeKind: {
3065-
const BlockEdge &E = Loc.castAs<BlockEdge>();
3066-
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
3067-
<< E.getDst()->getBlockID() << ')';
3068-
3069-
if (const Stmt *T = E.getSrc()->getTerminator()) {
3070-
SourceLocation SLoc = T->getBeginLoc();
3071-
3072-
Out << "\\|Terminator: ";
3073-
E.getSrc()->printTerminator(Out, Context.getLangOpts());
3074-
printLocation(Out, SLoc, SM, /*Postfix=*/"");
3075-
3076-
if (isa<SwitchStmt>(T)) {
3077-
const Stmt *Label = E.getDst()->getLabel();
3078-
3079-
if (Label) {
3080-
if (const auto *C = dyn_cast<CaseStmt>(Label)) {
3081-
Out << "\\lcase ";
3082-
if (C->getLHS())
3083-
C->getLHS()->printPretty(
3084-
Out, nullptr, Context.getPrintingPolicy(),
3085-
/*Indentation=*/0, /*NewlineSymbol=*/"\\l");
3086-
3087-
if (const Stmt *RHS = C->getRHS()) {
3088-
Out << " .. ";
3089-
RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
3090-
/*Indetation=*/0, /*NewlineSymbol=*/"\\l");
3091-
}
3092-
3093-
Out << ":";
3094-
} else {
3095-
assert(isa<DefaultStmt>(Label));
3096-
Out << "\\ldefault:";
3097-
}
3098-
} else
3099-
Out << "\\l(implicit) default:";
3100-
} else if (isa<IndirectGotoStmt>(T)) {
3101-
// FIXME
3102-
} else {
3103-
Out << "\\lCondition: ";
3104-
if (*E.getSrc()->succ_begin() == E.getDst())
3105-
Out << "true";
3106-
else
3107-
Out << "false";
3108-
}
3109-
3110-
Out << "\\l";
3111-
}
3112-
3113-
break;
3114-
}
3115-
3116-
default: {
3117-
const Stmt *S = Loc.castAs<StmtPoint>().getStmt();
3118-
assert(S != nullptr && "Expecting non-null Stmt");
3119-
3120-
Out << S->getStmtClassName() << " S"
3121-
<< S->getID(Context) << " <" << (const void *)S << "> ";
3122-
S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
3123-
/*Indentation=*/2, /*NewlineSymbol=*/"\\l");
3124-
printLocation(Out, S->getBeginLoc(), SM, /*Postfix=*/"");
3125-
3126-
if (Loc.getAs<PreStmt>())
3127-
Out << "\\lPreStmt\\l";
3128-
else if (Loc.getAs<PostLoad>())
3129-
Out << "\\lPostLoad\\l";
3130-
else if (Loc.getAs<PostStore>())
3131-
Out << "\\lPostStore\\l";
3132-
else if (Loc.getAs<PostLValue>())
3133-
Out << "\\lPostLValue\\l";
3134-
else if (Loc.getAs<PostAllocatorCall>())
3135-
Out << "\\lPostAllocatorCall\\l";
3136-
3137-
break;
3138-
}
3139-
}
3140-
}
3141-
31422965
static bool isNodeHidden(const ExplodedNode *N) {
31432966
return N->isTrivial();
31442967
}
@@ -3156,12 +2979,11 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
31562979
}
31572980

31582981
ProgramStateRef State = N->getState();
3159-
const ASTContext &Context = State->getStateManager().getContext();
31602982

31612983
// Dump program point for all the previously skipped nodes.
31622984
const ExplodedNode *OtherNode = FirstHiddenNode;
31632985
while (true) {
3164-
dumpProgramPoint(OtherNode->getLocation(), Context, Out);
2986+
OtherNode->getLocation().print(/*CR=*/"\\l", Out);
31652987

31662988
if (const ProgramPointTag *Tag = OtherNode->getLocation().getTag())
31672989
Out << "\\lTag:" << Tag->getTagDescription();

0 commit comments

Comments
 (0)