Compare commits

...

3 Commits

Author SHA1 Message Date
Will Dietz
c993908fc8
Merge 63c8800100 into 3799e38920 2025-07-06 07:46:49 +02:00
Fangrui Song
3799e38920 Adapt llvmorg-21 changes: clang::CompilerInstance and llvm::PointerUnion 2025-05-11 23:37:30 -07:00
Will Dietz
63c8800100 Help Clang find bottom of stacks for safety, use desired stack size
noteBottomOfStack:

Without this, checks against stack space within Clang don't work as
Clang doesn't know where the stack begins.

Needed per-thread, as early as possible.
(on threads using Clang)

Using Clang's desired stack size:

Additionally increase stack size of pthreads to Clang's desired size.

This is presently 8MB, and is used by Clang's stack management
mechanisms to check* if close to stack exhaustion when determining if
there's sufficient space (and warn or run on a new thread with more).
(see runWithSufficientStackSpace)

The constant is available in LLVM 7 onwards.

* (abs(cur - bottom) > DesiredStackSize - threshold)
2022-04-01 10:22:05 -05:00
4 changed files with 55 additions and 4 deletions

View File

@ -377,10 +377,17 @@ const Decl *getAdjustedDecl(const Decl *d) {
if (!s->isExplicitSpecialization()) { if (!s->isExplicitSpecialization()) {
llvm::PointerUnion<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> result = llvm::PointerUnion<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> result =
s->getSpecializedTemplateOrPartial(); s->getSpecializedTemplateOrPartial();
if (result.is<ClassTemplateDecl *>()) #if LLVM_VERSION_MAJOR >= 21
if (auto *ctd = dyn_cast<ClassTemplateDecl *>(result))
d = ctd;
else
d = cast<ClassTemplatePartialSpecializationDecl *>(result);
#else
if (isa<ClassTemplateDecl *>(result))
d = result.get<ClassTemplateDecl *>(); d = result.get<ClassTemplateDecl *>();
else else
d = result.get<ClassTemplatePartialSpecializationDecl *>(); d = result.get<ClassTemplatePartialSpecializationDecl *>();
#endif
continue; continue;
} }
} else if (auto *d1 = r->getInstantiatedFromMemberClass()) { } else if (auto *d1 = r->getInstantiatedFromMemberClass()) {
@ -964,10 +971,17 @@ public:
else if (auto *sd = dyn_cast<ClassTemplateSpecializationDecl>(rd)) { else if (auto *sd = dyn_cast<ClassTemplateSpecializationDecl>(rd)) {
llvm::PointerUnion<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> result = llvm::PointerUnion<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> result =
sd->getSpecializedTemplateOrPartial(); sd->getSpecializedTemplateOrPartial();
#if LLVM_VERSION_MAJOR >= 21
if (auto *ctd = dyn_cast<ClassTemplateDecl *>(result))
d1 = ctd;
else
d1 = cast<ClassTemplatePartialSpecializationDecl *>(result);
#else
if (result.is<ClassTemplateDecl *>()) if (result.is<ClassTemplateDecl *>())
d1 = result.get<ClassTemplateDecl *>(); d1 = result.get<ClassTemplateDecl *>();
else else
d1 = result.get<ClassTemplatePartialSpecializationDecl *>(); d1 = result.get<ClassTemplatePartialSpecializationDecl *>();
#endif
} else } else
d1 = rd->getInstantiatedFromMemberClass(); d1 = rd->getInstantiatedFromMemberClass();
@ -1241,15 +1255,23 @@ IndexResult index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, const st
} }
IndexDiags dc; IndexDiags dc;
#if LLVM_VERSION_MAJOR >= 21
auto clang = std::make_unique<CompilerInstance>(std::move(ci), pch);
#else
auto clang = std::make_unique<CompilerInstance>(pch); auto clang = std::make_unique<CompilerInstance>(pch);
clang->setInvocation(std::move(ci)); clang->setInvocation(std::move(ci));
#endif
clang->createDiagnostics( clang->createDiagnostics(
#if LLVM_VERSION_MAJOR >= 20 #if LLVM_VERSION_MAJOR >= 20
*fs, *fs,
#endif #endif
&dc, false); &dc, false);
clang->getDiagnostics().setIgnoreAllWarnings(true); clang->getDiagnostics().setIgnoreAllWarnings(true);
#if LLVM_VERSION_MAJOR >= 21
clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getTargetOpts()));
#else
clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getInvocation().TargetOpts)); clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getInvocation().TargetOpts));
#endif
if (!clang->hasTarget()) if (!clang->hasTarget())
return {}; return {};
clang->getPreprocessorOpts().RetainRemappedFileBuffers = true; clang->getPreprocessorOpts().RetainRemappedFileBuffers = true;

View File

@ -8,6 +8,7 @@
#include "test.hh" #include "test.hh"
#include "working_files.hh" #include "working_files.hh"
#include <clang/Basic/Stack.h>
#include <clang/Basic/Version.h> #include <clang/Basic/Version.h>
#include <llvm/Support/CommandLine.h> #include <llvm/Support/CommandLine.h>
#include <llvm/Support/CrashRecoveryContext.h> #include <llvm/Support/CrashRecoveryContext.h>
@ -69,8 +70,12 @@ int main(int argc, char **argv) {
pipeline::init(); pipeline::init();
const char *env = getenv("CCLS_CRASH_RECOVERY"); const char *env = getenv("CCLS_CRASH_RECOVERY");
if (!env || strcmp(env, "0") != 0) if (!env || strcmp(env, "0") != 0) {
CrashRecoveryContext::Enable(); CrashRecoveryContext::Enable();
#if LLVM_VERSION_MAJOR >= 10 // rL369940
clang::noteBottomOfStack(); // per-thread, needed to avoid stack exhaustion
#endif
}
bool language_server = true; bool language_server = true;

View File

@ -27,6 +27,8 @@
#include <malloc.h> #include <malloc.h>
#endif #endif
#include <clang/Basic/Stack.h>
#include <llvm/ADT/SmallString.h> #include <llvm/ADT/SmallString.h>
#include <llvm/Support/Path.h> #include <llvm/Support/Path.h>
@ -61,18 +63,32 @@ void traceMe() {
raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP);
} }
struct ThreadInfo {
void *(*fn)(void *);
void *arg;
};
void *threadWrapper(void *arg) {
ThreadInfo ti = *(ThreadInfo *)arg;
delete (ThreadInfo *)arg;
#if LLVM_VERSION_MAJOR >= 10 // rL369940
clang::noteBottomOfStack(); // per-thread, needed to avoid stack exhaustion
#endif
return ti.fn(ti.arg);
}
void spawnThread(void *(*fn)(void *), void *arg) { void spawnThread(void *(*fn)(void *), void *arg) {
pthread_t thd; pthread_t thd;
pthread_attr_t attr; pthread_attr_t attr;
struct rlimit rlim; struct rlimit rlim;
size_t stack_size = 4 * 1024 * 1024; size_t stack_size = clang::DesiredStackSize;
if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY) if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY)
stack_size = rlim.rlim_cur; stack_size = rlim.rlim_cur;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&attr, stack_size); pthread_attr_setstacksize(&attr, stack_size);
pipeline::threadEnter(); pipeline::threadEnter();
pthread_create(&thd, &attr, fn, arg); pthread_create(&thd, &attr, threadWrapper, new ThreadInfo{fn, arg});
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
} }
} // namespace ccls } // namespace ccls

View File

@ -261,14 +261,22 @@ std::unique_ptr<CompilerInstance> buildCompilerInstance(Session &session, std::u
else else
ci->getPreprocessorOpts().addRemappedFile(main, buf.get()); ci->getPreprocessorOpts().addRemappedFile(main, buf.get());
#if LLVM_VERSION_MAJOR >= 21
auto clang = std::make_unique<CompilerInstance>(std::move(ci), session.pch);
#else
auto clang = std::make_unique<CompilerInstance>(session.pch); auto clang = std::make_unique<CompilerInstance>(session.pch);
clang->setInvocation(std::move(ci)); clang->setInvocation(std::move(ci));
#endif
clang->createDiagnostics( clang->createDiagnostics(
#if LLVM_VERSION_MAJOR >= 20 #if LLVM_VERSION_MAJOR >= 20
*fs, *fs,
#endif #endif
&dc, false); &dc, false);
#if LLVM_VERSION_MAJOR >= 21
clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getTargetOpts()));
#else
clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getInvocation().TargetOpts)); clang->setTarget(TargetInfo::CreateTargetInfo(clang->getDiagnostics(), clang->getInvocation().TargetOpts));
#endif
if (!clang->hasTarget()) if (!clang->hasTarget())
return nullptr; return nullptr;
clang->getPreprocessorOpts().RetainRemappedFileBuffers = true; clang->getPreprocessorOpts().RetainRemappedFileBuffers = true;