Path: blob/main/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp
35233 views
//===--- ProfileList.h - ProfileList filter ---------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// User-provided filters include/exclude profile instrumentation in certain9// functions or files.10//11//===----------------------------------------------------------------------===//1213#include "clang/Basic/ProfileList.h"14#include "clang/Basic/FileManager.h"15#include "clang/Basic/SourceManager.h"16#include "llvm/Support/SpecialCaseList.h"1718#include "llvm/Support/raw_ostream.h"19#include <optional>2021using namespace clang;2223namespace clang {2425class ProfileSpecialCaseList : public llvm::SpecialCaseList {26public:27static std::unique_ptr<ProfileSpecialCaseList>28create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,29std::string &Error);3031static std::unique_ptr<ProfileSpecialCaseList>32createOrDie(const std::vector<std::string> &Paths,33llvm::vfs::FileSystem &VFS);3435bool isEmpty() const { return Sections.empty(); }3637bool hasPrefix(StringRef Prefix) const {38for (const auto &It : Sections)39if (It.second.Entries.count(Prefix) > 0)40return true;41return false;42}43};4445std::unique_ptr<ProfileSpecialCaseList>46ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,47llvm::vfs::FileSystem &VFS,48std::string &Error) {49auto PSCL = std::make_unique<ProfileSpecialCaseList>();50if (PSCL->createInternal(Paths, VFS, Error))51return PSCL;52return nullptr;53}5455std::unique_ptr<ProfileSpecialCaseList>56ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,57llvm::vfs::FileSystem &VFS) {58std::string Error;59if (auto PSCL = create(Paths, VFS, Error))60return PSCL;61llvm::report_fatal_error(llvm::Twine(Error));62}6364}6566ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM)67: SCL(ProfileSpecialCaseList::createOrDie(68Paths, SM.getFileManager().getVirtualFileSystem())),69Empty(SCL->isEmpty()), SM(SM) {}7071ProfileList::~ProfileList() = default;7273static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) {74switch (Kind) {75case CodeGenOptions::ProfileNone:76return "";77case CodeGenOptions::ProfileClangInstr:78return "clang";79case CodeGenOptions::ProfileIRInstr:80return "llvm";81case CodeGenOptions::ProfileCSIRInstr:82return "csllvm";83}84llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum");85}8687ProfileList::ExclusionType88ProfileList::getDefault(CodeGenOptions::ProfileInstrKind Kind) const {89StringRef Section = getSectionName(Kind);90// Check for "default:<type>"91if (SCL->inSection(Section, "default", "allow"))92return Allow;93if (SCL->inSection(Section, "default", "skip"))94return Skip;95if (SCL->inSection(Section, "default", "forbid"))96return Forbid;97// If any cases use "fun" or "src", set the default to FORBID.98if (SCL->hasPrefix("fun") || SCL->hasPrefix("src"))99return Forbid;100return Allow;101}102103std::optional<ProfileList::ExclusionType>104ProfileList::inSection(StringRef Section, StringRef Prefix,105StringRef Query) const {106if (SCL->inSection(Section, Prefix, Query, "allow"))107return Allow;108if (SCL->inSection(Section, Prefix, Query, "skip"))109return Skip;110if (SCL->inSection(Section, Prefix, Query, "forbid"))111return Forbid;112if (SCL->inSection(Section, Prefix, Query))113return Allow;114return std::nullopt;115}116117std::optional<ProfileList::ExclusionType>118ProfileList::isFunctionExcluded(StringRef FunctionName,119CodeGenOptions::ProfileInstrKind Kind) const {120StringRef Section = getSectionName(Kind);121// Check for "function:<regex>=<case>"122if (auto V = inSection(Section, "function", FunctionName))123return V;124if (SCL->inSection(Section, "!fun", FunctionName))125return Forbid;126if (SCL->inSection(Section, "fun", FunctionName))127return Allow;128return std::nullopt;129}130131std::optional<ProfileList::ExclusionType>132ProfileList::isLocationExcluded(SourceLocation Loc,133CodeGenOptions::ProfileInstrKind Kind) const {134return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind);135}136137std::optional<ProfileList::ExclusionType>138ProfileList::isFileExcluded(StringRef FileName,139CodeGenOptions::ProfileInstrKind Kind) const {140StringRef Section = getSectionName(Kind);141// Check for "source:<regex>=<case>"142if (auto V = inSection(Section, "source", FileName))143return V;144if (SCL->inSection(Section, "!src", FileName))145return Forbid;146if (SCL->inSection(Section, "src", FileName))147return Allow;148return std::nullopt;149}150151152