#include "../Test.h" #include "Compiler/Compiler.h" #include namespace clice { namespace { TEST(Compiler, buildAST) { const char* code = R"cpp( #include int main(){ printf("Hello world"); return 0; } )cpp"; llvm::SmallVector compileArgs = { "clang++", "-std=c++20", "main.cpp", "-resource-dir", "/home/ykiko/C++/clice2/build/lib/clang/20", }; CompliationParams params; params.srcPath = "main.cpp"; params.content = code; params.args = compileArgs; auto info = compile(params); ASSERT_TRUE(bool(info)); } TEST(Compiler, ComputeBounds) { llvm::SmallVector compileArgs = { "clang++", "-std=c++20", "main.cpp", "-resource-dir", "/home/ykiko/C++/clice2/build/lib/clang/20", }; const char* code = R"cpp( #include int main(){ printf("Hello world"); return 0; })cpp"; /// Test in no header file. CompliationParams params; params.srcPath = "main.cpp"; params.args = compileArgs; params.content = code; params.computeBounds(); ASSERT_TRUE(params.bounds.has_value()); ASSERT_EQ(params.bounds->Size, 19); params.bounds.reset(); compileArgs = {"clang++", "-std=c++20", "main.cpp"}; std::unique_ptr vfs(new vfs::InMemoryFileSystem); const char* header = R"cpp( #include "target.h" )cpp"; vfs->addFile("header.h", 0, llvm::MemoryBuffer::getMemBuffer(header)); vfs->addFile("header2.h", 0, llvm::MemoryBuffer::getMemBuffer("")); vfs->addFile("target.h", 0, llvm::MemoryBuffer::getMemBuffer("")); code = R"cpp( #include "header2.h" #include "header.h" int main(){ return 0; })cpp"; compileArgs = { "clang++", "-std=c++20", "main.cpp", }; params.srcPath = "main.cpp"; params.args = compileArgs; params.content = code; params.vfs = std::move(vfs); params.computeBounds("target.h"); ASSERT_TRUE(params.bounds.has_value()); ASSERT_EQ(params.bounds->Size, 43); } TEST(Compiler, buildPCH) { const char* code = R"cpp( #include int main(){ printf("Hello world"); return 0; } )cpp"; llvm::SmallVector compileArgs = { "clang++", "-std=c++20", "main.cpp", "-resource-dir", "/home/ykiko/C++/clice2/build/lib/clang/20", }; llvm::SmallString<128> outpath; if(auto error = llvm::sys::fs::createTemporaryFile("main", "pch", outpath)) { llvm::errs() << error.message() << "\n"; return; } if(auto error = fs::remove(outpath)) { llvm::errs() << error.message() << "\n"; return; } CompliationParams params; params.content = code; params.srcPath = "main.cpp"; params.outPath = outpath; params.args = compileArgs; params.computeBounds(); PCHInfo pch; ASSERT_TRUE(bool(clice::compile(params, pch))); params.bounds.reset(); params.addPCH(pch); auto ast = compile(params); ASSERT_TRUE(bool(ast)); } TEST(Compiler, buildPCM) { const char* code = R"cpp( export module A; export int foo() { return 0; } )cpp"; llvm::SmallString<128> outpath; if(auto error = llvm::sys::fs::createTemporaryFile("main", "pcm", outpath)) { llvm::errs() << error.message() << "\n"; return; } if(auto error = fs::remove(outpath)) { llvm::errs() << error.message() << "\n"; return; } llvm::SmallVector compileArgs = { "clang++", "-std=c++20", "main.cppm", }; CompliationParams params; params.srcPath = "main.cppm"; params.content = code; params.outPath = outpath; params.args = compileArgs; PCMInfo pcm; ASSERT_TRUE(bool(clice::compile(params, pcm))); ASSERT_EQ(pcm.name, "A"); const char* code2 = R"cpp( import A; int main(){ foo(); return 0; } )cpp"; params.srcPath = "main.cpp"; params.content = code2; params.args = compileArgs; params.addPCM(pcm); auto info = compile(params); ASSERT_TRUE(bool(info)); } TEST(Compiler, codeCompleteAt) { const char* code = R"cpp( export module A; export int foo = 1; )cpp"; llvm::SmallVector compileArgs = { "clang++", "-std=c++20", "main.cppm", }; CompliationParams params; params.srcPath = "main.cppm"; params.content = code; params.args = compileArgs; params.line = 3; params.column = 10; auto consumer = new clang::PrintingCodeCompleteConsumer({}, llvm::outs()); auto info = compile(params, consumer); ASSERT_TRUE(bool(info)); /// TODO: add tests in the case of PCH, PCM and override file. } } // namespace } // namespace clice