mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Internal: Update clang_check_annotations conditions (#4134)
This commit is contained in:
parent
843fdd3e57
commit
65a484e00b
@ -693,7 +693,7 @@ std::string VL_DECIMAL_NW(int width, const WDataInP lwp) VL_MT_SAFE {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t width) {
|
||||
std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t width) VL_MT_SAFE {
|
||||
const VerilatedContextImp* const ctxImpp = Verilated::threadContextp()->impp();
|
||||
const std::string suffix = ctxImpp->timeFormatSuffix();
|
||||
const int userUnits = ctxImpp->timeFormatUnits(); // 0..-15
|
||||
|
@ -148,7 +148,7 @@ public:
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
|
||||
// METHODS
|
||||
static VerilatedThreadMsgQueue& threadton() {
|
||||
static VerilatedThreadMsgQueue& threadton() VL_MT_SAFE {
|
||||
static thread_local VerilatedThreadMsgQueue t_s;
|
||||
return t_s;
|
||||
}
|
||||
|
@ -603,8 +603,12 @@ reverse_wrapper<T> reverse_view(const T& v) {
|
||||
}
|
||||
|
||||
// C++17's std::as_const
|
||||
// `VL_MT_SAFE` annotation only applies to this function.
|
||||
// Object that is returned by this function is not considered
|
||||
// as MT_SAFE and any function call on this object still
|
||||
// needs to be `VL_MT_SAFE`.
|
||||
template <class T>
|
||||
T const& as_const(T& v) {
|
||||
T const& as_const(T& v) VL_MT_SAFE {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -49,14 +49,16 @@ class VlAnnotations:
|
||||
release: bool = False
|
||||
|
||||
def is_mt_safe_context(self):
|
||||
return (not (self.mt_unsafe or self.mt_unsafe_one)
|
||||
and (self.mt_safe or self.mt_start))
|
||||
return (not (self.mt_unsafe or self.mt_unsafe_one) and self.mt_safe)
|
||||
|
||||
def is_pure_context(self):
|
||||
return self.pure
|
||||
|
||||
def is_stabe_tree_context(self):
|
||||
return self.stable_tree
|
||||
# stable tree context requires calls to be marked
|
||||
# as MT_SAFE or MT_STABLE
|
||||
# Functions in MT_START needs to be MT_SAFE or MT_STABLE
|
||||
return self.stable_tree or self.mt_start
|
||||
|
||||
def is_mt_unsafe_call(self):
|
||||
return self.mt_unsafe or self.mt_unsafe_one
|
||||
@ -389,7 +391,8 @@ class CallAnnotationsValidator:
|
||||
|
||||
# stable tree context
|
||||
if ctx.is_stabe_tree_context():
|
||||
if not (annotations.is_stabe_tree_call()
|
||||
if annotations.is_mt_unsafe_call() or not (
|
||||
annotations.is_stabe_tree_call()
|
||||
or annotations.is_pure_call()
|
||||
or self.check_mt_safe_call(node, refd, annotations)):
|
||||
self.emit_diagnostic(
|
||||
@ -417,7 +420,8 @@ class CallAnnotationsValidator:
|
||||
|
||||
# stable tree context
|
||||
if ctx.is_stabe_tree_context():
|
||||
if not (annotations.is_pure_call()
|
||||
if annotations.is_mt_unsafe_call() or not (
|
||||
annotations.is_pure_call()
|
||||
or annotations.is_mt_safe_call()
|
||||
or annotations.is_stabe_tree_call()):
|
||||
self.emit_diagnostic(
|
||||
@ -465,11 +469,19 @@ class CallAnnotationsValidator:
|
||||
if not supported:
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
return True
|
||||
|
||||
assert refd is not None
|
||||
if self._is_ignored_call(refd):
|
||||
return
|
||||
return True
|
||||
|
||||
if "std::function" in refd.displayname:
|
||||
# Workaroud for missing support for lambda annotations
|
||||
# in c++11.
|
||||
# If function takes std::function as argument,
|
||||
# assume, that this std::function will be called inside it.
|
||||
self.process_function_definition(node)
|
||||
return False
|
||||
|
||||
assert self._call_location is not None
|
||||
node_file = os.path.abspath(node.location.file.name)
|
||||
@ -481,47 +493,40 @@ class CallAnnotationsValidator:
|
||||
or refd.kind == CursorKind.CXX_METHOD
|
||||
and refd.is_static_method()):
|
||||
self.process_function_call(refd, annotations)
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
# Function pointer
|
||||
if refd.kind in [
|
||||
elif refd.kind in [
|
||||
CursorKind.VAR_DECL, CursorKind.FIELD_DECL,
|
||||
CursorKind.PARM_DECL
|
||||
]:
|
||||
self.process_function_call(refd, annotations)
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
# Non-static class methods
|
||||
if refd.kind == CursorKind.CXX_METHOD:
|
||||
elif refd.kind == CursorKind.CXX_METHOD:
|
||||
self.process_method_call(node, refd, annotations)
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
# Conversion method (e.g. `operator int()`)
|
||||
if refd.kind == CursorKind.CONVERSION_FUNCTION:
|
||||
elif refd.kind == CursorKind.CONVERSION_FUNCTION:
|
||||
self.process_method_call(node, refd, annotations)
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
# Constructors
|
||||
if refd.kind == CursorKind.CONSTRUCTOR:
|
||||
elif refd.kind == CursorKind.CONSTRUCTOR:
|
||||
self.process_constructor_call(refd, annotations)
|
||||
self.iterate_children(node.get_children(),
|
||||
self.dispatch_node_inside_definition)
|
||||
return
|
||||
|
||||
# Ignore other callables
|
||||
print(f"{refd.location.file.name}:{refd.location.line}: "
|
||||
f"{refd.displayname} {refd.kind}\n"
|
||||
f" from: {node.location.file.name}:{node.location.line}")
|
||||
else:
|
||||
# Ignore other callables, but report them
|
||||
print("Unknown callable: "
|
||||
f"{refd.location.file.name}:{refd.location.line}: "
|
||||
f"{refd.displayname} {refd.kind}\n"
|
||||
f" from: {node.location.file.name}:{node.location.line}")
|
||||
return True
|
||||
|
||||
# Definition handling
|
||||
|
||||
def dispatch_node_inside_definition(self, node: clang.cindex.Cursor):
|
||||
if node.kind == CursorKind.CALL_EXPR:
|
||||
self.dispatch_call_node(node)
|
||||
if self.dispatch_call_node(node) is False:
|
||||
return None
|
||||
elif node.is_definition() and node.kind in [
|
||||
CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL,
|
||||
CursorKind.CONSTRUCTOR, CursorKind.CONVERSION_FUNCTION
|
||||
]:
|
||||
self.process_function_definition(node)
|
||||
return None
|
||||
|
||||
return self.iterate_children(node.get_children(),
|
||||
@ -556,12 +561,14 @@ class CallAnnotationsValidator:
|
||||
# for callees validation.
|
||||
self._caller = FunctionInfo.from_node(node, refd,
|
||||
def_annotations | annotations)
|
||||
prev_call_location = self._call_location
|
||||
self._call_location = self._caller
|
||||
|
||||
self.iterate_children(node_children,
|
||||
self.dispatch_node_inside_definition)
|
||||
|
||||
self._call_location = None
|
||||
self._call_location = prev_call_location
|
||||
self._caller = prev_call_location
|
||||
|
||||
return None
|
||||
|
||||
@ -826,7 +833,7 @@ class TopDownSummaryPrinter():
|
||||
elif func.reason == DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX:
|
||||
name += "is pure but calls non-pure function(s)"
|
||||
elif func.reason == DiagnosticKind.NON_STABLE_TREE_CALL_IN_STABLE_TREE_CTX:
|
||||
name += "calls stable_tree function(s) but isn't annotated as stable_tree"
|
||||
name += "is stable_tree but calls non-stable_tree or non-mtsafe"
|
||||
else:
|
||||
name += "for unknown reason (please add description)"
|
||||
|
||||
|
@ -54,7 +54,7 @@ private:
|
||||
const string m_name; // Only used for .dot file generation
|
||||
const VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT)
|
||||
|
||||
string typestr() const { // "
|
||||
string typestr() const VL_MT_SAFE { // "
|
||||
switch (m_type) {
|
||||
case VT_BLOCK: return "(||)"; // basic block node
|
||||
case VT_BRANCH: return "(&&)"; // if/else branch mode
|
||||
|
@ -285,7 +285,7 @@ string AstNode::vpiName(const string& namein) {
|
||||
return pretty;
|
||||
}
|
||||
|
||||
string AstNode::prettyTypeName() const {
|
||||
string AstNode::prettyTypeName() const VL_MT_STABLE {
|
||||
if (name() == "") return typeName();
|
||||
return std::string{typeName()} + " '" + prettyName() + "'";
|
||||
}
|
||||
|
@ -470,7 +470,7 @@ public:
|
||||
_ENUM_MAX
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
const char* ascii() const VL_MT_SAFE {
|
||||
static const char* const names[] = {"%E-unk",
|
||||
"bit",
|
||||
"byte",
|
||||
@ -1693,13 +1693,14 @@ public:
|
||||
static string prettyNameQ(const string& namein) { // Quoted pretty name (for errors)
|
||||
return std::string{"'"} + prettyName(namein) + "'";
|
||||
}
|
||||
static string
|
||||
encodeName(const string& namein); // Encode user name into internal C representation
|
||||
// Encode user name into internal C representation
|
||||
static string encodeName(const string& namein);
|
||||
static string encodeNumber(int64_t num); // Encode number into internal C representation
|
||||
static string vcdName(const string& namein); // Name for printing out to vcd files
|
||||
string prettyName() const VL_MT_STABLE { return prettyName(name()); }
|
||||
string prettyNameQ() const { return prettyNameQ(name()); }
|
||||
string prettyTypeName() const; // "VARREF" for error messages (NOT dtype's pretty name)
|
||||
// "VARREF" for error messages (NOT dtype's pretty name)
|
||||
string prettyTypeName() const VL_MT_STABLE;
|
||||
virtual string prettyOperatorName() const { return "operator " + prettyTypeName(); }
|
||||
FileLine* fileline() const VL_MT_SAFE { return m_fileline; }
|
||||
void fileline(FileLine* fl) { m_fileline = fl; }
|
||||
|
@ -1151,7 +1151,7 @@ public:
|
||||
void cloneRelink() override { V3ERROR_NA; }
|
||||
string name() const override VL_MT_STABLE { return "$root"; }
|
||||
void dump(std::ostream& str) const override;
|
||||
AstNodeModule* topModulep() const { // Top module in hierarchy
|
||||
AstNodeModule* topModulep() const VL_MT_STABLE { // Top module in hierarchy
|
||||
return modulesp(); // First one in the list, for now
|
||||
}
|
||||
AstTypeTable* typeTablep() { return m_typeTablep; }
|
||||
@ -1789,7 +1789,7 @@ public:
|
||||
string dpiTmpVarType(const string& varName) const;
|
||||
// Return Verilator internal type for argument: CData, SData, IData, WData
|
||||
string vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc = "",
|
||||
bool asRef = false) const VL_MT_SAFE;
|
||||
bool asRef = false) const VL_MT_STABLE;
|
||||
string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc
|
||||
string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc
|
||||
string vlPropDecl(const string& propName) const; // Return VerilatorVarProps declaration
|
||||
@ -2001,8 +2001,8 @@ public:
|
||||
string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); }
|
||||
void dump(std::ostream& str) const override;
|
||||
bool hasDType() const override { return true; }
|
||||
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
||||
AstScope* scopep() const { return m_scopep; } // Pointer to scope it's under
|
||||
AstVar* varp() const VL_MT_STABLE { return m_varp; } // [After Link] Pointer to variable
|
||||
AstScope* scopep() const VL_MT_STABLE { return m_scopep; } // Pointer to scope it's under
|
||||
void scopep(AstScope* nodep) { m_scopep = nodep; }
|
||||
bool isTrace() const { return m_trace; }
|
||||
void trace(bool flag) { m_trace = flag; }
|
||||
|
@ -397,7 +397,7 @@ string AstVar::verilogKwd() const {
|
||||
}
|
||||
|
||||
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc,
|
||||
bool asRef) const VL_MT_SAFE {
|
||||
bool asRef) const VL_MT_STABLE {
|
||||
UASSERT_OBJ(!forReturn, this,
|
||||
"Internal data is never passed as return, but as first argument");
|
||||
string ostatic;
|
||||
|
@ -55,14 +55,14 @@ public:
|
||||
return className + "* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<" + className
|
||||
+ "*>(voidSelf);\n";
|
||||
}
|
||||
static string symClassName() {
|
||||
static string symClassName() VL_MT_STABLE {
|
||||
return v3Global.opt.prefix() + "_" + VIdProtect::protect("_Syms");
|
||||
}
|
||||
static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; }
|
||||
static string symClassAssign() {
|
||||
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
|
||||
}
|
||||
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
|
||||
static string prefixNameProtect(const AstNode* nodep) VL_MT_STABLE { // C++ name with prefix
|
||||
return v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
|
||||
}
|
||||
static bool isAnonOk(const AstVar* varp) {
|
||||
|
@ -165,7 +165,7 @@ private:
|
||||
static FileLineSingleton s;
|
||||
return s;
|
||||
}
|
||||
static FileLine& defaultFileLine() {
|
||||
static FileLine& defaultFileLine() VL_MT_SAFE {
|
||||
static FileLine s;
|
||||
return s;
|
||||
}
|
||||
@ -364,7 +364,7 @@ public:
|
||||
private:
|
||||
string warnContext() const;
|
||||
string warnContextParent() const VL_REQUIRES(V3Error::s().m_mutex);
|
||||
const MsgEnBitSet& msgEn() const { return singleton().msgEn(m_msgEnIdx); }
|
||||
const MsgEnBitSet& msgEn() const VL_MT_SAFE { return singleton().msgEn(m_msgEnIdx); }
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, FileLine* fileline);
|
||||
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
~GateEitherVertex() override = default;
|
||||
// ACCESSORS
|
||||
string dotStyle() const override { return m_consumed ? "" : "dotted"; }
|
||||
AstScope* scopep() const { return m_scopep; }
|
||||
AstScope* scopep() const VL_MT_STABLE { return m_scopep; }
|
||||
bool reducible() const { return m_reducible; }
|
||||
bool dedupable() const { return m_dedupable; }
|
||||
void setConsumed(const char* /*consumedReason*/) {
|
||||
@ -133,7 +133,7 @@ public:
|
||||
, m_varScp{varScp} {}
|
||||
~GateVarVertex() override = default;
|
||||
// ACCESSORS
|
||||
AstVarScope* varScp() const { return m_varScp; }
|
||||
AstVarScope* varScp() const VL_MT_STABLE { return m_varScp; }
|
||||
string name() const override VL_MT_STABLE {
|
||||
return (cvtToHex(m_varScp) + " " + varScp()->name());
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ void V3Number::create(const char* sourcep) {
|
||||
// m_value[0]);
|
||||
}
|
||||
|
||||
void V3Number::nodep(AstNode* nodep) {
|
||||
void V3Number::nodep(AstNode* nodep) VL_MT_STABLE {
|
||||
m_nodep = nodep;
|
||||
if (!nodep) return;
|
||||
m_fileline = nodep->fileline();
|
||||
@ -498,7 +498,7 @@ V3Number& V3Number::setMask(int nbits) {
|
||||
//======================================================================
|
||||
// ACCESSORS - as strings
|
||||
|
||||
string V3Number::ascii(bool prefixed, bool cleanVerilog) const VL_MT_SAFE {
|
||||
string V3Number::ascii(bool prefixed, bool cleanVerilog) const VL_MT_STABLE {
|
||||
std::ostringstream out;
|
||||
|
||||
if (is1Step()) {
|
||||
@ -604,11 +604,11 @@ string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& i
|
||||
return left ? (in + padding) : (padding + in);
|
||||
}
|
||||
|
||||
string V3Number::displayed(AstNode* nodep, const string& vformat) const VL_MT_SAFE {
|
||||
string V3Number::displayed(AstNode* nodep, const string& vformat) const VL_MT_STABLE {
|
||||
return displayed(nodep->fileline(), vformat);
|
||||
}
|
||||
|
||||
string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_SAFE {
|
||||
string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STABLE {
|
||||
auto pos = vformat.cbegin();
|
||||
UASSERT(pos != vformat.cend() && pos[0] == '%',
|
||||
"$display-like function with non format argument " << *this);
|
||||
@ -847,7 +847,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_SAFE
|
||||
}
|
||||
}
|
||||
|
||||
string V3Number::toDecimalS() const {
|
||||
string V3Number::toDecimalS() const VL_MT_STABLE {
|
||||
if (isNegative()) {
|
||||
V3Number lhsNoSign = *this;
|
||||
lhsNoSign.opNegate(*this);
|
||||
@ -857,7 +857,7 @@ string V3Number::toDecimalS() const {
|
||||
}
|
||||
}
|
||||
|
||||
string V3Number::toDecimalU() const {
|
||||
string V3Number::toDecimalU() const VL_MT_STABLE {
|
||||
const int maxdecwidth = (width() + 3) * 4 / 3;
|
||||
|
||||
// Or (maxdecwidth+7)/8], but can't have more than 4 BCD bits per word
|
||||
@ -1013,7 +1013,7 @@ bool V3Number::isAllX() const VL_MT_SAFE {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool V3Number::isEqZero() const {
|
||||
bool V3Number::isEqZero() const VL_MT_SAFE {
|
||||
if (isString()) return m_data.str().empty();
|
||||
for (int i = 0; i < words(); i++) {
|
||||
const ValueAndX v = m_data.num()[i];
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
uint32_t m_value;
|
||||
// Each bit is true if it's X or Z, 10=z, 11=x
|
||||
uint32_t m_valueX;
|
||||
bool operator==(const ValueAndX& other) const {
|
||||
bool operator==(const ValueAndX& other) const VL_MT_SAFE {
|
||||
return m_value == other.m_value && m_valueX == other.m_valueX;
|
||||
}
|
||||
};
|
||||
@ -210,7 +210,7 @@ public:
|
||||
UASSERT(isString(), "`str` member accessed when data type is " << m_type);
|
||||
return m_string;
|
||||
}
|
||||
const std::string& str() const {
|
||||
const std::string& str() const VL_MT_SAFE {
|
||||
UASSERT(isString(), "`str` member accessed when data type is " << m_type);
|
||||
return m_string;
|
||||
}
|
||||
@ -356,7 +356,7 @@ class V3Number final {
|
||||
void opCleanThis(bool warnOnTruncation = false);
|
||||
|
||||
public:
|
||||
void nodep(AstNode* nodep);
|
||||
void nodep(AstNode* nodep) VL_MT_STABLE;
|
||||
FileLine* fileline() const VL_MT_SAFE { return m_fileline; }
|
||||
V3Number& setZero();
|
||||
V3Number& setQuad(uint64_t value);
|
||||
@ -560,8 +560,8 @@ private:
|
||||
}
|
||||
}
|
||||
static string displayPad(size_t fmtsize, char pad, bool left, const string& in) VL_PURE;
|
||||
string displayed(FileLine* fl, const string& vformat) const VL_MT_SAFE;
|
||||
string displayed(const string& vformat) const VL_MT_SAFE {
|
||||
string displayed(FileLine* fl, const string& vformat) const VL_MT_STABLE;
|
||||
string displayed(const string& vformat) const VL_MT_STABLE {
|
||||
return displayed(m_fileline, vformat);
|
||||
}
|
||||
|
||||
@ -583,8 +583,8 @@ public:
|
||||
V3Number& setMask(int nbits); // IE if nbits=1, then 0b1, if 2->0b11, if 3->0b111 etc
|
||||
|
||||
// ACCESSORS
|
||||
string ascii(bool prefixed = true, bool cleanVerilog = false) const VL_MT_SAFE;
|
||||
string displayed(AstNode* nodep, const string& vformat) const VL_MT_SAFE;
|
||||
string ascii(bool prefixed = true, bool cleanVerilog = false) const VL_MT_STABLE;
|
||||
string displayed(AstNode* nodep, const string& vformat) const VL_MT_STABLE;
|
||||
static bool displayedFmtLegal(char format, bool isScan); // Is this a valid format letter?
|
||||
int width() const VL_MT_SAFE { return m_data.width(); }
|
||||
int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1)
|
||||
@ -612,7 +612,7 @@ public:
|
||||
return m_data.type() == V3NumberDataType::LOGIC
|
||||
|| m_data.type() == V3NumberDataType::DOUBLE;
|
||||
}
|
||||
bool isNegative() const { return !isString() && bitIs1(width() - 1); }
|
||||
bool isNegative() const VL_MT_SAFE { return !isString() && bitIs1(width() - 1); }
|
||||
bool is1Step() const VL_MT_SAFE { return m_data.m_is1Step; }
|
||||
bool isNull() const VL_MT_SAFE { return m_data.m_isNull; }
|
||||
bool isFourState() const VL_MT_SAFE;
|
||||
@ -626,7 +626,7 @@ public:
|
||||
}
|
||||
bool isAllZ() const VL_MT_SAFE;
|
||||
bool isAllX() const VL_MT_SAFE;
|
||||
bool isEqZero() const;
|
||||
bool isEqZero() const VL_MT_SAFE;
|
||||
bool isNeqZero() const;
|
||||
bool isBitsZero(int msb, int lsb) const;
|
||||
bool isEqOne() const;
|
||||
@ -642,8 +642,8 @@ public:
|
||||
uint64_t toUQuad() const VL_MT_SAFE;
|
||||
int64_t toSQuad() const VL_MT_SAFE;
|
||||
string toString() const VL_MT_SAFE;
|
||||
string toDecimalS() const; // return ASCII signed decimal number
|
||||
string toDecimalU() const; // return ASCII unsigned decimal number
|
||||
string toDecimalS() const VL_MT_STABLE; // return ASCII signed decimal number
|
||||
string toDecimalU() const VL_MT_STABLE; // return ASCII unsigned decimal number
|
||||
double toDouble() const VL_MT_SAFE;
|
||||
V3Hash toHash() const;
|
||||
uint32_t edataWord(int eword) const;
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
virtual bool domainMatters() = 0;
|
||||
|
||||
// ACCESSORS
|
||||
AstSenTree* domainp() const { return m_domainp; }
|
||||
AstSenTree* domainp() const VL_MT_STABLE { return m_domainp; }
|
||||
void domainp(AstSenTree* domainp) {
|
||||
#if VL_DEBUG
|
||||
UASSERT(!m_domainp, "Domain should only be set once");
|
||||
@ -154,8 +154,8 @@ public:
|
||||
bool domainMatters() override { return true; }
|
||||
|
||||
// ACCESSORS
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstScope* scopep() const { return m_scopep; }
|
||||
AstNode* nodep() const VL_MT_STABLE { return m_nodep; }
|
||||
AstScope* scopep() const VL_MT_STABLE { return m_scopep; }
|
||||
AstSenTree* hybridp() const { return m_hybridp; }
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
@ -181,7 +181,7 @@ public:
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
string dotShape() const override final { return "ellipse"; }
|
||||
virtual string nameSuffix() const = 0;
|
||||
virtual string nameSuffix() const VL_MT_SAFE = 0;
|
||||
string name() const override final VL_MT_STABLE {
|
||||
return cvtToHex(m_vscp) + " " + nameSuffix() + "\\n " + m_vscp->name();
|
||||
}
|
||||
@ -199,7 +199,7 @@ public:
|
||||
bool domainMatters() override { return true; }
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
string nameSuffix() const override { return ""; }
|
||||
string nameSuffix() const override VL_MT_SAFE { return ""; }
|
||||
string dotColor() const override { return "grey"; }
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
@ -215,7 +215,7 @@ public:
|
||||
bool domainMatters() override { return false; }
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
string nameSuffix() const override { return "PRE"; }
|
||||
string nameSuffix() const override VL_MT_SAFE { return "PRE"; }
|
||||
string dotColor() const override { return "green"; }
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
@ -231,7 +231,7 @@ public:
|
||||
bool domainMatters() override { return false; }
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
string nameSuffix() const override { return "POST"; }
|
||||
string nameSuffix() const override VL_MT_SAFE { return "POST"; }
|
||||
string dotColor() const override { return "red"; }
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
@ -247,7 +247,7 @@ public:
|
||||
bool domainMatters() override { return false; }
|
||||
|
||||
// LCOV_EXCL_START // Debug code
|
||||
string nameSuffix() const override { return "PORD"; }
|
||||
string nameSuffix() const override VL_MT_SAFE { return "PORD"; }
|
||||
string dotColor() const override { return "blue"; }
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
}
|
||||
return nm;
|
||||
}
|
||||
OrderLogicVertex* logicp() const { return m_logicp; }
|
||||
OrderLogicVertex* logicp() const VL_MT_STABLE { return m_logicp; }
|
||||
bool isWait() const { return m_state == POM_WAIT; }
|
||||
void setReady() {
|
||||
UASSERT(m_state == POM_WAIT, "Wait->Ready on node not in proper state");
|
||||
|
@ -268,7 +268,7 @@ public:
|
||||
uint32_t id() const override { return m_serialId; }
|
||||
void id(uint32_t id) { m_serialId = id; }
|
||||
// Abstract cost of every logic mtask
|
||||
uint32_t cost() const override { return m_cost; }
|
||||
uint32_t cost() const override VL_MT_SAFE { return m_cost; }
|
||||
void setCost(uint32_t cost) { m_cost = cost; } // For tests only
|
||||
uint32_t stepCost() const { return stepCost(m_cost); }
|
||||
static uint32_t stepCost(uint32_t cost) {
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
, m_bodyp{bodyp}
|
||||
, m_id{id} {}
|
||||
AstMTaskBody* bodyp() const { return m_bodyp; }
|
||||
uint32_t id() const override { return m_id; }
|
||||
uint32_t id() const override VL_MT_SAFE { return m_id; }
|
||||
uint32_t priority() const { return m_priority; }
|
||||
void priority(uint32_t pri) { m_priority = pri; }
|
||||
uint32_t cost() const override { return m_cost; }
|
||||
|
@ -85,8 +85,14 @@ public:
|
||||
void resize(unsigned n) VL_MT_UNSAFE;
|
||||
|
||||
// Enqueue a job for asynchronous execution
|
||||
// Due to missing support for lambda annotations in c++11,
|
||||
// `clang_check_attributes` script assumes that if
|
||||
// function takes `std::function` as argument, it
|
||||
// will call it. `VL_MT_START` here indicates that
|
||||
// every function call inside this `std::function` requires
|
||||
// annotations.
|
||||
template <typename T>
|
||||
std::future<T> enqueue(std::function<T()>&& f) VL_MT_SAFE;
|
||||
std::future<T> enqueue(std::function<T()>&& f) VL_MT_START;
|
||||
|
||||
// Request exclusive access to processing.
|
||||
// It sends request to stop all other threads and waits for them to stop.
|
||||
@ -190,7 +196,7 @@ T V3ThreadPool::waitForFuture(std::future<T>& future) VL_MT_SAFE_EXCLUDES(m_mute
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::future<T> V3ThreadPool::enqueue(std::function<T()>&& f) VL_MT_SAFE {
|
||||
std::future<T> V3ThreadPool::enqueue(std::function<T()>&& f) VL_MT_START {
|
||||
std::shared_ptr<std::promise<T>> prom = std::make_shared<std::promise<T>>();
|
||||
std::future<T> result = prom->get_future();
|
||||
pushJob(prom, std::move(f));
|
||||
|
@ -81,7 +81,7 @@ private:
|
||||
~DependencyVertex() override = default;
|
||||
|
||||
// ACCESSORS
|
||||
virtual AstNode* nodep() const { return m_nodep; }
|
||||
virtual AstNode* nodep() const VL_MT_STABLE { return m_nodep; }
|
||||
};
|
||||
|
||||
// NODE STATE
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
, m_nodep{nodep} {}
|
||||
~TristateVertex() override = default;
|
||||
// ACCESSORS
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstNode* nodep() const VL_MT_STABLE { return m_nodep; }
|
||||
const AstVar* varp() const { return VN_CAST(nodep(), Var); }
|
||||
string name() const override VL_MT_STABLE {
|
||||
return ((isTristate() ? "tri\\n"
|
||||
@ -170,9 +170,9 @@ public:
|
||||
}
|
||||
FileLine* fileline() const override { return nodep()->fileline(); }
|
||||
void isTristate(bool flag) { m_isTristate = flag; }
|
||||
bool isTristate() const { return m_isTristate; }
|
||||
bool isTristate() const VL_MT_SAFE { return m_isTristate; }
|
||||
void feedsTri(bool flag) { m_feedsTri = flag; }
|
||||
bool feedsTri() const { return m_feedsTri; }
|
||||
bool feedsTri() const VL_MT_SAFE { return m_feedsTri; }
|
||||
void processed(bool flag) { m_processed = flag; }
|
||||
bool processed() const { return m_processed; }
|
||||
};
|
||||
|
@ -65,7 +65,7 @@ t/t_dist_attributes_bad.h:204: [mt_unsafe_one] TestCla
|
||||
t/t_dist_attributes_bad.h:209: [mt_safe, mt_unsafe, pure] TestClass::cm_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:209: [mt_safe, mt_unsafe_one, pure] TestClass::cm_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::cm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::cm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:155: [mt_start] TestClass::cm_test_caller_smethod_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:191: [mt_unsafe] TestClass::cm_au_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:191: [mt_unsafe_one] TestClass::cm_au_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
@ -143,7 +143,7 @@ t/t_dist_attributes_bad.h:204: [mt_unsafe_one] TestCla
|
||||
t/t_dist_attributes_bad.h:209: [mt_safe, mt_unsafe, pure] TestClass::cm_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:209: [mt_safe, mt_unsafe_one, pure] TestClass::cm_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::cm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::cm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:212: [mt_start] TestClass::cm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:191: [mt_unsafe] TestClass::cm_au_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:191: [mt_unsafe_one] TestClass::cm_au_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
@ -273,7 +273,7 @@ t/t_dist_attributes_bad.cpp:175: [mt_safe] TestClass
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe] TestClass::icm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe_one] TestClass::icm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::icm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::icm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:175: [mt_start] TestClass::icm_test_caller_smethod_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe] TestClass::icm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe_one] TestClass::icm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
@ -299,7 +299,7 @@ t/t_dist_attributes_bad.h:238: [mt_safe] TestClass
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe] TestClass::icm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe_one] TestClass::icm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::icm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::icm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:238: [mt_start] TestClass::icm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe] TestClass::icm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:235: [mt_unsafe_one] TestClass::icm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
@ -327,7 +327,7 @@ t/t_dist_attributes_bad.h:170: [mt_start] TestCla
|
||||
t/t_dist_attributes_bad.h:170: [mt_unsafe] TestClass::iscm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [mt_unsafe_one] TestClass::iscm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::iscm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::iscm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:119: [mt_start] TestClass::iscm_test_caller_smethod_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [] TestClass::iscm_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [mt_start] TestClass::iscm_VL_MT_START(VerilatedMutex &)
|
||||
@ -357,7 +357,7 @@ t/t_dist_attributes_bad.h:170: [mt_start] TestCla
|
||||
t/t_dist_attributes_bad.h:170: [mt_unsafe] TestClass::iscm_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [mt_unsafe_one] TestClass::iscm_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::iscm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::iscm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:173: [mt_start] TestClass::iscm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [] TestClass::iscm_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:170: [mt_start] TestClass::iscm_VL_MT_START(VerilatedMutex &)
|
||||
@ -467,7 +467,7 @@ t/t_dist_attributes_bad.h:133: [mt_unsafe_one] TestCla
|
||||
t/t_dist_attributes_bad.h:138: [mt_safe, mt_unsafe, pure] TestClass::scm_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:138: [mt_safe, mt_unsafe_one, pure] TestClass::scm_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::scm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::scm_test_caller_smethod_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:93: [mt_start] TestClass::scm_test_caller_smethod_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:120: [] TestClass::scm_au_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:120: [mt_start] TestClass::scm_au_VL_MT_START(VerilatedMutex &)
|
||||
@ -585,7 +585,7 @@ t/t_dist_attributes_bad.h:133: [mt_unsafe_one] TestCla
|
||||
t/t_dist_attributes_bad.h:138: [mt_safe, mt_unsafe, pure] TestClass::scm_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:138: [mt_safe, mt_unsafe_one, pure] TestClass::scm_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "TestClass::scm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "TestClass::scm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:141: [mt_start] TestClass::scm_test_caller_smethod_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:120: [] TestClass::scm_au_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:120: [mt_start] TestClass::scm_au_VL_MT_START(VerilatedMutex &)
|
||||
@ -759,7 +759,7 @@ t/t_dist_attributes_bad.h:94: [mt_start] ifh_VL_
|
||||
t/t_dist_attributes_bad.h:94: [mt_unsafe] ifh_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [mt_unsafe_one] ifh_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "ifh_test_caller_func_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "ifh_test_caller_func_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:53: [mt_start] ifh_test_caller_func_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [] ifh_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [mt_start] ifh_VL_MT_START(VerilatedMutex &)
|
||||
@ -789,7 +789,7 @@ t/t_dist_attributes_bad.h:94: [mt_start] ifh_VL_
|
||||
t/t_dist_attributes_bad.h:94: [mt_unsafe] ifh_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [mt_unsafe_one] ifh_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "ifh_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "ifh_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:97: [mt_start] ifh_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [] ifh_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:94: [mt_start] ifh_VL_MT_START(VerilatedMutex &)
|
||||
@ -899,7 +899,7 @@ t/t_dist_attributes_bad.h:75: [mt_unsafe_one] nsf_ae_
|
||||
t/t_dist_attributes_bad.h:80: [mt_safe, mt_unsafe, pure] nsf_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:80: [mt_safe, mt_unsafe_one, pure] nsf_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "nsf_test_caller_func_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "nsf_test_caller_func_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:42: [mt_start] nsf_test_caller_func_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:62: [] nsf_au_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:62: [mt_start] nsf_au_VL_MT_START(VerilatedMutex &)
|
||||
@ -1017,7 +1017,7 @@ t/t_dist_attributes_bad.h:75: [mt_unsafe_one] nsf_ae_
|
||||
t/t_dist_attributes_bad.h:80: [mt_safe, mt_unsafe, pure] nsf_ea_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:80: [mt_safe, mt_unsafe_one, pure] nsf_ea_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "nsf_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "nsf_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.h:83: [mt_start] nsf_test_caller_func_hdr_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:62: [] nsf_au_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.h:62: [mt_start] nsf_au_VL_MT_START(VerilatedMutex &)
|
||||
@ -1163,7 +1163,7 @@ t/t_dist_attributes_bad.cpp:60: [mt_start] sfc_VL_
|
||||
t/t_dist_attributes_bad.cpp:60: [mt_unsafe] sfc_VL_MT_UNSAFE(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.cpp:60: [mt_unsafe_one] sfc_VL_MT_UNSAFE_ONE(VerilatedMutex &)
|
||||
|
||||
%Error: "sfc_test_caller_func_VL_MT_START(VerilatedMutex &)" is mtsafe but calls non-mtsafe function(s)
|
||||
%Error: "sfc_test_caller_func_VL_MT_START(VerilatedMutex &)" is stable_tree but calls non-stable_tree or non-mtsafe
|
||||
t/t_dist_attributes_bad.cpp:63: [mt_start] sfc_test_caller_func_VL_MT_START(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.cpp:60: [] sfc_NO_ANNOTATION(VerilatedMutex &)
|
||||
t/t_dist_attributes_bad.cpp:60: [mt_start] sfc_VL_MT_START(VerilatedMutex &)
|
||||
|
Loading…
Reference in New Issue
Block a user