summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--sphinx/domains/cpp.py295
-rw-r--r--tests/test_domain_cpp.py161
3 files changed, 332 insertions, 125 deletions
diff --git a/CHANGES b/CHANGES
index 4566566c7..1a8217c44 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,7 @@ Features added
* Intersphinx: Added support for fetching Intersphinx inventories with URLs
using HTTP basic auth
* C++, added support for template parameter in function info field lists.
+* C++, added support for pointers to member (function).
Bugs fixed
----------
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 00bfb8663..8cbf96e1d 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -151,7 +151,7 @@ from sphinx.util.docfields import Field, GroupedField
| "& attribute-specifier-seq[opt]
| "&&" attribute-specifier-seq[opt]
| "::"[opt] nested-name-specifier "*" attribute-specifier-seq[opt]
- cv-qualifier-seq[opt] # TOOD: not implemented
+ cv-qualifier-seq[opt]
# function_object must use a parameters-and-qualifiers, the others may
# use it (e.g., function poitners)
parameters-and-qualifiers ->
@@ -1402,9 +1402,14 @@ class ASTDeclaratorPtr(ASTBase):
def __unicode__(self):
res = ['*']
if self.volatile:
- res.append('volatile ')
+ res.append('volatile')
if self.const:
- res.append('const ')
+ if self.volatile:
+ res.append(' ')
+ res.append('const')
+ if self.const or self.volatile:
+ if self.next.require_space_after_declSpecs:
+ res.append(' ')
res.append(text_type(self.next))
return u''.join(res)
@@ -1459,6 +1464,18 @@ class ASTDeclaratorPtr(ASTBase):
def describe_signature(self, signode, mode, env, symbol):
_verify_description_mode(mode)
signode += nodes.Text("*")
+
+ def _add_anno(signode, text):
+ signode += addnodes.desc_annotation(text, text)
+ if self.volatile:
+ _add_anno(signode, 'volatile')
+ if self.const:
+ if self.volatile:
+ signode += nodes.Text(' ')
+ _add_anno(signode, 'const')
+ if self.const or self.volatile:
+ if self.next.require_space_after_declSpecs:
+ signode += nodes.Text(' ')
self.next.describe_signature(signode, mode, env, symbol)
@@ -1571,6 +1588,94 @@ class ASTDeclaratorParamPack(ASTBase):
self.next.describe_signature(signode, mode, env, symbol)
+class ASTDeclaratorMemPtr(ASTBase):
+ def __init__(self, className, const, volatile, next):
+ assert className
+ assert next
+ self.className = className
+ self.const = const
+ self.volatile = volatile
+ self.next = next
+
+ @property
+ def name(self):
+ return self.next.name
+
+ def require_space_after_declSpecs(self):
+ return True
+
+ def __unicode__(self):
+ res = []
+ res.append(text_type(self.className))
+ res.append('::*')
+ if self.volatile:
+ res.append(' volatile')
+ if self.const:
+ res.append(' const')
+ if self.next.require_space_after_declSpecs():
+ res.append(' ')
+ res.append(text_type(self.next))
+ return ''.join(res)
+
+ # Id v1 ------------------------------------------------------------------
+
+ def get_modifiers_id_v1(self):
+ raise NoOldIdError()
+
+ def get_param_id_v1(self): # only the parameters (if any)
+ raise NoOldIdError()
+
+ def get_ptr_suffix_id_v1(self):
+ raise NoOldIdError()
+
+ # Id v2 ------------------------------------------------------------------
+
+ def get_modifiers_id_v2(self):
+ return self.next.get_modifiers_id_v2()
+
+ def get_param_id_v2(self): # only the parameters (if any)
+ return self.next.get_param_id_v2()
+
+ def get_ptr_suffix_id_v2(self):
+ raise NotImplementedError()
+ return self.next.get_ptr_suffix_id_v2() + u'Dp'
+
+ def get_type_id_v2(self, returnTypeId):
+ # ReturnType name::* next, so we are part of the return type of next
+ nextReturnTypeId = ''
+ if self.volatile:
+ nextReturnTypeId += 'V'
+ if self.const:
+ nextReturnTypeId += 'K'
+ nextReturnTypeId += 'M'
+ nextReturnTypeId += self.className.get_id_v2()
+ nextReturnTypeId += returnTypeId
+ return self.next.get_type_id_v2(nextReturnTypeId)
+
+ # ------------------------------------------------------------------------
+
+ def is_function_type(self):
+ return self.next.is_function_type()
+
+ def describe_signature(self, signode, mode, env, symbol):
+ _verify_description_mode(mode)
+ self.className.describe_signature(signode, mode, env, symbol)
+ signode += nodes.Text('::*')
+
+ def _add_anno(signode, text):
+ signode += addnodes.desc_annotation(text, text)
+ if self.volatile:
+ _add_anno(signode, 'volatile')
+ if self.const:
+ if self.volatile:
+ signode += nodes.Text(' ')
+ _add_anno(signode, 'const')
+ if self.next.require_space_after_declSpecs():
+ if self.volatile or self.const:
+ signode += nodes.Text(' ')
+ self.next.describe_signature(signode, mode, env, symbol)
+
+
class ASTDeclaratorParen(ASTBase):
def __init__(self, inner, next):
assert inner
@@ -2541,6 +2646,30 @@ class DefinitionParser(object):
self.warnEnv = warnEnv
+ def _make_multi_error(self, errors, header):
+ if len(errors) == 1:
+ return DefinitionError(header + '\n' + errors[0][0].description)
+ result = [header, '\n']
+ for e in errors:
+ if len(e[1]) > 0:
+ ident = ' '
+ result.append(e[1])
+ result.append(':\n')
+ for line in e[0].description.split('\n'):
+ if len(line) == 0:
+ continue
+ result.append(ident)
+ result.append(line)
+ result.append('\n')
+ else:
+ result.append(e[0].description)
+ return DefinitionError(''.join(result))
+
+ def status(self, msg):
+ # for debugging
+ indicator = '-' * self.pos + '^'
+ print("%s\n%s\n%s" % (msg, self.definition, indicator))
+
def fail(self, msg):
indicator = '-' * self.pos + '^'
raise DefinitionError(
@@ -2672,6 +2801,7 @@ class DefinitionParser(object):
self.skip_ws()
if not self.skip_string('<'):
return None
+ prevErrors = []
templateArgs = []
while 1:
pos = self.pos
@@ -2688,7 +2818,7 @@ class DefinitionParser(object):
self.fail('Expected ">" or "," in template argument list.')
templateArgs.append(type)
except DefinitionError as e:
- errorType = e.description
+ prevErrors.append((e, "If type argument"))
self.pos = pos
try:
value = self._parse_expression(end=[',', '>'])
@@ -2701,18 +2831,16 @@ class DefinitionParser(object):
self.fail('Expected ">" or "," in template argument list.')
templateArgs.append(ASTTemplateArgConstant(value))
except DefinitionError as e:
- errorExpr = e.description
- msg = "Error in parsing template argument list. " \
- "Error if type argument:\n%s\n" \
- "Error if non-type argument:\n%s" \
- % (errorType, errorExpr)
- self.fail(msg)
+ self.pos = pos
+ prevErrors.append((e, "If non-type argument"))
+ header = "Error in parsing template argument list."
+ raise self._make_multi_error(prevErrors, header)
if parsedEnd:
assert not parsedComma
break
return ASTTemplateArgs(templateArgs)
- def _parse_nested_name(self):
+ def _parse_nested_name(self, memberPointer=False):
names = []
self.skip_ws()
@@ -2728,6 +2856,8 @@ class DefinitionParser(object):
names.append(op)
else:
if not self.match(_identifier_re):
+ if memberPointer and len(names) > 0:
+ break
self.fail("Expected identifier in nested name.")
identifier = self.matched_text
# make sure there isn't a keyword
@@ -2740,6 +2870,8 @@ class DefinitionParser(object):
self.skip_ws()
if not self.skip_string('::'):
+ if memberPointer:
+ self.fail("Expected '::' in pointer to member (function).")
break
return ASTNestedName(names, rooted)
@@ -2808,7 +2940,7 @@ class DefinitionParser(object):
'parameters_and_qualifiers.')
break
if paramMode == 'function':
- arg = self._parse_type_with_init(outer=None, named='maybe')
+ arg = self._parse_type_with_init(outer=None, named='single')
else:
arg = self._parse_type(named=False)
# TODO: parse default parameters # TODO: didn't we just do that?
@@ -2824,7 +2956,10 @@ class DefinitionParser(object):
'Expecting "," or ")" in parameters_and_qualifiers, '
'got "%s".' % self.current_char)
- if paramMode != 'function':
+ # TODO: why did we have this bail-out?
+ # does it hurt to parse the extra stuff?
+ # it's needed for pointer to member functions
+ if paramMode != 'function' and False:
return ASTParametersQualifiers(
args, None, None, None, None, None, None, None)
@@ -2965,26 +3100,27 @@ class DefinitionParser(object):
def _parse_declarator_name_param_qual(self, named, paramMode, typed):
# now we should parse the name, and then suffixes
if named == 'maybe':
+ pos = self.pos
try:
declId = self._parse_nested_name()
except DefinitionError:
+ self.pos = pos
declId = None
elif named == 'single':
if self.match(_identifier_re):
identifier = ASTIdentifier(self.matched_text)
nne = ASTNestedNameElement(identifier, None)
declId = ASTNestedName([nne], rooted=False)
+ # if it's a member pointer, we may have '::', which should be an error
+ self.skip_ws()
+ if self.current_char == ':':
+ self.fail("Unexpected ':' after identifier.")
else:
declId = None
elif named:
declId = self._parse_nested_name()
else:
declId = None
- self.skip_ws()
- if typed and declId:
- if self.skip_string("*"):
- self.fail("Member pointers not implemented.")
-
arrayOps = []
while 1:
self.skip_ws()
@@ -3005,6 +3141,7 @@ class DefinitionParser(object):
if paramMode not in ('type', 'function', 'operatorCast'):
raise Exception(
"Internal error, unknown paramMode '%s'." % paramMode)
+ prevErrors = []
self.skip_ws()
if typed and self.skip_string('*'):
self.skip_ws()
@@ -3023,13 +3160,39 @@ class DefinitionParser(object):
next = self._parse_declerator(named, paramMode, typed)
return ASTDeclaratorPtr(next=next, volatile=volatile, const=const)
# TODO: shouldn't we parse an R-value ref here first?
- elif typed and self.skip_string("&"):
+ if typed and self.skip_string("&"):
next = self._parse_declerator(named, paramMode, typed)
return ASTDeclaratorRef(next=next)
- elif typed and self.skip_string("..."):
+ if typed and self.skip_string("..."):
next = self._parse_declerator(named, paramMode, False)
return ASTDeclaratorParamPack(next=next)
- elif typed and self.current_char == '(': # note: peeking, not skipping
+ if typed: # pointer to member
+ pos = self.pos
+ try:
+ name = self._parse_nested_name(memberPointer=True)
+ self.skip_ws()
+ if not self.skip_string('*'):
+ self.fail("Expected '*' in pointer to member declarator.")
+ self.skip_ws()
+ except DefinitionError as e:
+ self.pos = pos
+ prevErrors.append((e, "If pointer to member declarator"))
+ else:
+ volatile = False
+ const = False
+ while 1:
+ if not volatile:
+ volatile = self.skip_word_and_ws('volatile')
+ if volatile:
+ continue
+ if not const:
+ const = self.skip_word_and_ws('const')
+ if const:
+ continue
+ break
+ next = self._parse_declerator(named, paramMode, typed)
+ return ASTDeclaratorMemPtr(name, const, volatile, next=next)
+ if typed and self.current_char == '(': # note: peeking, not skipping
if paramMode == "operatorCast":
# TODO: we should be able to parse cast operators which return
# function pointers. For now, just hax it and ignore.
@@ -3037,14 +3200,15 @@ class DefinitionParser(object):
paramQual=None)
# maybe this is the beginning of params and quals,try that first,
# otherwise assume it's noptr->declarator > ( ptr-declarator )
- startPos = self.pos
+ pos = self.pos
try:
# assume this is params and quals
res = self._parse_declarator_name_param_qual(named, paramMode,
typed)
return res
except DefinitionError as exParamQual:
- self.pos = startPos
+ prevErrors.append((exParamQual, "If declId, parameters, and qualifiers"))
+ self.pos = pos
try:
assert self.current_char == '('
self.skip_string('(')
@@ -3059,13 +3223,18 @@ class DefinitionParser(object):
typed=typed)
return ASTDeclaratorParen(inner=inner, next=next)
except DefinitionError as exNoPtrParen:
- raise DefinitionError(
- "If declId, parameters, and qualifiers {\n%s\n"
- "} else If parenthesis in noptr-declarator {\n%s\n}"
- % (exParamQual, exNoPtrParen))
- else:
- return self._parse_declarator_name_param_qual(named, paramMode,
- typed)
+ self.pos = pos
+ prevErrors.append((exNoPtrParen, "If parenthesis in noptr-declarator"))
+ header = "Error in declarator"
+ raise self._make_multi_error(prevErrors, header)
+ pos = self.pos
+ try:
+ return self._parse_declarator_name_param_qual(named, paramMode, typed)
+ except DefinitionError as e:
+ self.pos = pos
+ prevErrors.append((e, "If declarator-id"))
+ header = "Error in declarator or parameters and qualifiers"
+ raise self._make_multi_error(prevErrors, header)
def _parse_initializer(self, outer=None):
self.skip_ws()
@@ -3102,6 +3271,7 @@ class DefinitionParser(object):
# We allow type objects to just be a name.
# Some functions don't have normal return types: constructors,
# destrutors, cast operators
+ prevErrors = []
startPos = self.pos
# first try without the type
try:
@@ -3110,37 +3280,49 @@ class DefinitionParser(object):
typed=False)
self.assert_end()
except DefinitionError as exUntyped:
+ if outer == 'type':
+ desc = "If just a name"
+ elif outer == 'function':
+ desc = "If the function has no return type"
+ else:
+ assert False
+ prevErrors.append((exUntyped, desc))
self.pos = startPos
try:
declSpecs = self._parse_decl_specs(outer=outer)
decl = self._parse_declerator(named=True, paramMode=outer)
except DefinitionError as exTyped:
+ self.pos = startPos
+ if outer == 'type':
+ desc = "If typedef-like declaration"
+ elif outer == 'function':
+ desc = "If the function has a return type"
+ else:
+ assert False
+ prevErrors.append((exTyped, desc))
# Retain the else branch for easier debugging.
# TODO: it would be nice to save the previous stacktrace
# and output it here.
if True:
if outer == 'type':
- desc = ('Type must be either just a name or a '
- 'typedef-like declaration.\n'
- 'Just a name error: %s\n'
- 'Typedef-like expression error: %s')
+ header = "Type must be either just a name or a "
+ header += "typedef-like declaration."
elif outer == 'function':
- desc = ('Error when parsing function declaration:\n'
- 'If no return type {\n%s\n'
- '} else if return type {\n%s\n}')
+ header = "Error when parsing function declaration."
else:
assert False
- raise DefinitionError(
- desc % (exUntyped.description, exTyped.description))
+ raise self._make_multi_error(prevErrors, header)
else:
# For testing purposes.
# do it again to get the proper traceback (how do you
# relieable save a traceback when an exception is
# constructed?)
+ pass
self.pos = startPos
- declSpecs = self._parse_decl_specs(outer=outer, typed=False)
+ typed = True
+ declSpecs = self._parse_decl_specs(outer=outer, typed=typed)
decl = self._parse_declerator(named=True, paramMode=outer,
- typed=False)
+ typed=typed)
else:
paramMode = 'type'
if outer == 'member': # i.e., member
@@ -3226,7 +3408,7 @@ class DefinitionParser(object):
if not self.skip_string("<"):
self.fail("Expected '<' after 'template'")
while 1:
- extraError = ''
+ prevErrors = []
self.skip_ws()
if self.skip_word('template'):
# declare a tenplate template parameter
@@ -3272,19 +3454,20 @@ class DefinitionParser(object):
param = self._parse_type_with_init('maybe', 'templateParam')
templateParams.append(ASTTemplateParamNonType(param))
except DefinitionError as e:
+ prevErrors.append((e, "If non-type template parameter"))
self.pos = pos
- extraError = "Error if non-type template parameter: %s"
- extraError = extraError % e.description
self.skip_ws()
if self.skip_string('>'):
return ASTTemplateParams(templateParams)
elif self.skip_string(','):
continue
else:
- msg = 'Expected "=", ",", or ">" in template parameter list.'
- if len(extraError) > 0:
- msg += '\n%s' % extraError
- self.fail(msg)
+ header = "Error in template parameter list."
+ try:
+ self.fail('Expected "=", ",", or ">".')
+ except DefinitionError as e:
+ prevErrors.append((e, ""))
+ raise self._make_multi_error(prevErrors, header)
def _parse_template_declaration_prefix(self):
templates = []
@@ -3347,25 +3530,23 @@ class DefinitionParser(object):
templatePrefix = self._parse_template_declaration_prefix()
if objectType == 'type':
- error = None
+ prevErrors = []
pos = self.pos
try:
if not templatePrefix:
declaration = self._parse_type(named=True, outer='type')
except DefinitionError as e:
- error = e.description
+ prevErrors.append((e, "If typedef-like declaration"))
self.pos = pos
+ pos = self.pos
try:
if not declaration:
declaration = self._parse_type_using()
except DefinitionError as e:
- if error:
- msg = "Error if typedef:\n%s\n" \
- "Error if type alias or template alias:\n%s" \
- % (error, e.description)
- raise DefinitionError(msg)
- else:
- raise e
+ self.pos = pos
+ prevErrors.append((e, "If type alias or template alias"))
+ header = "Error in type declaration."
+ raise self._make_multi_error(prevErrors, header)
elif objectType == 'member':
declaration = self._parse_type_with_init(named=True, outer='member')
elif objectType == 'function':
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index 78ac9c2c8..ba96945fd 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -78,6 +78,27 @@ def check(name, input, idv1output=None, idv2output=None, output=None):
#print ".. %s:: %s" % (name, input)
+def test_fundamental_types():
+ # see http://en.cppreference.com/w/cpp/language/types
+ for t, id_v2 in cppDomain._id_fundamental_v2.items():
+ if t == "decltype(auto)":
+ continue
+
+ def makeIdV1():
+ id = t.replace(" ", "-").replace("long", "l").replace("int", "i")
+ id = id.replace("bool", "b").replace("char", "c")
+ id = id.replace("wc_t", "wchar_t").replace("c16_t", "char16_t")
+ id = id.replace("c32_t", "char32_t")
+ return "f__%s" % id
+
+ def makeIdV2():
+ id = id_v2
+ if t == "std::nullptr_t":
+ id = "NSt9nullptr_tE"
+ return "1f%s" % id
+ check("function", "void f(%s arg)" % t, makeIdV1(), makeIdV2())
+
+
def test_type_definitions():
check("type", "public bool b", "b", "1b", "bool b")
check("type", "bool A::b", "A::b", "N1A1bE")
@@ -107,6 +128,10 @@ def test_type_definitions():
# test name in global scope
check("type", "bool ::B::b", "B::b", "N1B1bE")
+ check('type', 'A = B', None, '1A')
+
+
+def test_member_definitions():
check('member', ' const std::string & name = 42',
"name__ssCR", "4name", output='const std::string &name = 42')
check('member', ' const std::string & name', "name__ssCR", "4name",
@@ -117,7 +142,10 @@ def test_type_definitions():
"name__std::vector:unsigned-i.l:CR",
"4name", output='const std::vector<unsigned int, long> &name')
check('member', 'module::myclass foo[n]', "foo__module::myclassA", "3foo")
+ check('member', 'int *const p', 'p__iPC', '1p')
+
+def test_function_definitions():
check('function', 'operator bool() const', "castto-b-operatorC", "NKcvbEv")
check('function', 'A::operator bool() const',
"A::castto-b-operatorC", "NK1AcvbEv")
@@ -223,6 +251,8 @@ def test_type_definitions():
"A::f__doubleC", "NK1A1fEd")
check("function", "void f(std::shared_ptr<int(double)> ptr)",
None, "1fNSt10shared_ptrIFidEEE")
+ check("function", "void f(int *const p)", "f__iPC", "1fPCi")
+ check("function", "void f(int *volatile const p)", "f__iPVC", "1fPVCi")
# TODO: make tests for functions in a template, e.g., Test<int&&()>
# such that the id generation for function type types is correct.
@@ -237,9 +267,72 @@ def test_type_definitions():
check('function', 'void f(enum E e)', 'f__E', '1f1E')
check('function', 'void f(union E e)', 'f__E', '1f1E')
+ # pointer to member (function)
+ check('function', 'void f(int C::*)', None, '1fM1Ci')
+ check('function', 'void f(int C::* p)', None, '1fM1Ci')
+ check('function', 'void f(int ::C::* p)', None, '1fM1Ci')
+ check('function', 'void f(int C::* const)', None, '1fKM1Ci')
+ check('function', 'void f(int C::* const&)', None, '1fRKM1Ci')
+ check('function', 'void f(int C::* volatile)', None, '1fVM1Ci')
+ check('function', 'void f(int C::* const volatile)', None, '1fVKM1Ci',
+ output='void f(int C::* volatile const)')
+ check('function', 'void f(int C::* volatile const)', None, '1fVKM1Ci')
+ check('function', 'void f(int (C::*)(float, double))', None, '1fM1CFifdE')
+ check('function', 'void f(int (C::* p)(float, double))', None, '1fM1CFifdE')
+ check('function', 'void f(int (::C::* p)(float, double))', None, '1fM1CFifdE')
+ check('function', 'void f(void (C::*)() const &)', None, '1fM1CKRFvvE')
+ check('function', 'int C::* f(int, double)', None, '1fid')
+ check('function', 'void f(int C::* *)', None, '1fPM1Ci')
+
+
+def test_operators():
+ check('function', 'void operator new [ ] ()',
+ "new-array-operator", "nav", output='void operator new[]()')
+ check('function', 'void operator delete ()',
+ "delete-operator", "dlv", output='void operator delete()')
+ check('function', 'operator bool() const',
+ "castto-b-operatorC", "NKcvbEv", output='operator bool() const')
+
+ check('function', 'void operator * ()',
+ "mul-operator", "mlv", output='void operator*()')
+ check('function', 'void operator - ()',
+ "sub-operator", "miv", output='void operator-()')
+ check('function', 'void operator + ()',
+ "add-operator", "plv", output='void operator+()')
+ check('function', 'void operator = ()',
+ "assign-operator", "aSv", output='void operator=()')
+ check('function', 'void operator / ()',
+ "div-operator", "dvv", output='void operator/()')
+ check('function', 'void operator % ()',
+ "mod-operator", "rmv", output='void operator%()')
+ check('function', 'void operator ! ()',
+ "not-operator", "ntv", output='void operator!()')
+
+ check('function', 'void operator "" _udl()',
+ None, 'li4_udlv', output='void operator""_udl()')
+
+
+def test_class_definitions():
check('class', 'public A', "A", "1A", output='A')
check('class', 'private A', "A", "1A")
+ check('class', 'A final', 'A', '1A')
+
+ # test bases
+ check('class', 'A', "A", "1A")
+ check('class', 'A::B::C', "A::B::C", "N1A1B1CE")
+ check('class', 'A : B', "A", "1A")
+ check('class', 'A : private B', "A", "1A", output='A : B')
+ check('class', 'A : public B', "A", "1A")
+ check('class', 'A : B, C', "A", "1A")
+ check('class', 'A : B, protected C, D', "A", "1A")
+ check('class', 'A : virtual private B', 'A', '1A', output='A : virtual B')
+ check('class', 'A : B, virtual C', 'A', '1A')
+ check('class', 'A : public virtual B', 'A', '1A')
+ check('class', 'A : B, C...', 'A', '1A')
+ check('class', 'A : B..., C', 'A', '1A')
+
+def test_enum_definitions():
check('enum', 'A', None, "1A")
check('enum', 'A : std::underlying_type<B>::type', None, "1A")
check('enum', 'A : unsigned int', None, "1A")
@@ -250,29 +343,6 @@ def test_type_definitions():
check('enumerator', 'A = std::numeric_limits<unsigned long>::max()',
None, "1A")
- check('type', 'A = B', None, '1A')
-
-
-def test_fundamental_types():
- # see http://en.cppreference.com/w/cpp/language/types
- for t, id_v2 in cppDomain._id_fundamental_v2.items():
- if t == "decltype(auto)":
- continue
-
- def makeIdV1():
- id = t.replace(" ", "-").replace("long", "l").replace("int", "i")
- id = id.replace("bool", "b").replace("char", "c")
- id = id.replace("wc_t", "wchar_t").replace("c16_t", "char16_t")
- id = id.replace("c32_t", "char32_t")
- return "f__%s" % id
-
- def makeIdV2():
- id = id_v2
- if t == "std::nullptr_t":
- id = "NSt9nullptr_tE"
- return "1f%s" % id
- check("function", "void f(%s arg)" % t, makeIdV1(), makeIdV2())
-
def test_templates():
check('class', "A<T>", None, "IE1AI1TE", output="template<> A<T>")
@@ -318,51 +388,6 @@ def test_templates():
"RK18c_string_view_baseIK4Char6TraitsE")
-def test_class():
- check('class', 'A final', 'A', '1A')
-
-
-def test_bases():
- check('class', 'A', "A", "1A")
- check('class', 'A::B::C', "A::B::C", "N1A1B1CE")
- check('class', 'A : B', "A", "1A")
- check('class', 'A : private B', "A", "1A", output='A : B')
- check('class', 'A : public B', "A", "1A")
- check('class', 'A : B, C', "A", "1A")
- check('class', 'A : B, protected C, D', "A", "1A")
- check('class', 'A : virtual private B', 'A', '1A', output='A : virtual B')
- check('class', 'A : B, virtual C', 'A', '1A')
- check('class', 'A : public virtual B', 'A', '1A')
- check('class', 'A : B, C...', 'A', '1A')
- check('class', 'A : B..., C', 'A', '1A')
-
-
-def test_operators():
- check('function', 'void operator new [ ] ()',
- "new-array-operator", "nav", output='void operator new[]()')
- check('function', 'void operator delete ()',
- "delete-operator", "dlv", output='void operator delete()')
- check('function', 'operator bool() const',
- "castto-b-operatorC", "NKcvbEv", output='operator bool() const')
-
- check('function', 'void operator * ()',
- "mul-operator", "mlv", output='void operator*()')
- check('function', 'void operator - ()',
- "sub-operator", "miv", output='void operator-()')
- check('function', 'void operator + ()',
- "add-operator", "plv", output='void operator+()')
- check('function', 'void operator = ()',
- "assign-operator", "aSv", output='void operator=()')
- check('function', 'void operator / ()',
- "div-operator", "dvv", output='void operator/()')
- check('function', 'void operator % ()',
- "mod-operator", "rmv", output='void operator%()')
- check('function', 'void operator ! ()',
- "not-operator", "ntv", output='void operator!()')
-
- check('function', 'void operator "" _udl()',
- None, 'li4_udlv', output='void operator""_udl()')
-
#def test_print():
# # used for getting all the ids out for checking
# for a in ids: