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 // To avoid false positives (Ex: finding user defined functions with 00042 // similar names), only perform fuzzy name matching when it's a builtin. 00043 // Using a string compare is slow, we might want to switch on BuiltinID here. 00044 unsigned BId = FD->getBuiltinID(); 00045 if (BId != 0) { 00046 if (Name.empty()) 00047 return true; 00048 StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId); 00049 if (BName.find(Name) != StringRef::npos) 00050 return true; 00051 } 00052 00053 const IdentifierInfo *II = FD->getIdentifier(); 00054 // If this is a special C++ name without IdentifierInfo, it can't be a 00055 // C library function. 00056 if (!II) 00057 return false; 00058 00059 // Look through 'extern "C"' and anything similar invented in the future. 00060 const DeclContext *DC = FD->getDeclContext(); 00061 while (DC->isTransparentContext()) 00062 DC = DC->getParent(); 00063 00064 // If this function is in a namespace, it is not a C library function. 00065 if (!DC->isTranslationUnit()) 00066 return false; 00067 00068 // If this function is not externally visible, it is not a C library function. 00069 // Note that we make an exception for inline functions, which may be 00070 // declared in header files without external linkage. 00071 if (!FD->isInlined() && !FD->isExternallyVisible()) 00072 return false; 00073 00074 if (Name.empty()) 00075 return true; 00076 00077 StringRef FName = II->getName(); 00078 if (FName.equals(Name)) 00079 return true; 00080 00081 if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) 00082 return true; 00083 00084 if (FName.startswith("__") && FName.endswith("_chk") && 00085 FName.find(Name) != StringRef::npos) 00086 return true; 00087 00088 return false; 00089 } 00090 00091 StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) { 00092 if (Loc.isMacroID()) 00093 return Lexer::getImmediateMacroName(Loc, getSourceManager(), 00094 getLangOpts()); 00095 SmallVector<char, 16> buf; 00096 return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts()); 00097 } 00098