docs: def read_cpp_source_file(self, source_file):
          """
          Reads C++ source file and returns declarations tree
  
          :param source_file: path to C++ source file
          :type source_file: str
  
          """
  
          xml_file = ''
          try:
              ffname = self.__file_full_name(source_file)
              self.logger.debug("Reading source file: [%s].", ffname)
              decls = self.__dcache.cached_value(ffname, self.__config)
              if not decls:
                  self.logger.debug(
                      "File has not been found in cache, parsing...")
                  xml_file = self.create_xml_file(ffname)
                  decls, files = self.__parse_xml_file(xml_file)
                  self.__dcache.update(
                      ffname, self.__config, decls, files)
              else:
                  self.logger.debug((
                      "File has not been changed, reading declarations " +
                      "from cache."))
          except Exception:
              if xml_file:
                  utils.remove_file_no_raise(xml_file, self.__config)
              raise
          if xml_file:
              utils.remove_file_no_raise(xml_file, self.__config)
  
          return decls