Skip to content

Commit c5962b7

Browse files
committed
C, update fundamental types, including GNU exts
Fixes #9535
1 parent 8fd4373 commit c5962b7

File tree

3 files changed

+85
-38
lines changed

3 files changed

+85
-38
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Features added
1919
template variable ``sphinx_version_tuple``
2020
* #9445: py domain: ``:py:property:`` directive supports ``:classmethod:``
2121
option to describe the class property
22+
* #9535: C, support more fundamental types, including GNU extensions.
2223

2324
Bugs fixed
2425
----------

sphinx/domains/c.py

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,33 @@
9292
_string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"
9393
r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
9494

95+
_simple_type_sepcifiers_re = re.compile(r"""(?x)
96+
\b(
97+
void|_Bool|bool
98+
# Integer
99+
# -------
100+
|((signed|unsigned)\s+)?(char|(
101+
((long\s+long|long)\s+)?int
102+
))
103+
|__uint128|__int128
104+
# extensions
105+
|((signed|unsigned)\s+)?__int(8|16|32|64|128)
106+
# Floating-point
107+
# --------------
108+
|(float|double|long\s+double)(\s+(_Complex|complex|_Imaginary|imaginary))?
109+
|_Decimal(32|64|128)
110+
# extensions
111+
|__float80|_Float64x|__float128|_Float128|__ibm128
112+
|__fp16
113+
# Fixed-point, extension
114+
|(_Sat\s+)?((signed|unsigned)\s+)?((short|long|long\s+long)\s+)?(_Fract|_Accum)
115+
# Integer types that could be prefixes of the previous ones
116+
# ---------------------------------------------------------
117+
|((signed|unsigned)\s+)?(short|long\s+long|long)
118+
|signed|unsigned
119+
)\b
120+
""")
121+
95122

96123
class _DuplicateSymbolError(Exception):
97124
def __init__(self, symbol: "Symbol", declaration: "ASTDeclaration") -> None:
@@ -2123,15 +2150,6 @@ def dump(self, indent: int) -> str:
21232150

21242151

21252152
class DefinitionParser(BaseParser):
2126-
# those without signedness and size modifiers
2127-
# see https://en.cppreference.com/w/cpp/language/types
2128-
_simple_fundamental_types = (
2129-
'void', '_Bool', 'bool', 'char', 'int', 'float', 'double',
2130-
'__int64',
2131-
)
2132-
2133-
_prefix_keys = ('struct', 'enum', 'union')
2134-
21352153
@property
21362154
def language(self) -> str:
21372155
return 'C'
@@ -2556,40 +2574,16 @@ def _parse_nested_name(self) -> ASTNestedName:
25562574
return ASTNestedName(names, rooted)
25572575

25582576
def _parse_trailing_type_spec(self) -> ASTTrailingTypeSpec:
2559-
# fundamental types
2577+
# fundamental types, https://en.cppreference.com/w/c/language/type
2578+
# and extensions
25602579
self.skip_ws()
2561-
for t in self._simple_fundamental_types:
2562-
if self.skip_word(t):
2563-
return ASTTrailingTypeSpecFundamental(t)
2564-
2565-
# TODO: this could/should be more strict
2566-
elements = []
2567-
if self.skip_word_and_ws('signed'):
2568-
elements.append('signed')
2569-
elif self.skip_word_and_ws('unsigned'):
2570-
elements.append('unsigned')
2571-
while 1:
2572-
if self.skip_word_and_ws('short'):
2573-
elements.append('short')
2574-
elif self.skip_word_and_ws('long'):
2575-
elements.append('long')
2576-
else:
2577-
break
2578-
if self.skip_word_and_ws('char'):
2579-
elements.append('char')
2580-
elif self.skip_word_and_ws('int'):
2581-
elements.append('int')
2582-
elif self.skip_word_and_ws('double'):
2583-
elements.append('double')
2584-
elif self.skip_word_and_ws('__int64'):
2585-
elements.append('__int64')
2586-
if len(elements) > 0:
2587-
return ASTTrailingTypeSpecFundamental(' '.join(elements))
2580+
if self.match(_simple_type_sepcifiers_re):
2581+
return ASTTrailingTypeSpecFundamental(self.matched_text)
25882582

25892583
# prefixed
25902584
prefix = None
25912585
self.skip_ws()
2592-
for k in self._prefix_keys:
2586+
for k in ('struct', 'enum', 'union'):
25932587
if self.skip_word_and_ws(k):
25942588
prefix = k
25952589
break

tests/test_domain_c.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,58 @@ def exprCheck(expr, output=None):
275275
exprCheck('a or_eq 5')
276276

277277

278+
def test_domain_c_ast_fundamental_types():
279+
def types():
280+
def signed(t):
281+
yield t
282+
yield 'signed ' + t
283+
yield 'unsigned ' + t
284+
285+
# integer types
286+
# -------------
287+
yield 'void'
288+
yield from ('_Bool', 'bool')
289+
yield from signed('char')
290+
yield from signed('short')
291+
yield from signed('int')
292+
yield from ('signed', 'unsigned')
293+
yield from signed('long')
294+
yield from signed('long int')
295+
yield from signed('long long')
296+
yield from signed('long long int')
297+
yield from ('__int128', '__uint128')
298+
# extensions
299+
for t in ('__int8', '__int16', '__int32', '__int64', '__int128'):
300+
yield from signed(t)
301+
302+
# floating point types
303+
# --------------------
304+
yield from ('_Decimal32', '_Decimal64', '_Decimal128')
305+
for f in ('float', 'double', 'long double'):
306+
yield f
307+
yield from (f + " _Complex", f + " complex")
308+
yield from (f + " _Imaginary", f + " imaginary")
309+
# extensions
310+
# https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types
311+
yield from ('__float80', '_Float64x',
312+
'__float128', '_Float128',
313+
'__ibm128')
314+
# https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html#Half-Precision
315+
yield '__fp16'
316+
317+
# fixed-point types (extension)
318+
# -----------------------------
319+
# https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html#Fixed-Point
320+
for sat in ('', '_Sat '):
321+
for t in ('_Fract', '_Accum'):
322+
for size in ('short ', '', 'long ', 'long long '):
323+
for tt in signed(size + t):
324+
yield sat + tt
325+
326+
for t in types():
327+
check('type', "{key}%s foo" % t, {1: 'foo'}, key='typedef')
328+
329+
278330
def test_domain_c_ast_type_definitions():
279331
check('type', "{key}T", {1: "T"})
280332

0 commit comments

Comments
 (0)