blob: 244fe4ac9e70385ceb2a6ad70fc8b078c6bf5948 [file] [log] [blame]
//===- subzero/src/IceRangeSpec.h - Include/exclude specs -------*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares a class for specifying inclusion/exclusion of values, such
/// as functions to match.
///
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICERANGESPEC_H
#define SUBZERO_SRC_ICERANGESPEC_H
#include "IceStringPool.h"
#include <string>
#include <unordered_set>
#include <vector>
#include "llvm/ADT/BitVector.h"
namespace Ice {
class RangeSpec {
RangeSpec(const RangeSpec &) = delete;
RangeSpec &operator=(const RangeSpec &) = delete;
public:
static constexpr char DELIM_LIST = ',';
static constexpr char DELIM_RANGE = ':';
static constexpr uint32_t RangeMax = std::numeric_limits<uint32_t>::max();
RangeSpec() = default;
struct Desc {
// Set of names explicitly provided.
std::unordered_set<std::string> Names;
// Set of numbers explicitly provided.
llvm::BitVector Numbers;
// The smallest X for which the open-ended interval "X:" was provided. This
// is needed because the intervals are parsed before we know the largest
// number that might be matched against, and we can't make the Numbers
// bitvector infinitely long.
uint32_t AllFrom = RangeMax;
// Whether a clause was explicitly provided.
bool IsExplicit = false;
};
void init(const std::string &Spec);
bool match(const std::string &Name, uint32_t Number) const;
bool match(GlobalString Name, uint32_t Number) const {
return match(Name.toStringOrEmpty(), Number);
}
// Returns true if any RangeSpec object has had init() called with an explicit
// name rather than (or in addition to) a numeric range. If so, we want to
// construct explicit names for functions even in a non-DUMP build so that
// matching on function name works correctly. Note that this is not
// thread-safe, so we count on all this being handled by the startup thread.
static bool hasNames() { return HasNames; }
// Helper function to tokenize a string into a vector of string tokens, given
// a single delimiter character. An empty string produces an empty token
// vector. Zero-length tokens are allowed, e.g. ",a,,,b," may tokenize to
// {"","a","","","b",""}.
static std::vector<std::string> tokenize(const std::string &Spec,
char Delimiter);
private:
void include(const std::string &Token);
void exclude(const std::string &Token);
Desc Includes;
Desc Excludes;
static bool HasNames;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICERANGESPEC_H