clang API Documentation
00001 //== CheckerContext.cpp - Context info for path-sensitive checkers-----------=// 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 CheckerContext that provides contextual info for 00011 // path-sensitive checkers. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 00016 #include "clang/Basic/Builtins.h" 00017 #include "clang/Lex/Lexer.h" 00018 00019 using namespace clang; 00020 using namespace ento; 00021 00022 const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const { 00023 ProgramStateRef State = getState(); 00024 const Expr *Callee = CE->getCallee(); 00025 SVal L = State->getSVal(Callee, Pred->getLocationContext()); 00026 return L.getAsFunctionDecl(); 00027 } 00028 00029 StringRef CheckerContext::getCalleeName(const FunctionDecl *FunDecl) const { 00030 if (!FunDecl) 00031 return StringRef(); 00032 IdentifierInfo *funI = FunDecl->getIdentifier(); 00033 if (!funI) 00034 return StringRef(); 00035 return funI->getName(); 00036 } 00037 00038 00039 bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, 00040 StringRef Name) { 00041 return isCLibraryFunction(FD, Name, getASTContext()); 00042 } 00043 00044 bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, 00045 StringRef Name, ASTContext &Context) { 00046 // To avoid false positives (Ex: finding user defined functions with 00047 // similar names), only perform fuzzy name matching when it's a builtin. 00048 // Using a string compare is slow, we might want to switch on BuiltinID here. 00049 unsigned BId = FD->getBuiltinID(); 00050 if (BId != 0) { 00051 StringRef BName = Context.BuiltinInfo.GetName(BId); 00052 if (BName.find(Name) != StringRef::npos) 00053 return true; 00054 } 00055 00056 const IdentifierInfo *II = FD->getIdentifier(); 00057 // If this is a special C++ name without IdentifierInfo, it can't be a 00058 // C library function. 00059 if (!II) 00060 return false; 00061 00062 StringRef FName = II->getName(); 00063 if (FName.equals(Name)) 00064 return true; 00065 00066 if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) 00067 return true; 00068 00069 if (FName.startswith("__") && FName.endswith("_chk") && 00070 FName.find(Name) != StringRef::npos) 00071 return true; 00072 00073 return false; 00074 } 00075 00076 StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) { 00077 if (Loc.isMacroID()) 00078 return Lexer::getImmediateMacroName(Loc, getSourceManager(), 00079 getLangOpts()); 00080 SmallVector<char, 16> buf; 00081 return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts()); 00082 } 00083