xref: /freebsd-src/contrib/llvm-project/clang/include/clang/Basic/Stack.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric //===--- Stack.h - Utilities for dealing with stack space -------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Defines utilities for dealing with stack allocation and stack space.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_BASIC_STACK_H
150b57cec5SDimitry Andric #define LLVM_CLANG_BASIC_STACK_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include <cstddef>
180b57cec5SDimitry Andric 
19a7dea167SDimitry Andric #include "llvm/ADT/STLExtras.h"
20a7dea167SDimitry Andric #include "llvm/Support/Compiler.h"
21a7dea167SDimitry Andric 
220b57cec5SDimitry Andric namespace clang {
230b57cec5SDimitry Andric   /// The amount of stack space that Clang would like to be provided with.
240b57cec5SDimitry Andric   /// If less than this much is available, we may be unable to reach our
250b57cec5SDimitry Andric   /// template instantiation depth limit and other similar limits.
260b57cec5SDimitry Andric   constexpr size_t DesiredStackSize = 8 << 20;
27a7dea167SDimitry Andric 
28a7dea167SDimitry Andric   /// Call this once on each thread, as soon after starting the thread as
29a7dea167SDimitry Andric   /// feasible, to note the approximate address of the bottom of the stack.
30a7dea167SDimitry Andric   void noteBottomOfStack();
31a7dea167SDimitry Andric 
32a7dea167SDimitry Andric   /// Determine whether the stack is nearly exhausted.
33a7dea167SDimitry Andric   bool isStackNearlyExhausted();
34a7dea167SDimitry Andric 
35a7dea167SDimitry Andric   void runWithSufficientStackSpaceSlow(llvm::function_ref<void()> Diag,
36a7dea167SDimitry Andric                                        llvm::function_ref<void()> Fn);
37a7dea167SDimitry Andric 
38a7dea167SDimitry Andric   /// Run a given function on a stack with "sufficient" space. If stack space
39a7dea167SDimitry Andric   /// is insufficient, calls Diag to emit a diagnostic before calling Fn.
runWithSufficientStackSpace(llvm::function_ref<void ()> Diag,llvm::function_ref<void ()> Fn)40a7dea167SDimitry Andric   inline void runWithSufficientStackSpace(llvm::function_ref<void()> Diag,
41a7dea167SDimitry Andric                                           llvm::function_ref<void()> Fn) {
42*349cc55cSDimitry Andric #if LLVM_ENABLE_THREADS
43a7dea167SDimitry Andric     if (LLVM_UNLIKELY(isStackNearlyExhausted()))
44a7dea167SDimitry Andric       runWithSufficientStackSpaceSlow(Diag, Fn);
45a7dea167SDimitry Andric     else
46a7dea167SDimitry Andric       Fn();
47a7dea167SDimitry Andric #else
48a7dea167SDimitry Andric     if (LLVM_UNLIKELY(isStackNearlyExhausted()))
49a7dea167SDimitry Andric       Diag();
50a7dea167SDimitry Andric     Fn();
51a7dea167SDimitry Andric #endif
52a7dea167SDimitry Andric   }
530b57cec5SDimitry Andric } // end namespace clang
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric #endif // LLVM_CLANG_BASIC_STACK_H
56