diff --git a/CHANGES b/CHANGES index a9c16ce4d..9c3ed67c8 100644 --- a/CHANGES +++ b/CHANGES @@ -65,6 +65,7 @@ Bugs fixed WebSupport feature. Now node.rawsource is fall backed to node.astext() during docutils transforming. * C++, fix parsing of 'signed char' and 'unsigned char' as types. +* C++, add missing support for 'friend' functions. Documentation ------------- diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index e2c4a099a..2b224ef4a 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -1195,7 +1195,7 @@ class ASTParametersQualifiers(ASTBase): class ASTDeclSpecsSimple(ASTBase): def __init__(self, storage, inline, virtual, explicit, - constexpr, volatile, const): + constexpr, volatile, const, friend): self.storage = storage self.inline = inline self.virtual = virtual @@ -1203,6 +1203,7 @@ class ASTDeclSpecsSimple(ASTBase): self.constexpr = constexpr self.volatile = volatile self.const = const + self.friend = friend def mergeWith(self, other): if not other: @@ -1213,7 +1214,8 @@ class ASTDeclSpecsSimple(ASTBase): self.explicit or other.explicit, self.constexpr or other.constexpr, self.volatile or other.volatile, - self.const or other.const) + self.const or other.const, + self.friend or other.friend) def __unicode__(self): res = [] @@ -1221,6 +1223,8 @@ class ASTDeclSpecsSimple(ASTBase): res.append(self.storage) if self.inline: res.append('inline') + if self.friend: + res.append('friend') if self.virtual: res.append('virtual') if self.explicit: @@ -1242,6 +1246,8 @@ class ASTDeclSpecsSimple(ASTBase): _add(modifiers, self.storage) if self.inline: _add(modifiers, 'inline') + if self.friend: + _add(modifiers, 'friend') if self.virtual: _add(modifiers, 'virtual') if self.explicit: @@ -2707,6 +2713,7 @@ class DefinitionParser(object): constexpr = None volatile = None const = None + friend = None while 1: # accept any permutation of a subset of some decl-specs self.skip_ws() if not storage: @@ -2728,6 +2735,10 @@ class DefinitionParser(object): inline = self.skip_word('inline') if inline: continue + if not friend: + friend = self.skip_word('friend') + if friend: + continue if not virtual: virtual = self.skip_word('virtual') if virtual: @@ -2751,7 +2762,7 @@ class DefinitionParser(object): continue break return ASTDeclSpecsSimple(storage, inline, virtual, explicit, constexpr, - volatile, const) + volatile, const, friend) def _parse_decl_specs(self, outer, typed=True): if outer: diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 178379aa6..178981294 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -223,6 +223,9 @@ def test_type_definitions(): # TODO: make tests for functions in a template, e.g., Test # such that the id generation for function type types is correct. + check('function', 'friend std::ostream &f(std::ostream&, int)', + 'f__osR.i', '1fRNSt7ostreamEi') + check('class', 'public A', "A", "1A", output='A') check('class', 'private A', "A", "1A")