This revision was automatically updated to reflect the committed changes. Closed by commit rL364044: [clangd] Add include-mapping for C symbols. (authored by hokein, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D63270?vs=204731&id=205988#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63270/new/ https://reviews.llvm.org/D63270 Files: clang-tools-extra/trunk/clangd/CSymbolMap.inc clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/StdSymbolMap.inc clang-tools-extra/trunk/clangd/include-mapping/cppreference_parser.py clang-tools-extra/trunk/clangd/include-mapping/gen_std.py clang-tools-extra/trunk/clangd/include-mapping/test.py clang-tools-extra/trunk/clangd/index/CanonicalIncludes.cpp clang-tools-extra/trunk/clangd/index/CanonicalIncludes.h clang-tools-extra/trunk/clangd/index/IndexAction.cpp clang-tools-extra/trunk/clangd/unittests/CanonicalIncludesTests.cpp clang-tools-extra/trunk/clangd/unittests/SymbolCollectorTests.cpp
Index: clang-tools-extra/trunk/clangd/unittests/SymbolCollectorTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/SymbolCollectorTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/SymbolCollectorTests.cpp @@ -945,7 +945,9 @@ TEST_F(SymbolCollectorTest, CanonicalSTLHeader) { CollectorOpts.CollectIncludePath = true; CanonicalIncludes Includes; - addSystemHeadersMapping(&Includes); + auto Language = LangOptions(); + Language.CPlusPlus = true; + addSystemHeadersMapping(&Includes, Language); CollectorOpts.Includes = &Includes; runSymbolCollector("namespace std { class string {}; }", /*Main=*/""); EXPECT_THAT(Symbols, Index: clang-tools-extra/trunk/clangd/unittests/CanonicalIncludesTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/CanonicalIncludesTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/CanonicalIncludesTests.cpp @@ -13,12 +13,24 @@ namespace clangd { namespace { +TEST(CanonicalIncludesTest, CStandardLibrary) { + CanonicalIncludes CI; + auto Language = LangOptions(); + Language.C11 = true; + addSystemHeadersMapping(&CI, Language); + // Usual standard library symbols are mapped correctly. + EXPECT_EQ("<stdio.h>", CI.mapHeader("path/stdio.h", "printf")); +} + TEST(CanonicalIncludesTest, CXXStandardLibrary) { CanonicalIncludes CI; - addSystemHeadersMapping(&CI); + auto Language = LangOptions(); + Language.CPlusPlus = true; + addSystemHeadersMapping(&CI, Language); // Usual standard library symbols are mapped correctly. EXPECT_EQ("<vector>", CI.mapHeader("path/vector.h", "std::vector")); + EXPECT_EQ("<cstdio>", CI.mapHeader("path/stdio.h", "std::printf")); // std::move is ambiguous, currently mapped only based on path EXPECT_EQ("<utility>", CI.mapHeader("libstdc++/bits/move.h", "std::move")); EXPECT_EQ("path/utility.h", CI.mapHeader("path/utility.h", "std::move")); Index: clang-tools-extra/trunk/clangd/CSymbolMap.inc =================================================================== --- clang-tools-extra/trunk/clangd/CSymbolMap.inc +++ clang-tools-extra/trunk/clangd/CSymbolMap.inc @@ -0,0 +1,944 @@ +//===-- gen_std.py generated file -------------------------------*- C++ -*-===// +// +// Used to build a lookup table (qualified names => include headers) for C +// Standard Library symbols. +// +// Automatically generated file, DO NOT EDIT! +// +// Generated from cppreference offline HTML book (modified on 2018-10-28). +//===----------------------------------------------------------------------===// + +SYMBOL(ATOMIC_BOOL_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_CHAR16_T_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_CHAR32_T_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_CHAR_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_FLAG_INIT, None, <stdatomic.h>) +SYMBOL(ATOMIC_INT_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_LLONG_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_LONG_LOGK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_POINTER_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_SHORT_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(ATOMIC_VAR_INIT, None, <stdatomic.h>) +SYMBOL(ATOMIC_WCHAR_T_LOCK_FREE, None, <stdatomic.h>) +SYMBOL(BUFSIZ, None, <stdio.h>) +SYMBOL(CHAR_BIT, None, <limits.h>) +SYMBOL(CHAR_MAX, None, <limits.h>) +SYMBOL(CHAR_MIN, None, <limits.h>) +SYMBOL(CLOCKS_PER_SEC, None, <time.h>) +SYMBOL(CMPLX, None, <complex.h>) +SYMBOL(CMPLXF, None, <complex.h>) +SYMBOL(CMPLXL, None, <complex.h>) +SYMBOL(DBL_DECIMAL_DIG, None, <float.h>) +SYMBOL(DBL_DIG, None, <float.h>) +SYMBOL(DBL_EPSILON, None, <float.h>) +SYMBOL(DBL_HAS_SUBNORM, None, <float.h>) +SYMBOL(DBL_MANT_DIG, None, <float.h>) +SYMBOL(DBL_MAX, None, <float.h>) +SYMBOL(DBL_MAX_10_EXP, None, <float.h>) +SYMBOL(DBL_MAX_EXP, None, <float.h>) +SYMBOL(DBL_MIN, None, <float.h>) +SYMBOL(DBL_MIN_10_EXP, None, <float.h>) +SYMBOL(DBL_MIN_EXP, None, <float.h>) +SYMBOL(DBL_TRUE_MIN, None, <float.h>) +SYMBOL(DECIMAL_DIG, None, <float.h>) +SYMBOL(EDOM, None, <errno.h>) +SYMBOL(EILSEQ, None, <errno.h>) +SYMBOL(EOF, None, <stdio.h>) +SYMBOL(ERANGE, None, <errno.h>) +SYMBOL(EXIT_FAILURE, None, <stdlib.h>) +SYMBOL(EXIT_SUCCESS, None, <stdlib.h>) +SYMBOL(FE_ALL_EXCEPT, None, <fenv.h>) +SYMBOL(FE_DFL_ENV, None, <fenv.h>) +SYMBOL(FE_DIVBYZERO, None, <fenv.h>) +SYMBOL(FE_DOWNWARD, None, <fenv.h>) +SYMBOL(FE_INEXACT, None, <fenv.h>) +SYMBOL(FE_INVALID, None, <fenv.h>) +SYMBOL(FE_OVERFLOW, None, <fenv.h>) +SYMBOL(FE_TONEAREST, None, <fenv.h>) +SYMBOL(FE_TOWARDZERO, None, <fenv.h>) +SYMBOL(FE_UNDERFLOW, None, <fenv.h>) +SYMBOL(FE_UPWARD, None, <fenv.h>) +SYMBOL(FILE, None, <stdio.h>) +SYMBOL(FILENAME_MAX, None, <stdio.h>) +SYMBOL(FLT_DECIMAL_DIG, None, <float.h>) +SYMBOL(FLT_DIG, None, <float.h>) +SYMBOL(FLT_EPSILON, None, <float.h>) +SYMBOL(FLT_EVAL_METHOD, None, <float.h>) +SYMBOL(FLT_HAS_SUBNORM, None, <float.h>) +SYMBOL(FLT_MANT_DIG, None, <float.h>) +SYMBOL(FLT_MAX, None, <float.h>) +SYMBOL(FLT_MAX_10_EXP, None, <float.h>) +SYMBOL(FLT_MAX_EXP, None, <float.h>) +SYMBOL(FLT_MIN, None, <float.h>) +SYMBOL(FLT_MIN_10_EXP, None, <float.h>) +SYMBOL(FLT_MIN_EXP, None, <float.h>) +SYMBOL(FLT_RADIX, None, <float.h>) +SYMBOL(FLT_ROUNDS, None, <float.h>) +SYMBOL(FLT_TRUE_MIN, None, <float.h>) +SYMBOL(FOPEN_MAX, None, <stdio.h>) +SYMBOL(FP_INFINITE, None, <math.h>) +SYMBOL(FP_NAN, None, <math.h>) +SYMBOL(FP_NORNAL, None, <math.h>) +SYMBOL(FP_SUBNORMAL, None, <math.h>) +SYMBOL(FP_ZERO, None, <math.h>) +SYMBOL(HUGE_VAL, None, <math.h>) +SYMBOL(HUGE_VALF, None, <math.h>) +SYMBOL(HUGE_VALL, None, <math.h>) +SYMBOL(I, None, <complex.h>) +SYMBOL(INFINITY, None, <math.h>) +SYMBOL(INT16_MAX, None, <stdint.h>) +SYMBOL(INT16_MIN, None, <stdint.h>) +SYMBOL(INT32_MAX, None, <stdint.h>) +SYMBOL(INT32_MIN, None, <stdint.h>) +SYMBOL(INT64_MAX, None, <stdint.h>) +SYMBOL(INT64_MIN, None, <stdint.h>) +SYMBOL(INT8_MAX, None, <stdint.h>) +SYMBOL(INT8_MIN, None, <stdint.h>) +SYMBOL(INTMAX_MAX, None, <stdint.h>) +SYMBOL(INTMAX_MIN, None, <stdint.h>) +SYMBOL(INTPTR_MAX, None, <stdint.h>) +SYMBOL(INTPTR_MIN, None, <stdint.h>) +SYMBOL(INT_FAST16_MAX, None, <stdint.h>) +SYMBOL(INT_FAST16_MIN, None, <stdint.h>) +SYMBOL(INT_FAST32_MAX, None, <stdint.h>) +SYMBOL(INT_FAST32_MIN, None, <stdint.h>) +SYMBOL(INT_FAST64_MAX, None, <stdint.h>) +SYMBOL(INT_FAST64_MIN, None, <stdint.h>) +SYMBOL(INT_FAST8_MAX, None, <stdint.h>) +SYMBOL(INT_FAST8_MIN, None, <stdint.h>) +SYMBOL(INT_LEAST16_MAX, None, <stdint.h>) +SYMBOL(INT_LEAST16_MIN, None, <stdint.h>) +SYMBOL(INT_LEAST32_MAX, None, <stdint.h>) +SYMBOL(INT_LEAST32_MIN, None, <stdint.h>) +SYMBOL(INT_LEAST64_MAX, None, <stdint.h>) +SYMBOL(INT_LEAST64_MIN, None, <stdint.h>) +SYMBOL(INT_LEAST8_MAX, None, <stdint.h>) +SYMBOL(INT_LEAST8_MIN, None, <stdint.h>) +SYMBOL(INT_MAX, None, <limits.h>) +SYMBOL(INT_MIN, None, <limits.h>) +SYMBOL(LC_ALL, None, <locale.h>) +SYMBOL(LC_COLLATE, None, <locale.h>) +SYMBOL(LC_CTYPE, None, <locale.h>) +SYMBOL(LC_MONETARY, None, <locale.h>) +SYMBOL(LC_NUMERIC, None, <locale.h>) +SYMBOL(LC_TIME, None, <locale.h>) +SYMBOL(LDBL_DECIMAL_DIG, None, <float.h>) +SYMBOL(LDBL_DIG, None, <float.h>) +SYMBOL(LDBL_EPSILON, None, <float.h>) +SYMBOL(LDBL_HAS_SUBNORM, None, <float.h>) +SYMBOL(LDBL_MANT_DIG, None, <float.h>) +SYMBOL(LDBL_MAX, None, <float.h>) +SYMBOL(LDBL_MAX_10_EXP, None, <float.h>) +SYMBOL(LDBL_MAX_EXP, None, <float.h>) +SYMBOL(LDBL_MIN, None, <float.h>) +SYMBOL(LDBL_MIN_10_EXP, None, <float.h>) +SYMBOL(LDBL_MIN_EXP, None, <float.h>) +SYMBOL(LDBL_TRUE_MIN, None, <float.h>) +SYMBOL(LLONG_MAX, None, <limits.h>) +SYMBOL(LLONG_MIN, None, <limits.h>) +SYMBOL(LONG_MAX, None, <limits.h>) +SYMBOL(LONG_MIN, None, <limits.h>) +SYMBOL(L_tmpnam, None, <stdio.h>) +SYMBOL(L_tmpnam_s, None, <stdio.h>) +SYMBOL(MATH_ERREXCEPT, None, <math.h>) +SYMBOL(MATH_ERRNO, None, <math.h>) +SYMBOL(MB_CUR_MAX, None, <stdlib.h>) +SYMBOL(MB_LEN_MAX, None, <limits.h>) +SYMBOL(NAN, None, <math.h>) +SYMBOL(ONCE_FLAG_INIT, None, <threads.h>) +SYMBOL(PTRDIFF_MAX, None, <stdint.h>) +SYMBOL(PTRDIFF_MIN, None, <stdint.h>) +SYMBOL(RAND_MAX, None, <stdlib.h>) +SYMBOL(RSIZE_MAX, None, <stdint.h>) +SYMBOL(SCHAR_MAX, None, <limits.h>) +SYMBOL(SCHAR_MIN, None, <limits.h>) +SYMBOL(SEEK_CUR, None, <stdio.h>) +SYMBOL(SEEK_END, None, <stdio.h>) +SYMBOL(SEEK_SET, None, <stdio.h>) +SYMBOL(SHRT_MAX, None, <limits.h>) +SYMBOL(SHRT_MIN, None, <limits.h>) +SYMBOL(SIGABRT, None, <signal.h>) +SYMBOL(SIGFPE, None, <signal.h>) +SYMBOL(SIGILL, None, <signal.h>) +SYMBOL(SIGINT, None, <signal.h>) +SYMBOL(SIGSEGV, None, <signal.h>) +SYMBOL(SIGTERM, None, <signal.h>) +SYMBOL(SIG_ATOMIC_MAX, None, <stdint.h>) +SYMBOL(SIG_ATOMIC_MIN, None, <stdint.h>) +SYMBOL(SIG_DFL, None, <signal.h>) +SYMBOL(SIG_ERR, None, <signal.h>) +SYMBOL(SIG_IGN, None, <signal.h>) +SYMBOL(SIZE_MAX, None, <stdint.h>) +SYMBOL(TIME_UTC, None, <time.h>) +SYMBOL(TMP_MAX, None, <stdio.h>) +SYMBOL(TMP_MAX_S, None, <stdio.h>) +SYMBOL(TSS_DTOR_ITERATIONS, None, <threads.h>) +SYMBOL(UCHAR_MAX, None, <limits.h>) +SYMBOL(UINT16_MAX, None, <stdint.h>) +SYMBOL(UINT32_MAX, None, <stdint.h>) +SYMBOL(UINT64_MAX, None, <stdint.h>) +SYMBOL(UINT8_MAX, None, <stdint.h>) +SYMBOL(UINTMAX_MAX, None, <stdint.h>) +SYMBOL(UINTPTR_MAX, None, <stdint.h>) +SYMBOL(UINT_FAST16_MAX, None, <stdint.h>) +SYMBOL(UINT_FAST32_MAX, None, <stdint.h>) +SYMBOL(UINT_FAST64_MAX, None, <stdint.h>) +SYMBOL(UINT_FAST8_MAX, None, <stdint.h>) +SYMBOL(UINT_LEAST16_MAX, None, <stdint.h>) +SYMBOL(UINT_LEAST32_MAX, None, <stdint.h>) +SYMBOL(UINT_LEAST64_MAX, None, <stdint.h>) +SYMBOL(UINT_LEAST8_MAX, None, <stdint.h>) +SYMBOL(UINT_MAX, None, <limits.h>) +SYMBOL(ULLONG_MAX, None, <limits.h>) +SYMBOL(ULONG_MAX, None, <limits.h>) +SYMBOL(USHRT_MAX, None, <limits.h>) +SYMBOL(WCHAR_MAX, None, <wchar.h>) +SYMBOL(WCHAR_MIN, None, <wchar.h>) +SYMBOL(WEOF, None, <wchar.h>) +SYMBOL(WINT_MAX, None, <stdint.h>) +SYMBOL(WINT_MIN, None, <stdint.h>) +SYMBOL(_Complex_I, None, <complex.h>) +SYMBOL(_IOFBF, None, <stdio.h>) +SYMBOL(_IOLBF, None, <stdio.h>) +SYMBOL(_IONBF, None, <stdio.h>) +SYMBOL(_Imaginary_I, None, <complex.h>) +SYMBOL(__alignas_is_defined, None, <stdalign.h>) +SYMBOL(__alignof_is_defined, None, <stdalign.h>) +SYMBOL(abort_handler_s, None, <stdlib.h>) +SYMBOL(abs, None, <stdlib.h>) +SYMBOL(acos, None, <math.h>) +SYMBOL(acosf, None, <math.h>) +SYMBOL(acosh, None, <math.h>) +SYMBOL(acoshf, None, <math.h>) +SYMBOL(acoshl, None, <math.h>) +SYMBOL(acosl, None, <math.h>) +SYMBOL(alignas, None, <stdalign.h>) +SYMBOL(aligned_alloc, None, <stdlib.h>) +SYMBOL(alignof, None, <stdalign.h>) +SYMBOL(and, None, <iso646.h>) +SYMBOL(and_eq, None, <iso646.h>) +SYMBOL(asctime, None, <time.h>) +SYMBOL(asctime_s, None, <time.h>) +SYMBOL(asin, None, <math.h>) +SYMBOL(asinf, None, <math.h>) +SYMBOL(asinh, None, <math.h>) +SYMBOL(asinhf, None, <math.h>) +SYMBOL(asinhl, None, <math.h>) +SYMBOL(asinl, None, <math.h>) +SYMBOL(assert, None, <assert.h>) +SYMBOL(at_quick_exit, None, <stdlib.h>) +SYMBOL(atan, None, <math.h>) +SYMBOL(atan2, None, <math.h>) +SYMBOL(atan2f, None, <math.h>) +SYMBOL(atan2l, None, <math.h>) +SYMBOL(atanf, None, <math.h>) +SYMBOL(atanh, None, <math.h>) +SYMBOL(atanhf, None, <math.h>) +SYMBOL(atanhl, None, <math.h>) +SYMBOL(atanl, None, <math.h>) +SYMBOL(atexit, None, <stdlib.h>) +SYMBOL(atof, None, <stdlib.h>) +SYMBOL(atoi, None, <stdlib.h>) +SYMBOL(atol, None, <stdlib.h>) +SYMBOL(atoll, None, <stdlib.h>) +SYMBOL(atomic_bool, None, <stdatomic.h>) +SYMBOL(atomic_char, None, <stdatomic.h>) +SYMBOL(atomic_char16_t, None, <stdatomic.h>) +SYMBOL(atomic_char32_t, None, <stdatomic.h>) +SYMBOL(atomic_compare_exchange_strong, None, <stdatomic.h>) +SYMBOL(atomic_compare_exchange_strong_explicit, None, <stdatomic.h>) +SYMBOL(atomic_compare_exchange_weak, None, <stdatomic.h>) +SYMBOL(atomic_compare_exchange_weak_explicit, None, <stdatomic.h>) +SYMBOL(atomic_exchange, None, <stdatomic.h>) +SYMBOL(atomic_exchange_explicit, None, <stdatomic.h>) +SYMBOL(atomic_fetch_add, None, <stdatomic.h>) +SYMBOL(atomic_fetch_add_explicit, None, <stdatomic.h>) +SYMBOL(atomic_fetch_and, None, <stdatomic.h>) +SYMBOL(atomic_fetch_and_explicit, None, <stdatomic.h>) +SYMBOL(atomic_fetch_or, None, <stdatomic.h>) +SYMBOL(atomic_fetch_or_explicit, None, <stdatomic.h>) +SYMBOL(atomic_fetch_sub, None, <stdatomic.h>) +SYMBOL(atomic_fetch_sub_explicit, None, <stdatomic.h>) +SYMBOL(atomic_fetch_xor, None, <stdatomic.h>) +SYMBOL(atomic_fetch_xor_explicit, None, <stdatomic.h>) +SYMBOL(atomic_flag, None, <stdatomic.h>) +SYMBOL(atomic_flag_clear, None, <stdatomic.h>) +SYMBOL(atomic_flag_clear_explicit, None, <stdatomic.h>) +SYMBOL(atomic_flag_test_and_set, None, <stdatomic.h>) +SYMBOL(atomic_flag_test_and_set_explicit, None, <stdatomic.h>) +SYMBOL(atomic_init, None, <stdatomic.h>) +SYMBOL(atomic_int, None, <stdatomic.h>) +SYMBOL(atomic_int_fast16_t, None, <stdatomic.h>) +SYMBOL(atomic_int_fast32_t, None, <stdatomic.h>) +SYMBOL(atomic_int_fast64_t, None, <stdatomic.h>) +SYMBOL(atomic_int_fast8_t, None, <stdatomic.h>) +SYMBOL(atomic_int_least16_t, None, <stdatomic.h>) +SYMBOL(atomic_int_least32_t, None, <stdatomic.h>) +SYMBOL(atomic_int_least64_t, None, <stdatomic.h>) +SYMBOL(atomic_int_least8_t, None, <stdatomic.h>) +SYMBOL(atomic_intmax_t, None, <stdatomic.h>) +SYMBOL(atomic_intptr_t, None, <stdatomic.h>) +SYMBOL(atomic_is_lock_free, None, <stdatomic.h>) +SYMBOL(atomic_llong, None, <stdatomic.h>) +SYMBOL(atomic_load, None, <stdatomic.h>) +SYMBOL(atomic_load_explicit, None, <stdatomic.h>) +SYMBOL(atomic_long, None, <stdatomic.h>) +SYMBOL(atomic_ptrdiff_t, None, <stdatomic.h>) +SYMBOL(atomic_schar, None, <stdatomic.h>) +SYMBOL(atomic_short, None, <stdatomic.h>) +SYMBOL(atomic_signal_fence, None, <stdatomic.h>) +SYMBOL(atomic_size_t, None, <stdatomic.h>) +SYMBOL(atomic_store, None, <stdatomic.h>) +SYMBOL(atomic_store_explicit, None, <stdatomic.h>) +SYMBOL(atomic_thread_fence, None, <stdatomic.h>) +SYMBOL(atomic_uchar, None, <stdatomic.h>) +SYMBOL(atomic_uint, None, <stdatomic.h>) +SYMBOL(atomic_uint_fast16_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_fast32_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_fast64_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_fast8_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_least16_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_least32_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_least64_t, None, <stdatomic.h>) +SYMBOL(atomic_uint_least8_t, None, <stdatomic.h>) +SYMBOL(atomic_uintmax_t, None, <stdatomic.h>) +SYMBOL(atomic_uintptr_t, None, <stdatomic.h>) +SYMBOL(atomic_ullong, None, <stdatomic.h>) +SYMBOL(atomic_ulong, None, <stdatomic.h>) +SYMBOL(atomic_ushort, None, <stdatomic.h>) +SYMBOL(atomic_wchar_t, None, <stdatomic.h>) +SYMBOL(bitand, None, <iso646.h>) +SYMBOL(bitor, None, <iso646.h>) +SYMBOL(bsearch, None, <stdlib.h>) +SYMBOL(bsearch_s, None, <stdlib.h>) +SYMBOL(btowc, None, <wchar.h>) +SYMBOL(c16rtomb, None, <uchar.h>) +SYMBOL(c32rtomb, None, <uchar.h>) +SYMBOL(cabs, None, <complex.h>) +SYMBOL(cabsf, None, <complex.h>) +SYMBOL(cabsl, None, <complex.h>) +SYMBOL(cacos, None, <complex.h>) +SYMBOL(cacosf, None, <complex.h>) +SYMBOL(cacosh, None, <complex.h>) +SYMBOL(cacoshf, None, <complex.h>) +SYMBOL(cacoshl, None, <complex.h>) +SYMBOL(cacosl, None, <complex.h>) +SYMBOL(call_once, None, <threads.h>) +SYMBOL(calloc, None, <stdlib.h>) +SYMBOL(carg, None, <complex.h>) +SYMBOL(cargf, None, <complex.h>) +SYMBOL(cargl, None, <complex.h>) +SYMBOL(casin, None, <complex.h>) +SYMBOL(casinf, None, <complex.h>) +SYMBOL(casinh, None, <complex.h>) +SYMBOL(casinhf, None, <complex.h>) +SYMBOL(casinhl, None, <complex.h>) +SYMBOL(casinl, None, <complex.h>) +SYMBOL(catan, None, <complex.h>) +SYMBOL(catanf, None, <complex.h>) +SYMBOL(catanh, None, <complex.h>) +SYMBOL(catanhf, None, <complex.h>) +SYMBOL(catanhl, None, <complex.h>) +SYMBOL(catanl, None, <complex.h>) +SYMBOL(cbrt, None, <math.h>) +SYMBOL(cbrtf, None, <math.h>) +SYMBOL(cbrtl, None, <math.h>) +SYMBOL(ccos, None, <complex.h>) +SYMBOL(ccosf, None, <complex.h>) +SYMBOL(ccosh, None, <complex.h>) +SYMBOL(ccoshf, None, <complex.h>) +SYMBOL(ccoshl, None, <complex.h>) +SYMBOL(ccosl, None, <complex.h>) +SYMBOL(ceil, None, <math.h>) +SYMBOL(ceilf, None, <math.h>) +SYMBOL(ceill, None, <math.h>) +SYMBOL(cexp, None, <complex.h>) +SYMBOL(cexpf, None, <complex.h>) +SYMBOL(cexpl, None, <complex.h>) +SYMBOL(char16_t, None, <uchar.h>) +SYMBOL(char32_t, None, <uchar.h>) +SYMBOL(cimag, None, <complex.h>) +SYMBOL(cimagf, None, <complex.h>) +SYMBOL(cimagl, None, <complex.h>) +SYMBOL(clearerr, None, <stdio.h>) +SYMBOL(clock, None, <time.h>) +SYMBOL(clock_t, None, <time.h>) +SYMBOL(clog, None, <complex.h>) +SYMBOL(clogf, None, <complex.h>) +SYMBOL(clogl, None, <complex.h>) +SYMBOL(cnd_broadcast, None, <threads.h>) +SYMBOL(cnd_destroy, None, <threads.h>) +SYMBOL(cnd_init, None, <threads.h>) +SYMBOL(cnd_signal, None, <threads.h>) +SYMBOL(cnd_t, None, <threads.h>) +SYMBOL(cnd_timedwait, None, <threads.h>) +SYMBOL(cnd_wait, None, <threads.h>) +SYMBOL(compl, None, <iso646.h>) +SYMBOL(complex, None, <complex.h>) +SYMBOL(conj, None, <complex.h>) +SYMBOL(conjf, None, <complex.h>) +SYMBOL(conjl, None, <complex.h>) +SYMBOL(constraint_handler_t, None, <stdlib.h>) +SYMBOL(copysign, None, <math.h>) +SYMBOL(copysignf, None, <math.h>) +SYMBOL(copysignl, None, <math.h>) +SYMBOL(cos, None, <math.h>) +SYMBOL(cosf, None, <math.h>) +SYMBOL(cosh, None, <math.h>) +SYMBOL(coshf, None, <math.h>) +SYMBOL(coshl, None, <math.h>) +SYMBOL(cosl, None, <math.h>) +SYMBOL(cpow, None, <complex.h>) +SYMBOL(cpowf, None, <complex.h>) +SYMBOL(cpowl, None, <complex.h>) +SYMBOL(cproj, None, <complex.h>) +SYMBOL(cprojf, None, <complex.h>) +SYMBOL(cprojl, None, <complex.h>) +SYMBOL(creal, None, <complex.h>) +SYMBOL(crealf, None, <complex.h>) +SYMBOL(creall, None, <complex.h>) +SYMBOL(csin, None, <complex.h>) +SYMBOL(csinf, None, <complex.h>) +SYMBOL(csinh, None, <complex.h>) +SYMBOL(csinhf, None, <complex.h>) +SYMBOL(csinhl, None, <complex.h>) +SYMBOL(csinl, None, <complex.h>) +SYMBOL(csqrt, None, <complex.h>) +SYMBOL(csqrtf, None, <complex.h>) +SYMBOL(csqrtl, None, <complex.h>) +SYMBOL(ctan, None, <complex.h>) +SYMBOL(ctanf, None, <complex.h>) +SYMBOL(ctanh, None, <complex.h>) +SYMBOL(ctanhf, None, <complex.h>) +SYMBOL(ctanhl, None, <complex.h>) +SYMBOL(ctanl, None, <complex.h>) +SYMBOL(ctime, None, <time.h>) +SYMBOL(ctime_s, None, <time.h>) +SYMBOL(difftime, None, <time.h>) +SYMBOL(double_t, None, <math.h>) +SYMBOL(erf, None, <math.h>) +SYMBOL(erfc, None, <math.h>) +SYMBOL(erfcf, None, <math.h>) +SYMBOL(erfcl, None, <math.h>) +SYMBOL(erff, None, <math.h>) +SYMBOL(erfl, None, <math.h>) +SYMBOL(errno, None, <errno.h>) +SYMBOL(exit, None, <stdlib.h>) +SYMBOL(exp, None, <math.h>) +SYMBOL(exp2, None, <math.h>) +SYMBOL(exp2f, None, <math.h>) +SYMBOL(exp2l, None, <math.h>) +SYMBOL(expf, None, <math.h>) +SYMBOL(expl, None, <math.h>) +SYMBOL(expm1, None, <math.h>) +SYMBOL(expm1f, None, <math.h>) +SYMBOL(expm1l, None, <math.h>) +SYMBOL(fabs, None, <math.h>) +SYMBOL(fabsf, None, <math.h>) +SYMBOL(fabsl, None, <math.h>) +SYMBOL(fclose, None, <stdio.h>) +SYMBOL(fdim, None, <math.h>) +SYMBOL(fdimf, None, <math.h>) +SYMBOL(fdiml, None, <math.h>) +SYMBOL(feclearexcept, None, <fenv.h>) +SYMBOL(fegetenv, None, <fenv.h>) +SYMBOL(fegetexceptflag, None, <fenv.h>) +SYMBOL(fegetround, None, <fenv.h>) +SYMBOL(feholdexcept, None, <fenv.h>) +SYMBOL(fenv_t, None, <fenv.h>) +SYMBOL(feof, None, <stdio.h>) +SYMBOL(feraiseexcept, None, <fenv.h>) +SYMBOL(ferror, None, <stdio.h>) +SYMBOL(fesetenv, None, <fenv.h>) +SYMBOL(fesetexceptflag, None, <fenv.h>) +SYMBOL(fesetround, None, <fenv.h>) +SYMBOL(fetestexcept, None, <fenv.h>) +SYMBOL(feupdateenv, None, <fenv.h>) +SYMBOL(fexcept_t, None, <fenv.h>) +SYMBOL(fflush, None, <stdio.h>) +SYMBOL(fgetc, None, <stdio.h>) +SYMBOL(fgetpos, None, <stdio.h>) +SYMBOL(fgets, None, <stdio.h>) +SYMBOL(fgetwc, None, <wchar.h>) +SYMBOL(fgetws, None, <wchar.h>) +SYMBOL(float_t, None, <math.h>) +SYMBOL(floor, None, <math.h>) +SYMBOL(floorf, None, <math.h>) +SYMBOL(floorl, None, <math.h>) +SYMBOL(fma, None, <math.h>) +SYMBOL(fmaf, None, <math.h>) +SYMBOL(fmal, None, <math.h>) +SYMBOL(fmax, None, <math.h>) +SYMBOL(fmaxf, None, <math.h>) +SYMBOL(fmaxl, None, <math.h>) +SYMBOL(fmin, None, <math.h>) +SYMBOL(fminf, None, <math.h>) +SYMBOL(fminl, None, <math.h>) +SYMBOL(fmod, None, <math.h>) +SYMBOL(fmodf, None, <math.h>) +SYMBOL(fmodl, None, <math.h>) +SYMBOL(fopen, None, <stdio.h>) +SYMBOL(fopen_s, None, <stdio.h>) +SYMBOL(fpclassify, None, <math.h>) +SYMBOL(fpos_t, None, <stdio.h>) +SYMBOL(fprintf, None, <stdio.h>) +SYMBOL(fprintf_s, None, <stdio.h>) +SYMBOL(fputc, None, <stdio.h>) +SYMBOL(fputs, None, <stdio.h>) +SYMBOL(fputwc, None, <wchar.h>) +SYMBOL(fputws, None, <wchar.h>) +SYMBOL(fread, None, <stdio.h>) +SYMBOL(free, None, <stdlib.h>) +SYMBOL(freopen, None, <stdio.h>) +SYMBOL(freopen_s, None, <stdio.h>) +SYMBOL(frexp, None, <math.h>) +SYMBOL(frexpf, None, <math.h>) +SYMBOL(frexpl, None, <math.h>) +SYMBOL(fscanf, None, <stdio.h>) +SYMBOL(fscanf_s, None, <stdio.h>) +SYMBOL(fseek, None, <stdio.h>) +SYMBOL(fsetpos, None, <stdio.h>) +SYMBOL(ftell, None, <stdio.h>) +SYMBOL(fwide, None, <wchar.h>) +SYMBOL(fwprintf, None, <wchar.h>) +SYMBOL(fwprintf_s, None, <wchar.h>) +SYMBOL(fwrite, None, <stdio.h>) +SYMBOL(fwscanf, None, <wchar.h>) +SYMBOL(fwscanf_s, None, <wchar.h>) +SYMBOL(getc, None, <stdio.h>) +SYMBOL(getchar, None, <stdio.h>) +SYMBOL(getenv, None, <stdlib.h>) +SYMBOL(getenv_s, None, <stdlib.h>) +SYMBOL(gets, None, <stdio.h>) +SYMBOL(gets_s, None, <stdio.h>) +SYMBOL(getwc, None, <wchar.h>) +SYMBOL(getwchar, None, <wchar.h>) +SYMBOL(gmtime, None, <time.h>) +SYMBOL(gmtime_s, None, <time.h>) +SYMBOL(hypot, None, <math.h>) +SYMBOL(hypotf, None, <math.h>) +SYMBOL(hypotl, None, <math.h>) +SYMBOL(ignore_handler_s, None, <stdlib.h>) +SYMBOL(ilogb, None, <math.h>) +SYMBOL(ilogbf, None, <math.h>) +SYMBOL(ilogbl, None, <math.h>) +SYMBOL(imaginary, None, <complex.h>) +SYMBOL(imaxabs, None, <inttypes.h>) +SYMBOL(int16_t, None, <stdint.h>) +SYMBOL(int32_t, None, <stdint.h>) +SYMBOL(int64_t, None, <stdint.h>) +SYMBOL(int8_t, None, <stdint.h>) +SYMBOL(int_fast16_t, None, <stdint.h>) +SYMBOL(int_fast32_t, None, <stdint.h>) +SYMBOL(int_fast64_t, None, <stdint.h>) +SYMBOL(int_fast8_t, None, <stdint.h>) +SYMBOL(int_least16_t, None, <stdint.h>) +SYMBOL(int_least32_t, None, <stdint.h>) +SYMBOL(int_least64_t, None, <stdint.h>) +SYMBOL(int_least8_t, None, <stdint.h>) +SYMBOL(intmax_t, None, <stdint.h>) +SYMBOL(intptr_t, None, <stdint.h>) +SYMBOL(isalnum, None, <ctype.h>) +SYMBOL(isalpha, None, <ctype.h>) +SYMBOL(isblank, None, <ctype.h>) +SYMBOL(iscntrl, None, <ctype.h>) +SYMBOL(isdigit, None, <ctype.h>) +SYMBOL(isfinite, None, <math.h>) +SYMBOL(isgraph, None, <ctype.h>) +SYMBOL(isgreater, None, <math.h>) +SYMBOL(isgreaterequal, None, <math.h>) +SYMBOL(isinf, None, <math.h>) +SYMBOL(isless, None, <math.h>) +SYMBOL(islessequal, None, <math.h>) +SYMBOL(islessgreater, None, <math.h>) +SYMBOL(islower, None, <ctype.h>) +SYMBOL(isnan, None, <math.h>) +SYMBOL(isnormal, None, <math.h>) +SYMBOL(isprint, None, <ctype.h>) +SYMBOL(ispunct, None, <ctype.h>) +SYMBOL(isspace, None, <ctype.h>) +SYMBOL(isunordered, None, <math.h>) +SYMBOL(isupper, None, <ctype.h>) +SYMBOL(iswalnum, None, <wctype.h>) +SYMBOL(iswalpha, None, <wctype.h>) +SYMBOL(iswblank, None, <wctype.h>) +SYMBOL(iswcntrl, None, <wctype.h>) +SYMBOL(iswctype, None, <wctype.h>) +SYMBOL(iswdigit, None, <wctype.h>) +SYMBOL(iswgraph, None, <wctype.h>) +SYMBOL(iswlower, None, <wctype.h>) +SYMBOL(iswprint, None, <wctype.h>) +SYMBOL(iswpunct, None, <wctype.h>) +SYMBOL(iswspace, None, <wctype.h>) +SYMBOL(iswupper, None, <wctype.h>) +SYMBOL(iswxdigit, None, <wctype.h>) +SYMBOL(isxdigit, None, <ctype.h>) +SYMBOL(jmp_buf, None, <setjmp.h>) +SYMBOL(kill_dependency, None, <stdatomic.h>) +SYMBOL(labs, None, <stdlib.h>) +SYMBOL(lconv, None, <locale.h>) +SYMBOL(ldexp, None, <math.h>) +SYMBOL(ldexpf, None, <math.h>) +SYMBOL(ldexpl, None, <math.h>) +SYMBOL(lgamma, None, <math.h>) +SYMBOL(lgammaf, None, <math.h>) +SYMBOL(lgammal, None, <math.h>) +SYMBOL(llabs, None, <stdlib.h>) +SYMBOL(llrint, None, <math.h>) +SYMBOL(llrintf, None, <math.h>) +SYMBOL(llrintl, None, <math.h>) +SYMBOL(llround, None, <math.h>) +SYMBOL(llroundf, None, <math.h>) +SYMBOL(llroundl, None, <math.h>) +SYMBOL(localeconv, None, <locale.h>) +SYMBOL(localtime, None, <time.h>) +SYMBOL(localtime_s, None, <time.h>) +SYMBOL(log, None, <math.h>) +SYMBOL(log10, None, <math.h>) +SYMBOL(log10f, None, <math.h>) +SYMBOL(log10l, None, <math.h>) +SYMBOL(log1p, None, <math.h>) +SYMBOL(log1pf, None, <math.h>) +SYMBOL(log1pl, None, <math.h>) +SYMBOL(log2, None, <math.h>) +SYMBOL(log2f, None, <math.h>) +SYMBOL(log2l, None, <math.h>) +SYMBOL(logb, None, <math.h>) +SYMBOL(logbf, None, <math.h>) +SYMBOL(logbl, None, <math.h>) +SYMBOL(logf, None, <math.h>) +SYMBOL(logl, None, <math.h>) +SYMBOL(longjmp, None, <setjmp.h>) +SYMBOL(lrint, None, <math.h>) +SYMBOL(lrintf, None, <math.h>) +SYMBOL(lrintl, None, <math.h>) +SYMBOL(lround, None, <math.h>) +SYMBOL(lroundf, None, <math.h>) +SYMBOL(lroundl, None, <math.h>) +SYMBOL(malloc, None, <stdlib.h>) +SYMBOL(math_errhandling, None, <math.h>) +SYMBOL(max_align_t, None, <stddef.h>) +SYMBOL(mblen, None, <stdlib.h>) +SYMBOL(mbrlen, None, <wchar.h>) +SYMBOL(mbrtoc16, None, <uchar.h>) +SYMBOL(mbrtoc32, None, <uchar.h>) +SYMBOL(mbrtowc, None, <wchar.h>) +SYMBOL(mbsinit, None, <wchar.h>) +SYMBOL(mbsrtowcs, None, <wchar.h>) +SYMBOL(mbsrtowcs_s, None, <wchar.h>) +SYMBOL(mbstowcs, None, <stdlib.h>) +SYMBOL(mbstowcs_s, None, <stdlib.h>) +SYMBOL(mbtowc, None, <stdlib.h>) +SYMBOL(memchr, None, <string.h>) +SYMBOL(memcmp, None, <string.h>) +SYMBOL(memcpy, None, <string.h>) +SYMBOL(memcpy_s, None, <string.h>) +SYMBOL(memmove, None, <string.h>) +SYMBOL(memmove_s, None, <string.h>) +SYMBOL(memory_order, None, <stdatomic.h>) +SYMBOL(memory_order_acq_rel, None, <stdatomic.h>) +SYMBOL(memory_order_acquire, None, <stdatomic.h>) +SYMBOL(memory_order_consume, None, <stdatomic.h>) +SYMBOL(memory_order_relaxed, None, <stdatomic.h>) +SYMBOL(memory_order_release, None, <stdatomic.h>) +SYMBOL(memory_order_seq_cst, None, <stdatomic.h>) +SYMBOL(memset, None, <string.h>) +SYMBOL(memset_s, None, <string.h>) +SYMBOL(mktime, None, <time.h>) +SYMBOL(modf, None, <math.h>) +SYMBOL(modff, None, <math.h>) +SYMBOL(modfl, None, <math.h>) +SYMBOL(mtx_destroy, None, <threads.h>) +SYMBOL(mtx_init, None, <threads.h>) +SYMBOL(mtx_lock, None, <threads.h>) +SYMBOL(mtx_plain, None, <threads.h>) +SYMBOL(mtx_recursive, None, <threads.h>) +SYMBOL(mtx_t, None, <threads.h>) +SYMBOL(mtx_timed, None, <threads.h>) +SYMBOL(mtx_timedlock, None, <threads.h>) +SYMBOL(mtx_trylock, None, <threads.h>) +SYMBOL(mtx_unlock, None, <threads.h>) +SYMBOL(nan, None, <math.h>) +SYMBOL(nanf, None, <math.h>) +SYMBOL(nanl, None, <math.h>) +SYMBOL(nearbyint, None, <math.h>) +SYMBOL(nearbyintf, None, <math.h>) +SYMBOL(nearbyintl, None, <math.h>) +SYMBOL(nextafter, None, <math.h>) +SYMBOL(nextafterf, None, <math.h>) +SYMBOL(nextafterl, None, <math.h>) +SYMBOL(nexttoward, None, <math.h>) +SYMBOL(nexttowardf, None, <math.h>) +SYMBOL(nexttowardl, None, <math.h>) +SYMBOL(noreturn, None, <stdnoreturn.h>) +SYMBOL(not, None, <iso646.h>) +SYMBOL(not_eq, None, <iso646.h>) +SYMBOL(offsetof, None, <stddef.h>) +SYMBOL(once_flag, None, <threads.h>) +SYMBOL(or, None, <iso646.h>) +SYMBOL(or_eq, None, <iso646.h>) +SYMBOL(perror, None, <stdio.h>) +SYMBOL(pow, None, <math.h>) +SYMBOL(powf, None, <math.h>) +SYMBOL(powl, None, <math.h>) +SYMBOL(printf, None, <stdio.h>) +SYMBOL(printf_s, None, <stdio.h>) +SYMBOL(ptrdiff_t, None, <stddef.h>) +SYMBOL(putc, None, <stdio.h>) +SYMBOL(putchar, None, <stdio.h>) +SYMBOL(puts, None, <stdio.h>) +SYMBOL(putwc, None, <wchar.h>) +SYMBOL(putwchar, None, <wchar.h>) +SYMBOL(qsort, None, <stdlib.h>) +SYMBOL(qsort_s, None, <stdlib.h>) +SYMBOL(quick_exit, None, <stdlib.h>) +SYMBOL(raise, None, <signal.h>) +SYMBOL(rand, None, <stdlib.h>) +SYMBOL(realloc, None, <stdlib.h>) +SYMBOL(remainder, None, <math.h>) +SYMBOL(remainderf, None, <math.h>) +SYMBOL(remainderl, None, <math.h>) +SYMBOL(remove, None, <stdio.h>) +SYMBOL(remquo, None, <math.h>) +SYMBOL(remquof, None, <math.h>) +SYMBOL(remquol, None, <math.h>) +SYMBOL(rename, None, <stdio.h>) +SYMBOL(rewind, None, <stdio.h>) +SYMBOL(rint, None, <math.h>) +SYMBOL(rintf, None, <math.h>) +SYMBOL(rintl, None, <math.h>) +SYMBOL(round, None, <math.h>) +SYMBOL(roundf, None, <math.h>) +SYMBOL(roundl, None, <math.h>) +SYMBOL(rsize_t, None, <stddef.h>) +SYMBOL(scalbln, None, <math.h>) +SYMBOL(scalblnf, None, <math.h>) +SYMBOL(scalblnl, None, <math.h>) +SYMBOL(scalbn, None, <math.h>) +SYMBOL(scalbnf, None, <math.h>) +SYMBOL(scalbnl, None, <math.h>) +SYMBOL(scanf, None, <stdio.h>) +SYMBOL(scanf_s, None, <stdio.h>) +SYMBOL(set_constraint_handler_s, None, <stdlib.h>) +SYMBOL(setbuf, None, <stdio.h>) +SYMBOL(setjmp, None, <setjmp.h>) +SYMBOL(setlocale, None, <locale.h>) +SYMBOL(setvbuf, None, <stdio.h>) +SYMBOL(sig_atomic_t, None, <signal.h>) +SYMBOL(signal, None, <signal.h>) +SYMBOL(signbit, None, <math.h>) +SYMBOL(sin, None, <math.h>) +SYMBOL(sinf, None, <math.h>) +SYMBOL(sinh, None, <math.h>) +SYMBOL(sinhf, None, <math.h>) +SYMBOL(sinhl, None, <math.h>) +SYMBOL(sinl, None, <math.h>) +SYMBOL(snprintf, None, <stdio.h>) +SYMBOL(snprintf_s, None, <stdio.h>) +SYMBOL(snwprintf_s, None, <wchar.h>) +SYMBOL(sprintf, None, <stdio.h>) +SYMBOL(sprintf_s, None, <stdio.h>) +SYMBOL(sqrt, None, <math.h>) +SYMBOL(sqrtf, None, <math.h>) +SYMBOL(sqrtl, None, <math.h>) +SYMBOL(srand, None, <stdlib.h>) +SYMBOL(sscanf, None, <stdio.h>) +SYMBOL(sscanf_s, None, <stdio.h>) +SYMBOL(static_assert, None, <assert.h>) +SYMBOL(stderr, None, <stdio.h>) +SYMBOL(stdin, None, <stdio.h>) +SYMBOL(stdout, None, <stdio.h>) +SYMBOL(strcat, None, <string.h>) +SYMBOL(strcat_s, None, <string.h>) +SYMBOL(strchr, None, <string.h>) +SYMBOL(strcmp, None, <string.h>) +SYMBOL(strcoll, None, <string.h>) +SYMBOL(strcpy, None, <string.h>) +SYMBOL(strcpy_s, None, <string.h>) +SYMBOL(strcspn, None, <string.h>) +SYMBOL(strerror, None, <string.h>) +SYMBOL(strerror_s, None, <string.h>) +SYMBOL(strerrorlen_s, None, <string.h>) +SYMBOL(strftime, None, <time.h>) +SYMBOL(strlen, None, <string.h>) +SYMBOL(strncat, None, <string.h>) +SYMBOL(strncat_s, None, <string.h>) +SYMBOL(strncmp, None, <string.h>) +SYMBOL(strncpy, None, <string.h>) +SYMBOL(strncpy_s, None, <string.h>) +SYMBOL(strnlen_s, None, <string.h>) +SYMBOL(strpbrk, None, <string.h>) +SYMBOL(strrchr, None, <string.h>) +SYMBOL(strspn, None, <string.h>) +SYMBOL(strstr, None, <string.h>) +SYMBOL(strtod, None, <stdlib.h>) +SYMBOL(strtof, None, <stdlib.h>) +SYMBOL(strtoimax, None, <inttypes.h>) +SYMBOL(strtok, None, <string.h>) +SYMBOL(strtok_s, None, <string.h>) +SYMBOL(strtol, None, <stdlib.h>) +SYMBOL(strtold, None, <stdlib.h>) +SYMBOL(strtoll, None, <stdlib.h>) +SYMBOL(strtoul, None, <stdlib.h>) +SYMBOL(strtoull, None, <stdlib.h>) +SYMBOL(strtoumax, None, <inttypes.h>) +SYMBOL(strxfrm, None, <string.h>) +SYMBOL(swprintf, None, <wchar.h>) +SYMBOL(swprintf_s, None, <wchar.h>) +SYMBOL(swscanf, None, <wchar.h>) +SYMBOL(swscanf_s, None, <wchar.h>) +SYMBOL(system, None, <stdlib.h>) +SYMBOL(tan, None, <math.h>) +SYMBOL(tanf, None, <math.h>) +SYMBOL(tanh, None, <math.h>) +SYMBOL(tanhf, None, <math.h>) +SYMBOL(tanhl, None, <math.h>) +SYMBOL(tanl, None, <math.h>) +SYMBOL(tgamma, None, <math.h>) +SYMBOL(tgammaf, None, <math.h>) +SYMBOL(tgammal, None, <math.h>) +SYMBOL(thrd_busy, None, <threads.h>) +SYMBOL(thrd_create, None, <threads.h>) +SYMBOL(thrd_current, None, <threads.h>) +SYMBOL(thrd_detach, None, <threads.h>) +SYMBOL(thrd_equal, None, <threads.h>) +SYMBOL(thrd_error, None, <threads.h>) +SYMBOL(thrd_join, None, <threads.h>) +SYMBOL(thrd_nomem, None, <threads.h>) +SYMBOL(thrd_sleep, None, <threads.h>) +SYMBOL(thrd_start_t, None, <threads.h>) +SYMBOL(thrd_success, None, <threads.h>) +SYMBOL(thrd_t, None, <threads.h>) +SYMBOL(thrd_timedout, None, <threads.h>) +SYMBOL(thrd_yield, None, <threads.h>) +SYMBOL(thread_local, None, <threads.h>) +SYMBOL(time, None, <time.h>) +SYMBOL(time_t, None, <time.h>) +SYMBOL(timespec, None, <time.h>) +SYMBOL(timespec_get, None, <time.h>) +SYMBOL(tm, None, <time.h>) +SYMBOL(tmpfile, None, <stdio.h>) +SYMBOL(tmpfile_s, None, <stdio.h>) +SYMBOL(tmpnam, None, <stdio.h>) +SYMBOL(tmpnam_s, None, <stdio.h>) +SYMBOL(tolower, None, <ctype.h>) +SYMBOL(toupper, None, <ctype.h>) +SYMBOL(towctrans, None, <wctype.h>) +SYMBOL(towlower, None, <wctype.h>) +SYMBOL(towupper, None, <wctype.h>) +SYMBOL(trunc, None, <math.h>) +SYMBOL(truncf, None, <math.h>) +SYMBOL(truncl, None, <math.h>) +SYMBOL(tss_create, None, <threads.h>) +SYMBOL(tss_delete, None, <threads.h>) +SYMBOL(tss_dtor_t, None, <threads.h>) +SYMBOL(tss_get, None, <threads.h>) +SYMBOL(tss_set, None, <threads.h>) +SYMBOL(tss_t, None, <threads.h>) +SYMBOL(uint16_t, None, <stdint.h>) +SYMBOL(uint32_t, None, <stdint.h>) +SYMBOL(uint64_t, None, <stdint.h>) +SYMBOL(uint8_t, None, <stdint.h>) +SYMBOL(uint_fast16_t, None, <stdint.h>) +SYMBOL(uint_fast32_t, None, <stdint.h>) +SYMBOL(uint_fast64_t, None, <stdint.h>) +SYMBOL(uint_fast8_t, None, <stdint.h>) +SYMBOL(uint_least16_t, None, <stdint.h>) +SYMBOL(uint_least32_t, None, <stdint.h>) +SYMBOL(uint_least64_t, None, <stdint.h>) +SYMBOL(uint_least8_t, None, <stdint.h>) +SYMBOL(uintmax_t, None, <stdint.h>) +SYMBOL(uintptr_t, None, <stdint.h>) +SYMBOL(ungetc, None, <stdio.h>) +SYMBOL(ungetwc, None, <wchar.h>) +SYMBOL(va_arg, None, <stdarg.h>) +SYMBOL(va_copy, None, <stdarg.h>) +SYMBOL(va_end, None, <stdarg.h>) +SYMBOL(va_start, None, <stdarg.h>) +SYMBOL(vfprintf, None, <stdio.h>) +SYMBOL(vfprintf_s, None, <stdio.h>) +SYMBOL(vfscanf, None, <stdio.h>) +SYMBOL(vfscanf_s, None, <stdio.h>) +SYMBOL(vfwprintf, None, <wchar.h>) +SYMBOL(vfwprintf_s, None, <wchar.h>) +SYMBOL(vfwscanf, None, <wchar.h>) +SYMBOL(vfwscanf_s, None, <wchar.h>) +SYMBOL(vprintf, None, <stdio.h>) +SYMBOL(vprintf_s, None, <stdio.h>) +SYMBOL(vscanf, None, <stdio.h>) +SYMBOL(vscanf_s, None, <stdio.h>) +SYMBOL(vsnprintf, None, <stdio.h>) +SYMBOL(vsnprintf_s, None, <stdio.h>) +SYMBOL(vsnwprintf_s, None, <wchar.h>) +SYMBOL(vsprintf, None, <stdio.h>) +SYMBOL(vsprintf_s, None, <stdio.h>) +SYMBOL(vsscanf, None, <stdio.h>) +SYMBOL(vsscanf_s, None, <stdio.h>) +SYMBOL(vswprintf, None, <wchar.h>) +SYMBOL(vswprintf_s, None, <wchar.h>) +SYMBOL(vswscanf, None, <wchar.h>) +SYMBOL(vswscanf_s, None, <wchar.h>) +SYMBOL(vwprintf, None, <wchar.h>) +SYMBOL(vwprintf_s, None, <wchar.h>) +SYMBOL(vwscanf, None, <wchar.h>) +SYMBOL(vwscanf_s, None, <wchar.h>) +SYMBOL(wchar_t, None, <wchar.h>) +SYMBOL(wcrtomb, None, <wchar.h>) +SYMBOL(wcrtomb_s, None, <wchar.h>) +SYMBOL(wcscat, None, <wchar.h>) +SYMBOL(wcscat_s, None, <wchar.h>) +SYMBOL(wcschr, None, <wchar.h>) +SYMBOL(wcscmp, None, <wchar.h>) +SYMBOL(wcscoll, None, <wchar.h>) +SYMBOL(wcscpy, None, <wchar.h>) +SYMBOL(wcscpy_s, None, <wchar.h>) +SYMBOL(wcscspn, None, <wchar.h>) +SYMBOL(wcsftime, None, <wchar.h>) +SYMBOL(wcslen, None, <wchar.h>) +SYMBOL(wcsncat, None, <wchar.h>) +SYMBOL(wcsncat_s, None, <wchar.h>) +SYMBOL(wcsncmp, None, <wchar.h>) +SYMBOL(wcsncpy, None, <wchar.h>) +SYMBOL(wcsncpy_s, None, <wchar.h>) +SYMBOL(wcsnlen_s, None, <wchar.h>) +SYMBOL(wcspbrk, None, <wchar.h>) +SYMBOL(wcsrchr, None, <wchar.h>) +SYMBOL(wcsrtombs, None, <wchar.h>) +SYMBOL(wcsrtombs_s, None, <wchar.h>) +SYMBOL(wcsspn, None, <wchar.h>) +SYMBOL(wcsstr, None, <wchar.h>) +SYMBOL(wcstod, None, <wchar.h>) +SYMBOL(wcstof, None, <wchar.h>) +SYMBOL(wcstoimax, None, <inttypes.h>) +SYMBOL(wcstok, None, <wchar.h>) +SYMBOL(wcstok_s, None, <wchar.h>) +SYMBOL(wcstol, None, <wchar.h>) +SYMBOL(wcstold, None, <wchar.h>) +SYMBOL(wcstoll, None, <wchar.h>) +SYMBOL(wcstombs, None, <stdlib.h>) +SYMBOL(wcstombs_s, None, <stdlib.h>) +SYMBOL(wcstoul, None, <wchar.h>) +SYMBOL(wcstoull, None, <wchar.h>) +SYMBOL(wcstoumax, None, <inttypes.h>) +SYMBOL(wcsxfrm, None, <wchar.h>) +SYMBOL(wctob, None, <wchar.h>) +SYMBOL(wctomb, None, <stdlib.h>) +SYMBOL(wctomb_s, None, <stdlib.h>) +SYMBOL(wctrans, None, <wctype.h>) +SYMBOL(wctrans_t, None, <wctype.h>) +SYMBOL(wctype, None, <wctype.h>) +SYMBOL(wctype_t, None, <wctype.h>) +SYMBOL(wint_t, None, <wctype.h>) +SYMBOL(wmemchr, None, <wchar.h>) +SYMBOL(wmemcmp, None, <wchar.h>) +SYMBOL(wmemcpy, None, <wchar.h>) +SYMBOL(wmemcpy_s, None, <wchar.h>) +SYMBOL(wmemmove, None, <wchar.h>) +SYMBOL(wmemmove_s, None, <wchar.h>) +SYMBOL(wmemset, None, <wchar.h>) +SYMBOL(wprintf, None, <wchar.h>) +SYMBOL(wprintf_s, None, <wchar.h>) +SYMBOL(wscanf, None, <wchar.h>) +SYMBOL(wscanf_s, None, <wchar.h>) +SYMBOL(xor, None, <iso646.h>) +SYMBOL(xor_eq, None, <iso646.h>) Index: clang-tools-extra/trunk/clangd/index/CanonicalIncludes.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/CanonicalIncludes.cpp +++ clang-tools-extra/trunk/clangd/index/CanonicalIncludes.cpp @@ -86,16 +86,25 @@ return llvm::make_unique<PragmaCommentHandler>(Includes); } -void addSystemHeadersMapping(CanonicalIncludes *Includes) { +void addSystemHeadersMapping(CanonicalIncludes *Includes, + const LangOptions &Language) { static const std::vector<std::pair<const char *, const char *>> SymbolMap = { #define SYMBOL(Name, NameSpace, Header) { #NameSpace#Name, #Header }, #include "StdSymbolMap.inc" #undef SYMBOL }; - - for (const auto &Pair : SymbolMap) - Includes->addSymbolMapping(Pair.first, Pair.second); - + static const std::vector<std::pair<const char *, const char *>> CSymbolMap = { +#define SYMBOL(Name, NameSpace, Header) { #Name, #Header }, + #include "CSymbolMap.inc" +#undef SYMBOL + }; + if (Language.CPlusPlus) { + for (const auto &Pair : SymbolMap) + Includes->addSymbolMapping(Pair.first, Pair.second); + } else if (Language.C11) { + for (const auto &Pair : CSymbolMap) + Includes->addSymbolMapping(Pair.first, Pair.second); + } // FIXME: remove the std header mapping once we support ambiguous symbols, now // it serves as a fallback to disambiguate: // - symbols with mulitiple headers (e.g. std::move) Index: clang-tools-extra/trunk/clangd/index/IndexAction.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/IndexAction.cpp +++ clang-tools-extra/trunk/clangd/index/IndexAction.cpp @@ -128,6 +128,7 @@ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override { CI.getPreprocessor().addCommentHandler(PragmaHandler.get()); + addSystemHeadersMapping(Includes.get(), CI.getLangOpts()); if (IncludeGraphCallback != nullptr) CI.getPreprocessor().addPPCallbacks( llvm::make_unique<IncludeGraphCollector>(CI.getSourceManager(), IG)); @@ -200,7 +201,6 @@ Opts.RefsInHeaders = true; } auto Includes = llvm::make_unique<CanonicalIncludes>(); - addSystemHeadersMapping(Includes.get()); Opts.Includes = Includes.get(); return llvm::make_unique<IndexAction>( std::make_shared<SymbolCollector>(std::move(Opts)), std::move(Includes), Index: clang-tools-extra/trunk/clangd/index/CanonicalIncludes.h =================================================================== --- clang-tools-extra/trunk/clangd/index/CanonicalIncludes.h +++ clang-tools-extra/trunk/clangd/index/CanonicalIncludes.h @@ -84,7 +84,8 @@ /// - Compiler extensions, e.g. include/avx512bwintrin.h$ -> <immintrin.h> /// The mapping is hardcoded and hand-maintained, so it might not cover all /// headers. -void addSystemHeadersMapping(CanonicalIncludes *Includes); +void addSystemHeadersMapping(CanonicalIncludes *Includes, + const LangOptions &Language); } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/StdSymbolMap.inc =================================================================== --- clang-tools-extra/trunk/clangd/StdSymbolMap.inc +++ clang-tools-extra/trunk/clangd/StdSymbolMap.inc @@ -1,6 +1,6 @@ //===-- gen_std.py generated file -------------------------------*- C++ -*-===// // -// Used to build a lookup table (qualified names => include headers) for C++ +// Used to build a lookup table (qualified names => include headers) for CPP // Standard Library symbols. // // Automatically generated file, DO NOT EDIT! Index: clang-tools-extra/trunk/clangd/ClangdUnit.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp @@ -130,7 +130,6 @@ public: CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) : File(File), ParsedCallback(ParsedCallback) { - addSystemHeadersMapping(&CanonIncludes); } IncludeStructure takeIncludes() { return std::move(Includes); } @@ -149,6 +148,7 @@ } void BeforeExecute(CompilerInstance &CI) override { + addSystemHeadersMapping(&CanonIncludes, CI.getLangOpts()); SourceMgr = &CI.getSourceManager(); } @@ -414,7 +414,7 @@ if (Preamble) CanonIncludes = Preamble->CanonIncludes; else - addSystemHeadersMapping(&CanonIncludes); + addSystemHeadersMapping(&CanonIncludes, Clang->getLangOpts()); std::unique_ptr<CommentHandler> IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes); Clang->getPreprocessor().addCommentHandler(IWYUHandler.get()); Index: clang-tools-extra/trunk/clangd/include-mapping/gen_std.py =================================================================== --- clang-tools-extra/trunk/clangd/include-mapping/gen_std.py +++ clang-tools-extra/trunk/clangd/include-mapping/gen_std.py @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# """gen_std.py is a tool to generate a lookup table (from qualified names to -include headers) for C++ Standard Library symbols by parsing archieved HTML +include headers) for C/C++ Standard Library symbols by parsing archieved HTML files from cppreference. Caveats and FIXMEs: @@ -25,24 +25,23 @@ 3. Unzip the zip file from step 2 to directory </cppreference>, you should get a "reference" directory in </cppreference> 4. Run the command: - gen_std.py -cppreference </cppreference/reference> > StdSymbolMap.inc + // Generate C++ symbols + gen_std.py -cppreference </cppreference/reference> -language=cpp > StdSymbolMap.inc + // Generate C symbols + gen_std.py -cppreference </cppreference/reference> -language=c > CSymbolMap.inc """ -from bs4 import BeautifulSoup, NavigableString +import cppreference_parser import argparse -import collections import datetime -import multiprocessing import os -import re -import signal import sys -STDGEN_CODE_PREFIX = """\ +CODE_PREFIX = """\ //===-- gen_std.py generated file -------------------------------*- C++ -*-===// // -// Used to build a lookup table (qualified names => include headers) for C++ +// Used to build a lookup table (qualified names => include headers) for %s // Standard Library symbols. // // Automatically generated file, DO NOT EDIT! @@ -51,189 +50,56 @@ //===----------------------------------------------------------------------===// """ -def HasClass(tag, *classes): - for c in tag.get('class', []): - if c in classes: - return True - return False - -def ParseSymbolPage(symbol_page_html, symbol_name): - """Parse symbol page and retrieve the include header defined in this page. - The symbol page provides header for the symbol, specifically in - "Defined in header <header>" section. An example: - - <tr class="t-dsc-header"> - <td colspan="2"> <div>Defined in header <code><ratio></code> </div> - </td></tr> - - Returns a list of headers. - """ - headers = set() - all_headers = set() - - soup = BeautifulSoup(symbol_page_html, "html.parser") - # Rows in table are like: - # Defined in header <foo> .t-dsc-header - # Defined in header <bar> .t-dsc-header - # decl1 .t-dcl - # Defined in header <baz> .t-dsc-header - # decl2 .t-dcl - for table in soup.select('table.t-dcl-begin, table.t-dsc-begin'): - current_headers = [] - was_decl = False - for row in table.select('tr'): - if HasClass(row, 't-dcl', 't-dsc'): - was_decl = True - # Symbols are in the first cell. - found_symbols = row.find('td').stripped_strings - if not symbol_name in found_symbols: - continue - headers.update(current_headers) - elif HasClass(row, 't-dsc-header'): - # If we saw a decl since the last header, this is a new block of headers - # for a new block of decls. - if was_decl: - current_headers = [] - was_decl = False - # There are also .t-dsc-header for "defined in namespace". - if not "Defined in header " in row.text: - continue - # The interesting header content (e.g. <cstdlib>) is wrapped in <code>. - for header_code in row.find_all("code"): - current_headers.append(header_code.text) - all_headers.add(header_code.text) - # If the symbol was never named, consider all named headers. - return headers or all_headers - - -def ParseIndexPage(index_page_html): - """Parse index page. - The index page lists all std symbols and hrefs to their detailed pages - (which contain the defined header). An example: - - <a href="abs.html" title="abs"><tt>abs()</tt></a> (int) <br> - <a href="acos.html" title="acos"><tt>acos()</tt></a> <br> - - Returns a list of tuple (symbol_name, relative_path_to_symbol_page, variant). - """ - symbols = [] - soup = BeautifulSoup(index_page_html, "html.parser") - for symbol_href in soup.select("a[title]"): - # Ignore annotated symbols like "acos<>() (std::complex)". - # These tend to be overloads, and we the primary is more useful. - # This accidentally accepts begin/end despite the (iterator) caption: the - # (since C++11) note is first. They are good symbols, so the bug is unfixed. - caption = symbol_href.next_sibling - variant = isinstance(caption, NavigableString) and "(" in caption - symbol_tt = symbol_href.find("tt") - if symbol_tt: - symbols.append((symbol_tt.text.rstrip("<>()"), # strip any trailing <>() - symbol_href["href"], variant)) - 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 ReadSymbolPage(path, name): - with open(path) as f: - return ParseSymbolPage(f.read(), name) - - -def GetSymbols(pool, 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) - with open(index_page_path, "r") as f: - # Read each symbol page in parallel. - results = [] # (symbol_name, promise of [header...]) - for symbol_name, symbol_page_path, variant in ParseIndexPage(f.read()): - # Variant symbols (e.g. the std::locale version of isalpha) add ambiguity. - # FIXME: use these as a fallback rather than ignoring entirely. - if variant: - continue - path = os.path.join(root_dir, symbol_page_path) - results.append((symbol_name, - pool.apply_async(ReadSymbolPage, (path, symbol_name)))) - - # Build map from symbol name to a set of headers. - symbol_headers = collections.defaultdict(set) - for symbol_name, lazy_headers in results: - symbol_headers[symbol_name].update(lazy_headers.get()) - - symbols = [] - 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') parser.add_argument('-cppreference', metavar='PATH', default='', help='path to the cppreference offline HTML directory', required=True - ) + ) + parser.add_argument('-language', + default='cpp', + help='Generate c or cpp symbols', + required=True) return parser.parse_args() def main(): args = ParseArg() - cpp_root = os.path.join(args.cppreference, "en", "cpp") - symbol_index_root = os.path.join(cpp_root, "symbol_index") + if args.language == 'cpp': + page_root = os.path.join(args.cppreference, "en", "cpp") + symbol_index_root = os.path.join(page_root, "symbol_index") + parse_pages = [ + (page_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::<symbol_name>. + # 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::"), + ] + elif args.language == 'c': + page_root = os.path.join(args.cppreference, "en", "c") + symbol_index_root = page_root + parse_pages = [(page_root, "index.html", None)] + 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::<symbol_name>. - # 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 = [] - # Run many workers to process individual symbol pages under the symbol index. - # Don't allow workers to capture Ctrl-C. - pool = multiprocessing.Pool( - initializer=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN)) - try: - for root_dir, page_name, namespace in parse_pages: - symbols.extend(GetSymbols(pool, root_dir, page_name, namespace)) - finally: - pool.terminate() - pool.join() + symbols = cppreference_parser.GetSymbols(parse_pages) # 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") + index_page_path = os.path.join(page_root, "index.html") cppreference_modified_date = datetime.datetime.fromtimestamp( os.stat(index_page_path).st_mtime).strftime('%Y-%m-%d') - print STDGEN_CODE_PREFIX % cppreference_modified_date + print CODE_PREFIX % (args.language.upper(), cppreference_modified_date) for symbol in symbols: if len(symbol.headers) == 1: # SYMBOL(unqualified_name, namespace, header) Index: clang-tools-extra/trunk/clangd/include-mapping/test.py =================================================================== --- clang-tools-extra/trunk/clangd/include-mapping/test.py +++ clang-tools-extra/trunk/clangd/include-mapping/test.py @@ -7,7 +7,7 @@ # #===------------------------------------------------------------------------===# -from gen_std import ParseSymbolPage, ParseIndexPage +from cppreference_parser import _ParseSymbolPage, _ParseIndexPage import unittest @@ -22,7 +22,7 @@ <a href="as_bytes.html" title="as bytes"><tt>as_bytes<>()</tt></a> <span class="t-mark-rev t-since-cxx20">(since C++20)</span> <br> """ - actual = ParseIndexPage(html) + actual = _ParseIndexPage(html) expected = [ ("abs", "abs.html", True), ("abs", "complex/abs.html", True), @@ -53,7 +53,7 @@ </tr> </tbody></table> """ - self.assertEqual(ParseSymbolPage(html, 'foo'), set(['<cmath>'])) + self.assertEqual(_ParseSymbolPage(html, 'foo'), set(['<cmath>'])) def testParseSymbolPage_MulHeaders(self): @@ -94,7 +94,7 @@ </tr> </tbody></table> """ - self.assertEqual(ParseSymbolPage(html, "foo"), + self.assertEqual(_ParseSymbolPage(html, "foo"), set(['<cstdio>', '<cstdlib>'])) @@ -121,7 +121,7 @@ </tr> </tbody></table> """ - self.assertEqual(ParseSymbolPage(html, "foo"), + self.assertEqual(_ParseSymbolPage(html, "foo"), set(['<algorithm>', '<utility>'])) def testParseSymbolPage_MulSymbolsInSameTd(self): @@ -145,9 +145,9 @@ </tr> </tbody></table> """ - self.assertEqual(ParseSymbolPage(html, "int8_t"), + self.assertEqual(_ParseSymbolPage(html, "int8_t"), set(['<cstdint>'])) - self.assertEqual(ParseSymbolPage(html, "int16_t"), + self.assertEqual(_ParseSymbolPage(html, "int16_t"), set(['<cstdint>'])) Index: clang-tools-extra/trunk/clangd/include-mapping/cppreference_parser.py =================================================================== --- clang-tools-extra/trunk/clangd/include-mapping/cppreference_parser.py +++ clang-tools-extra/trunk/clangd/include-mapping/cppreference_parser.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +#===- cppreference_parser.py - ------------------------------*- python -*--===# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#===------------------------------------------------------------------------===# + +from bs4 import BeautifulSoup, NavigableString + +import collections +import multiprocessing +import os +import re +import signal +import sys + + +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::", "" (global scope) + # None for C symbols. + self.namespace = namespace + # a list of corresponding headers + self.headers = headers + + +def _HasClass(tag, *classes): + for c in tag.get('class', []): + if c in classes: + return True + return False + + +def _ParseSymbolPage(symbol_page_html, symbol_name): + """Parse symbol page and retrieve the include header defined in this page. + The symbol page provides header for the symbol, specifically in + "Defined in header <header>" section. An example: + + <tr class="t-dsc-header"> + <td colspan="2"> <div>Defined in header <code><ratio></code> </div> + </td></tr> + + Returns a list of headers. + """ + headers = set() + all_headers = set() + + soup = BeautifulSoup(symbol_page_html, "html.parser") + # Rows in table are like: + # Defined in header <foo> .t-dsc-header + # Defined in header <bar> .t-dsc-header + # decl1 .t-dcl + # Defined in header <baz> .t-dsc-header + # decl2 .t-dcl + for table in soup.select('table.t-dcl-begin, table.t-dsc-begin'): + current_headers = [] + was_decl = False + for row in table.select('tr'): + if _HasClass(row, 't-dcl', 't-dsc'): + was_decl = True + # Symbols are in the first cell. + found_symbols = row.find('td').stripped_strings + if not symbol_name in found_symbols: + continue + headers.update(current_headers) + elif _HasClass(row, 't-dsc-header'): + # If we saw a decl since the last header, this is a new block of headers + # for a new block of decls. + if was_decl: + current_headers = [] + was_decl = False + # There are also .t-dsc-header for "defined in namespace". + if not "Defined in header " in row.text: + continue + # The interesting header content (e.g. <cstdlib>) is wrapped in <code>. + for header_code in row.find_all("code"): + current_headers.append(header_code.text) + all_headers.add(header_code.text) + # If the symbol was never named, consider all named headers. + return headers or all_headers + + +def _ParseIndexPage(index_page_html): + """Parse index page. + The index page lists all std symbols and hrefs to their detailed pages + (which contain the defined header). An example: + + <a href="abs.html" title="abs"><tt>abs()</tt></a> (int) <br> + <a href="acos.html" title="acos"><tt>acos()</tt></a> <br> + + Returns a list of tuple (symbol_name, relative_path_to_symbol_page, variant). + """ + symbols = [] + soup = BeautifulSoup(index_page_html, "html.parser") + for symbol_href in soup.select("a[title]"): + # Ignore annotated symbols like "acos<>() (std::complex)". + # These tend to be overloads, and we the primary is more useful. + # This accidentally accepts begin/end despite the (iterator) caption: the + # (since C++11) note is first. They are good symbols, so the bug is unfixed. + caption = symbol_href.next_sibling + variant = isinstance(caption, NavigableString) and "(" in caption + symbol_tt = symbol_href.find("tt") + if symbol_tt: + symbols.append((symbol_tt.text.rstrip("<>()"), # strip any trailing <>() + symbol_href["href"], variant)) + return symbols + + +def _ReadSymbolPage(path, name): + with open(path) as f: + return _ParseSymbolPage(f.read(), name) + + +def _GetSymbols(pool, 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) + with open(index_page_path, "r") as f: + # Read each symbol page in parallel. + results = [] # (symbol_name, promise of [header...]) + for symbol_name, symbol_page_path, variant in _ParseIndexPage(f.read()): + # Variant symbols (e.g. the std::locale version of isalpha) add ambiguity. + # FIXME: use these as a fallback rather than ignoring entirely. + if variant: + continue + path = os.path.join(root_dir, symbol_page_path) + results.append((symbol_name, + pool.apply_async(_ReadSymbolPage, (path, symbol_name)))) + + # Build map from symbol name to a set of headers. + symbol_headers = collections.defaultdict(set) + for symbol_name, lazy_headers in results: + symbol_headers[symbol_name].update(lazy_headers.get()) + + symbols = [] + for name, headers in sorted(symbol_headers.items(), key=lambda t : t[0]): + symbols.append(Symbol(name, namespace, list(headers))) + return symbols + + +def GetSymbols(parse_pages): + """Get all symbols by parsing the given pages. + + Args: + parse_pages: a list of tuples (page_root_dir, index_page_name, namespace) + """ + symbols = [] + # Run many workers to process individual symbol pages under the symbol index. + # Don't allow workers to capture Ctrl-C. + pool = multiprocessing.Pool( + initializer=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN)) + try: + for root_dir, page_name, namespace in parse_pages: + symbols.extend(_GetSymbols(pool, root_dir, page_name, namespace)) + finally: + pool.terminate() + pool.join() + return symbols
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits