mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
bpo-36876: Add a tool that identifies unsupported global C variables. (#15877)
This commit is contained in:
parent
9936371af2
commit
ee536b2020
51 changed files with 9467 additions and 19 deletions
78
Tools/c-analyzer/c_parser/info.py
Normal file
78
Tools/c-analyzer/c_parser/info.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
from collections import namedtuple
|
||||
|
||||
from c_analyzer_common import info, util
|
||||
from c_analyzer_common.util import classonly, _NTBase
|
||||
|
||||
|
||||
def normalize_vartype(vartype):
|
||||
"""Return the canonical form for a variable type (or func signature)."""
|
||||
# We allow empty strring through for semantic reasons.
|
||||
if vartype is None:
|
||||
return None
|
||||
|
||||
# XXX finish!
|
||||
# XXX Return (modifiers, type, pointer)?
|
||||
return str(vartype)
|
||||
|
||||
|
||||
class Variable(_NTBase,
|
||||
namedtuple('Variable', 'id vartype')):
|
||||
"""Information about a single variable declaration."""
|
||||
|
||||
__slots__ = ()
|
||||
_isglobal = util.Slot()
|
||||
|
||||
@classonly
|
||||
def from_parts(cls, filename, funcname, name, vartype, isglobal=False):
|
||||
id = info.ID(filename, funcname, name)
|
||||
self = cls(id, vartype)
|
||||
if isglobal:
|
||||
self._isglobal = True
|
||||
return self
|
||||
|
||||
def __new__(cls, id, vartype):
|
||||
self = super().__new__(
|
||||
cls,
|
||||
id=info.ID.from_raw(id),
|
||||
vartype=normalize_vartype(vartype) if vartype else None,
|
||||
)
|
||||
return self
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.id)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.id, name)
|
||||
|
||||
def _validate_id(self):
|
||||
if not self.id:
|
||||
raise TypeError('missing id')
|
||||
|
||||
if not self.filename or self.filename == info.UNKNOWN:
|
||||
raise TypeError(f'id missing filename ({self.id})')
|
||||
|
||||
if self.funcname and self.funcname == info.UNKNOWN:
|
||||
raise TypeError(f'id missing funcname ({self.id})')
|
||||
|
||||
self.id.validate()
|
||||
|
||||
def validate(self):
|
||||
"""Fail if the object is invalid (i.e. init with bad data)."""
|
||||
self._validate_id()
|
||||
|
||||
if self.vartype is None or self.vartype == info.UNKNOWN:
|
||||
raise TypeError('missing vartype')
|
||||
|
||||
@property
|
||||
def isglobal(self):
|
||||
try:
|
||||
return self._isglobal
|
||||
except AttributeError:
|
||||
# XXX Include extern variables.
|
||||
# XXX Ignore functions.
|
||||
self._isglobal = ('static' in self.vartype.split())
|
||||
return self._isglobal
|
||||
|
||||
@property
|
||||
def isconst(self):
|
||||
return 'const' in self.vartype.split()
|
||||
Loading…
Add table
Add a link
Reference in a new issue