clang API Documentation
00001 //== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a summary of a function gathered/used by static analysis. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H 00015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H 00016 00017 #include "clang/Basic/LLVM.h" 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "llvm/ADT/DenseSet.h" 00020 #include "llvm/ADT/Optional.h" 00021 #include "llvm/ADT/SmallBitVector.h" 00022 #include <deque> 00023 00024 namespace clang { 00025 class Decl; 00026 00027 namespace ento { 00028 typedef std::deque<Decl*> SetOfDecls; 00029 typedef llvm::DenseSet<const Decl*> SetOfConstDecls; 00030 00031 class FunctionSummariesTy { 00032 class FunctionSummary { 00033 public: 00034 /// Marks the IDs of the basic blocks visited during the analyzes. 00035 llvm::SmallBitVector VisitedBasicBlocks; 00036 00037 /// Total number of blocks in the function. 00038 unsigned TotalBasicBlocks : 30; 00039 00040 /// True if this function has been checked against the rules for which 00041 /// functions may be inlined. 00042 unsigned InlineChecked : 1; 00043 00044 /// True if this function may be inlined. 00045 unsigned MayInline : 1; 00046 00047 /// The number of times the function has been inlined. 00048 unsigned TimesInlined : 32; 00049 00050 FunctionSummary() : 00051 TotalBasicBlocks(0), 00052 InlineChecked(0), 00053 TimesInlined(0) {} 00054 }; 00055 00056 typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy; 00057 MapTy Map; 00058 00059 public: 00060 MapTy::iterator findOrInsertSummary(const Decl *D) { 00061 MapTy::iterator I = Map.find(D); 00062 if (I != Map.end()) 00063 return I; 00064 00065 typedef std::pair<const Decl *, FunctionSummary> KVPair; 00066 I = Map.insert(KVPair(D, FunctionSummary())).first; 00067 assert(I != Map.end()); 00068 return I; 00069 } 00070 00071 void markMayInline(const Decl *D) { 00072 MapTy::iterator I = findOrInsertSummary(D); 00073 I->second.InlineChecked = 1; 00074 I->second.MayInline = 1; 00075 } 00076 00077 void markShouldNotInline(const Decl *D) { 00078 MapTy::iterator I = findOrInsertSummary(D); 00079 I->second.InlineChecked = 1; 00080 I->second.MayInline = 0; 00081 } 00082 00083 void markReachedMaxBlockCount(const Decl *D) { 00084 markShouldNotInline(D); 00085 } 00086 00087 Optional<bool> mayInline(const Decl *D) { 00088 MapTy::const_iterator I = Map.find(D); 00089 if (I != Map.end() && I->second.InlineChecked) 00090 return I->second.MayInline; 00091 return None; 00092 } 00093 00094 void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { 00095 MapTy::iterator I = findOrInsertSummary(D); 00096 llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks; 00097 assert(ID < TotalIDs); 00098 if (TotalIDs > Blocks.size()) { 00099 Blocks.resize(TotalIDs); 00100 I->second.TotalBasicBlocks = TotalIDs; 00101 } 00102 Blocks.set(ID); 00103 } 00104 00105 unsigned getNumVisitedBasicBlocks(const Decl* D) { 00106 MapTy::const_iterator I = Map.find(D); 00107 if (I != Map.end()) 00108 return I->second.VisitedBasicBlocks.count(); 00109 return 0; 00110 } 00111 00112 unsigned getNumTimesInlined(const Decl* D) { 00113 MapTy::const_iterator I = Map.find(D); 00114 if (I != Map.end()) 00115 return I->second.TimesInlined; 00116 return 0; 00117 } 00118 00119 void bumpNumTimesInlined(const Decl* D) { 00120 MapTy::iterator I = findOrInsertSummary(D); 00121 I->second.TimesInlined++; 00122 } 00123 00124 /// Get the percentage of the reachable blocks. 00125 unsigned getPercentBlocksReachable(const Decl *D) { 00126 MapTy::const_iterator I = Map.find(D); 00127 if (I != Map.end()) 00128 return ((I->second.VisitedBasicBlocks.count() * 100) / 00129 I->second.TotalBasicBlocks); 00130 return 0; 00131 } 00132 00133 unsigned getTotalNumBasicBlocks(); 00134 unsigned getTotalNumVisitedBasicBlocks(); 00135 00136 }; 00137 00138 }} // end clang ento namespaces 00139 00140 #endif