Index: clangd/StdSymbolMap.inc =================================================================== --- clangd/StdSymbolMap.inc +++ clangd/StdSymbolMap.inc @@ -1224,3 +1224,218 @@ SYMBOL(yotta, std::, ) SYMBOL(zepto, std::, ) SYMBOL(zetta, std::, ) +SYMBOL(April, std::chrono::, ) +SYMBOL(August, std::chrono::, ) +SYMBOL(December, std::chrono::, ) +SYMBOL(February, std::chrono::, ) +SYMBOL(Friday, std::chrono::, ) +SYMBOL(January, std::chrono::, ) +SYMBOL(July, std::chrono::, ) +SYMBOL(June, std::chrono::, ) +SYMBOL(March, std::chrono::, ) +SYMBOL(May, std::chrono::, ) +SYMBOL(Monday, std::chrono::, ) +SYMBOL(November, std::chrono::, ) +SYMBOL(October, std::chrono::, ) +SYMBOL(Saturday, std::chrono::, ) +SYMBOL(September, std::chrono::, ) +SYMBOL(Sunday, std::chrono::, ) +SYMBOL(Thursday, std::chrono::, ) +SYMBOL(Tuesday, std::chrono::, ) +SYMBOL(Wednesday, std::chrono::, ) +SYMBOL(abs, std::chrono::, ) +SYMBOL(ambiguous_local_time, std::chrono::, ) +SYMBOL(ceil, std::chrono::, ) +SYMBOL(choose, std::chrono::, ) +SYMBOL(clock_cast, std::chrono::, ) +SYMBOL(clock_time_conversion, std::chrono::, ) +SYMBOL(current_zone, std::chrono::, ) +SYMBOL(day, std::chrono::, ) +SYMBOL(duration, std::chrono::, ) +SYMBOL(duration_values, std::chrono::, ) +SYMBOL(file_clock, std::chrono::, ) +SYMBOL(file_seconds, std::chrono::, ) +SYMBOL(file_time, std::chrono::, ) +SYMBOL(floor, std::chrono::, ) +SYMBOL(gps_clock, std::chrono::, ) +SYMBOL(gps_seconds, std::chrono::, ) +SYMBOL(gps_time, std::chrono::, ) +SYMBOL(high_resolution_clock, std::chrono::, ) +SYMBOL(hours, std::chrono::, ) +SYMBOL(is_clock, std::chrono::, ) +SYMBOL(is_clock_v, std::chrono::, ) +SYMBOL(last, std::chrono::, ) +SYMBOL(last_spec, std::chrono::, ) +SYMBOL(leap, std::chrono::, ) +SYMBOL(link, std::chrono::, ) +SYMBOL(local_info, std::chrono::, ) +SYMBOL(local_seconds, std::chrono::, ) +SYMBOL(local_t, std::chrono::, ) +SYMBOL(local_time, std::chrono::, ) +SYMBOL(locate_zone, std::chrono::, ) +SYMBOL(microseconds, std::chrono::, ) +SYMBOL(milliseconds, std::chrono::, ) +SYMBOL(minutes, std::chrono::, ) +SYMBOL(month, std::chrono::, ) +SYMBOL(month_day, std::chrono::, ) +SYMBOL(month_day_last, std::chrono::, ) +SYMBOL(month_weekday, std::chrono::, ) +SYMBOL(month_weekday_last, std::chrono::, ) +SYMBOL(nanoseconds, std::chrono::, ) +SYMBOL(nonexistent_local_time, std::chrono::, ) +SYMBOL(round, std::chrono::, ) +SYMBOL(seconds, std::chrono::, ) +SYMBOL(steady_clock, std::chrono::, ) +SYMBOL(sys_days, std::chrono::, ) +SYMBOL(sys_info, std::chrono::, ) +SYMBOL(sys_seconds, std::chrono::, ) +SYMBOL(sys_time, std::chrono::, ) +SYMBOL(system_clock, std::chrono::, ) +SYMBOL(tai_clock, std::chrono::, ) +SYMBOL(tai_seconds, std::chrono::, ) +SYMBOL(tai_time, std::chrono::, ) +SYMBOL(time_of_day, std::chrono::, ) +SYMBOL(time_point, std::chrono::, ) +SYMBOL(time_zone, std::chrono::, ) +SYMBOL(treat_as_floating_point, std::chrono::, ) +SYMBOL(treat_as_floating_point_v, std::chrono::, ) +SYMBOL(tzdb, std::chrono::, ) +SYMBOL(tzdb_list, std::chrono::, ) +SYMBOL(utc_clock, std::chrono::, ) +SYMBOL(utc_seconds, std::chrono::, ) +SYMBOL(utc_time, std::chrono::, ) +SYMBOL(weekday, std::chrono::, ) +SYMBOL(weekday_indexed, std::chrono::, ) +SYMBOL(weekday_last, std::chrono::, ) +SYMBOL(year, std::chrono::, ) +SYMBOL(year_month, std::chrono::, ) +SYMBOL(year_month_day, std::chrono::, ) +SYMBOL(year_month_day_last, std::chrono::, ) +SYMBOL(year_month_weekday, std::chrono::, ) +SYMBOL(year_month_weekday_last, std::chrono::, ) +SYMBOL(zoned_time, std::chrono::, ) +SYMBOL(zoned_traits, std::chrono::, ) +SYMBOL(absolute, std::filesystem::, ) +SYMBOL(canonical, std::filesystem::, ) +SYMBOL(copy, std::filesystem::, ) +SYMBOL(copy_file, std::filesystem::, ) +SYMBOL(copy_options, std::filesystem::, ) +SYMBOL(copy_symlink, std::filesystem::, ) +SYMBOL(create_directories, std::filesystem::, ) +SYMBOL(create_directory, std::filesystem::, ) +SYMBOL(create_directory_symlink, std::filesystem::, ) +SYMBOL(create_hard_link, std::filesystem::, ) +SYMBOL(create_symlink, std::filesystem::, ) +SYMBOL(current_path, std::filesystem::, ) +SYMBOL(directory_entry, std::filesystem::, ) +SYMBOL(directory_iterator, std::filesystem::, ) +SYMBOL(directory_options, std::filesystem::, ) +SYMBOL(equivalent, std::filesystem::, ) +SYMBOL(exists, std::filesystem::, ) +SYMBOL(file_size, std::filesystem::, ) +SYMBOL(file_status, std::filesystem::, ) +SYMBOL(file_time_type, std::filesystem::, ) +SYMBOL(file_type, std::filesystem::, ) +SYMBOL(filesystem_error, std::filesystem::, ) +SYMBOL(hard_link_count, std::filesystem::, ) +SYMBOL(is_block_file, std::filesystem::, ) +SYMBOL(is_character_file, std::filesystem::, ) +SYMBOL(is_directory, std::filesystem::, ) +SYMBOL(is_empty, std::filesystem::, ) +SYMBOL(is_fifo, std::filesystem::, ) +SYMBOL(is_other, std::filesystem::, ) +SYMBOL(is_regular_file, std::filesystem::, ) +SYMBOL(is_socket, std::filesystem::, ) +SYMBOL(is_symlink, std::filesystem::, ) +SYMBOL(last_write_time, std::filesystem::, ) +SYMBOL(path, std::filesystem::, ) +SYMBOL(perm_options, std::filesystem::, ) +SYMBOL(permissions, std::filesystem::, ) +SYMBOL(perms, std::filesystem::, ) +SYMBOL(proximate, std::filesystem::, ) +SYMBOL(read_symlink, std::filesystem::, ) +SYMBOL(recursive_directory_iterator, std::filesystem::, ) +SYMBOL(relative, std::filesystem::, ) +SYMBOL(remove, std::filesystem::, ) +SYMBOL(remove_all, std::filesystem::, ) +SYMBOL(rename, std::filesystem::, ) +SYMBOL(resize_file, std::filesystem::, ) +SYMBOL(space, std::filesystem::, ) +SYMBOL(space_info, std::filesystem::, ) +SYMBOL(status, std::filesystem::, ) +SYMBOL(status_known, std::filesystem::, ) +SYMBOL(symlink_status, std::filesystem::, ) +SYMBOL(temp_directory_path, std::filesystem::, ) +SYMBOL(u8path, std::filesystem::, ) +SYMBOL(weakly_canonical, std::filesystem::, ) +SYMBOL(basic_string, std::pmr::, ) +SYMBOL(deque, std::pmr::, ) +SYMBOL(forward_list, std::pmr::, ) +SYMBOL(get_default_resource, std::pmr::, ) +SYMBOL(list, std::pmr::, ) +SYMBOL(map, std::pmr::, ) +SYMBOL(memory_resource, std::pmr::, ) +SYMBOL(monotonic_buffer_resource, std::pmr::, ) +SYMBOL(multimap, std::pmr::, ) +SYMBOL(multiset, std::pmr::, ) +SYMBOL(new_delete_resource, std::pmr::, ) +SYMBOL(null_memory_resource, std::pmr::, ) +SYMBOL(polymorphic_allocator, std::pmr::, ) +SYMBOL(pool_options, std::pmr::, ) +SYMBOL(set, std::pmr::, ) +SYMBOL(set_default_resource, std::pmr::, ) +SYMBOL(string, std::pmr::, ) +SYMBOL(synchronized_pool_resource, std::pmr::, ) +SYMBOL(u16string, std::pmr::, ) +SYMBOL(u32string, std::pmr::, ) +SYMBOL(unordered_map, std::pmr::, ) +SYMBOL(unordered_multimap, std::pmr::, ) +SYMBOL(unordered_multiset, std::pmr::, ) +SYMBOL(unordered_set, std::pmr::, ) +SYMBOL(unsynchronized_pool_resource, std::pmr::, ) +SYMBOL(vector, std::pmr::, ) +SYMBOL(wstring, std::pmr::, ) +SYMBOL(ECMAScript, std::regex_constants::, ) +SYMBOL(awk, std::regex_constants::, ) +SYMBOL(basic, std::regex_constants::, ) +SYMBOL(collate, std::regex_constants::, ) +SYMBOL(egrep, std::regex_constants::, ) +SYMBOL(error_backref, std::regex_constants::, ) +SYMBOL(error_badbrace, std::regex_constants::, ) +SYMBOL(error_badrepeat, std::regex_constants::, ) +SYMBOL(error_brace, std::regex_constants::, ) +SYMBOL(error_brack, std::regex_constants::, ) +SYMBOL(error_collate, std::regex_constants::, ) +SYMBOL(error_complexity, std::regex_constants::, ) +SYMBOL(error_ctype, std::regex_constants::, ) +SYMBOL(error_escape, std::regex_constants::, ) +SYMBOL(error_paren, std::regex_constants::, ) +SYMBOL(error_range, std::regex_constants::, ) +SYMBOL(error_space, std::regex_constants::, ) +SYMBOL(error_stack, std::regex_constants::, ) +SYMBOL(error_type, std::regex_constants::, ) +SYMBOL(extended, std::regex_constants::, ) +SYMBOL(format_default, std::regex_constants::, ) +SYMBOL(format_first_only, std::regex_constants::, ) +SYMBOL(format_no_copy, std::regex_constants::, ) +SYMBOL(format_sed, std::regex_constants::, ) +SYMBOL(grep, std::regex_constants::, ) +SYMBOL(icase, std::regex_constants::, ) +SYMBOL(match_any, std::regex_constants::, ) +SYMBOL(match_continuous, std::regex_constants::, ) +SYMBOL(match_default, std::regex_constants::, ) +SYMBOL(match_flag_type, std::regex_constants::, ) +SYMBOL(match_not_bol, std::regex_constants::, ) +SYMBOL(match_not_bow, std::regex_constants::, ) +SYMBOL(match_not_eol, std::regex_constants::, ) +SYMBOL(match_not_eow, std::regex_constants::, ) +SYMBOL(match_not_null, std::regex_constants::, ) +SYMBOL(match_prev_avail, std::regex_constants::, ) +SYMBOL(multiline, std::regex_constants::, ) +SYMBOL(nosubs, std::regex_constants::, ) +SYMBOL(optimize, std::regex_constants::, ) +SYMBOL(syntax_option_type, std::regex_constants::, ) +SYMBOL(get_id, std::this_thread::, ) +SYMBOL(sleep_for, std::this_thread::, ) +SYMBOL(sleep_until, std::this_thread::, ) +SYMBOL(yield, std::this_thread::, ) Index: clangd/include-mapping/gen_std.py =================================================================== --- clangd/include-mapping/gen_std.py +++ clangd/include-mapping/gen_std.py @@ -90,6 +90,50 @@ symbol_href["href"])) return symbols +class Symbol: + + def __init__(self, name, namespace, headers): + # unqualifed symbol name, e.g. "move" + self.name = name + # namespace of the symbol (with trailing "::"), e.g. "std::" + self.namespace = namespace + # a list of corresponding headers + self.headers = headers + + +def GetSymbols(root_dir, index_page_name, namespace): + """Get all symbols listed in the index page. All symbols should be in the + given namespace. + + Returns a list of Symbols. + """ + + # Workflow steps: + # 1. Parse index page which lists all symbols to get symbol + # name (unqualified name) and its href link to the symbol page which + # contains the defined header. + # 2. Parse the symbol page to get the defined header. + index_page_path = os.path.join(root_dir, index_page_name) + symbols = [] + with open(index_page_path, "r") as f: + # A map from symbol name to a set of headers. + symbol_headers = {} + for symbol_name, symbol_page_path in ParseIndexPage(f.read()): + with open(os.path.join(root_dir, symbol_page_path), "r") as f: + headers = ParseSymbolPage(f.read()) + if not headers: + sys.stderr.write("No header found for symbol %s at %s\n" % (symbol_name, + symbol_page_path)) + continue + + if symbol_name not in symbol_headers: + symbol_headers[symbol_name] = set() + symbol_headers[symbol_name].update(headers) + + for name, headers in sorted(symbol_headers.items(), key=lambda t : t[0]): + symbols.append(Symbol(name, namespace, list(headers))) + return symbols + def ParseArg(): parser = argparse.ArgumentParser(description='Generate StdGen file') @@ -103,46 +147,44 @@ def main(): args = ParseArg() - cpp_reference_root = args.cppreference - cpp_symbol_root = os.path.join(cpp_reference_root, "en", "cpp") - index_page_path = os.path.join(cpp_symbol_root, "symbol_index.html") - if not os.path.exists(index_page_path): - exit("Path %s doesn't exist!" % index_page_path) + cpp_root = os.path.join(args.cppreference, "en", "cpp") + symbol_index_root = os.path.join(cpp_root, "symbol_index") + if not os.path.exists(symbol_index_root): + exit("Path %s doesn't exist!" % symbol_index_root) + + parse_pages = [ + (cpp_root, "symbol_index.html", "std::"), + # std sub-namespace symbols have separated pages. + # We don't index std literal operators (e.g. + # std::literals::chrono_literals::operator""d), these symbols can't be + # accessed by std::. + # FIXME: index std::placeholders symbols, placeholders.html page is + # different (which contains one entry for _1, _2, ..., _N), we need special + # handling. + (symbol_index_root, "chrono.html", "std::chrono::"), + (symbol_index_root, "filesystem.html", "std::filesystem::"), + (symbol_index_root, "pmr.html", "std::pmr::"), + (symbol_index_root, "regex_constants.html", "std::regex_constants::"), + (symbol_index_root, "this_thread.html", "std::this_thread::"), + ] + + symbols = [] + for root_dir, page_name, namespace in parse_pages: + symbols.extend(GetSymbols(root_dir, page_name, namespace)) # We don't have version information from the unzipped offline HTML files. # so we use the modified time of the symbol_index.html as the version. + index_page_path = os.path.join(cpp_root, "symbol_index.html") cppreference_modified_date = datetime.datetime.fromtimestamp( os.stat(index_page_path).st_mtime).strftime('%Y-%m-%d') - - # Workflow steps: - # 1. Parse index page which lists all symbols to get symbol - # name (unqualified name) and its href link to the symbol page which - # contains the defined header. - # 2. Parse the symbol page to get the defined header. - - # A map from symbol name to a set of headers. - symbols = {} - with open(index_page_path, "r") as f: - for symbol_name, symbol_page_path in ParseIndexPage(f.read()): - with open(os.path.join(cpp_symbol_root, symbol_page_path), "r") as f: - headers = ParseSymbolPage(f.read()) - if not headers: - sys.stderr.write("No header found for symbol %s at %s\n" % (symbol_name, - symbol_page_path)) - continue - - if symbol_name not in symbols: - symbols[symbol_name] = set() - symbols[symbol_name].update(headers) - - # Emit results to stdout. - print STDGEN_CODE_PREFIX % cppreference_modified_date - for name, headers in sorted(symbols.items(), key=lambda t : t[0]): - if len(headers) > 1: - # FIXME: support symbols with multiple headers (e.g. std::move). - continue - # SYMBOL(unqualified_name, namespace, header) - print "SYMBOL(%s, %s, %s)" % (name, "std::", list(headers)[0]) + print STDGEN_CODE_PREFIX % cppreference_modified_date + for symbol in symbols: + if len(symbol.headers) > 1: + # FIXME: support symbols with multiple headers (e.g. std::move). + continue + # SYMBOL(unqualified_name, namespace, header) + print "SYMBOL(%s, %s, %s)" % (symbol.name, symbol.namespace, + symbol.headers[0]) if __name__ == '__main__':