diff --git a/CHANGES b/CHANGES index b3e9dd4fa..b5030e728 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,8 @@ Translations Bugs fixed ---------- +- C++, added support for 'extern' and 'thread_local'. + Release 1.4 (released Mar 28, 2016) =================================== diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 2ce107484..6b106df52 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -90,8 +90,13 @@ from sphinx.util.docfields import Field, GroupedField decl-specifier -> storage-class-specifier -> - "static" (only for member_object and function_object) + ( "static" (only for member_object and function_object) | "register" + | "extern" (only for member_object) + ) + thread_local[opt] (only for member_object) + (it can also appear before the others) + | type-specifier -> trailing-type-specifier | function-specifier -> "inline" | "virtual" | "explicit" (only for function_object) @@ -1239,9 +1244,10 @@ class ASTParametersQualifiers(ASTBase): class ASTDeclSpecsSimple(ASTBase): - def __init__(self, storage, inline, virtual, explicit, + def __init__(self, storage, threadLocal, inline, virtual, explicit, constexpr, volatile, const, friend): self.storage = storage + self.threadLocal = threadLocal self.inline = inline self.virtual = virtual self.explicit = explicit @@ -1254,6 +1260,7 @@ class ASTDeclSpecsSimple(ASTBase): if not other: return self return ASTDeclSpecsSimple(self.storage or other.storage, + self.threadLocal or other.threadLocal, self.inline or other.inline, self.virtual or other.virtual, self.explicit or other.explicit, @@ -1266,6 +1273,8 @@ class ASTDeclSpecsSimple(ASTBase): res = [] if self.storage: res.append(self.storage) + if self.threadLocal: + res.append('thread_local') if self.inline: res.append('inline') if self.friend: @@ -1289,6 +1298,8 @@ class ASTDeclSpecsSimple(ASTBase): modifiers.append(addnodes.desc_annotation(text, text)) if self.storage: _add(modifiers, self.storage) + if self.threadLocal: + _add(modifiers, 'thread_local') if self.inline: _add(modifiers, 'inline') if self.friend: @@ -3039,6 +3050,7 @@ class DefinitionParser(object): def _parse_decl_specs_simple(self, outer, typed): """Just parse the simple ones.""" storage = None + threadLocal = None inline = None virtual = None explicit = None @@ -3057,9 +3069,16 @@ class DefinitionParser(object): if self.skip_word('mutable'): storage = 'mutable' continue + if self.skip_word('extern'): + storage = 'extern' + continue if self.skip_word('register'): storage = 'register' continue + if not threadLocal and outer == 'member': + threadLocal = self.skip_word('thread_local') + if threadLocal: + continue if outer == 'function': # function-specifiers @@ -3093,8 +3112,8 @@ class DefinitionParser(object): if const: continue break - return ASTDeclSpecsSimple(storage, inline, virtual, explicit, constexpr, - volatile, const, friend) + return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual, + explicit, constexpr, 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 aef7e8ed4..cc0a7fd8a 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -145,6 +145,11 @@ def test_member_definitions(): "4name", output='const std::vector &name') check('member', 'module::myclass foo[n]', "foo__module::myclassA", "3foo") check('member', 'int *const p', 'p__iPC', '1p') + check('member', 'extern int myInt', 'myInt__i', '5myInt') + check('member', 'thread_local int myInt', 'myInt__i', '5myInt') + check('member', 'extern thread_local int myInt', 'myInt__i', '5myInt') + check('member', 'thread_local extern int myInt', 'myInt__i', '5myInt', + 'extern thread_local int myInt') def test_function_definitions():