docs: def cached_value(self, source_file, configuration):
          """Return the cached declarations or None.
  
          :param source_file: Header file name
          :type source_file: str
          :param configuration: Configuration object
          :type configuration: :class:`parser.xml_generator_configuration_t`
          :rtype: Cached declarations or None
          """
  
          # Check if the cache contains an entry for source_file
          key = self._create_cache_key(source_file)
          entry = self.__index.get(key)
          if entry is None:
              # print "CACHE: %s: Not cached"%source_file
              return None
  
          # Check if the entry is still valid. It is not valid if:
          #  - the source_file has been updated
          #  - the configuration object has changed (i.e. the header is parsed
          #    by gccxml with different settings which may influence the
          #    declarations)
          #  - the included files have been updated
          #    (this list is part of the cache entry as it cannot be known
          #    by the caller when cached_value() is called. It was instead
          #    passed to update())
  
          # Check if the config is different...
          configsig = self._create_config_signature(configuration)
          if configsig != entry.configsig:
              # print "CACHE: %s: Config mismatch"%source_file
              return None
  
          # Check if any of the dependent files has been modified...
          for id_, sig in entry.filesigs:
              if self.__filename_rep.is_file_modified(id_, sig):
                  # print "CACHE: %s: Entry not up to date"%source_file
                  return None
  
          # Load and return the cached declarations
          cachefilename = self._create_cache_filename(source_file)
          decls = self._read_file(cachefilename)
  
          # print "CACHE: Using cached decls for",source_file
          return decls