diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 784762d71..7000f77d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -682,7 +682,7 @@ jobs: -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_DOCS=OFF \ ../llvm - cmake --build . --target clang FileCheck llvm-config --parallel ${CPU_COUNT} + cmake --build . --target clang FileCheck llvm-config clang-repl --parallel ${CPU_COUNT} cd ../../ - name: Save Cache LLVM/Clang runtime build directory (debug_build==true) uses: actions/cache/save@v3 diff --git a/test/Misc/Repl.cpp b/test/Misc/Repl.cpp new file mode 100644 index 000000000..e6b7bae73 --- /dev/null +++ b/test/Misc/Repl.cpp @@ -0,0 +1,10 @@ +// REQUIRES: clang-repl +// UNSUPPORTED: clang-13, clang-14, clang-15, clang-17 +// RUN: cat %s | %clang-repl -Xcc -fplugin=%cladlib -Xcc -I%S/../../include | FileCheck %s + +double sq(double x) { return x*x; } +extern "C" int printf(const char*,...); +#include "clad/Differentiator/Differentiator.h" +auto dsq = clad::differentiate(sq, "x"); +auto r1 = printf("dsq(1)=%f\n", dsq.execute(1)); +// CHECK: dsq(1)=2.00 diff --git a/test/lit.cfg b/test/lit.cfg index 8c3271983..d5bd3aff5 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -297,6 +297,20 @@ if platform.system() not in ['Windows'] or lit_config.getBashPath() != '': config.available_features.add("clang-{0}".format(config.clang_version_major)) +# Check if we have clang-repl next to the inferred clang folder. +inferred_binary_dir = os.path.dirname(config.clang) +clang_repl_path = "" + +if os.path.exists(os.path.join(inferred_binary_dir, "clang-repl-{0}".format(config.clang_version_major))): + clang_repl_path = os.path.join(inferred_binary_dir, "clang-repl-{0}".format(config.clang_version_major)) +elif os.path.exists(os.path.join(inferred_binary_dir, 'clang-repl')): + clang_repl_path = os.path.join(inferred_binary_dir, 'clang-repl') + config.available_features.add("clang-repl-{0}".format(config.clang_version_major)) + +if clang_repl_path: + config.available_features.add("clang-repl") + config.substitutions.append(("%clang-repl", clang_repl_path)) + # Loadable module # FIXME: This should be supplied by Makefile or autoconf. #if sys.platform in ['win32', 'cygwin']: diff --git a/tools/ClangPlugin.cpp b/tools/ClangPlugin.cpp index 3f2ba506a..a99c61ce3 100644 --- a/tools/ClangPlugin.cpp +++ b/tools/ClangPlugin.cpp @@ -292,7 +292,9 @@ namespace clad { } void CladPlugin::SendToMultiplexer() { - for (auto DelayedCall : m_DelayedCalls) { + for (unsigned i = m_MultiplexerProcessedDelayedCallsIdx; + i < m_DelayedCalls.size(); ++i) { + auto DelayedCall = m_DelayedCalls[i]; DeclGroupRef& D = DelayedCall.m_DGR; switch (DelayedCall.m_Kind) { case CallKind::HandleCXXStaticMemberVarInstantiation: @@ -350,7 +352,8 @@ namespace clad { break; }; } - m_HasMultiplexerProcessedDelayedCalls = true; + + m_MultiplexerProcessedDelayedCallsIdx = m_DelayedCalls.size(); } bool CladPlugin::CheckBuiltins() { diff --git a/tools/ClangPlugin.h b/tools/ClangPlugin.h index c69016681..4d569c1cd 100644 --- a/tools/ClangPlugin.h +++ b/tools/ClangPlugin.h @@ -16,6 +16,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Version.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Sema/SemaConsumer.h" @@ -27,7 +28,6 @@ namespace clang { class ASTContext; class CallExpr; - class CompilerInstance; class DeclGroupRef; class Expr; class FunctionDecl; @@ -153,7 +153,7 @@ class CladTimerGroup { std::unique_ptr m_Multiplexer; /// Have we processed all delayed calls. - bool m_HasMultiplexerProcessedDelayedCalls = false; + unsigned m_MultiplexerProcessedDelayedCallsIdx = 0; /// The Sema::TUScope to restore in CladPlugin::HandleTranslationUnit. clang::Scope* m_StoredTUScope = nullptr; @@ -247,7 +247,11 @@ class CladTimerGroup { private: void AppendDelayed(DelayedCallInfo DCI) { - assert(!m_HasMultiplexerProcessedDelayedCalls); + // Incremental processing handles the translation unit in chunks and it is + // expected to have multiple calls to this functionality. + assert((!m_MultiplexerProcessedDelayedCallsIdx || + m_CI.getPreprocessor().isIncrementalProcessingEnabled()) && + "Must start from index 0!"); m_DelayedCalls.push_back(DCI); } void SendToMultiplexer();