1221339Sdim//== CheckerContext.cpp - Context info for path-sensitive checkers-----------=// 2221339Sdim// 3221339Sdim// The LLVM Compiler Infrastructure 4221339Sdim// 5221339Sdim// This file is distributed under the University of Illinois Open Source 6221339Sdim// License. See LICENSE.TXT for details. 7221339Sdim// 8221339Sdim//===----------------------------------------------------------------------===// 9221339Sdim// 10221339Sdim// This file defines CheckerContext that provides contextual info for 11221339Sdim// path-sensitive checkers. 12221339Sdim// 13221339Sdim//===----------------------------------------------------------------------===// 14221339Sdim 15221339Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 16235633Sdim#include "clang/Basic/Builtins.h" 17235633Sdim#include "clang/Lex/Lexer.h" 18235633Sdim 19221339Sdimusing namespace clang; 20221339Sdimusing namespace ento; 21221339Sdim 22235633Sdimconst FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const { 23235633Sdim ProgramStateRef State = getState(); 24235633Sdim const Expr *Callee = CE->getCallee(); 25235633Sdim SVal L = State->getSVal(Callee, Pred->getLocationContext()); 26235633Sdim return L.getAsFunctionDecl(); 27235633Sdim} 28235633Sdim 29235633SdimStringRef CheckerContext::getCalleeName(const FunctionDecl *FunDecl) const { 30235633Sdim if (!FunDecl) 31235633Sdim return StringRef(); 32235633Sdim IdentifierInfo *funI = FunDecl->getIdentifier(); 33235633Sdim if (!funI) 34235633Sdim return StringRef(); 35235633Sdim return funI->getName(); 36235633Sdim} 37235633Sdim 38235633Sdim 39235633Sdimbool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, 40235633Sdim StringRef Name) { 41235633Sdim // To avoid false positives (Ex: finding user defined functions with 42235633Sdim // similar names), only perform fuzzy name matching when it's a builtin. 43235633Sdim // Using a string compare is slow, we might want to switch on BuiltinID here. 44235633Sdim unsigned BId = FD->getBuiltinID(); 45235633Sdim if (BId != 0) { 46245431Sdim if (Name.empty()) 47245431Sdim return true; 48245431Sdim StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId); 49235633Sdim if (BName.find(Name) != StringRef::npos) 50235633Sdim return true; 51221339Sdim } 52235633Sdim 53235633Sdim const IdentifierInfo *II = FD->getIdentifier(); 54235633Sdim // If this is a special C++ name without IdentifierInfo, it can't be a 55235633Sdim // C library function. 56235633Sdim if (!II) 57235633Sdim return false; 58235633Sdim 59245431Sdim // Look through 'extern "C"' and anything similar invented in the future. 60245431Sdim const DeclContext *DC = FD->getDeclContext(); 61245431Sdim while (DC->isTransparentContext()) 62245431Sdim DC = DC->getParent(); 63245431Sdim 64245431Sdim // If this function is in a namespace, it is not a C library function. 65245431Sdim if (!DC->isTranslationUnit()) 66245431Sdim return false; 67245431Sdim 68245431Sdim // If this function is not externally visible, it is not a C library function. 69245431Sdim // Note that we make an exception for inline functions, which may be 70245431Sdim // declared in header files without external linkage. 71263509Sdim if (!FD->isInlined() && !FD->isExternallyVisible()) 72245431Sdim return false; 73245431Sdim 74245431Sdim if (Name.empty()) 75245431Sdim return true; 76245431Sdim 77235633Sdim StringRef FName = II->getName(); 78235633Sdim if (FName.equals(Name)) 79235633Sdim return true; 80235633Sdim 81235633Sdim if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) 82235633Sdim return true; 83235633Sdim 84235633Sdim if (FName.startswith("__") && FName.endswith("_chk") && 85235633Sdim FName.find(Name) != StringRef::npos) 86235633Sdim return true; 87235633Sdim 88235633Sdim return false; 89221339Sdim} 90235633Sdim 91235633SdimStringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) { 92235633Sdim if (Loc.isMacroID()) 93235633Sdim return Lexer::getImmediateMacroName(Loc, getSourceManager(), 94235633Sdim getLangOpts()); 95235633Sdim SmallVector<char, 16> buf; 96235633Sdim return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts()); 97235633Sdim} 98235633Sdim 99