[PATCH] D28207: Add second fast path for DiagnosticsEngine::GetDiagStatePointForLoc
djasper created this revision. djasper added a reviewer: rsmith. djasper added a subscriber: cfe-commits. Herald added a subscriber: sanjoy. In many translation units I have tested, many of the calls to DiagnosticsEngine::GetDiagStatePointForLoc are for source locations before the first diag state point. AFAICT, this happens frequently for locations in the STL and other base libraries. This patch adds a fast path for this case to avoid the costly binary search. This binary search is costly, because the relatively slow SourceManager::isBeforeInTranslationUnit() is used to compare DiagStatePoints. https://reviews.llvm.org/D28207 Files: lib/Basic/Diagnostic.cpp Index: lib/Basic/Diagnostic.cpp === --- lib/Basic/Diagnostic.cpp +++ lib/Basic/Diagnostic.cpp @@ -163,21 +163,28 @@ assert(DiagStatePoints.front().Loc.isInvalid() && "Should have created a DiagStatePoint for command-line"); - if (!SourceMgr) + if (!SourceMgr || DiagStatePoints.size() == 1) return DiagStatePoints.end() - 1; FullSourceLoc Loc(L, *SourceMgr); if (Loc.isInvalid()) return DiagStatePoints.end() - 1; - DiagStatePointsTy::iterator Pos = DiagStatePoints.end(); + // Most frequent case: L is after the last diag state change. FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; - if (LastStateChangePos.isValid() && - Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) -Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), - DiagStatePoint(nullptr, Loc)); - --Pos; - return Pos; + assert(LastStateChangePos.isValid()); + if (!Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) +return DiagStatePoints.end() - 1; + + // 2nd most frequent case: L is before the first diag state change. + FullSourceLoc FirstStateChangePos = DiagStatePoints[1].Loc; + assert(FirstStateChangePos.isValid()); + if (Loc.isBeforeInTranslationUnitThan(FirstStateChangePos)) +return DiagStatePoints.begin(); + + // Fall back to binary search. + return std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), + DiagStatePoint(nullptr, Loc)) - 1; } void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, Index: lib/Basic/Diagnostic.cpp === --- lib/Basic/Diagnostic.cpp +++ lib/Basic/Diagnostic.cpp @@ -163,21 +163,28 @@ assert(DiagStatePoints.front().Loc.isInvalid() && "Should have created a DiagStatePoint for command-line"); - if (!SourceMgr) + if (!SourceMgr || DiagStatePoints.size() == 1) return DiagStatePoints.end() - 1; FullSourceLoc Loc(L, *SourceMgr); if (Loc.isInvalid()) return DiagStatePoints.end() - 1; - DiagStatePointsTy::iterator Pos = DiagStatePoints.end(); + // Most frequent case: L is after the last diag state change. FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; - if (LastStateChangePos.isValid() && - Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) -Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), - DiagStatePoint(nullptr, Loc)); - --Pos; - return Pos; + assert(LastStateChangePos.isValid()); + if (!Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) +return DiagStatePoints.end() - 1; + + // 2nd most frequent case: L is before the first diag state change. + FullSourceLoc FirstStateChangePos = DiagStatePoints[1].Loc; + assert(FirstStateChangePos.isValid()); + if (Loc.isBeforeInTranslationUnitThan(FirstStateChangePos)) +return DiagStatePoints.begin(); + + // Fall back to binary search. + return std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), + DiagStatePoint(nullptr, Loc)) - 1; } void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28208: Remove isIgnored()-test that is more expensive than the analysis behind it
djasper created this revision. djasper added a reviewer: rsmith. djasper added a subscriber: cfe-commits. In many translation units I have tried, the calls to isIgnored() removed in this patch are more expensive than doing the analysis that is behind it. The speed-up in translation units I have tried is between 10 and 20%. https://reviews.llvm.org/D28208 Files: lib/Sema/SemaTemplate.cpp Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -4244,7 +4244,7 @@ UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { } bool Visit(QualType T) { - return inherited::Visit(T.getTypePtr()); + return T.isNull() ? false : inherited::Visit(T.getTypePtr()); } #define TYPE(Class, Parent) \ @@ -4497,17 +4497,7 @@ // // C++11 allows these, and even in C++03 we allow them as an extension with // a warning. - bool NeedsCheck; - if (LangOpts.CPlusPlus11) -NeedsCheck = -!Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type, - SR.getBegin()) || -!Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type, - SR.getBegin()); - else -NeedsCheck = Arg->hasUnnamedOrLocalType(); - - if (NeedsCheck) { + if (LangOpts.CPlusPlus11 || Arg->hasUnnamedOrLocalType()) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); } Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -4244,7 +4244,7 @@ UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { } bool Visit(QualType T) { - return inherited::Visit(T.getTypePtr()); + return T.isNull() ? false : inherited::Visit(T.getTypePtr()); } #define TYPE(Class, Parent) \ @@ -4497,17 +4497,7 @@ // // C++11 allows these, and even in C++03 we allow them as an extension with // a warning. - bool NeedsCheck; - if (LangOpts.CPlusPlus11) -NeedsCheck = -!Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type, - SR.getBegin()) || -!Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type, - SR.getBegin()); - else -NeedsCheck = Arg->hasUnnamedOrLocalType(); - - if (NeedsCheck) { + if (LangOpts.CPlusPlus11 || Arg->hasUnnamedOrLocalType()) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r290792 - [c++17] Implement P0522R0 as written. This allows a template template argument
> On Dec 31, 2016, at 4:41 PM, Richard Smith via cfe-commits > wrote: > > Author: rsmith > Date: Sat Dec 31 15:41:23 2016 > New Revision: 290792 > > URL: http://llvm.org/viewvc/llvm-project?rev=290792&view=rev > Log: > [c++17] Implement P0522R0 as written. This allows a template template argument > to be specified for a template template parameter whenever the parameter is at > least as specialized as the argument (when there's an obvious and correct > mapping from uses of the parameter to uses of the argument). For example, a > template with more parameters can be passed to a template template parameter > with fewer, if those trailing parameters have default arguments. > > This is disabled by default, despite being a DR resolution, as it's fairly > broken in its current state: there are no partial ordering rules to cope with > template template parameters that have different parameter lists, meaning that > code that attempts to decompose template-ids based on arity can hit > unavoidable > ambiguity issues. > > The diagnostics produced on a non-matching argument are also pretty bad right > now, but I aim to improve them in a subsequent commit. > > Added: >cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp > Modified: >cfe/trunk/include/clang/Basic/LangOptions.def >cfe/trunk/include/clang/Driver/Options.td >cfe/trunk/include/clang/Sema/Sema.h >cfe/trunk/lib/Driver/Tools.cpp >cfe/trunk/lib/Frontend/CompilerInvocation.cpp >cfe/trunk/lib/Sema/SemaTemplate.cpp >cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp >cfe/trunk/test/SemaTemplate/temp_arg_template.cpp >cfe/trunk/www/cxx_status.html > > Modified: cfe/trunk/include/clang/Basic/LangOptions.def > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=290792&r1=290791&r2=290792&view=diff > == > --- cfe/trunk/include/clang/Basic/LangOptions.def (original) > +++ cfe/trunk/include/clang/Basic/LangOptions.def Sat Dec 31 15:41:23 2016 > @@ -134,6 +134,7 @@ LANGOPT(NoBuiltin , 1, 0, "disab > LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") > LANGOPT(GNUAsm, 1, 1, "GNU-style inline assembly") > LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS") > +LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of > tempalte template arguments") > > BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") > LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") > > Modified: cfe/trunk/include/clang/Driver/Options.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=290792&r1=290791&r2=290792&view=diff > == > --- cfe/trunk/include/clang/Driver/Options.td (original) > +++ cfe/trunk/include/clang/Driver/Options.td Sat Dec 31 15:41:23 2016 > @@ -1088,6 +1088,11 @@ def fapplication_extension : Flag<["-"], > HelpText<"Restrict code to those available for App Extensions">; > def fno_application_extension : Flag<["-"], "fno-application-extension">, > Group; > +def frelaxed_template_template_args : Flag<["-"], > "frelaxed-template-template-args">, > + Flags<[CC1Option]>, HelpText<"Enable C++17 relaxed template template > argument matching">, > + Group; > +def fno_relaxed_template_template_args : Flag<["-"], > "fno-relaxed-template-template-args">, > + Group; > def fsized_deallocation : Flag<["-"], "fsized-deallocation">, > Flags<[CC1Option]>, > HelpText<"Enable C++14 sized global deallocation functions">, > Group; > def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, > Group; > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=290792&r1=290791&r2=290792&view=diff > == > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Sat Dec 31 15:41:23 2016 > @@ -6719,6 +6719,9 @@ public: > bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T, > sema::TemplateDeductionInfo &Info); > > + bool isTemplateTemplateParameterAtLeastAsSpecializedAs( > + TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc); > + > void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, > bool OnlyDeduced, > unsigned Depth, > > Modified: cfe/trunk/lib/Driver/Tools.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=290792&r1=290791&r2=290792&view=diff > == > --- cfe/trunk/lib/Driver/Tools.cpp (original) > +++ cfe/trunk/lib/Driver/Tools.cpp Sat Dec 31 15:41:23 2016 >
[PATCH] D28081: Make GetStyle return Expected instead of FormatStyle
amaiorano added inline comments. Comment at: lib/Format/Format.cpp:1900 - if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) { -llvm::errs() << "Invalid fallback style \"" << FallbackStyle - << "\" using LLVM style\n"; -return Style; - } + FormatStyle FallbackStyle = getNoStyle(); + if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) amaiorano wrote: > Going over my diff, I realize that I didn't revert this local FormatStyle > instance to make use of the top-level declared "FormatStyle Style" local > variable. I will revert this one too. I wrote the above comment before realizing there was a bug when fallback style is "none". As I explained in my long comment, we may actually want to keep this as a separate variable to fix the bug and ensure fallback style is only ever returned when no config is found, which is exactly what my change currently does. https://reviews.llvm.org/D28081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r290799 - CodeGen: update comment about RTTI field
Author: compnerd Date: Sun Jan 1 13:16:02 2017 New Revision: 290799 URL: http://llvm.org/viewvc/llvm-project?rev=290799&view=rev Log: CodeGen: update comment about RTTI field The MS ABI RTTI has a reserved field which is used as a cache for the demangled name. It must be zero-initialized, which is used as a hint by the runtime to say that the cache has not been populated. Since this field is populated at runtime, the RTTI structures must be placed in the .data section rather than .rdata. NFC Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=290799&r1=290798&r2=290799&view=diff == --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Sun Jan 1 13:16:02 2017 @@ -3536,7 +3536,7 @@ llvm::GlobalVariable *MSRTTIBuilder::get // Initialize the base class ClassHierarchyDescriptor. llvm::Constant *Fields[] = { - llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown + llvm::ConstantInt::get(CGM.IntTy, 0), // reserved by the runtime llvm::ConstantInt::get(CGM.IntTy, Flags), llvm::ConstantInt::get(CGM.IntTy, Classes.size()), ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr( ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290802 - build: further improve flags handling for cl
Author: compnerd Date: Sun Jan 1 14:20:40 2017 New Revision: 290802 URL: http://llvm.org/viewvc/llvm-project?rev=290802&view=rev Log: build: further improve flags handling for cl This allows us to build with cl (or rather clang-cl) by using the correct spelling for `-include` (`/FI` for cl). clang-cl and cl default to C++11/C++14 as they support it rather than permitting an explicit language standard. Modified: libcxx/trunk/CMakeLists.txt Modified: libcxx/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=290802&r1=290801&r2=290802&view=diff == --- libcxx/trunk/CMakeLists.txt (original) +++ libcxx/trunk/CMakeLists.txt Sun Jan 1 14:20:40 2017 @@ -354,8 +354,10 @@ if (LIBCXX_HAS_MUSL_LIBC) endif() add_compile_flags_if_supported(-std=${LIBCXX_STANDARD_VER}) mangle_name("LIBCXX_SUPPORTS_STD_EQ_${LIBCXX_STANDARD_VER}_FLAG" SUPPORTS_DIALECT_NAME) -if (NOT MSVC AND NOT ${SUPPORTS_DIALECT_NAME}) - message(FATAL_ERROR "C++11 or greater is required but the compiler does not support ${LIBCXX_STANDARD_VER}") +if(NOT ${SUPPORTS_DIALECT_NAME}) + if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") +message(FATAL_ERROR "C++11 or greater is required but the compiler does not support ${LIBCXX_STANDARD_VER}") + endif() endif() # On all systems the system c++ standard library headers need to be excluded. @@ -515,13 +517,17 @@ if (DEFINED WIN32 AND LIBCXX_ENABLE_STAT endif() if (LIBCXX_NEEDS_SITE_CONFIG) - configure_file( -include/__config_site.in -${LIBCXX_BINARY_DIR}/__config_site -@ONLY) + configure_file("include/__config_site.in" + "${LIBCXX_BINARY_DIR}/__config_site" + @ONLY) + # Provide the config definitions by included the generated __config_site # file at compile time. - add_compile_flags("-include ${LIBCXX_BINARY_DIR}/__config_site") + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") +add_compile_flags("/FI\"${LIBCXX_BINARY_DIR}/__config_site\"") + else() +add_compile_flags("-include ${LIBCXX_BINARY_DIR}/__config_site") + endif() endif() #=== ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290804 - chrono: give Windows a steady_clock
Author: compnerd Date: Sun Jan 1 14:20:43 2017 New Revision: 290804 URL: http://llvm.org/viewvc/llvm-project?rev=290804&view=rev Log: chrono: give Windows a steady_clock Provide a definition for a steady monotonic clock by wrapping QueryPerformanceCounter. Modified: libcxx/trunk/src/chrono.cpp Modified: libcxx/trunk/src/chrono.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290804&r1=290803&r2=290804&view=diff == --- libcxx/trunk/src/chrono.cpp (original) +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:43 2017 @@ -25,10 +25,10 @@ #endif #endif -#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC) +#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) #if __APPLE__ #include // mach_absolute_time, mach_timebase_info_data_t -#else +#elif !defined(_WIN32) && !defined(CLOCK_MONOTONIC) #error "Monotonic clock not implemented" #endif #endif @@ -101,18 +101,7 @@ system_clock::from_time_t(time_t t) _NOE const bool steady_clock::is_steady; -#ifdef CLOCK_MONOTONIC - -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ -struct timespec tp; -if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) -__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); -return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); -} - -#elif defined(__APPLE__) +#if defined(__APPLE__) // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom @@ -166,6 +155,32 @@ steady_clock::now() _NOEXCEPT return time_point(duration(fp())); } +#elif defined(_WIN32) + +steady_clock::time_point +steady_clock::now() _NOEXCEPT +{ + static LARGE_INTEGER liFreq; + static BOOL bQPFRun = FALSE; + if (bQPFRun == FALSE) +bQPFRun = QueryPerformanceFrequency(&liFreq); + + LARGE_INTEGER liCntr; + QueryPerformanceCounter(&liCntr); + return time_point(duration(liCntr.QuadPart * nano::den / liFreq.QuadPart)); +} + +#elif defined(CLOCK_MONOTONIC) + +steady_clock::time_point +steady_clock::now() _NOEXCEPT +{ +struct timespec tp; +if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) +__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); +return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); +} + #else #error "Monotonic clock not implemented" #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290803 - chrono: implement a Windows version of system_clock::now
Author: compnerd Date: Sun Jan 1 14:20:41 2017 New Revision: 290803 URL: http://llvm.org/viewvc/llvm-project?rev=290803&view=rev Log: chrono: implement a Windows version of system_clock::now system_clock::now is not entirely straight forward on Windows, which does not have a clock_gettime function. GetSystemTimeAsFileTime gives us the value relative to the NT epoch (Jan 1 1601) rather than the Unix epoch (Jan 1 1970). However, this function has a low resolution (~10ms). Newer versions of Windows provide GetSystemTimePreciseAsFileTime which gives us a much more accurate time (<1us). Unfortunately, the latter is only available on Windows 8+ when targeting desktop apps. Modified: libcxx/trunk/src/chrono.cpp Modified: libcxx/trunk/src/chrono.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290803&r1=290802&r2=290803&view=diff == --- libcxx/trunk/src/chrono.cpp (original) +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:41 2017 @@ -12,9 +12,18 @@ #include "system_error" // __throw_system_error #include // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRA_LEAN +#include +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 +#include +#endif +#else #if !defined(CLOCK_REALTIME) #include // for gettimeofday and timeval #endif +#endif #if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC) #if __APPLE__ @@ -36,6 +45,28 @@ const bool system_clock::is_steady; system_clock::time_point system_clock::now() _NOEXCEPT { +#if defined(_WIN32) + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The difference + // in nanoseconds is the windows epoch offset. + static const constexpr __int64 kWindowsEpochOffset = 0x19db1ded53e8000; + + FILETIME ftSystemTime; +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + GetSystemTimePreciseAsFileTime(&ftSystemTime); +#else + GetSystemTimeAsFileTime(&ftSystemTime); +#endif +#else + GetSystemTimeAsFileTime(&ftSystemTime); +#endif + __int64 llWinTimeNS = + ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | + static_cast<__int64>(ftSystemTime.dwLowDateTime)) * + 100; + return time_point(duration_cast( + (nanoseconds(llWinTimeNS - kWindowsEpochOffset; +#else #ifdef CLOCK_REALTIME struct timespec tp; if (0 != clock_gettime(CLOCK_REALTIME, &tp)) @@ -46,6 +77,7 @@ system_clock::now() _NOEXCEPT gettimeofday(&tv, 0); return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); #endif // CLOCK_REALTIME +#endif } time_t ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290801 - build: dont detect libraries for Windows
Author: compnerd Date: Sun Jan 1 14:20:38 2017 New Revision: 290801 URL: http://llvm.org/viewvc/llvm-project?rev=290801&view=rev Log: build: dont detect libraries for Windows Hard code the defaults for Windows for the time being. The checks really are always going to return the same value. Technically, the pthread linkage is possible, however, it seems better to use the Win32 threading along with the external threading support that we have added. Modified: libcxx/trunk/cmake/config-ix.cmake Modified: libcxx/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/cmake/config-ix.cmake?rev=290801&r1=290800&r2=290801&view=diff == --- libcxx/trunk/cmake/config-ix.cmake (original) +++ libcxx/trunk/cmake/config-ix.cmake Sun Jan 1 14:20:38 2017 @@ -1,9 +1,20 @@ include(CheckLibraryExists) include(CheckCXXCompilerFlag) -check_library_exists(c fopen "" LIBCXX_HAS_C_LIB) +if(WIN32 AND NOT MINGW) + # NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets + # let the default linking take care of that. + set(LIBCXX_HAS_C_LIB NO) +else() + check_library_exists(c fopen "" LIBCXX_HAS_C_LIB) +endif() + if (NOT LIBCXX_USE_COMPILER_RT) - check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB) + if(WIN32 AND NOT MINGW) +set(LIBCXX_HAS_GCC_S_LIB NO) + else() +check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB) + endif() endif() # libc++ is built with -nodefaultlibs, so we want all our checks to also @@ -32,7 +43,9 @@ if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) endif () endif () -include(CheckLibcxxAtomic) +if(NOT WIN32 OR MINGW) + include(CheckLibcxxAtomic) +endif() # Check compiler flags @@ -45,6 +58,14 @@ check_cxx_compiler_flag(/GR- # Check libraries -check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB) -check_library_exists(m ccos "" LIBCXX_HAS_M_LIB) -check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB) +if(WIN32 AND NOT MINGW) + # TODO(compnerd) do we want to support an emulation layer that allows for the + # use of pthread-win32 or similar libraries to emulate pthreads on Windows? + set(LIBCXX_HAS_PTHREAD_LIB NO) + set(LIBCXX_HAS_M_LIB NO) + set(LIBCXX_HAS_RT_LIB NO) +else() + check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB) + check_library_exists(m ccos "" LIBCXX_HAS_M_LIB) + check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB) +endif() ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290800 - build: differentiate between building for and on Windows
Author: compnerd Date: Sun Jan 1 14:20:36 2017 New Revision: 290800 URL: http://llvm.org/viewvc/llvm-project?rev=290800&view=rev Log: build: differentiate between building for and on Windows This is necessary to support cross-compiling a Windows libc++ from Linux. The CMAKE_SYSTEM_HOST_NAME tells you what, in autotools parlance, is known as the build as opposed to WIN32 which maps to, in autotools parlance, host. Modified: libcxx/trunk/include/CMakeLists.txt Modified: libcxx/trunk/include/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/CMakeLists.txt?rev=290800&r1=290799&r2=290800&view=diff == --- libcxx/trunk/include/CMakeLists.txt (original) +++ libcxx/trunk/include/CMakeLists.txt Sun Jan 1 14:20:36 2017 @@ -29,7 +29,7 @@ if (LIBCXX_INSTALL_HEADERS) if (LIBCXX_NEEDS_SITE_CONFIG) set(UNIX_CAT cat) -if (WIN32) +if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") set(UNIX_CAT type) endif() # Generate and install a custom __config header. The new header is created ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libcxx] r290803 - chrono: implement a Windows version of system_clock::now
On Jan 1, 2017, at 3:20 PM, Saleem Abdulrasool via cfe-commits wrote: > > Author: compnerd > Date: Sun Jan 1 14:20:41 2017 > New Revision: 290803 > > URL: http://llvm.org/viewvc/llvm-project?rev=290803&view=rev > Log: > chrono: implement a Windows version of system_clock::now > > system_clock::now is not entirely straight forward on Windows, which > does not have a clock_gettime function. > > GetSystemTimeAsFileTime gives us the value relative to the NT epoch (Jan > 1 1601) rather than the Unix epoch (Jan 1 1970). However, this function > has a low resolution (~10ms). Newer versions of Windows provide > GetSystemTimePreciseAsFileTime which gives us a much more accurate time > (<1us). Unfortunately, the latter is only available on Windows 8+ when > targeting desktop apps. > > Modified: >libcxx/trunk/src/chrono.cpp > > Modified: libcxx/trunk/src/chrono.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290803&r1=290802&r2=290803&view=diff > == > --- libcxx/trunk/src/chrono.cpp (original) > +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:41 2017 > @@ -12,9 +12,18 @@ > #include "system_error" // __throw_system_error > #include // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME > > +#if defined(_WIN32) > +#define WIN32_LEAN_AND_MEAN > +#define VC_EXTRA_LEAN > +#include > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > +#include > +#endif > +#else > #if !defined(CLOCK_REALTIME) > #include // for gettimeofday and timeval > #endif > +#endif > > #if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC) > #if __APPLE__ > @@ -36,6 +45,28 @@ const bool system_clock::is_steady; > system_clock::time_point > system_clock::now() _NOEXCEPT > { > +#if defined(_WIN32) > + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The > difference > + // in nanoseconds is the windows epoch offset. > + static const constexpr __int64 kWindowsEpochOffset = 0x19db1ded53e8000; This is the correct difference, but the comment is wrong. It isn’t nanoseconds. It is 100ns units. > + > + FILETIME ftSystemTime; > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) > + GetSystemTimePreciseAsFileTime(&ftSystemTime); > +#else > + GetSystemTimeAsFileTime(&ftSystemTime); > +#endif > +#else > + GetSystemTimeAsFileTime(&ftSystemTime); > +#endif > + __int64 llWinTimeNS = > + ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | > + static_cast<__int64>(ftSystemTime.dwLowDateTime)) * > + 100; The * 100 will overflow. The * 100 converts 100ns to ns. ns has a signed 64bit range of +/- 292 years, which is greater than the difference between the two epochs. > + return time_point(duration_cast( > + (nanoseconds(llWinTimeNS - kWindowsEpochOffset; It really isn’t desirable to bounce this off of nanoseconds because of the overflow. > +#else > #ifdef CLOCK_REALTIME > struct timespec tp; > if (0 != clock_gettime(CLOCK_REALTIME, &tp)) > @@ -46,6 +77,7 @@ system_clock::now() _NOEXCEPT > gettimeofday(&tv, 0); > return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); > #endif // CLOCK_REALTIME > +#endif > } Thank you for preserving the 1970 epoch. Though not currently specified by the standard, it is very important. And hopefully will be specified by a future standard. Here is code written by Billy O’Neal (MS) doing the conversion you’re looking for: https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#FILETIME It has no intermediate results with precision finer than 100ns. The range of the 64bit 100ns unit goes out to +/- 29 thousand years. Howard ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290806 - chrono: address post commit comments from Howard
Author: compnerd Date: Sun Jan 1 16:04:38 2017 New Revision: 290806 URL: http://llvm.org/viewvc/llvm-project?rev=290806&view=rev Log: chrono: address post commit comments from Howard Drawing some inspiration from code from Bill O'Neal as pointed out by Howard, rework the code to avoid an overflow in the duration. Adjust the style to match libc++ style as well. Create a local typedef for the FILETIME duration (100-ns units). Use this to define the difference between the NT and the UNIX epochs (which previously overflowed due to the representation limits due to the bouncing to ns). Return the FILETIME duration biased by the NT-to-UNIX epoch conversion. Use of the custom duration makes it easier to read and reason about the code. Modified: libcxx/trunk/src/chrono.cpp Modified: libcxx/trunk/src/chrono.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290806&r1=290805&r2=290806&view=diff == --- libcxx/trunk/src/chrono.cpp (original) +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 16:04:38 2017 @@ -46,26 +46,30 @@ system_clock::time_point system_clock::now() _NOEXCEPT { #if defined(_WIN32) - // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The difference - // in nanoseconds is the windows epoch offset. - static const constexpr __int64 kWindowsEpochOffset = 0x19db1ded53e8000; + // FILETIME is in 100ns units + using filetime_duration = + _VSTD::chrono::duration<__int64, + _VSTD::ratio_multiply<_VSTD::ratio<100, 1>, +nanoseconds::period>>; - FILETIME ftSystemTime; + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. + static _LIBCPP_CONSTEXPR const filetime_duration + nt_to_unix_epoch{11644473600}; + + FILETIME ft; #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - GetSystemTimePreciseAsFileTime(&ftSystemTime); + GetSystemTimePreciseAsFileTime(&ft); #else - GetSystemTimeAsFileTime(&ftSystemTime); + GetSystemTimeAsFileTime(&ft); #endif #else - GetSystemTimeAsFileTime(&ftSystemTime); + GetSystemTimeAsFileTime(&ft); #endif - __int64 llWinTimeNS = - ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | - static_cast<__int64>(ftSystemTime.dwLowDateTime)) * - 100; - return time_point(duration_cast( - (nanoseconds(llWinTimeNS - kWindowsEpochOffset; + + filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) | + static_cast<__int64>(ft.dwLowDateTime)}; + return time_point(duration_cast(d - nt_to_unix_epoch)); #else #ifdef CLOCK_REALTIME struct timespec tp; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r290805 - chrono: address post-commit comments from majnemer
Author: compnerd Date: Sun Jan 1 16:04:36 2017 New Revision: 290805 URL: http://llvm.org/viewvc/llvm-project?rev=290805&view=rev Log: chrono: address post-commit comments from majnemer Correct style to match libc++ style as pointed out by David Majnemer on IRC. NFC. Modified: libcxx/trunk/src/chrono.cpp Modified: libcxx/trunk/src/chrono.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290805&r1=290804&r2=290805&view=diff == --- libcxx/trunk/src/chrono.cpp (original) +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 16:04:36 2017 @@ -160,14 +160,14 @@ steady_clock::now() _NOEXCEPT steady_clock::time_point steady_clock::now() _NOEXCEPT { - static LARGE_INTEGER liFreq; - static BOOL bQPFRun = FALSE; - if (bQPFRun == FALSE) -bQPFRun = QueryPerformanceFrequency(&liFreq); + static LARGE_INTEGER freq; + static BOOL initialized = FALSE; + if (!initialized) +initialized = QueryPerformanceFrequency(&freq); // always succceeds - LARGE_INTEGER liCntr; - QueryPerformanceCounter(&liCntr); - return time_point(duration(liCntr.QuadPart * nano::den / liFreq.QuadPart)); + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart)); } #elif defined(CLOCK_MONOTONIC) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libcxx] r290803 - chrono: implement a Windows version of system_clock::now
Thanks for the review on this! I hope you wont mind taking a look at SVN r290806 as well which tries to address the comments. On Sun, Jan 1, 2017 at 1:09 PM, Howard Hinnant wrote: > On Jan 1, 2017, at 3:20 PM, Saleem Abdulrasool via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > > > > Author: compnerd > > Date: Sun Jan 1 14:20:41 2017 > > New Revision: 290803 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=290803&view=rev > > Log: > > chrono: implement a Windows version of system_clock::now > > > > system_clock::now is not entirely straight forward on Windows, which > > does not have a clock_gettime function. > > > > GetSystemTimeAsFileTime gives us the value relative to the NT epoch (Jan > > 1 1601) rather than the Unix epoch (Jan 1 1970). However, this function > > has a low resolution (~10ms). Newer versions of Windows provide > > GetSystemTimePreciseAsFileTime which gives us a much more accurate time > > (<1us). Unfortunately, the latter is only available on Windows 8+ when > > targeting desktop apps. > > > > Modified: > >libcxx/trunk/src/chrono.cpp > > > > Modified: libcxx/trunk/src/chrono.cpp > > URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/ > chrono.cpp?rev=290803&r1=290802&r2=290803&view=diff > > > == > > --- libcxx/trunk/src/chrono.cpp (original) > > +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:41 2017 > > @@ -12,9 +12,18 @@ > > #include "system_error" // __throw_system_error > > #include // clock_gettime, CLOCK_MONOTONIC and > CLOCK_REALTIME > > > > +#if defined(_WIN32) > > +#define WIN32_LEAN_AND_MEAN > > +#define VC_EXTRA_LEAN > > +#include > > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > > +#include > > +#endif > > +#else > > #if !defined(CLOCK_REALTIME) > > #include // for gettimeofday and timeval > > #endif > > +#endif > > > > #if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && > !defined(CLOCK_MONOTONIC) > > #if __APPLE__ > > @@ -36,6 +45,28 @@ const bool system_clock::is_steady; > > system_clock::time_point > > system_clock::now() _NOEXCEPT > > { > > +#if defined(_WIN32) > > + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The > difference > > + // in nanoseconds is the windows epoch offset. > > + static const constexpr __int64 kWindowsEpochOffset = > 0x19db1ded53e8000; > > This is the correct difference, but the comment is wrong. It isn’t > nanoseconds. It is 100ns units. > > Maybe I got the math wrong, but this was supposed to be ns, which is why I bounced between 100ns and ns. > > + > > + FILETIME ftSystemTime; > > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > > +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) > > + GetSystemTimePreciseAsFileTime(&ftSystemTime); > > +#else > > + GetSystemTimeAsFileTime(&ftSystemTime); > > +#endif > > +#else > > + GetSystemTimeAsFileTime(&ftSystemTime); > > +#endif > > + __int64 llWinTimeNS = > > + ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | > > + static_cast<__int64>(ftSystemTime.dwLowDateTime)) * > > + 100; > > The * 100 will overflow. The * 100 converts 100ns to ns. ns has a signed > 64bit range of +/- 292 years, which is greater than the difference between > the two epochs. > > This is what I get for trying to be clever and not use durations. > > + return time_point(duration_cast( > > + (nanoseconds(llWinTimeNS - kWindowsEpochOffset; > > It really isn’t desirable to bounce this off of nanoseconds because of the > overflow. Yeap; This now becomes a duration_cast(filetime_duration) ... letting durations figure out how to do the conversion from 100ns (filetime_duration) to us (sytem_clock::duration) units. > > +#else > > #ifdef CLOCK_REALTIME > > struct timespec tp; > > if (0 != clock_gettime(CLOCK_REALTIME, &tp)) > > @@ -46,6 +77,7 @@ system_clock::now() _NOEXCEPT > > gettimeofday(&tv, 0); > > return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); > > #endif // CLOCK_REALTIME > > +#endif > > } > > Thank you for preserving the 1970 epoch. Though not currently specified > by the standard, it is very important. And hopefully will be specified by > a future standard. > > Here is code written by Billy O’Neal (MS) doing the conversion you’re > looking for: > > https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#FILETIME > > It has no intermediate results with precision finer than 100ns. The range > of the 64bit 100ns unit goes out to +/- 29 thousand years. Thanks for the pointer! > > Howard > > -- Saleem Abdulrasool compnerd (at) compnerd (dot) org ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28210: system_error: inline error_category ctor on Win32
compnerd created this revision. compnerd added reviewers: EricWF, mclow.lists, majnemer. compnerd added subscribers: smeenai, cfe-commits. compnerd set the repository for this revision to rL LLVM. Because the class is marked as `dllexport` and instantiated in `algorithm.cpp` and is strongly defined in `system_error.cpp`, we end up with multiple definitions. By keeping the definition as an inline definition, the `dllexport` will instantiate it. Being inlined, they will be marked as COMDAT(SELECT_ANY) and will still be exported from the dll. Repository: rL LLVM https://reviews.llvm.org/D28210 Files: src/system_error.cpp Index: src/system_error.cpp === --- src/system_error.cpp +++ src/system_error.cpp @@ -9,7 +9,9 @@ #include "__config" +#if !defined(_WIN32) #define _LIBCPP_BUILDING_SYSTEM_ERROR +#endif #include "system_error" #include "include/config_elast.h" @@ -29,9 +31,11 @@ // class error_category +#if !defined(_WIN32) error_category::error_category() _NOEXCEPT { } +#endif error_category::~error_category() _NOEXCEPT { Index: src/system_error.cpp === --- src/system_error.cpp +++ src/system_error.cpp @@ -9,7 +9,9 @@ #include "__config" +#if !defined(_WIN32) #define _LIBCPP_BUILDING_SYSTEM_ERROR +#endif #include "system_error" #include "include/config_elast.h" @@ -29,9 +31,11 @@ // class error_category +#if !defined(_WIN32) error_category::error_category() _NOEXCEPT { } +#endif error_category::~error_category() _NOEXCEPT { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28211: typeinfo: provide a destructor for type_info
compnerd created this revision. compnerd added reviewers: EricWF, mclow.lists. compnerd added subscribers: smeenai, cfe-commits. compnerd set the repository for this revision to rL LLVM. When building without libc++abi and libcxxrt, provide the definition for the std::type_info destructor. Repository: rL LLVM https://reviews.llvm.org/D28211 Files: src/typeinfo.cpp Index: src/typeinfo.cpp === --- src/typeinfo.cpp +++ src/typeinfo.cpp @@ -17,6 +17,10 @@ #if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) +std::type_info::~type_info() +{ +} + std::bad_cast::bad_cast() _NOEXCEPT { } Index: src/typeinfo.cpp === --- src/typeinfo.cpp +++ src/typeinfo.cpp @@ -17,6 +17,10 @@ #if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) +std::type_info::~type_info() +{ +} + std::bad_cast::bad_cast() _NOEXCEPT { } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libcxx] r290806 - chrono: address post commit comments from Howard
Very close! Comment below: On Jan 1, 2017, at 5:04 PM, Saleem Abdulrasool via cfe-commits wrote: > > Author: compnerd > Date: Sun Jan 1 16:04:38 2017 > New Revision: 290806 > > URL: http://llvm.org/viewvc/llvm-project?rev=290806&view=rev > Log: > chrono: address post commit comments from Howard > > Drawing some inspiration from code from Bill O'Neal as pointed out by > Howard, rework the code to avoid an overflow in the duration. Adjust > the style to match libc++ style as well. > > Create a local typedef for the FILETIME duration (100-ns units). Use > this to define the difference between the NT and the UNIX epochs (which > previously overflowed due to the representation limits due to the > bouncing to ns). Return the FILETIME duration biased by the NT-to-UNIX > epoch conversion. > > Use of the custom duration makes it easier to read and reason about the > code. > > Modified: >libcxx/trunk/src/chrono.cpp > > Modified: libcxx/trunk/src/chrono.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290806&r1=290805&r2=290806&view=diff > == > --- libcxx/trunk/src/chrono.cpp (original) > +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 16:04:38 2017 > @@ -46,26 +46,30 @@ system_clock::time_point > system_clock::now() _NOEXCEPT > { > #if defined(_WIN32) > - // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The > difference > - // in nanoseconds is the windows epoch offset. > - static const constexpr __int64 kWindowsEpochOffset = 0x19db1ded53e8000; > + // FILETIME is in 100ns units > + using filetime_duration = > + _VSTD::chrono::duration<__int64, > + _VSTD::ratio_multiply<_VSTD::ratio<100, 1>, > +nanoseconds::period>>; > > - FILETIME ftSystemTime; > + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. > + static _LIBCPP_CONSTEXPR const filetime_duration > + nt_to_unix_epoch{11644473600}; If you give nt_to_unix_epoch units of seconds, instead of filetime_duration, then I _believe_ this will be correct. But I have not tested it. I like this direction much better as all of your computations have units now. Howard > + > + FILETIME ft; > #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) > - GetSystemTimePreciseAsFileTime(&ftSystemTime); > + GetSystemTimePreciseAsFileTime(&ft); > #else > - GetSystemTimeAsFileTime(&ftSystemTime); > + GetSystemTimeAsFileTime(&ft); > #endif > #else > - GetSystemTimeAsFileTime(&ftSystemTime); > + GetSystemTimeAsFileTime(&ft); > #endif > - __int64 llWinTimeNS = > - ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | > - static_cast<__int64>(ftSystemTime.dwLowDateTime)) * > - 100; > - return time_point(duration_cast( > - (nanoseconds(llWinTimeNS - kWindowsEpochOffset; > + > + filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) | > + static_cast<__int64>(ft.dwLowDateTime)}; > + return time_point(duration_cast(d - nt_to_unix_epoch)); > #else > #ifdef CLOCK_REALTIME > struct timespec tp; > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28212: typeinfo: provide a partial implementation for Win32
compnerd created this revision. compnerd added reviewers: EricWF, mclow.lists, majnemer, rnk. compnerd added subscribers: smeenai, kastiglione, cfe-commits. compnerd set the repository for this revision to rL LLVM. The RTTI structure is different on Windows when building under MS ABI. Update the definition to reflect this. The structure itself contains an area for caching the undecorated name (which is 0-initialized). The decorated name has a bitfield followed by the linkage name. When std::type_info::name is invoked for the first time, the runtime should undecorate the name, cache it, and return the undecorated name. This requires access to an implementation of `__unDName`. For now, return the raw name. This uses the fnv-1a hash to hash the name of the RTTI. We could use an alternate hash (murmur? city?), but, this was the quickest to throw together. Repository: rL LLVM https://reviews.llvm.org/D28212 Files: include/typeinfo src/typeinfo.cpp Index: src/typeinfo.cpp === --- src/typeinfo.cpp +++ src/typeinfo.cpp @@ -15,6 +15,44 @@ #include "typeinfo" +#if defined(_WIN32) +#include + +const char *std::type_info::name(std::type_info::data *__data) { + // TODO(compnerd) cache demangled &__data.__decorated_name[1] + return &__data->__decorated_name[1]; +} + +size_t std::type_info::hash(const std::type_info::data *__data) { +#if defined(_WIN64) + static constexpr const size_t fnv_offset_basis = 14695981039346656037; + static constexpr const size_t fnv_prime = 10995116282110; +#else + static constexpr const size_t fnv_offset_basis = 2166136261; + static constexpr const size_t fnv_prime = 16777619; +#endif + + size_t value = fnv_offset_basis; + for (const char *c = &__data->__decorated_name[1]; *c; ++c) { +value ^= static_cast(static_cast(*c)); +value *= fnv_prime; + } + +#if defined(_WIN64) + value ^= value >> 32; +#endif + + return value; +} + +int std::type_info::compare(const std::type_info::data *__lhs, +const std::type_info::data *__rhs) { + if (__lhs == __rhs) +return 0; + return strcmp(&__lhs->__decorated_name[1], &__rhs->__decorated_name[1]); +} +#endif + #if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) std::type_info::~type_info() Index: include/typeinfo === --- include/typeinfo +++ include/typeinfo @@ -72,6 +72,49 @@ namespace std // purposefully not using versioning namespace { +#if defined(_WIN32) +class _LIBCPP_EXCEPTION_ABI type_info +{ + type_info & operator=(const type_info &) _LIBCPP_EQUAL_DELETE; + type_info (const type_info &) _LIBCPP_EQUAL_DELETE; + + mutable struct data { +const char *__undecorated_name; +const char __decorated_name[1]; + } __data; + + static const char *name(type_info::data *__data); + static size_t hash(const type_info::data *__data); + static int compare(const type_info::data *__l, const type_info::data *__r); + +public: + virtual ~type_info() _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + const char *name() const _NOEXCEPT { +return name(&__data); + } + + _LIBCPP_INLINE_VISIBILITY + bool before(const type_info &__arg) const _NOEXCEPT { +return compare(&__data, &__arg.__data) < 0; + } + + _LIBCPP_INLINE_VISIBILITY + size_t hash_code() const _NOEXCEPT { +return hash(&__data); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(const type_info &__arg) const _NOEXCEPT { +return compare(&__data, &__arg.__data) == 0; + } + + bool operator!=(const type_info &__arg) const _NOEXCEPT { +return compare(&__data, &__arg.__data) != 0; + } +}; +#else class _LIBCPP_EXCEPTION_ABI type_info { type_info& operator=(const type_info&); @@ -148,6 +191,7 @@ {return __builtin_strcmp(name(), __arg.name());} #endif }; +#endif class _LIBCPP_EXCEPTION_ABI bad_cast : public exception ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28213: [Frontend] Correct values of ATOMIC_*_LOCK_FREE to match builtin
mgorny created this revision. mgorny added reviewers: rsmith, t.p.northover, hfinkel, EricWF. mgorny added a subscriber: cfe-commits. Correct the logic used to set `ATOMIC_*_LOCK_FREE` preprocessor macros not to rely on the ABI alignment of types. Instead, just assume all those types are aligned correctly by default since clang uses safe alignment for `_Atomic` types even if the underlying types are aligned to a lower boundary by default. For example, the `long long` and `double` types on x86 are aligned to 32-bit boundary by default. However, `_Atomic long long` and `_Atomic double` are aligned to 64-bit boundary, therefore satisfying the requirements of lock-free atomic operations. This fixes PR #19355 by correcting the value of `__GCC_ATOMIC_LLONG_LOCK_FREE` on x86, and therefore also fixing the assumption made in libc++ tests. This also fixes PR #30581 by applying a consistent logic between the functions used to implement both interfaces. https://reviews.llvm.org/D28213 Files: lib/Frontend/InitPreprocessor.cpp test/Sema/atomic-ops.c Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -14,11 +14,7 @@ _Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == 2, ""); _Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2, ""); _Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == 2, ""); -#ifdef __i386__ -_Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, ""); -#else _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 2, ""); -#endif _Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == 2, ""); _Static_assert(__c11_atomic_is_lock_free(1), ""); Index: lib/Frontend/InitPreprocessor.cpp === --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -286,12 +286,12 @@ /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with /// the specified properties. -static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign, -unsigned InlineWidth) { +static const char *getLockFreeValue(unsigned TypeWidth, unsigned InlineWidth) { // Fully-aligned, power-of-2 sizes no larger than the inline // width will be inlined as lock-free operations. - if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 && - TypeWidth <= InlineWidth) + // Note: we do not need to check alignment since _Atomic(T) is always + // appropriately-aligned in clang. + if ((TypeWidth & (TypeWidth - 1)) == 0 && TypeWidth <= InlineWidth) return "2"; // "always lock free" // We cannot be certain what operations the lib calls might be // able to implement as lock-free on future processors. @@ -881,7 +881,6 @@ #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \ getLockFreeValue(TI.get##Type##Width(), \ - TI.get##Type##Align(), \ InlineWidthBits)); DEFINE_LOCK_FREE_MACRO(BOOL, Bool); DEFINE_LOCK_FREE_MACRO(CHAR, Char); @@ -894,7 +893,6 @@ DEFINE_LOCK_FREE_MACRO(LLONG, LongLong); Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE", getLockFreeValue(TI.getPointerWidth(0), - TI.getPointerAlign(0), InlineWidthBits)); #undef DEFINE_LOCK_FREE_MACRO } Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -14,11 +14,7 @@ _Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == 2, ""); _Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2, ""); _Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == 2, ""); -#ifdef __i386__ -_Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, ""); -#else _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 2, ""); -#endif _Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == 2, ""); _Static_assert(__c11_atomic_is_lock_free(1), ""); Index: lib/Frontend/InitPreprocessor.cpp === --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -286,12 +286,12 @@ /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with /// the specified properties. -static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign, -unsigned InlineWidth) { +static const char *getLockFreeValue(unsigned TypeWidth, unsigned InlineWidth) { // Fully-aligned, power-of-2 sizes no larger than the inline // width will be inlined as lock-free operations. - if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 && - TypeWidth <= InlineWidth) + // Note: we do not need to check alignment since _Atomic(T) is always + // appropriately-aligned in clang. + if ((TypeWidth & (Ty
[PATCH] D28212: typeinfo: provide a partial implementation for Win32
majnemer added inline comments. Comment at: src/typeinfo.cpp:28-29 +#if defined(_WIN64) + static constexpr const size_t fnv_offset_basis = 14695981039346656037; + static constexpr const size_t fnv_prime = 10995116282110; +#else majnemer wrote: > Why make these static? Seems strange to use that storage duration. These literals are ill-formed, I think you need a ULL suffix here. Comment at: src/typeinfo.cpp:28-32 + static constexpr const size_t fnv_offset_basis = 14695981039346656037; + static constexpr const size_t fnv_prime = 10995116282110; +#else + static constexpr const size_t fnv_offset_basis = 2166136261; + static constexpr const size_t fnv_prime = 16777619; Why make these static? Seems strange to use that storage duration. Repository: rL LLVM https://reviews.llvm.org/D28212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r290807 - Address post-commit review comments.
Author: rsmith Date: Sun Jan 1 20:38:22 2017 New Revision: 290807 URL: http://llvm.org/viewvc/llvm-project?rev=290807&view=rev Log: Address post-commit review comments. Modified: cfe/trunk/include/clang/Basic/LangOptions.def cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Modified: cfe/trunk/include/clang/Basic/LangOptions.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=290807&r1=290806&r2=290807&view=diff == --- cfe/trunk/include/clang/Basic/LangOptions.def (original) +++ cfe/trunk/include/clang/Basic/LangOptions.def Sun Jan 1 20:38:22 2017 @@ -134,7 +134,7 @@ LANGOPT(NoBuiltin , 1, 0, "disab LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") LANGOPT(GNUAsm, 1, 1, "GNU-style inline assembly") LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS") -LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of tempalte template arguments") +LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=290807&r1=290806&r2=290807&view=diff == --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sun Jan 1 20:38:22 2017 @@ -4786,9 +4786,6 @@ bool Sema::isTemplateTemplateParameterAt QualType AType = Context.getTemplateSpecializationType(X, AArgs); QualType PType = Context.getTemplateSpecializationType(X, PArgs); - SmallVector Deduced; - Deduced.resize(A->size()); - // ... the function template corresponding to P is at least as specialized // as the function template corresponding to A according to the partial // ordering rules for function templates. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r290792 - [c++17] Implement P0522R0 as written. This allows a template template argument
Thanks both of you, r290807. On 1 January 2017 at 07:28, Erik Pilkington wrote: > > > On Dec 31, 2016, at 4:41 PM, Richard Smith via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > > > > Author: rsmith > > Date: Sat Dec 31 15:41:23 2016 > > New Revision: 290792 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=290792&view=rev > > Log: > > [c++17] Implement P0522R0 as written. This allows a template template > argument > > to be specified for a template template parameter whenever the parameter > is at > > least as specialized as the argument (when there's an obvious and correct > > mapping from uses of the parameter to uses of the argument). For > example, a > > template with more parameters can be passed to a template template > parameter > > with fewer, if those trailing parameters have default arguments. > > > > This is disabled by default, despite being a DR resolution, as it's > fairly > > broken in its current state: there are no partial ordering rules to cope > with > > template template parameters that have different parameter lists, > meaning that > > code that attempts to decompose template-ids based on arity can hit > unavoidable > > ambiguity issues. > > > > The diagnostics produced on a non-matching argument are also pretty bad > right > > now, but I aim to improve them in a subsequent commit. > > > > Added: > >cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp > > Modified: > >cfe/trunk/include/clang/Basic/LangOptions.def > >cfe/trunk/include/clang/Driver/Options.td > >cfe/trunk/include/clang/Sema/Sema.h > >cfe/trunk/lib/Driver/Tools.cpp > >cfe/trunk/lib/Frontend/CompilerInvocation.cpp > >cfe/trunk/lib/Sema/SemaTemplate.cpp > >cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp > >cfe/trunk/test/SemaTemplate/temp_arg_template.cpp > >cfe/trunk/www/cxx_status.html > > > > Modified: cfe/trunk/include/clang/Basic/LangOptions.def > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/LangOptions.def?rev=290792&r1=290791&r2=290792&view=diff > > > == > > --- cfe/trunk/include/clang/Basic/LangOptions.def (original) > > +++ cfe/trunk/include/clang/Basic/LangOptions.def Sat Dec 31 15:41:23 > 2016 > > @@ -134,6 +134,7 @@ LANGOPT(NoBuiltin , 1, 0, "disab > > LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") > > LANGOPT(GNUAsm, 1, 1, "GNU-style inline assembly") > > LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS") > > +LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of > tempalte template arguments") > > > > BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static > initializers") > > LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") > > > > Modified: cfe/trunk/include/clang/Driver/Options.td > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Driver/Options.td?rev=290792&r1=290791&r2=290792&view=diff > > > == > > --- cfe/trunk/include/clang/Driver/Options.td (original) > > +++ cfe/trunk/include/clang/Driver/Options.td Sat Dec 31 15:41:23 2016 > > @@ -1088,6 +1088,11 @@ def fapplication_extension : Flag<["-"], > > HelpText<"Restrict code to those available for App Extensions">; > > def fno_application_extension : Flag<["-"], "fno-application-extension">, > > Group; > > +def frelaxed_template_template_args : Flag<["-"], > "frelaxed-template-template-args">, > > + Flags<[CC1Option]>, HelpText<"Enable C++17 relaxed template template > argument matching">, > > + Group; > > +def fno_relaxed_template_template_args : Flag<["-"], > "fno-relaxed-template-template-args">, > > + Group; > > def fsized_deallocation : Flag<["-"], "fsized-deallocation">, > Flags<[CC1Option]>, > > HelpText<"Enable C++14 sized global deallocation functions">, > Group; > > def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, > Group; > > > > Modified: cfe/trunk/include/clang/Sema/Sema.h > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Sema/Sema.h?rev=290792&r1=290791&r2=290792&view=diff > > > == > > --- cfe/trunk/include/clang/Sema/Sema.h (original) > > +++ cfe/trunk/include/clang/Sema/Sema.h Sat Dec 31 15:41:23 2016 > > @@ -6719,6 +6719,9 @@ public: > > bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl > *T, > > sema::TemplateDeductionInfo &Info); > > > > + bool isTemplateTemplateParameterAtLeastAsSpecializedAs( > > + TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc); > > + > > void MarkUsedTemplateParameters(const TemplateArgumentList > &TemplateArgs, > > bool OnlyDeduced, > > unsigned Depth, > > > > Modified: cfe/trunk/lib/Driver/Tools.cpp > > URL: http
r290808 - DR1391: Check for implicit conversion sequences for non-dependent function
Author: rsmith Date: Sun Jan 1 20:42:17 2017 New Revision: 290808 URL: http://llvm.org/viewvc/llvm-project?rev=290808&view=rev Log: DR1391: Check for implicit conversion sequences for non-dependent function template parameters between deduction and substitution. The idea is to accept as many cases as possible, on the basis that substitution failure outside the immediate context is much more common during substitution than during implicit conversion sequence formation. This does not implement the partial ordering portion of DR1391, which so far appears to be misguided. Modified: cfe/trunk/include/clang/Sema/Overload.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/test/CXX/drs/dr13xx.cpp cfe/trunk/test/Misc/diag-template-diffing.cpp cfe/trunk/test/SemaCXX/overload-call.cpp cfe/trunk/test/SemaCXX/overload-member-call.cpp cfe/trunk/www/cxx_dr_status.html Modified: cfe/trunk/include/clang/Sema/Overload.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=290808&r1=290807&r2=290808&view=diff == --- cfe/trunk/include/clang/Sema/Overload.h (original) +++ cfe/trunk/include/clang/Sema/Overload.h Sun Jan 1 20:42:17 2017 @@ -531,6 +531,13 @@ namespace clang { Ambiguous.construct(); } +void setAsIdentityConversion(QualType T) { + setStandard(); + Standard.setAsIdentityConversion(); + Standard.setFromType(T); + Standard.setAllToTypes(T); +} + /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool isStdInitializerListElement() const { @@ -603,6 +610,11 @@ namespace clang { ovl_fail_ext_disabled, }; + /// A list of implicit conversion sequences for the arguments of an + /// OverloadCandidate. + typedef llvm::MutableArrayRef + ConversionSequenceList; + /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). struct OverloadCandidate { /// Function - The actual function that this candidate @@ -627,18 +639,13 @@ namespace clang { /// is a surrogate, but only if IsSurrogate is true. CXXConversionDecl *Surrogate; -/// Conversions - The conversion sequences used to convert the -/// function arguments to the function parameters, the pointer points to a -/// fixed size array with NumConversions elements. The memory is owned by -/// the OverloadCandidateSet. -ImplicitConversionSequence *Conversions; +/// The conversion sequences used to convert the function arguments +/// to the function parameters. +ConversionSequenceList Conversions; /// The FixIt hints which can be used to fix the Bad candidate. ConversionFixItGenerator Fix; -/// NumConversions - The number of elements in the Conversions array. -unsigned NumConversions; - /// Viable - True to indicate that this overload candidate is viable. bool Viable; @@ -677,9 +684,9 @@ namespace clang { /// hasAmbiguousConversion - Returns whether this overload /// candidate requires an ambiguous conversion or not. bool hasAmbiguousConversion() const { - for (unsigned i = 0, e = NumConversions; i != e; ++i) { -if (!Conversions[i].isInitialized()) return false; -if (Conversions[i].isAmbiguous()) return true; + for (auto &C : Conversions) { +if (!C.isInitialized()) return false; +if (C.isAmbiguous()) return true; } return false; } @@ -728,7 +735,7 @@ namespace clang { SmallVector Candidates; llvm::SmallPtrSet Functions; -// Allocator for OverloadCandidate::Conversions. We store the first few +// Allocator for ConversionSequenceLists. We store the first few // elements inline to avoid allocation for small sets. llvm::BumpPtrAllocator ConversionSequenceAllocator; @@ -769,30 +776,45 @@ namespace clang { size_t size() const { return Candidates.size(); } bool empty() const { return Candidates.empty(); } -/// \brief Add a new candidate with NumConversions conversion sequence slots -/// to the overload set. -OverloadCandidate &addCandidate(unsigned NumConversions = 0) { - Candidates.push_back(OverloadCandidate()); - OverloadCandidate &C = Candidates.back(); +/// \brief Allocate storage for conversion sequences for NumConversions +/// conversions. +ConversionSequenceList +allocateConversionSequences(unsigned NumConversions) { + ImplicitConversionSequence *Conversions; // Assign space from the inline array if there are enough free slots // available. if (NumConversions + NumInlineSequences <= 16) { ImplicitConversionSequence *I = (ImplicitConversionSequence *)InlineSpace.buffer; -C.Conversions = &I[Nu