clang  8.0.0svn
ProgramPoint.cpp
Go to the documentation of this file.
1 //==- ProgramPoint.cpp - Program Points for Path-Sensitive Analysis -*- C++ -*-/
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the interface ProgramPoint, which identifies a
11 // distinct location in a function.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 
17 using namespace clang;
18 
20 
22  const LocationContext *LC,
23  const ProgramPointTag *tag){
24  switch (K) {
25  default:
26  llvm_unreachable("Unhandled ProgramPoint kind");
28  return PreStmt(S, LC, tag);
30  return PostStmt(S, LC, tag);
32  return PreLoad(S, LC, tag);
34  return PostLoad(S, LC, tag);
36  return PreStore(S, LC, tag);
38  return PostLValue(S, LC, tag);
40  return PostStmtPurgeDeadSymbols(S, LC, tag);
42  return PreStmtPurgeDeadSymbols(S, LC, tag);
43  }
44 }
45 
46 LLVM_DUMP_METHOD void ProgramPoint::dump() const {
47  return print(/*CR=*/"\n", llvm::errs());
48 }
49 
50 static void printLocation(raw_ostream &Out, SourceLocation SLoc,
51  const SourceManager &SM,
52  StringRef CR,
53  StringRef Postfix) {
54  if (SLoc.isFileID()) {
55  Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)
56  << " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;
57  }
58 }
59 
60 void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {
61  const ASTContext &Context =
62  getLocationContext()->getAnalysisDeclContext()->getASTContext();
63  const SourceManager &SM = Context.getSourceManager();
64  switch (getKind()) {
66  Out << "Block Entrance: B"
67  << castAs<BlockEntrance>().getBlock()->getBlockID();
68  break;
69 
71  auto FEP = getAs<FunctionExitPoint>();
72  Out << "Function Exit: B" << FEP->getBlock()->getBlockID();
73  if (const ReturnStmt *RS = FEP->getStmt()) {
74  Out << CR << " Return: S" << RS->getID(Context) << CR;
75  RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
76  /*Indentation=*/2, /*NewlineSymbol=*/CR);
77  }
78  break;
79  }
81  assert(false);
82  break;
83 
85  Out << "CallEnter";
86  break;
87 
89  Out << "CallExitBegin";
90  break;
91 
93  Out << "CallExitEnd";
94  break;
95 
97  Out << "PostStmtPurgeDeadSymbols";
98  break;
99 
101  Out << "PreStmtPurgeDeadSymbols";
102  break;
103 
105  Out << "Epsilon Point";
106  break;
107 
109  LoopExit LE = castAs<LoopExit>();
110  Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
111  break;
112  }
113 
115  ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
116  Out << "PreCall: ";
117  PC.getDecl()->print(Out, Context.getLangOpts());
118  printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
119  break;
120  }
121 
123  ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
124  Out << "PostCall: ";
125  PC.getDecl()->print(Out, Context.getLangOpts());
126  printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
127  break;
128  }
129 
131  Out << "PostInitializer: ";
132  const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();
133  if (const FieldDecl *FD = Init->getAnyMember())
134  Out << *FD;
135  else {
136  QualType Ty = Init->getTypeSourceInfo()->getType();
137  Ty = Ty.getLocalUnqualifiedType();
138  Ty.print(Out, Context.getLangOpts());
139  }
140  break;
141  }
142 
144  const BlockEdge &E = castAs<BlockEdge>();
145  Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
146  << E.getDst()->getBlockID() << ')';
147 
148  if (const Stmt *T = E.getSrc()->getTerminator()) {
149  SourceLocation SLoc = T->getBeginLoc();
150 
151  Out << "\\|Terminator: ";
152  E.getSrc()->printTerminator(Out, Context.getLangOpts());
153  printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");
154 
155  if (isa<SwitchStmt>(T)) {
156  const Stmt *Label = E.getDst()->getLabel();
157 
158  if (Label) {
159  if (const auto *C = dyn_cast<CaseStmt>(Label)) {
160  Out << CR << "case ";
161  if (C->getLHS())
162  C->getLHS()->printPretty(
163  Out, nullptr, Context.getPrintingPolicy(),
164  /*Indentation=*/0, /*NewlineSymbol=*/CR);
165 
166  if (const Stmt *RHS = C->getRHS()) {
167  Out << " .. ";
168  RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
169  /*Indetation=*/0, /*NewlineSymbol=*/CR);
170  }
171 
172  Out << ":";
173  } else {
174  assert(isa<DefaultStmt>(Label));
175  Out << CR << "default:";
176  }
177  } else
178  Out << CR << "(implicit) default:";
179  } else if (isa<IndirectGotoStmt>(T)) {
180  // FIXME
181  } else {
182  Out << CR << "Condition: ";
183  if (*E.getSrc()->succ_begin() == E.getDst())
184  Out << "true";
185  else
186  Out << "false";
187  }
188 
189  Out << CR;
190  }
191 
192  break;
193  }
194 
195  default: {
196  const Stmt *S = castAs<StmtPoint>().getStmt();
197  assert(S != nullptr && "Expecting non-null Stmt");
198 
199  Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"
200  << (const void *)S << "> ";
201  S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
202  /*Indentation=*/2, /*NewlineSymbol=*/CR);
203  printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");
204 
205  if (getAs<PreStmt>())
206  Out << CR << "PreStmt" << CR;
207  else if (getAs<PostLoad>())
208  Out << CR << "PostLoad" << CR;
209  else if (getAs<PostStore>())
210  Out << CR << "PostStore" << CR;
211  else if (getAs<PostLValue>())
212  Out << CR << "PostLValue" << CR;
213  else if (getAs<PostAllocatorCall>())
214  Out << CR << "PostAllocatorCall" << CR;
215 
216  break;
217  }
218  }
219 }
220 
222  StringRef Msg)
223  : Desc((MsgProvider + " : " + Msg).str()) {}
224 
226  return Desc;
227 }
A (possibly-)qualified type.
Definition: Type.h:642
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:985
succ_iterator succ_begin()
Definition: CFG.h:751
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned getBlockID() const
Definition: CFG.h:856
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:513
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
Definition: ProgramPoint.h:475
Represents a point when we exit a loop.
Definition: ProgramPoint.h:715
Represents an implicit call event.
Definition: ProgramPoint.h:561
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: Type.h:881
const char * getStmtClassName() const
Definition: Stmt.cpp:75
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:280
Represents a member of a struct/union/class.
Definition: Decl.h:2575
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
Definition: DeclCXX.h:2380
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:568
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:491
FieldDecl * getAnyMember() const
Definition: DeclCXX.h:2392
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:517
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2197
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const SourceManager & SM
Definition: Format.cpp:1490
CFGTerminator getTerminator()
Definition: CFG.h:840
const Stmt * getLoopStmt() const
Definition: ProgramPoint.h:720
Encodes a location in the source.
Stmt * getLabel()
Definition: CFG.h:851
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
int64_t getID(const ASTContext &Context) const
Definition: Stmt.cpp:305
const Decl * getDecl() const
Definition: ProgramPoint.h:567
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Dataflow Directional Tag Classes.
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2253
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:954
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