PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/sphinx/domains/cpp.py

https://bitbucket.org/aohta/sphinx
Python | 1272 lines | 1194 code | 44 blank | 34 comment | 93 complexity | f048eec77aa9f4d7d9a45c5e4ff232a2 MD5 | raw file
Possible License(s): BSD-2-Clause
  1. # -*- coding: utf-8 -*-
  2. """
  3. sphinx.domains.cpp
  4. ~~~~~~~~~~~~~~~~~~
  5. The C++ language domain.
  6. :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. from copy import deepcopy
  11. from docutils import nodes
  12. from sphinx import addnodes
  13. from sphinx.roles import XRefRole
  14. from sphinx.locale import l_, _
  15. from sphinx.domains import Domain, ObjType
  16. from sphinx.directives import ObjectDescription
  17. from sphinx.util.nodes import make_refnode
  18. from sphinx.util.compat import Directive
  19. from sphinx.util.docfields import Field, GroupedField
  20. _identifier_re = re.compile(r'(~?\b[a-zA-Z_][a-zA-Z0-9_]*)\b')
  21. _whitespace_re = re.compile(r'\s+(?u)')
  22. _string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"
  23. r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
  24. _visibility_re = re.compile(r'\b(public|private|protected)\b')
  25. _array_def_re = re.compile(r'\[\s*([^\]]+?)?\s*\]')
  26. _template_arg_re = re.compile(r'(%s)|([^,>]+)' % _string_re.pattern, re.S)
  27. _operator_re = re.compile(r'''(?x)
  28. \[\s*\]
  29. | \(\s*\)
  30. | \+\+ | --
  31. | ->\*? | \,
  32. | (<<|>>)=? | && | \|\|
  33. | [!<>=/*%+|&^~-]=?
  34. ''')
  35. _id_shortwords = {
  36. 'char': 'c',
  37. 'signed char': 'c',
  38. 'unsigned char': 'C',
  39. 'int': 'i',
  40. 'signed int': 'i',
  41. 'unsigned int': 'U',
  42. 'long': 'l',
  43. 'signed long': 'l',
  44. 'unsigned long': 'L',
  45. 'bool': 'b',
  46. 'size_t': 's',
  47. 'std::string': 'ss',
  48. 'std::ostream': 'os',
  49. 'std::istream': 'is',
  50. 'std::iostream': 'ios',
  51. 'std::vector': 'v',
  52. 'std::map': 'm',
  53. 'operator[]': 'subscript-operator',
  54. 'operator()': 'call-operator',
  55. 'operator!': 'not-operator',
  56. 'operator<': 'lt-operator',
  57. 'operator<=': 'lte-operator',
  58. 'operator>': 'gt-operator',
  59. 'operator>=': 'gte-operator',
  60. 'operator=': 'assign-operator',
  61. 'operator/': 'div-operator',
  62. 'operator*': 'mul-operator',
  63. 'operator%': 'mod-operator',
  64. 'operator+': 'add-operator',
  65. 'operator-': 'sub-operator',
  66. 'operator|': 'or-operator',
  67. 'operator&': 'and-operator',
  68. 'operator^': 'xor-operator',
  69. 'operator&&': 'sand-operator',
  70. 'operator||': 'sor-operator',
  71. 'operator==': 'eq-operator',
  72. 'operator!=': 'neq-operator',
  73. 'operator<<': 'lshift-operator',
  74. 'operator>>': 'rshift-operator',
  75. 'operator-=': 'sub-assign-operator',
  76. 'operator+=': 'add-assign-operator',
  77. 'operator*-': 'mul-assign-operator',
  78. 'operator/=': 'div-assign-operator',
  79. 'operator%=': 'mod-assign-operator',
  80. 'operator&=': 'and-assign-operator',
  81. 'operator|=': 'or-assign-operator',
  82. 'operator<<=': 'lshift-assign-operator',
  83. 'operator>>=': 'rshift-assign-operator',
  84. 'operator^=': 'xor-assign-operator',
  85. 'operator,': 'comma-operator',
  86. 'operator->': 'pointer-operator',
  87. 'operator->*': 'pointer-by-pointer-operator',
  88. 'operator~': 'inv-operator',
  89. 'operator++': 'inc-operator',
  90. 'operator--': 'dec-operator',
  91. 'operator new': 'new-operator',
  92. 'operator new[]': 'new-array-operator',
  93. 'operator delete': 'delete-operator',
  94. 'operator delete[]': 'delete-array-operator'
  95. }
  96. class DefinitionError(Exception):
  97. def __init__(self, description):
  98. self.description = description
  99. def __str__(self):
  100. return unicode(self).encode('utf-8')
  101. def __unicode__(self):
  102. return self.description
  103. class DefExpr(object):
  104. def __eq__(self, other):
  105. if type(self) is not type(other):
  106. return False
  107. try:
  108. for key, value in self.__dict__.iteritems():
  109. if value != getattr(other, key):
  110. return False
  111. except AttributeError:
  112. return False
  113. return True
  114. def __ne__(self, other):
  115. return not self.__eq__(other)
  116. __hash__ = None
  117. def clone(self):
  118. """Clone a definition expression node."""
  119. return deepcopy(self)
  120. def get_id(self):
  121. """Return the id for the node."""
  122. return u''
  123. def get_name(self):
  124. """Return the name.
  125. Returns either `None` or a node with a name you might call
  126. :meth:`split_owner` on.
  127. """
  128. return None
  129. def split_owner(self):
  130. """Nodes returned by :meth:`get_name` can split off their
  131. owning parent. This function returns the owner and the
  132. name as a tuple of two items. If a node does not support
  133. it, it returns None as owner and self as name.
  134. """
  135. return None, self
  136. def prefix(self, prefix):
  137. """Prefix a name node (a node returned by :meth:`get_name`)."""
  138. raise NotImplementedError()
  139. def __str__(self):
  140. return unicode(self).encode('utf-8')
  141. def __unicode__(self):
  142. raise NotImplementedError()
  143. def __repr__(self):
  144. return '<%s %s>' % (self.__class__.__name__, self)
  145. class PrimaryDefExpr(DefExpr):
  146. def get_name(self):
  147. return self
  148. def prefix(self, prefix):
  149. if isinstance(prefix, PathDefExpr):
  150. prefix = prefix.clone()
  151. prefix.path.append(self)
  152. return prefix
  153. return PathDefExpr([prefix, self])
  154. class NameDefExpr(PrimaryDefExpr):
  155. def __init__(self, name):
  156. self.name = name
  157. def get_id(self):
  158. name = _id_shortwords.get(self.name)
  159. if name is not None:
  160. return name
  161. return self.name.replace(u' ', u'-')
  162. def __unicode__(self):
  163. return unicode(self.name)
  164. class PathDefExpr(PrimaryDefExpr):
  165. def __init__(self, parts):
  166. self.path = parts
  167. def get_id(self):
  168. rv = u'::'.join(x.get_id() for x in self.path)
  169. return _id_shortwords.get(rv, rv)
  170. def split_owner(self):
  171. if len(self.path) > 1:
  172. return PathDefExpr(self.path[:-1]), self.path[-1]
  173. return None, self
  174. def prefix(self, prefix):
  175. if isinstance(prefix, PathDefExpr):
  176. prefix = prefix.clone()
  177. prefix.path.extend(self.path)
  178. return prefix
  179. return PathDefExpr([prefix] + self.path)
  180. def __unicode__(self):
  181. return u'::'.join(map(unicode, self.path))
  182. class ArrayTypeSuffixDefExpr(object):
  183. def __init__(self, size_hint=None):
  184. self.size_hint = size_hint
  185. def get_id_suffix(self):
  186. return 'A'
  187. def __unicode__(self):
  188. return u'[%s]' % (
  189. self.size_hint is not None and unicode(self.size_hint) or u'',
  190. )
  191. class TemplateDefExpr(PrimaryDefExpr):
  192. def __init__(self, typename, args):
  193. self.typename = typename
  194. self.args = args
  195. def split_owner(self):
  196. owner, typename = self.typename.split_owner()
  197. return owner, TemplateDefExpr(typename, self.args)
  198. def get_id(self):
  199. return u'%s:%s:' % (self.typename.get_id(),
  200. u'.'.join(x.get_id() for x in self.args))
  201. def __unicode__(self):
  202. return u'%s<%s>' % (self.typename, u', '.join(map(unicode, self.args)))
  203. class ConstantTemplateArgExpr(PrimaryDefExpr):
  204. def __init__(self, arg):
  205. self.arg = arg
  206. def get_id(self):
  207. return self.arg.replace(u' ', u'-')
  208. def __unicode__(self):
  209. return unicode(self.arg)
  210. class WrappingDefExpr(DefExpr):
  211. def __init__(self, typename):
  212. self.typename = typename
  213. def get_name(self):
  214. return self.typename.get_name()
  215. class ModifierDefExpr(WrappingDefExpr):
  216. def __init__(self, typename, modifiers):
  217. WrappingDefExpr.__init__(self, typename)
  218. self.modifiers = modifiers
  219. def get_id(self):
  220. pieces = [_id_shortwords.get(unicode(x), unicode(x))
  221. for x in self.modifiers]
  222. pieces.append(self.typename.get_id())
  223. return u'-'.join(pieces)
  224. def __unicode__(self):
  225. return u' '.join(map(unicode, list(self.modifiers) + [self.typename]))
  226. class PtrDefExpr(WrappingDefExpr):
  227. def get_id(self):
  228. return self.typename.get_id() + u'P'
  229. def __unicode__(self):
  230. return u'%s*' % self.typename
  231. class LValRefDefExpr(WrappingDefExpr):
  232. def get_id(self):
  233. return self.typename.get_id() + u'R'
  234. def __unicode__(self):
  235. return u'%s&' % self.typename
  236. class RValRefDefExpr(WrappingDefExpr):
  237. def get_id(self):
  238. return self.typename.get_id() + u'RR'
  239. def __unicode__(self):
  240. return u'%s&&' % self.typename
  241. class ConstDefExpr(WrappingDefExpr):
  242. def __init__(self, typename, prefix=False):
  243. WrappingDefExpr.__init__(self, typename)
  244. self.prefix = prefix
  245. def get_id(self):
  246. return self.typename.get_id() + u'C'
  247. def __unicode__(self):
  248. return (self.prefix and u'const %s' or u'%s const') % self.typename
  249. class CastOpDefExpr(PrimaryDefExpr):
  250. def __init__(self, typename):
  251. self.typename = typename
  252. def get_id(self):
  253. return u'castto-%s-operator' % self.typename.get_id()
  254. def __unicode__(self):
  255. return u'operator %s' % self.typename
  256. class ArgumentDefExpr(DefExpr):
  257. def __init__(self, type, name, type_suffixes, default=None):
  258. self.name = name
  259. self.type = type
  260. self.type_suffixes = type_suffixes
  261. self.default = default
  262. def get_name(self):
  263. return self.name.get_name()
  264. def get_id(self):
  265. buf = []
  266. buf.append(self.type and self.type.get_id() or 'X')
  267. for suffix in self.type_suffixes:
  268. buf.append(suffix.get_id_suffix())
  269. return u''.join(buf)
  270. def __unicode__(self):
  271. buf = [(u'%s %s' % (self.type or u'', self.name or u'')).strip()]
  272. if self.default is not None:
  273. buf.append('=%s' % self.default)
  274. for suffix in self.type_suffixes:
  275. buf.append(unicode(suffix))
  276. return u''.join(buf)
  277. class NamedDefExpr(DefExpr):
  278. def __init__(self, name, visibility, static):
  279. self.name = name
  280. self.visibility = visibility
  281. self.static = static
  282. def get_name(self):
  283. return self.name.get_name()
  284. def get_modifiers(self, visibility='public'):
  285. rv = []
  286. if self.visibility != visibility:
  287. rv.append(self.visibility)
  288. if self.static:
  289. rv.append(u'static')
  290. return rv
  291. class TypeObjDefExpr(NamedDefExpr):
  292. def __init__(self, name, visibility, static, typename, type_suffixes):
  293. NamedDefExpr.__init__(self, name, visibility, static)
  294. self.typename = typename
  295. self.type_suffixes = type_suffixes
  296. def get_id(self):
  297. if self.typename is None:
  298. buf = [self.name.get_id()]
  299. else:
  300. buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
  301. for suffix in self.type_suffixes:
  302. buf.append(suffix.get_id_suffix())
  303. return u''.join(buf)
  304. def __unicode__(self):
  305. buf = self.get_modifiers()
  306. if self.typename is None:
  307. buf.append(unicode(self.name))
  308. else:
  309. buf.extend(map(unicode, (self.typename, self.name)))
  310. buf = [u' '.join(buf)]
  311. for suffix in self.type_suffixes:
  312. buf.append(unicode(suffix))
  313. return u''.join(buf)
  314. class MemberObjDefExpr(NamedDefExpr):
  315. def __init__(self, name, visibility, static, typename, type_suffixes,
  316. value):
  317. NamedDefExpr.__init__(self, name, visibility, static)
  318. self.typename = typename
  319. self.type_suffixes = type_suffixes
  320. self.value = value
  321. def get_id(self):
  322. buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
  323. for suffix in self.type_suffixes:
  324. buf.append(suffix.get_id_suffix())
  325. return u''.join(buf)
  326. def __unicode__(self):
  327. buf = self.get_modifiers()
  328. buf.extend((unicode(self.typename), unicode(self.name)))
  329. buf = [u' '.join(buf)]
  330. for suffix in self.type_suffixes:
  331. buf.append(unicode(suffix))
  332. if self.value is not None:
  333. buf.append(u' = %s' % self.value)
  334. return u''.join(buf)
  335. class FuncDefExpr(NamedDefExpr):
  336. def __init__(self, name, visibility, static, explicit, constexpr, rv,
  337. signature, const, noexcept, pure_virtual):
  338. NamedDefExpr.__init__(self, name, visibility, static)
  339. self.rv = rv
  340. self.signature = signature
  341. self.explicit = explicit
  342. self.constexpr = constexpr
  343. self.const = const
  344. self.noexcept = noexcept
  345. self.pure_virtual = pure_virtual
  346. def get_id(self):
  347. return u'%s%s%s%s' % (
  348. self.name.get_id(),
  349. self.signature and u'__' +
  350. u'.'.join(x.get_id() for x in self.signature) or u'',
  351. self.const and u'C' or u'',
  352. self.constexpr and 'CE' or ''
  353. )
  354. def __unicode__(self):
  355. buf = self.get_modifiers()
  356. if self.explicit:
  357. buf.append(u'explicit')
  358. if self.constexpr:
  359. buf.append(u'constexpr')
  360. if self.rv is not None:
  361. buf.append(unicode(self.rv))
  362. buf.append(u'%s(%s)' % (self.name, u', '.join(
  363. map(unicode, self.signature))))
  364. if self.const:
  365. buf.append(u'const')
  366. if self.noexcept:
  367. buf.append(u'noexcept')
  368. if self.pure_virtual:
  369. buf.append(u'= 0')
  370. return u' '.join(buf)
  371. class ClassDefExpr(NamedDefExpr):
  372. def __init__(self, name, visibility, static, bases):
  373. NamedDefExpr.__init__(self, name, visibility, static)
  374. self.bases = bases
  375. def get_id(self):
  376. return self.name.get_id()
  377. def _tostring(self, visibility='public'):
  378. buf = self.get_modifiers(visibility)
  379. buf.append(unicode(self.name))
  380. if self.bases:
  381. buf.append(u':')
  382. buf.append(u', '.join(base._tostring('private')
  383. for base in self.bases))
  384. return u' '.join(buf)
  385. def __unicode__(self):
  386. return self._tostring('public')
  387. class DefinitionParser(object):
  388. # mapping of valid type modifiers. if the set is None it means
  389. # the modifier can prefix all types, otherwise only the types
  390. # (actually more keywords) in the set. Also check
  391. # _guess_typename when changing this.
  392. _modifiers = {
  393. 'volatile': None,
  394. 'register': None,
  395. 'mutable': None,
  396. 'const': None,
  397. 'typename': None,
  398. 'unsigned': set(('char', 'short', 'int', 'long')),
  399. 'signed': set(('char', 'short', 'int', 'long')),
  400. 'short': set(('int',)),
  401. 'long': set(('int', 'long', 'double'))
  402. }
  403. def __init__(self, definition):
  404. self.definition = definition.strip()
  405. self.pos = 0
  406. self.end = len(self.definition)
  407. self.last_match = None
  408. self._previous_state = (0, None)
  409. def fail(self, msg):
  410. raise DefinitionError('Invalid definition: %s [error at %d]\n %s' %
  411. (msg, self.pos, self.definition))
  412. def match(self, regex):
  413. match = regex.match(self.definition, self.pos)
  414. if match is not None:
  415. self._previous_state = (self.pos, self.last_match)
  416. self.pos = match.end()
  417. self.last_match = match
  418. return True
  419. return False
  420. def backout(self):
  421. self.pos, self.last_match = self._previous_state
  422. def skip_string(self, string):
  423. strlen = len(string)
  424. if self.definition[self.pos:self.pos + strlen] == string:
  425. self.pos += strlen
  426. return True
  427. return False
  428. def skip_word(self, word):
  429. return self.match(re.compile(r'\b%s\b' % re.escape(word)))
  430. def skip_ws(self):
  431. return self.match(_whitespace_re)
  432. def skip_word_and_ws(self, word):
  433. if self.skip_word(word):
  434. self.skip_ws()
  435. return True
  436. return False
  437. @property
  438. def eof(self):
  439. return self.pos >= self.end
  440. @property
  441. def current_char(self):
  442. try:
  443. return self.definition[self.pos]
  444. except IndexError:
  445. return 'EOF'
  446. @property
  447. def matched_text(self):
  448. if self.last_match is not None:
  449. return self.last_match.group()
  450. def _parse_operator(self):
  451. self.skip_ws()
  452. # thank god, a regular operator definition
  453. if self.match(_operator_re):
  454. return NameDefExpr('operator' +
  455. _whitespace_re.sub('', self.matched_text))
  456. # new/delete operator?
  457. for allocop in 'new', 'delete':
  458. if not self.skip_word(allocop):
  459. continue
  460. self.skip_ws()
  461. if self.skip_string('['):
  462. self.skip_ws()
  463. if not self.skip_string(']'):
  464. self.fail('expected "]" for ' + allocop)
  465. allocop += '[]'
  466. return NameDefExpr('operator ' + allocop)
  467. # oh well, looks like a cast operator definition.
  468. # In that case, eat another type.
  469. type = self._parse_type()
  470. return CastOpDefExpr(type)
  471. def _parse_name(self):
  472. return self._parse_name_or_template_arg(False)
  473. def _parse_name_or_template_arg(self, in_template):
  474. if not self.match(_identifier_re):
  475. if not in_template:
  476. self.fail('expected name')
  477. if not self.match(_template_arg_re):
  478. self.fail('expected name or constant template argument')
  479. return ConstantTemplateArgExpr(self.matched_text.strip())
  480. identifier = self.matched_text
  481. # strictly speaking, operators are not regular identifiers
  482. # but because operator is a keyword, it might not be used
  483. # for variable names anyways, so we can safely parse the
  484. # operator here as identifier
  485. if identifier == 'operator':
  486. return self._parse_operator()
  487. return NameDefExpr(identifier)
  488. def _guess_typename(self, path):
  489. if not path:
  490. return [], 'int'
  491. # for the long type, we don't want the int in there
  492. if 'long' in path:
  493. path = [x for x in path if x != 'int']
  494. # remove one long
  495. path.remove('long')
  496. return path, 'long'
  497. if path[-1] in ('int', 'char'):
  498. return path[:-1], path[-1]
  499. return path, 'int'
  500. def _attach_crefptr(self, expr, is_const=False):
  501. if is_const:
  502. expr = ConstDefExpr(expr, prefix=True)
  503. while 1:
  504. self.skip_ws()
  505. if self.skip_word('const'):
  506. expr = ConstDefExpr(expr)
  507. elif self.skip_string('*'):
  508. expr = PtrDefExpr(expr)
  509. elif self.skip_string('&'):
  510. if self.skip_string('&'):
  511. expr = RValRefDefExpr(expr)
  512. else:
  513. expr = LValRefDefExpr(expr)
  514. else:
  515. return expr
  516. def _try_parse_type_suffixes(self):
  517. rv = []
  518. while self.match(_array_def_re):
  519. rv.append(ArrayTypeSuffixDefExpr(self.last_match.group(1)))
  520. self.skip_ws()
  521. return rv
  522. def _peek_const(self, path):
  523. try:
  524. path.remove('const')
  525. return True
  526. except ValueError:
  527. return False
  528. def _parse_builtin(self, modifiers):
  529. modifier = modifiers[-1]
  530. path = modifiers
  531. following = self._modifiers[modifier]
  532. while 1:
  533. self.skip_ws()
  534. if not self.match(_identifier_re):
  535. break
  536. identifier = self.matched_text
  537. if identifier in following:
  538. path.append(identifier)
  539. following = self._modifiers[modifier]
  540. assert following
  541. else:
  542. self.backout()
  543. break
  544. is_const = self._peek_const(path)
  545. modifiers, typename = self._guess_typename(path)
  546. rv = ModifierDefExpr(NameDefExpr(typename), modifiers)
  547. return self._attach_crefptr(rv, is_const)
  548. def _parse_type_expr(self, in_template=False):
  549. typename = self._parse_name_or_template_arg(in_template)
  550. self.skip_ws()
  551. if not self.skip_string('<'):
  552. return typename
  553. args = []
  554. while 1:
  555. self.skip_ws()
  556. if self.skip_string('>'):
  557. break
  558. if args:
  559. if not self.skip_string(','):
  560. self.fail('"," or ">" in template expected')
  561. self.skip_ws()
  562. args.append(self._parse_type(True))
  563. return TemplateDefExpr(typename, args)
  564. def _parse_type(self, in_template=False):
  565. self.skip_ws()
  566. result = []
  567. modifiers = []
  568. # if there is a leading :: or not, we don't care because we
  569. # treat them exactly the same. Buf *if* there is one, we
  570. # don't have to check for type modifiers
  571. if not self.skip_string('::'):
  572. self.skip_ws()
  573. while self.match(_identifier_re):
  574. modifier = self.matched_text
  575. if modifier in self._modifiers:
  576. following = self._modifiers[modifier]
  577. # if the set is not none, there is a limited set
  578. # of types that might follow. It is technically
  579. # impossible for a template to follow, so what
  580. # we do is go to a different function that just
  581. # eats types
  582. modifiers.append(modifier)
  583. if following is not None:
  584. return self._parse_builtin(modifiers)
  585. self.skip_ws()
  586. else:
  587. self.backout()
  588. break
  589. while 1:
  590. self.skip_ws()
  591. if (in_template and self.current_char in ',>') or \
  592. (result and not self.skip_string('::')) or \
  593. self.eof:
  594. break
  595. result.append(self._parse_type_expr(in_template))
  596. if not result:
  597. self.fail('expected type')
  598. if len(result) == 1:
  599. rv = result[0]
  600. else:
  601. rv = PathDefExpr(result)
  602. is_const = self._peek_const(modifiers)
  603. if modifiers:
  604. rv = ModifierDefExpr(rv, modifiers)
  605. return self._attach_crefptr(rv, is_const)
  606. def _parse_default_expr(self):
  607. self.skip_ws()
  608. if self.match(_string_re):
  609. return self.matched_text
  610. paren_stack_depth = 0
  611. max_pos = len(self.definition)
  612. rv_start = self.pos
  613. while 1:
  614. idx0 = self.definition.find('(', self.pos)
  615. idx1 = self.definition.find(',', self.pos)
  616. idx2 = self.definition.find(')', self.pos)
  617. if idx0 < 0:
  618. idx0 = max_pos
  619. if idx1 < 0:
  620. idx1 = max_pos
  621. if idx2 < 0:
  622. idx2 = max_pos
  623. idx = min(idx0, idx1, idx2)
  624. if idx >= max_pos:
  625. self.fail('unexpected end in default expression')
  626. if idx == idx0:
  627. paren_stack_depth += 1
  628. elif idx == idx2:
  629. paren_stack_depth -= 1
  630. if paren_stack_depth < 0:
  631. break
  632. elif paren_stack_depth == 0:
  633. break
  634. self.pos = idx+1
  635. rv = self.definition[rv_start:idx]
  636. self.pos = idx
  637. return rv
  638. def _parse_signature(self):
  639. self.skip_ws()
  640. if not self.skip_string('('):
  641. self.fail('expected parentheses for function')
  642. args = []
  643. while 1:
  644. self.skip_ws()
  645. if self.eof:
  646. self.fail('missing closing parentheses')
  647. if self.skip_string(')'):
  648. break
  649. if args:
  650. if not self.skip_string(','):
  651. self.fail('expected comma between arguments')
  652. self.skip_ws()
  653. if self.skip_string('...'):
  654. args.append(ArgumentDefExpr(None, '...', [], None))
  655. if self.skip_string(')'):
  656. break
  657. else:
  658. self.fail('expected closing parenthesis after ellipses')
  659. argname = default = None
  660. argtype = self._parse_type()
  661. self.skip_ws()
  662. type_suffixes = self._try_parse_type_suffixes()
  663. if self.skip_string('='):
  664. default = self._parse_default_expr()
  665. elif self.current_char not in ',)':
  666. argname = self._parse_name()
  667. self.skip_ws()
  668. type_suffixes.extend(self._try_parse_type_suffixes())
  669. if self.skip_string('='):
  670. default = self._parse_default_expr()
  671. if argname is None:
  672. argname = argtype
  673. argtype = None
  674. args.append(ArgumentDefExpr(argtype, argname,
  675. type_suffixes, default))
  676. self.skip_ws()
  677. const = self.skip_word_and_ws('const')
  678. noexcept = self.skip_word_and_ws('noexcept')
  679. if self.skip_string('='):
  680. self.skip_ws()
  681. if not (self.skip_string('0') or \
  682. self.skip_word('NULL') or \
  683. self.skip_word('nullptr')):
  684. self.fail('pure virtual functions must be defined with '
  685. 'either 0, NULL or nullptr, other macros are '
  686. 'not allowed')
  687. pure_virtual = True
  688. else:
  689. pure_virtual = False
  690. return args, const, noexcept, pure_virtual
  691. def _parse_visibility_static(self):
  692. visibility = 'public'
  693. if self.match(_visibility_re):
  694. visibility = self.matched_text
  695. static = self.skip_word_and_ws('static')
  696. return visibility, static
  697. def parse_type(self):
  698. return self._parse_type()
  699. def parse_type_object(self):
  700. visibility, static = self._parse_visibility_static()
  701. typename = self._parse_type()
  702. self.skip_ws()
  703. if not self.eof:
  704. name = self._parse_type()
  705. type_suffixes = self._try_parse_type_suffixes()
  706. else:
  707. name = typename
  708. typename = None
  709. type_suffixes = []
  710. return TypeObjDefExpr(name, visibility, static, typename, type_suffixes)
  711. def parse_member_object(self):
  712. visibility, static = self._parse_visibility_static()
  713. typename = self._parse_type()
  714. name = self._parse_type()
  715. type_suffixes = self._try_parse_type_suffixes()
  716. self.skip_ws()
  717. if self.skip_string('='):
  718. value = self.read_rest().strip()
  719. else:
  720. value = None
  721. return MemberObjDefExpr(name, visibility, static, typename,
  722. type_suffixes, value)
  723. def parse_function(self):
  724. visibility, static = self._parse_visibility_static()
  725. explicit = self.skip_word_and_ws('explicit')
  726. constexpr = self.skip_word_and_ws('constexpr')
  727. rv = self._parse_type()
  728. self.skip_ws()
  729. # some things just don't have return values
  730. if self.current_char == '(':
  731. name = rv
  732. rv = None
  733. else:
  734. name = self._parse_type()
  735. return FuncDefExpr(name, visibility, static, explicit, constexpr, rv,
  736. *self._parse_signature())
  737. def parse_class(self):
  738. visibility, static = self._parse_visibility_static()
  739. name = self._parse_type()
  740. bases = []
  741. if self.skip_string(':'):
  742. self.skip_ws()
  743. while 1:
  744. access = 'private'
  745. if self.match(_visibility_re):
  746. access = self.matched_text
  747. base = self._parse_type()
  748. bases.append(ClassDefExpr(base, access, False, []))
  749. if self.skip_string(','):
  750. self.skip_ws()
  751. else:
  752. break
  753. return ClassDefExpr(name, visibility, static, bases)
  754. def read_rest(self):
  755. rv = self.definition[self.pos:]
  756. self.pos = self.end
  757. return rv
  758. def assert_end(self):
  759. self.skip_ws()
  760. if not self.eof:
  761. self.fail('expected end of definition, got %r' %
  762. self.definition[self.pos:])
  763. class CPPObject(ObjectDescription):
  764. """Description of a C++ language object."""
  765. doc_field_types = [
  766. GroupedField('parameter', label=l_('Parameters'),
  767. names=('param', 'parameter', 'arg', 'argument'),
  768. can_collapse=True),
  769. GroupedField('exceptions', label=l_('Throws'), rolename='cpp:class',
  770. names=('throws', 'throw', 'exception'),
  771. can_collapse=True),
  772. Field('returnvalue', label=l_('Returns'), has_arg=False,
  773. names=('returns', 'return')),
  774. ]
  775. def attach_name(self, node, name):
  776. owner, name = name.split_owner()
  777. varname = unicode(name)
  778. if owner is not None:
  779. owner = unicode(owner) + '::'
  780. node += addnodes.desc_addname(owner, owner)
  781. node += addnodes.desc_name(varname, varname)
  782. def attach_type_suffixes(self, node, suffixes):
  783. for suffix in suffixes:
  784. node += nodes.Text(unicode(suffix))
  785. def attach_type(self, node, type):
  786. # XXX: link to c?
  787. text = unicode(type)
  788. pnode = addnodes.pending_xref(
  789. '', refdomain='cpp', reftype='type',
  790. reftarget=text, modname=None, classname=None)
  791. pnode['cpp:parent'] = self.env.temp_data.get('cpp:parent')
  792. pnode += nodes.Text(text)
  793. node += pnode
  794. def attach_modifiers(self, node, obj, visibility='public'):
  795. if obj.visibility != visibility:
  796. node += addnodes.desc_annotation(obj.visibility,
  797. obj.visibility)
  798. node += nodes.Text(' ')
  799. if obj.static:
  800. node += addnodes.desc_annotation('static', 'static')
  801. node += nodes.Text(' ')
  802. if getattr(obj, 'constexpr', False):
  803. node += addnodes.desc_annotation('constexpr', 'constexpr')
  804. node += nodes.Text(' ')
  805. def add_target_and_index(self, sigobj, sig, signode):
  806. theid = sigobj.get_id()
  807. name = unicode(sigobj.name)
  808. if theid not in self.state.document.ids:
  809. signode['names'].append(theid)
  810. signode['ids'].append(theid)
  811. signode['first'] = (not self.names)
  812. self.state.document.note_explicit_target(signode)
  813. self.env.domaindata['cpp']['objects'].setdefault(name,
  814. (self.env.docname, self.objtype, theid))
  815. indextext = self.get_index_text(name)
  816. if indextext:
  817. self.indexnode['entries'].append(('single', indextext, theid, ''))
  818. def before_content(self):
  819. lastname = self.names and self.names[-1]
  820. if lastname and not self.env.temp_data.get('cpp:parent'):
  821. assert isinstance(lastname, NamedDefExpr)
  822. self.env.temp_data['cpp:parent'] = lastname.name
  823. self.parentname_set = True
  824. else:
  825. self.parentname_set = False
  826. def after_content(self):
  827. if self.parentname_set:
  828. self.env.temp_data['cpp:parent'] = None
  829. def parse_definition(self, parser):
  830. raise NotImplementedError()
  831. def describe_signature(self, signode, arg):
  832. raise NotImplementedError()
  833. def handle_signature(self, sig, signode):
  834. parser = DefinitionParser(sig)
  835. try:
  836. rv = self.parse_definition(parser)
  837. parser.assert_end()
  838. except DefinitionError, e:
  839. self.state_machine.reporter.warning(e.description, line=self.lineno)
  840. raise ValueError
  841. self.describe_signature(signode, rv)
  842. parent = self.env.temp_data.get('cpp:parent')
  843. if parent is not None:
  844. rv = rv.clone()
  845. rv.name = rv.name.prefix(parent)
  846. return rv
  847. class CPPClassObject(CPPObject):
  848. def get_index_text(self, name):
  849. return _('%s (C++ class)') % name
  850. def parse_definition(self, parser):
  851. return parser.parse_class()
  852. def describe_signature(self, signode, cls):
  853. self.attach_modifiers(signode, cls)
  854. signode += addnodes.desc_annotation('class ', 'class ')
  855. self.attach_name(signode, cls.name)
  856. if cls.bases:
  857. signode += nodes.Text(' : ')
  858. for base in cls.bases:
  859. self.attach_modifiers(signode, base, 'private')
  860. signode += nodes.emphasis(unicode(base.name),
  861. unicode(base.name))
  862. signode += nodes.Text(', ')
  863. signode.pop() # remove the trailing comma
  864. class CPPTypeObject(CPPObject):
  865. def get_index_text(self, name):
  866. if self.objtype == 'type':
  867. return _('%s (C++ type)') % name
  868. return ''
  869. def parse_definition(self, parser):
  870. return parser.parse_type_object()
  871. def describe_signature(self, signode, obj):
  872. self.attach_modifiers(signode, obj)
  873. signode += addnodes.desc_annotation('type ', 'type ')
  874. if obj.typename is not None:
  875. self.attach_type(signode, obj.typename)
  876. signode += nodes.Text(' ')
  877. self.attach_name(signode, obj.name)
  878. self.attach_type_suffixes(signode, obj.type_suffixes)
  879. class CPPMemberObject(CPPObject):
  880. def get_index_text(self, name):
  881. if self.objtype == 'member':
  882. return _('%s (C++ member)') % name
  883. return ''
  884. def parse_definition(self, parser):
  885. return parser.parse_member_object()
  886. def describe_signature(self, signode, obj):
  887. self.attach_modifiers(signode, obj)
  888. self.attach_type(signode, obj.typename)
  889. signode += nodes.Text(' ')
  890. self.attach_name(signode, obj.name)
  891. self.attach_type_suffixes(signode, obj.type_suffixes)
  892. if obj.value is not None:
  893. signode += nodes.Text(u' = ' + obj.value)
  894. class CPPFunctionObject(CPPObject):
  895. def attach_function(self, node, func):
  896. owner, name = func.name.split_owner()
  897. if owner is not None:
  898. owner = unicode(owner) + '::'
  899. node += addnodes.desc_addname(owner, owner)
  900. # cast operator is special. in this case the return value
  901. # is reversed.
  902. if isinstance(name, CastOpDefExpr):
  903. node += addnodes.desc_name('operator', 'operator')
  904. node += nodes.Text(u' ')
  905. self.attach_type(node, name.typename)
  906. else:
  907. funcname = unicode(name)
  908. node += addnodes.desc_name(funcname, funcname)
  909. paramlist = addnodes.desc_parameterlist()
  910. for arg in func.signature:
  911. param = addnodes.desc_parameter('', '', noemph=True)
  912. if arg.type is not None:
  913. self.attach_type(param, arg.type)
  914. param += nodes.Text(u' ')
  915. param += nodes.emphasis(unicode(arg.name), unicode(arg.name))
  916. self.attach_type_suffixes(param, arg.type_suffixes)
  917. if arg.default is not None:
  918. def_ = u'=' + unicode(arg.default)
  919. param += nodes.emphasis(def_, def_)
  920. paramlist += param
  921. node += paramlist
  922. if func.const:
  923. node += addnodes.desc_addname(' const', ' const')
  924. if func.noexcept:
  925. node += addnodes.desc_addname(' noexcept', ' noexcept')
  926. if func.pure_virtual:
  927. node += addnodes.desc_addname(' = 0', ' = 0')
  928. def get_index_text(self, name):
  929. return _('%s (C++ function)') % name
  930. def parse_definition(self, parser):
  931. return parser.parse_function()
  932. def describe_signature(self, signode, func):
  933. self.attach_modifiers(signode, func)
  934. if func.explicit:
  935. signode += addnodes.desc_annotation('explicit', 'explicit')
  936. signode += nodes.Text(' ')
  937. # return value is None for things with a reverse return value
  938. # such as casting operator definitions or constructors
  939. # and destructors.
  940. if func.rv is not None:
  941. self.attach_type(signode, func.rv)
  942. signode += nodes.Text(u' ')
  943. self.attach_function(signode, func)
  944. class CPPCurrentNamespace(Directive):
  945. """
  946. This directive is just to tell Sphinx that we're documenting stuff in
  947. namespace foo.
  948. """
  949. has_content = False
  950. required_arguments = 1
  951. optional_arguments = 0
  952. final_argument_whitespace = True
  953. option_spec = {}
  954. def run(self):
  955. env = self.state.document.settings.env
  956. if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
  957. env.temp_data['cpp:prefix'] = None
  958. else:
  959. parser = DefinitionParser(self.arguments[0])
  960. try:
  961. prefix = parser.parse_type()
  962. parser.assert_end()
  963. except DefinitionError, e:
  964. self.state_machine.reporter.warning(e.description,
  965. line=self.lineno)
  966. else:
  967. env.temp_data['cpp:prefix'] = prefix
  968. return []
  969. class CPPXRefRole(XRefRole):
  970. def process_link(self, env, refnode, has_explicit_title, title, target):
  971. refnode['cpp:parent'] = env.temp_data.get('cpp:parent')
  972. if not has_explicit_title:
  973. target = target.lstrip('~') # only has a meaning for the title
  974. # if the first character is a tilde, don't display the module/class
  975. # parts of the contents
  976. if title[:1] == '~':
  977. title = title[1:]
  978. dcolon = title.rfind('::')
  979. if dcolon != -1:
  980. title = title[dcolon + 2:]
  981. return title, target
  982. class CPPDomain(Domain):
  983. """C++ language domain."""
  984. name = 'cpp'
  985. label = 'C++'
  986. object_types = {
  987. 'class': ObjType(l_('class'), 'class'),
  988. 'function': ObjType(l_('function'), 'func'),
  989. 'member': ObjType(l_('member'), 'member'),
  990. 'type': ObjType(l_('type'), 'type')
  991. }
  992. directives = {
  993. 'class': CPPClassObject,
  994. 'function': CPPFunctionObject,
  995. 'member': CPPMemberObject,
  996. 'type': CPPTypeObject,
  997. 'namespace': CPPCurrentNamespace
  998. }
  999. roles = {
  1000. 'class': CPPXRefRole(),
  1001. 'func' : CPPXRefRole(fix_parens=True),
  1002. 'member': CPPXRefRole(),
  1003. 'type': CPPXRefRole()
  1004. }
  1005. initial_data = {
  1006. 'objects': {}, # fullname -> docname, objtype
  1007. }
  1008. def clear_doc(self, docname):
  1009. for fullname, (fn, _, _) in self.data['objects'].items():
  1010. if fn == docname:
  1011. del self.data['objects'][fullname]
  1012. def resolve_xref(self, env, fromdocname, builder,
  1013. typ, target, node, contnode):
  1014. def _create_refnode(expr):
  1015. name = unicode(expr)
  1016. if name not in self.data['objects']:
  1017. return None
  1018. obj = self.data['objects'][name]
  1019. if obj[1] not in self.objtypes_for_role(typ):
  1020. return None
  1021. return make_refnode(builder, fromdocname, obj[0], obj[2],
  1022. contnode, name)
  1023. parser = DefinitionParser(target)
  1024. try:
  1025. expr = parser.parse_type().get_name()
  1026. parser.skip_ws()
  1027. if not parser.eof or expr is None:
  1028. raise DefinitionError('')
  1029. except DefinitionError:
  1030. env.warn_node('unparseable C++ definition: %r' % target, node)
  1031. return None
  1032. parent = node.get('cpp:parent', None)
  1033. rv = _create_refnode(expr)
  1034. if rv is not None or parent is None:
  1035. return rv
  1036. parent = parent.get_name()
  1037. rv = _create_refnode(expr.prefix(parent))
  1038. if rv is not None:
  1039. return rv
  1040. parent, name = parent.split_owner()
  1041. return _create_refnode(expr.prefix(parent))
  1042. def get_objects(self):
  1043. for refname, (docname, type, theid) in self.data['objects'].iteritems():
  1044. yield (refname, refname, type, docname, refname, 1)