def _parse_declarator(self, named: Union[(bool, str)], paramMode: str, typed: bool=True) -> ASTDeclarator:
    if (paramMode not in ('type', 'function', 'operatorCast', 'new')):
        raise Exception(("Internal error, unknown paramMode '%s'." % paramMode))
    prevErrors = []
    self.skip_ws()
    if (typed and self.skip_string('*')):
        self.skip_ws()
        volatile = False
        const = False
        attrs = []
        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
            attr = self._parse_attribute()
            if (attr is not None):
                attrs.append(attr)
                continue
            break
        next = self._parse_declarator(named, paramMode, typed)
        return ASTDeclaratorPtr(next=next, volatile=volatile, const=const, attrs=attrs)
    if (typed and self.skip_string('&')):
        attrs = []
        while 1:
            attr = self._parse_attribute()
            if (attr is None):
                break
            attrs.append(attr)
        next = self._parse_declarator(named, paramMode, typed)
        return ASTDeclaratorRef(next=next, attrs=attrs)
    if (typed and self.skip_string('...')):
        next = self._parse_declarator(named, paramMode, False)
        return ASTDeclaratorParamPack(next=next)
    if (typed and (self.current_char == '(')):
        if (paramMode == 'operatorCast'):
            return ASTDeclaratorNameParamQual(declId=None, arrayOps=[], paramQual=None)
        pos = self.pos
        try:
            res = self._parse_declarator_name_suffix(named, paramMode, typed)
            return res
        except DefinitionError as exParamQual:
            prevErrors.append((exParamQual, 'If declarator-id with parameters-and-qualifiers'))
            self.pos = pos
            try:
                assert (self.current_char == '(')
                self.skip_string('(')
                inner = self._parse_declarator(named, paramMode, typed)
                if (not self.skip_string(')')):
                    self.fail('Expected \')\' in "( ptr-declarator )"')
                next = self._parse_declarator(named=False, paramMode='type', typed=typed)
                return ASTDeclaratorParen(inner=inner, next=next)
            except DefinitionError as exNoPtrParen:
                self.pos = pos
                prevErrors.append((exNoPtrParen, 'If parenthesis in noptr-declarator'))
                header = 'Error in declarator'
                raise self._make_multi_error(prevErrors, header)
    if typed:
        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_declarator(named, paramMode, typed)
            return ASTDeclaratorMemPtr(name, const, volatile, next=next)
    pos = self.pos
    try:
        res = self._parse_declarator_name_suffix(named, paramMode, typed)
        if (self.current_char == '<'):
            self.otherErrors.append(self._make_multi_error(prevErrors, ''))
        return res
    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_declarator(self, named: Union[(bool, str)], paramMode: str, typed: bool=True) -> ASTDeclarator:
    if (paramMode not in ('type', 'function', 'operatorCast', 'new')):
        raise Exception(("Internal error, unknown paramMode '%s'." % paramMode))
    prevErrors = []
    self.skip_ws()
    if (typed and self.skip_string('*')):
        self.skip_ws()
        volatile = False
        const = False
        attrs = []
        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
            attr = self._parse_attribute()
            if (attr is not None):
                attrs.append(attr)
                continue
            break
        next = self._parse_declarator(named, paramMode, typed)
        return ASTDeclaratorPtr(next=next, volatile=volatile, const=const, attrs=attrs)
    if (typed and self.skip_string('&')):
        attrs = []
        while 1:
            attr = self._parse_attribute()
            if (attr is None):
                break
            attrs.append(attr)
        next = self._parse_declarator(named, paramMode, typed)
        return ASTDeclaratorRef(next=next, attrs=attrs)
    if (typed and self.skip_string('...')):
        next = self._parse_declarator(named, paramMode, False)
        return ASTDeclaratorParamPack(next=next)
    if (typed and (self.current_char == '(')):
        if (paramMode == 'operatorCast'):
            return ASTDeclaratorNameParamQual(declId=None, arrayOps=[], paramQual=None)
        pos = self.pos
        try:
            res = self._parse_declarator_name_suffix(named, paramMode, typed)
            return res
        except DefinitionError as exParamQual:
            prevErrors.append((exParamQual, 'If declarator-id with parameters-and-qualifiers'))
            self.pos = pos
            try:
                assert (self.current_char == '(')
                self.skip_string('(')
                inner = self._parse_declarator(named, paramMode, typed)
                if (not self.skip_string(')')):
                    self.fail('Expected \')\' in "( ptr-declarator )"')
                next = self._parse_declarator(named=False, paramMode='type', typed=typed)
                return ASTDeclaratorParen(inner=inner, next=next)
            except DefinitionError as exNoPtrParen:
                self.pos = pos
                prevErrors.append((exNoPtrParen, 'If parenthesis in noptr-declarator'))
                header = 'Error in declarator'
                raise self._make_multi_error(prevErrors, header)
    if typed:
        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_declarator(named, paramMode, typed)
            return ASTDeclaratorMemPtr(name, const, volatile, next=next)
    pos = self.pos
    try:
        res = self._parse_declarator_name_suffix(named, paramMode, typed)
        if (self.current_char == '<'):
            self.otherErrors.append(self._make_multi_error(prevErrors, ))
        return res
    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)