docs: private void visitMemberDeclarator(AstNode node) {
  
      if (isOverriddenMethod(node)) {
        // assume that ancestor method is documented
        // and do not count as public API
        return;
      }
  
      AstNode container = node.getFirstAncestor(
        CxxGrammarImpl.templateDeclaration,
        CxxGrammarImpl.classSpecifier);
  
      AstNode docNode = node;
      List<Token> comments;
  
      if (container == null || container.getType().equals(CxxGrammarImpl.classSpecifier)) {
        comments = getBlockDocumentation(docNode);
      } else { // template
        do {
          comments = getBlockDocumentation(container);
          if (!comments.isEmpty()) {
            break;
          }
          container = container.getFirstAncestor(CxxGrammarImpl.templateDeclaration);
        } while (container != null);
      }
  
      // documentation may be inlined
      if (comments.isEmpty()) {
        comments = getDeclaratorInlineComment(node);
      }
  
      // find the identifier to present to concrete visitors
      String id = null;
  
      // first look for an operator function id
      AstNode idNode = node.getFirstDescendant(CxxGrammarImpl.operatorFunctionId);
  
      if (idNode != null) {
        id = getOperatorId(idNode);
      } else {
        // look for a declarator id
        idNode = node.getFirstDescendant(CxxGrammarImpl.declaratorId);
  
        if (idNode != null) {
          id = idNode.getTokenValue();
        } else {
          // look for an identifier (e.g in bitfield declaration)
          idNode = node.getFirstDescendant(GenericTokenType.IDENTIFIER);
  
          if (idNode != null) {
            id = idNode.getTokenValue();
          } else {
            LOG.error("Unsupported declarator at {}", node.getTokenLine());
          }
        }
      }
  
      if (idNode != null && id != null) {
        visitPublicApi(idNode, id, comments);
      }
    }