std::string getClangRepositoryPath() { #ifdef SVN_REPOSITORY llvm::StringRef URL(SVN_REPOSITORY); #else llvm::StringRef URL(""); #endif // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. static llvm::StringRef SVNRepository("$URL$"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); } // Strip off version from a build from an integration branch. URL = URL.slice(0, URL.find("/src/tools/clang")); // Trim path prefix off, assuming path came from standard cfe path. size_t Start = URL.find("cfe/"); if (Start != llvm::StringRef::npos) URL = URL.substr(Start + 4); return URL; }
PythonObject PythonObject::ResolveName(llvm::StringRef name) const { // Resolve the name in the context of the specified object. If, for example, // `this` refers to a PyModule, then this will look for `name` in this // module. If `this` refers to a PyType, then it will resolve `name` as an // attribute of that type. If `this` refers to an instance of an object, // then it will resolve `name` as the value of the specified field. // // This function handles dotted names so that, for example, if `m_py_obj` // refers to the `sys` module, and `name` == "path.append", then it will find // the function `sys.path.append`. size_t dot_pos = name.find('.'); if (dot_pos == llvm::StringRef::npos) { // No dots in the name, we should be able to find the value immediately as // an attribute of `m_py_obj`. return GetAttributeValue(name); } // Look up the first piece of the name, and resolve the rest as a child of // that. PythonObject parent = ResolveName(name.substr(0, dot_pos)); if (!parent.IsAllocated()) return PythonObject(); // Tail recursion.. should be optimized by the compiler return parent.ResolveName(name.substr(dot_pos + 1)); }
/// HandleComment - Hook into the preprocessor and extract comments containing /// expected errors and warnings. bool VerifyDiagnosticConsumer::HandleComment(Lexer &PP, const SourceLocation& CommentBegin, const llvm::StringRef &C) { const llvm::SourceMgr &SM = PP.getSourceManager(); // If this comment is for a different source manager, ignore it. if (SrcManager && &SM != SrcManager) return false; if (C.empty()) return false; // Fold any "\<EOL>" sequences size_t loc = C.find('\\'); if (loc == StringRef::npos) { ParseDirective(C, &ED, SM, &PP, CommentBegin, Status); return false; } std::string C2; C2.reserve(C.size()); for (size_t last = 0;; loc = C.find('\\', last)) { if (loc == StringRef::npos || loc == C.size()) { C2 += C.substr(last); break; } C2 += C.substr(last, loc-last); last = loc + 1; if (C[last] == '\n' || C[last] == '\r') { ++last; // Escape \r\n or \n\r, but not \n\n. if (last < C.size()) if (C[last] == '\n' || C[last] == '\r') if (C[last] != C[last-1]) ++last; } else { // This was just a normal backslash. C2 += '\\'; } } if (!C2.empty()) ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status); return false; }
// Return the index to RSA if found; otherwise -1 is returned. static int32_t WithRSAIndex(llvm::StringRef &Arg) { uint32_t i; for (i = 0; i < 4; ++i) if (Arg.find(RSA[i]) != llvm::StringRef::npos) return i; return -1; }
bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) { #if defined(__APPLE__) || defined(__CYGWIN__) Paths.push_back("/usr/local/lib/"); Paths.push_back("/usr/X11R6/lib/"); Paths.push_back("/usr/lib/"); Paths.push_back("/lib/"); #ifndef __APPLE__ Paths.push_back("/lib/x86_64-linux-gnu/"); Paths.push_back("/usr/local/lib64/"); Paths.push_back("/usr/lib64/"); Paths.push_back("/lib64/"); #endif #else llvm::SmallString<1024> Buf; platform::Popen("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls", Buf, true); const llvm::StringRef Result = Buf.str(); const std::size_t NPos = std::string::npos; const std::size_t LD = Result.find("(LD_LIBRARY_PATH)"); std::size_t From = Result.find("search path=", LD == NPos ? 0 : LD); if (From != NPos) { const std::size_t To = Result.find("(system search path)", From); if (To != NPos) { From += 12; std::string SysPath = Result.substr(From, To-From); SysPath.erase(std::remove_if(SysPath.begin(), SysPath.end(), isspace), SysPath.end()); llvm::SmallVector<llvm::StringRef, 10> CurPaths; SplitPaths(SysPath, CurPaths); for (const auto& Path : CurPaths) Paths.push_back(Path.str()); } } #endif return true; }
PythonObject PythonObject::ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict) { size_t dot_pos = name.find('.'); llvm::StringRef piece = name.substr(0, dot_pos); PythonObject result = dict.GetItemForKey(PythonString(piece)); if (dot_pos == llvm::StringRef::npos) { // There was no dot, we're done. return result; } // There was a dot. The remaining portion of the name should be looked up in // the context of the object that was found in the dictionary. return result.ResolveName(name.substr(dot_pos + 1)); }
static bool opstring(llvm::SmallString<16> &x) { const char *p = save(); const char *q = p; char y; while (next(y)) { if (opchars.find(y) != llvm::StringRef::npos) q = save(); else break; } restore(q); if (p == q) return false; x = llvm::StringRef(p,q-p); return true; }
void InitHeaderSearch::AddDelimitedPaths(llvm::StringRef at) { if (at.empty()) // Empty string should not add '.' path. return; llvm::StringRef::size_type delim; while ((delim = at.find(llvm::sys::PathSeparator)) != llvm::StringRef::npos) { if (delim == 0) AddPath(".", Angled, false, true, false); else AddPath(at.substr(0, delim), Angled, false, true, false); at = at.substr(delim + 1); } if (at.empty()) AddPath(".", Angled, false, true, false); else AddPath(at, Angled, false, true, false); }
bool IncrementalExecutor::diagnoseUnresolvedSymbols(llvm::StringRef trigger, llvm::StringRef title) { if (m_unresolvedSymbols.empty()) return false; llvm::SmallVector<llvm::Function*, 128> funcsToFree; for (std::set<std::string>::const_iterator i = m_unresolvedSymbols.begin(), e = m_unresolvedSymbols.end(); i != e; ++i) { #if 0 // FIXME: This causes a lot of test failures, for some reason it causes // the call to HandleMissingFunction to be elided. unsigned diagID = m_Diags.getCustomDiagID(clang::DiagnosticsEngine::Error, "%0 unresolved while jitting %1"); (void)diagID; //m_Diags.Report(diagID) << *i << funcname; // TODO: demangle the names. #endif llvm::errs() << "IncrementalExecutor::executeFunction: symbol '" << *i << "' unresolved while linking "; if (trigger.find(utils::Synthesize::UniquePrefix) != llvm::StringRef::npos) llvm::errs() << "[cling interface function]"; else { if (!title.empty()) llvm::errs() << title << " '"; llvm::errs() << trigger; if (!title.empty()) llvm::errs() << "'"; } llvm::errs() << "!\n"; // Be helpful, demangle! std::string demangledName; { #ifndef LLVM_ON_WIN32 int status = 0; char *demang = abi::__cxa_demangle(i->c_str(), 0, 0, &status); if (status == 0) demangledName = demang; free(demang); #else if (char* demang = __unDName(0, i->c_str(), 0, malloc, free, 0)) { demangledName = demang; free(demang); } #endif } if (!demangledName.empty()) { llvm::errs() << "You are probably missing the definition of " << demangledName << "\n" << "Maybe you need to load the corresponding shared library?\n"; } //llvm::Function *ff = m_engine->FindFunctionNamed(i->c_str()); // i could also reference a global variable, in which case ff == 0. //if (ff) // funcsToFree.push_back(ff); } //freeCallersOfUnresolvedSymbols(funcsToFree, m_engine.get()); m_unresolvedSymbols.clear(); return true; }
bool needsQuotes(const llvm::StringRef &arg) { return // not already quoted !(arg.size() > 1 && arg[0] == '"' && arg.back() == '"') && // empty or min 1 space or min 1 double quote (arg.empty() || arg.find(' ') != arg.npos || arg.find('"') != arg.npos); }
void InefficientAlgorithmCheck::check(const MatchFinder::MatchResult &Result) { const auto *AlgCall = Result.Nodes.getNodeAs<CallExpr>("IneffAlg"); const auto *IneffCont = Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("IneffCont"); bool PtrToContainer = false; if (!IneffCont) { IneffCont = Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("IneffContPtr"); PtrToContainer = true; } const llvm::StringRef IneffContName = IneffCont->getName(); const bool Unordered = IneffContName.find("unordered") != llvm::StringRef::npos; const bool Maplike = IneffContName.find("map") != llvm::StringRef::npos; // Store if the key type of the container is compatible with the value // that is searched for. QualType ValueType = AlgCall->getArg(2)->getType(); QualType KeyType = IneffCont->getTemplateArgs()[0].getAsType().getCanonicalType(); const bool CompatibleTypes = areTypesCompatible(KeyType, ValueType); // Check if the comparison type for the algorithm and the container matches. if (AlgCall->getNumArgs() == 4 && !Unordered) { const Expr *Arg = AlgCall->getArg(3); const QualType AlgCmp = Arg->getType().getUnqualifiedType().getCanonicalType(); const unsigned CmpPosition = (IneffContName.find("map") == llvm::StringRef::npos) ? 1 : 2; const QualType ContainerCmp = IneffCont->getTemplateArgs()[CmpPosition] .getAsType() .getUnqualifiedType() .getCanonicalType(); if (AlgCmp != ContainerCmp) { diag(Arg->getLocStart(), "different comparers used in the algorithm and the container"); return; } } const auto *AlgDecl = AlgCall->getDirectCallee(); if (!AlgDecl) return; if (Unordered && AlgDecl->getName().find("bound") != llvm::StringRef::npos) return; const auto *AlgParam = Result.Nodes.getNodeAs<Expr>("AlgParam"); const auto *IneffContExpr = Result.Nodes.getNodeAs<Expr>("IneffContExpr"); FixItHint Hint; SourceManager &SM = *Result.SourceManager; LangOptions LangOpts = Result.Context->getLangOpts(); CharSourceRange CallRange = CharSourceRange::getTokenRange(AlgCall->getSourceRange()); // FIXME: Create a common utility to extract a file range that the given token // sequence is exactly spelled at (without macro argument expansions etc.). // We can't use Lexer::makeFileCharRange here, because for // // #define F(x) x // x(a b c); // // it will return "x(a b c)", when given the range "a"-"c". It makes sense for // removals, but not for replacements. // // This code is over-simplified, but works for many real cases. if (SM.isMacroArgExpansion(CallRange.getBegin()) && SM.isMacroArgExpansion(CallRange.getEnd())) { CallRange.setBegin(SM.getSpellingLoc(CallRange.getBegin())); CallRange.setEnd(SM.getSpellingLoc(CallRange.getEnd())); } if (!CallRange.getBegin().isMacroID() && !Maplike && CompatibleTypes) { StringRef ContainerText = Lexer::getSourceText( CharSourceRange::getTokenRange(IneffContExpr->getSourceRange()), SM, LangOpts); StringRef ParamText = Lexer::getSourceText( CharSourceRange::getTokenRange(AlgParam->getSourceRange()), SM, LangOpts); std::string ReplacementText = (llvm::Twine(ContainerText) + (PtrToContainer ? "->" : ".") + AlgDecl->getName() + "(" + ParamText + ")") .str(); Hint = FixItHint::CreateReplacement(CallRange, ReplacementText); } diag(AlgCall->getLocStart(), "this STL algorithm call should be replaced with a container method") << Hint; }