PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/sphinx/domains/cpp.py

https://bitbucket.org/andrea_crotti/sphinx
Python | 1254 lines | 1177 code | 43 blank | 34 comment | 88 complexity | 5fef69c7d66acef46997aaad3d79bc10 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-2011 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, modifier):
  529. path = [modifier]
  530. following = self._modifiers[modifier]
  531. while 1:
  532. self.skip_ws()
  533. if not self.match(_identifier_re):
  534. break
  535. identifier = self.matched_text
  536. if identifier in following:
  537. path.append(identifier)
  538. following = self._modifiers[modifier]
  539. assert following
  540. else:
  541. self.backout()
  542. break
  543. is_const = self._peek_const(path)
  544. modifiers, typename = self._guess_typename(path)
  545. rv = ModifierDefExpr(NameDefExpr(typename), modifiers)
  546. return self._attach_crefptr(rv, is_const)
  547. def _parse_type_expr(self, in_template=False):
  548. typename = self._parse_name_or_template_arg(in_template)
  549. self.skip_ws()
  550. if not self.skip_string('<'):
  551. return typename
  552. args = []
  553. while 1:
  554. self.skip_ws()
  555. if self.skip_string('>'):
  556. break
  557. if args:
  558. if not self.skip_string(','):
  559. self.fail('"," or ">" in template expected')
  560. self.skip_ws()
  561. args.append(self._parse_type(True))
  562. return TemplateDefExpr(typename, args)
  563. def _parse_type(self, in_template=False):
  564. self.skip_ws()
  565. result = []
  566. modifiers = []
  567. # if there is a leading :: or not, we don't care because we
  568. # treat them exactly the same. Buf *if* there is one, we
  569. # don't have to check for type modifiers
  570. if not self.skip_string('::'):
  571. self.skip_ws()
  572. while self.match(_identifier_re):
  573. modifier = self.matched_text
  574. if modifier in self._modifiers:
  575. following = self._modifiers[modifier]
  576. # if the set is not none, there is a limited set
  577. # of types that might follow. It is technically
  578. # impossible for a template to follow, so what
  579. # we do is go to a different function that just
  580. # eats types
  581. if following is not None:
  582. return self._parse_builtin(modifier)
  583. modifiers.append(modifier)
  584. else:
  585. self.backout()
  586. break
  587. while 1:
  588. self.skip_ws()
  589. if (in_template and self.current_char in ',>') or \
  590. (result and not self.skip_string('::')) or \
  591. self.eof:
  592. break
  593. result.append(self._parse_type_expr(in_template))
  594. if not result:
  595. self.fail('expected type')
  596. if len(result) == 1:
  597. rv = result[0]
  598. else:
  599. rv = PathDefExpr(result)
  600. is_const = self._peek_const(modifiers)
  601. if modifiers:
  602. rv = ModifierDefExpr(rv, modifiers)
  603. return self._attach_crefptr(rv, is_const)
  604. def _parse_default_expr(self):
  605. self.skip_ws()
  606. if self.match(_string_re):
  607. return self.matched_text
  608. idx1 = self.definition.find(',', self.pos)
  609. idx2 = self.definition.find(')', self.pos)
  610. if idx1 < 0:
  611. idx = idx2
  612. elif idx2 < 0:
  613. idx = idx1
  614. else:
  615. idx = min(idx1, idx2)
  616. if idx < 0:
  617. self.fail('unexpected end in default expression')
  618. rv = self.definition[self.pos:idx]
  619. self.pos = idx
  620. return rv
  621. def _parse_signature(self):
  622. self.skip_ws()
  623. if not self.skip_string('('):
  624. self.fail('expected parentheses for function')
  625. args = []
  626. while 1:
  627. self.skip_ws()
  628. if self.eof:
  629. self.fail('missing closing parentheses')
  630. if self.skip_string(')'):
  631. break
  632. if args:
  633. if not self.skip_string(','):
  634. self.fail('expected comma between arguments')
  635. self.skip_ws()
  636. if self.skip_string('...'):
  637. args.append(ArgumentDefExpr(None, '...', [], None))
  638. if self.skip_string(')'):
  639. break
  640. else:
  641. self.fail('expected closing parenthesis after ellipses')
  642. argname = default = None
  643. argtype = self._parse_type()
  644. self.skip_ws()
  645. type_suffixes = self._try_parse_type_suffixes()
  646. if self.skip_string('='):
  647. default = self._parse_default_expr()
  648. elif self.current_char not in ',)':
  649. argname = self._parse_name()
  650. self.skip_ws()
  651. type_suffixes.extend(self._try_parse_type_suffixes())
  652. if self.skip_string('='):
  653. default = self._parse_default_expr()
  654. if argname is None:
  655. argname = argtype
  656. argtype = None
  657. args.append(ArgumentDefExpr(argtype, argname,
  658. type_suffixes, default))
  659. self.skip_ws()
  660. const = self.skip_word_and_ws('const')
  661. noexcept = self.skip_word_and_ws('noexcept')
  662. if self.skip_string('='):
  663. self.skip_ws()
  664. if not (self.skip_string('0') or \
  665. self.skip_word('NULL') or \
  666. self.skip_word('nullptr')):
  667. self.fail('pure virtual functions must be defined with '
  668. 'either 0, NULL or nullptr, other macros are '
  669. 'not allowed')
  670. pure_virtual = True
  671. else:
  672. pure_virtual = False
  673. return args, const, noexcept, pure_virtual
  674. def _parse_visibility_static(self):
  675. visibility = 'public'
  676. if self.match(_visibility_re):
  677. visibility = self.matched_text
  678. static = self.skip_word('static')
  679. return visibility, static
  680. def parse_type(self):
  681. return self._parse_type()
  682. def parse_type_object(self):
  683. visibility, static = self._parse_visibility_static()
  684. typename = self._parse_type()
  685. self.skip_ws()
  686. if not self.eof:
  687. name = self._parse_type()
  688. type_suffixes = self._try_parse_type_suffixes()
  689. else:
  690. name = typename
  691. typename = None
  692. type_suffixes = []
  693. return TypeObjDefExpr(name, visibility, static, typename, type_suffixes)
  694. def parse_member_object(self):
  695. visibility, static = self._parse_visibility_static()
  696. typename = self._parse_type()
  697. name = self._parse_type()
  698. type_suffixes = self._try_parse_type_suffixes()
  699. self.skip_ws()
  700. if self.skip_string('='):
  701. value = self.read_rest().strip()
  702. else:
  703. value = None
  704. return MemberObjDefExpr(name, visibility, static, typename,
  705. type_suffixes, value)
  706. def parse_function(self):
  707. visibility, static = self._parse_visibility_static()
  708. explicit = self.skip_word_and_ws('explicit')
  709. constexpr = self.skip_word_and_ws('constexpr')
  710. rv = self._parse_type()
  711. self.skip_ws()
  712. # some things just don't have return values
  713. if self.current_char == '(':
  714. name = rv
  715. rv = None
  716. else:
  717. name = self._parse_type()
  718. return FuncDefExpr(name, visibility, static, explicit, constexpr, rv,
  719. *self._parse_signature())
  720. def parse_class(self):
  721. visibility, static = self._parse_visibility_static()
  722. name = self._parse_type()
  723. bases = []
  724. if self.skip_string(':'):
  725. self.skip_ws()
  726. while 1:
  727. access = 'private'
  728. if self.match(_visibility_re):
  729. access = self.matched_text
  730. base = self._parse_type()
  731. bases.append(ClassDefExpr(base, access, False, []))
  732. if self.skip_string(','):
  733. self.skip_ws()
  734. else:
  735. break
  736. return ClassDefExpr(name, visibility, static, bases)
  737. def read_rest(self):
  738. rv = self.definition[self.pos:]
  739. self.pos = self.end
  740. return rv
  741. def assert_end(self):
  742. self.skip_ws()
  743. if not self.eof:
  744. self.fail('expected end of definition, got %r' %
  745. self.definition[self.pos:])
  746. class CPPObject(ObjectDescription):
  747. """Description of a C++ language object."""
  748. doc_field_types = [
  749. GroupedField('parameter', label=l_('Parameters'),
  750. names=('param', 'parameter', 'arg', 'argument'),
  751. can_collapse=True),
  752. GroupedField('exceptions', label=l_('Throws'), rolename='cpp:class',
  753. names=('throws', 'throw', 'exception'),
  754. can_collapse=True),
  755. Field('returnvalue', label=l_('Returns'), has_arg=False,
  756. names=('returns', 'return')),
  757. ]
  758. def attach_name(self, node, name):
  759. owner, name = name.split_owner()
  760. varname = unicode(name)
  761. if owner is not None:
  762. owner = unicode(owner) + '::'
  763. node += addnodes.desc_addname(owner, owner)
  764. node += addnodes.desc_name(varname, varname)
  765. def attach_type_suffixes(self, node, suffixes):
  766. for suffix in suffixes:
  767. node += nodes.Text(unicode(suffix))
  768. def attach_type(self, node, type):
  769. # XXX: link to c?
  770. text = unicode(type)
  771. pnode = addnodes.pending_xref(
  772. '', refdomain='cpp', reftype='type',
  773. reftarget=text, modname=None, classname=None)
  774. pnode['cpp:parent'] = self.env.temp_data.get('cpp:parent')
  775. pnode += nodes.Text(text)
  776. node += pnode
  777. def attach_modifiers(self, node, obj, visibility='public'):
  778. if obj.visibility != visibility:
  779. node += addnodes.desc_annotation(obj.visibility,
  780. obj.visibility)
  781. node += nodes.Text(' ')
  782. if obj.static:
  783. node += addnodes.desc_annotation('static', 'static')
  784. node += nodes.Text(' ')
  785. if getattr(obj, 'constexpr', False):
  786. node += addnodes.desc_annotation('constexpr', 'constexpr')
  787. node += nodes.Text(' ')
  788. def add_target_and_index(self, sigobj, sig, signode):
  789. theid = sigobj.get_id()
  790. name = unicode(sigobj.name)
  791. if theid not in self.state.document.ids:
  792. signode['names'].append(theid)
  793. signode['ids'].append(theid)
  794. signode['first'] = (not self.names)
  795. self.state.document.note_explicit_target(signode)
  796. self.env.domaindata['cpp']['objects'].setdefault(name,
  797. (self.env.docname, self.objtype, theid))
  798. indextext = self.get_index_text(name)
  799. if indextext:
  800. self.indexnode['entries'].append(('single', indextext, theid, ''))
  801. def before_content(self):
  802. lastname = self.names and self.names[-1]
  803. if lastname and not self.env.temp_data.get('cpp:parent'):
  804. assert isinstance(lastname, NamedDefExpr)
  805. self.env.temp_data['cpp:parent'] = lastname.name
  806. self.parentname_set = True
  807. else:
  808. self.parentname_set = False
  809. def after_content(self):
  810. if self.parentname_set:
  811. self.env.temp_data['cpp:parent'] = None
  812. def parse_definition(self, parser):
  813. raise NotImplementedError()
  814. def describe_signature(self, signode, arg):
  815. raise NotImplementedError()
  816. def handle_signature(self, sig, signode):
  817. parser = DefinitionParser(sig)
  818. try:
  819. rv = self.parse_definition(parser)
  820. parser.assert_end()
  821. except DefinitionError, e:
  822. self.state_machine.reporter.warning(e.description, line=self.lineno)
  823. raise ValueError
  824. self.describe_signature(signode, rv)
  825. parent = self.env.temp_data.get('cpp:parent')
  826. if parent is not None:
  827. rv = rv.clone()
  828. rv.name = rv.name.prefix(parent)
  829. return rv
  830. class CPPClassObject(CPPObject):
  831. def get_index_text(self, name):
  832. return _('%s (C++ class)') % name
  833. def parse_definition(self, parser):
  834. return parser.parse_class()
  835. def describe_signature(self, signode, cls):
  836. self.attach_modifiers(signode, cls)
  837. signode += addnodes.desc_annotation('class ', 'class ')
  838. self.attach_name(signode, cls.name)
  839. if cls.bases:
  840. signode += nodes.Text(' : ')
  841. for base in cls.bases:
  842. self.attach_modifiers(signode, base, 'private')
  843. signode += nodes.emphasis(unicode(base.name),
  844. unicode(base.name))
  845. signode += nodes.Text(', ')
  846. signode.pop() # remove the trailing comma
  847. class CPPTypeObject(CPPObject):
  848. def get_index_text(self, name):
  849. if self.objtype == 'type':
  850. return _('%s (C++ type)') % name
  851. return ''
  852. def parse_definition(self, parser):
  853. return parser.parse_type_object()
  854. def describe_signature(self, signode, obj):
  855. self.attach_modifiers(signode, obj)
  856. signode += addnodes.desc_annotation('type ', 'type ')
  857. if obj.typename is not None:
  858. self.attach_type(signode, obj.typename)
  859. signode += nodes.Text(' ')
  860. self.attach_name(signode, obj.name)
  861. self.attach_type_suffixes(signode, obj.type_suffixes)
  862. class CPPMemberObject(CPPObject):
  863. def get_index_text(self, name):
  864. if self.objtype == 'member':
  865. return _('%s (C++ member)') % name
  866. return ''
  867. def parse_definition(self, parser):
  868. return parser.parse_member_object()
  869. def describe_signature(self, signode, obj):
  870. self.attach_modifiers(signode, obj)
  871. self.attach_type(signode, obj.typename)
  872. signode += nodes.Text(' ')
  873. self.attach_name(signode, obj.name)
  874. self.attach_type_suffixes(signode, obj.type_suffixes)
  875. if obj.value is not None:
  876. signode += nodes.Text(u' = ' + obj.value)
  877. class CPPFunctionObject(CPPObject):
  878. def attach_function(self, node, func):
  879. owner, name = func.name.split_owner()
  880. if owner is not None:
  881. owner = unicode(owner) + '::'
  882. node += addnodes.desc_addname(owner, owner)
  883. # cast operator is special. in this case the return value
  884. # is reversed.
  885. if isinstance(name, CastOpDefExpr):
  886. node += addnodes.desc_name('operator', 'operator')
  887. node += nodes.Text(u' ')
  888. self.attach_type(node, name.typename)
  889. else:
  890. funcname = unicode(name)
  891. node += addnodes.desc_name(funcname, funcname)
  892. paramlist = addnodes.desc_parameterlist()
  893. for arg in func.signature:
  894. param = addnodes.desc_parameter('', '', noemph=True)
  895. if arg.type is not None:
  896. self.attach_type(param, arg.type)
  897. param += nodes.Text(u' ')
  898. param += nodes.emphasis(unicode(arg.name), unicode(arg.name))
  899. self.attach_type_suffixes(param, arg.type_suffixes)
  900. if arg.default is not None:
  901. def_ = u'=' + unicode(arg.default)
  902. param += nodes.emphasis(def_, def_)
  903. paramlist += param
  904. node += paramlist
  905. if func.const:
  906. node += addnodes.desc_addname(' const', ' const')
  907. if func.noexcept:
  908. node += addnodes.desc_addname(' noexcept', ' noexcept')
  909. if func.pure_virtual:
  910. node += addnodes.desc_addname(' = 0', ' = 0')
  911. def get_index_text(self, name):
  912. return _('%s (C++ function)') % name
  913. def parse_definition(self, parser):
  914. return parser.parse_function()
  915. def describe_signature(self, signode, func):
  916. self.attach_modifiers(signode, func)
  917. if func.explicit:
  918. signode += addnodes.desc_annotation('explicit', 'explicit')
  919. signode += nodes.Text(' ')
  920. # return value is None for things with a reverse return value
  921. # such as casting operator definitions or constructors
  922. # and destructors.
  923. if func.rv is not None:
  924. self.attach_type(signode, func.rv)
  925. signode += nodes.Text(u' ')
  926. self.attach_function(signode, func)
  927. class CPPCurrentNamespace(Directive):
  928. """
  929. This directive is just to tell Sphinx that we're documenting stuff in
  930. namespace foo.
  931. """
  932. has_content = False
  933. required_arguments = 1
  934. optional_arguments = 0
  935. final_argument_whitespace = True
  936. option_spec = {}
  937. def run(self):
  938. env = self.state.document.settings.env
  939. if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
  940. env.temp_data['cpp:prefix'] = None
  941. else:
  942. parser = DefinitionParser(self.arguments[0])
  943. try:
  944. prefix = parser.parse_type()
  945. parser.assert_end()
  946. except DefinitionError, e:
  947. self.state_machine.reporter.warning(e.description,
  948. line=self.lineno)
  949. else:
  950. env.temp_data['cpp:prefix'] = prefix
  951. return []
  952. class CPPXRefRole(XRefRole):
  953. def process_link(self, env, refnode, has_explicit_title, title, target):
  954. refnode['cpp:parent'] = env.temp_data.get('cpp:parent')
  955. if not has_explicit_title:
  956. target = target.lstrip('~') # only has a meaning for the title
  957. # if the first character is a tilde, don't display the module/class
  958. # parts of the contents
  959. if title[:1] == '~':
  960. title = title[1:]
  961. dcolon = title.rfind('::')
  962. if dcolon != -1:
  963. title = title[dcolon + 2:]
  964. return title, target
  965. class CPPDomain(Domain):
  966. """C++ language domain."""
  967. name = 'cpp'
  968. label = 'C++'
  969. object_types = {
  970. 'class': ObjType(l_('class'), 'class'),
  971. 'function': ObjType(l_('function'), 'func'),
  972. 'member': ObjType(l_('member'), 'member'),
  973. 'type': ObjType(l_('type'), 'type')
  974. }
  975. directives = {
  976. 'class': CPPClassObject,
  977. 'function': CPPFunctionObject,
  978. 'member': CPPMemberObject,
  979. 'type': CPPTypeObject,
  980. 'namespace': CPPCurrentNamespace
  981. }
  982. roles = {
  983. 'class': CPPXRefRole(),
  984. 'func' : CPPXRefRole(fix_parens=True),
  985. 'member': CPPXRefRole(),
  986. 'type': CPPXRefRole()
  987. }
  988. initial_data = {
  989. 'objects': {}, # fullname -> docname, objtype
  990. }
  991. def clear_doc(self, docname):
  992. for fullname, (fn, _, _) in self.data['objects'].items():
  993. if fn == docname:
  994. del self.data['objects'][fullname]
  995. def resolve_xref(self, env, fromdocname, builder,
  996. typ, target, node, contnode):
  997. def _create_refnode(expr):
  998. name = unicode(expr)
  999. if name not in self.data['objects']:
  1000. return None
  1001. obj = self.data['objects'][name]
  1002. if obj[1] not in self.objtypes_for_role(typ):
  1003. return None
  1004. return make_refnode(builder, fromdocname, obj[0], obj[2],
  1005. contnode, name)
  1006. parser = DefinitionParser(target)
  1007. try:
  1008. expr = parser.parse_type().get_name()
  1009. parser.skip_ws()
  1010. if not parser.eof or expr is None:
  1011. raise DefinitionError('')
  1012. except DefinitionError:
  1013. env.warn_node('unparseable C++ definition: %r' % target, node)
  1014. return None
  1015. parent = node.get('cpp:parent', None)
  1016. rv = _create_refnode(expr)
  1017. if rv is not None or parent is None:
  1018. return rv
  1019. parent = parent.get_name()
  1020. rv = _create_refnode(expr.prefix(parent))
  1021. if rv is not None:
  1022. return rv
  1023. parent, name = parent.split_owner()
  1024. return _create_refnode(expr.prefix(parent))
  1025. def get_objects(self):
  1026. for refname, (docname, type, theid) in self.data['objects'].iteritems():
  1027. yield (refname, refname, type, docname, refname, 1)