clang  9.0.0svn
ProgramPoint.cpp
Go to the documentation of this file.
1 //==- ProgramPoint.cpp - Program Points for Path-Sensitive Analysis -*- C++ -*-/
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the interface ProgramPoint, which identifies a
10 // distinct location in a function.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
16 using namespace clang;
17 
19 
21  const LocationContext *LC,
22  const ProgramPointTag *tag){
23  switch (K) {
24  default:
25  llvm_unreachable("Unhandled ProgramPoint kind");
27  return PreStmt(S, LC, tag);
29  return PostStmt(S, LC, tag);
31  return PreLoad(S, LC, tag);
33  return PostLoad(S, LC, tag);
35  return PreStore(S, LC, tag);
37  return PostLValue(S, LC, tag);
39  return PostStmtPurgeDeadSymbols(S, LC, tag);
41  return PreStmtPurgeDeadSymbols(S, LC, tag);
42  }
43 }
44 
45 LLVM_DUMP_METHOD void ProgramPoint::dump() const {
46  return print(/*CR=*/"\n", llvm::errs());
47 }
48 
49 static void printLocation(raw_ostream &Out, SourceLocation SLoc,
50  const SourceManager &SM,
51  StringRef CR,
52  StringRef Postfix) {
53  if (SLoc.isFileID()) {
54  Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)
55  << " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;
56  }
57 }
58 
59 void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {
60  const ASTContext &Context =
61  getLocationContext()->getAnalysisDeclContext()->getASTContext();
62  const SourceManager &SM = Context.getSourceManager();
63  switch (getKind()) {
65  Out << "Block Entrance: B"
66  << castAs<BlockEntrance>().getBlock()->getBlockID();
67  break;
68 
70  auto FEP = getAs<FunctionExitPoint>();
71  Out << "Function Exit: B" << FEP->getBlock()->getBlockID();
72  if (const ReturnStmt *RS = FEP->getStmt()) {
73  Out << CR << " Return: S" << RS->getID(Context) << CR;
74  RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
75  /*Indentation=*/2, /*NewlineSymbol=*/CR);
76  }
77  break;
78  }
80  assert(false);
81  break;
82 
84  Out << "CallEnter";
85  break;
86 
88  Out << "CallExitBegin";
89  break;
90 
92  Out << "CallExitEnd";
93  break;
94 
96  Out << "PostStmtPurgeDeadSymbols";
97  break;
98 
100  Out << "PreStmtPurgeDeadSymbols";
101  break;
102 
104  Out << "Epsilon Point";
105  break;
106 
108  LoopExit LE = castAs<LoopExit>();
109  Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
110  break;
111  }
112 
114  ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
115  Out << "PreCall: ";
116  PC.getDecl()->print(Out, Context.getLangOpts());
117  printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
118  break;
119  }
120 
122  ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
123  Out << "PostCall: ";
124  PC.getDecl()->print(Out, Context.getLangOpts());
125  printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
126  break;
127  }
128 
130  Out << "PostInitializer: ";
131  const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();
132  if (const FieldDecl *FD = Init->getAnyMember())
133  Out << *FD;
134  else {
135  QualType Ty = Init->getTypeSourceInfo()->getType();
136  Ty = Ty.getLocalUnqualifiedType();
137  Ty.print(Out, Context.getLangOpts());
138  }
139  break;
140  }
141 
143  const BlockEdge &E = castAs<BlockEdge>();
144  Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
145  << E.getDst()->getBlockID() << ')';
146 
147  if (const Stmt *T = E.getSrc()->getTerminator()) {
148  SourceLocation SLoc = T->getBeginLoc();
149 
150  Out << "\\|Terminator: ";
151  E.getSrc()->printTerminator(Out, Context.getLangOpts());
152  printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");
153 
154  if (isa<SwitchStmt>(T)) {
155  const Stmt *Label = E.getDst()->getLabel();
156 
157  if (Label) {
158  if (const auto *C = dyn_cast<CaseStmt>(Label)) {
159  Out << CR << "case ";
160  if (C->getLHS())
161  C->getLHS()->printPretty(
162  Out, nullptr, Context.getPrintingPolicy(),
163  /*Indentation=*/0, /*NewlineSymbol=*/CR);
164 
165  if (const Stmt *RHS = C->getRHS()) {
166  Out << " .. ";
167  RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
168  /*Indetation=*/0, /*NewlineSymbol=*/CR);
169  }
170 
171  Out << ":";
172  } else {
173  assert(isa<DefaultStmt>(Label));
174  Out << CR << "default:";
175  }
176  } else
177  Out << CR << "(implicit) default:";
178  } else if (isa<IndirectGotoStmt>(T)) {
179  // FIXME
180  } else {
181  Out << CR << "Condition: ";
182  if (*E.getSrc()->succ_begin() == E.getDst())
183  Out << "true";
184  else
185  Out << "false";
186  }
187 
188  Out << CR;
189  }
190 
191  break;
192  }
193 
194  default: {
195  const Stmt *S = castAs<StmtPoint>().getStmt();
196  assert(S != nullptr && "Expecting non-null Stmt");
197 
198  Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"
199  << (const void *)S << "> ";
200  S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
201  /*Indentation=*/2, /*NewlineSymbol=*/CR);
202  printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");
203 
204  if (getAs<PreStmt>())
205  Out << CR << "PreStmt" << CR;
206  else if (getAs<PostLoad>())
207  Out << CR << "PostLoad" << CR;
208  else if (getAs<PostStore>())
209  Out << CR << "PostStore" << CR;
210  else if (getAs<PostLValue>())
211  Out << CR << "PostLValue" << CR;
212  else if (getAs<PostAllocatorCall>())
213  Out << CR << "PostAllocatorCall" << CR;
214 
215  break;
216  }
217  }
218 }
219 
221  StringRef Msg)
222  : Desc((MsgProvider + " : " + Msg).str()) {}
223 
225  return Desc;
226 }
A (possibly-)qualified type.
Definition: Type.h:634
succ_iterator succ_begin()
Definition: CFG.h:750
Stmt - This represents one statement.
Definition: Stmt.h:65
unsigned getBlockID() const
Definition: CFG.h:855
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:512
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
Definition: ProgramPoint.h:474
Represents a point when we exit a loop.
Definition: ProgramPoint.h:714
Represents an implicit call event.
Definition: ProgramPoint.h:560
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: Type.h:873
const char * getStmtClassName() const
Definition: Stmt.cpp:74
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:263
Represents a member of a struct/union/class.
Definition: Decl.h:2578
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
Definition: DeclCXX.h:2393
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
Definition: CFG.cpp:5461
LLVM_DUMP_METHOD void dump() const
SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg)
SourceLocation getLocation() const
Definition: ProgramPoint.h:567
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
StringRef getTagDescription() const override
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:653
Represents a point after we ran remove dead bindings AFTER processing the given statement.
Definition: ProgramPoint.h:490
FieldDecl * getAnyMember() const
Definition: DeclCXX.h:2405
void print(StringRef CR, llvm::raw_ostream &Out) const
return Out str()
static void printLocation(raw_ostream &Out, SourceLocation SLoc, const SourceManager &SM, StringRef CR, StringRef Postfix)
std::string Label
const CFGBlock * getDst() const
Definition: ProgramPoint.h:516
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2462
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const SourceManager & SM
Definition: Format.cpp:1489
CFGTerminator getTerminator()
Definition: CFG.h:839
const Stmt * getLoopStmt() const
Definition: ProgramPoint.h:719
Encodes a location in the source.
Stmt * getLabel()
Definition: CFG.h:850
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:39
int64_t getID(const ASTContext &Context) const
Definition: Stmt.cpp:288
const Decl * getDecl() const
Definition: ProgramPoint.h:566
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Dataflow Directional Tag Classes.
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2263
SourceManager & getSourceManager()
Definition: ASTContext.h:661
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:956
const LangOptions & getLangOpts() const
Definition: ASTContext.h:706
This class handles loading and caching of source files into memory.
QualType getType() const
Return the type wrapped by this type source info.
Definition: Decl.h:97