Files
clice/unittests/Compiler/Directive.cpp
2025-01-16 22:48:35 +08:00

142 lines
3.8 KiB
C++

#include "Test/CTest.h"
#include "Basic/SourceConverter.h"
namespace clice::testing {
namespace {
TEST(Directive, Include) {
const char* test = "";
const char* test2 = R"cpp(
#include "test.h"
)cpp";
const char* main = R"cpp(
#$(0)include "test.h"
#$(1)include "test2.h"
#$(2)include "test3.h"
)cpp";
Tester tester("main.cpp", main);
tester.addFile("./test.h", test);
tester.addFile("./test2.h", test2);
tester.addFile("./test3.h", "");
tester.run();
auto& info = tester.info;
auto& includes = info.directive(info.srcMgr().getMainFileID()).includes;
auto EXPECT_INCLUDE = [&](std::size_t index,
llvm::StringRef position,
llvm::StringRef path,
std::source_location current = std::source_location::current()) {
auto& include = includes[index];
EXPECT_EQ(SourceConverter().toPosition(include.loc, info.srcMgr()), tester.pos(position));
EXPECT_EQ(include.path, path);
};
EXPECT_EQ(includes.size(), 3);
EXPECT_INCLUDE(0, "0", "test.h");
EXPECT_INCLUDE(1, "1", "test2.h");
EXPECT_INCLUDE(2, "2", "test3.h");
}
TEST(Directive, Condition) {
const char* code = R"cpp(
#$(0)if 0
#$(1)elif 1
#$(2)else
#$(3)endif
#$(4)ifdef name
#$(5)elifdef name
#$(6)else
#$(7)endif
)cpp";
Tester tester("main.cpp", code);
tester.run("-std=c++23");
auto& info = tester.info;
auto& conditions = info.directive(info.srcMgr().getMainFileID()).conditions;
auto EPXECT_CON = [&](std::size_t index,
Condition::BranchKind kind,
llvm::StringRef position,
std::source_location current = std::source_location::current()) {
auto& condition = conditions[index];
EXPECT_EQ(condition.kind, kind, current);
EXPECT_EQ(SourceConverter().toPosition(condition.loc, info.srcMgr()),
tester.pos(position),
current);
};
EXPECT_EQ(conditions.size(), 8);
EPXECT_CON(0, Condition::BranchKind::If, "0");
EPXECT_CON(1, Condition::BranchKind::Elif, "1");
EPXECT_CON(2, Condition::BranchKind::Else, "2");
EPXECT_CON(3, Condition::BranchKind::EndIf, "3");
EPXECT_CON(4, Condition::BranchKind::Ifdef, "4");
EPXECT_CON(5, Condition::BranchKind::Elifdef, "5");
EPXECT_CON(6, Condition::BranchKind::Else, "6");
EPXECT_CON(7, Condition::BranchKind::EndIf, "7");
}
TEST(Directive, Macro) {
const char* code = R"cpp(
#define $(0)expr(v) v
#ifdef $(1)expr
int x = $(2)expr(1);
#endif
#undef $(3)expr
#define $(4)expr(v) v
#ifdef $(5)expr
int y = $(6)expr($(7)expr(1));
#endif
#undef $(8)expr
)cpp";
Tester tester("main.cpp", code);
tester.run();
auto& info = tester.info;
auto& macros = info.directive(info.srcMgr().getMainFileID()).macros;
auto EXPECT_MACRO = [&](std::size_t index,
MacroRef::Kind kind,
llvm::StringRef position,
std::source_location current = std::source_location::current()) {
auto& macro = macros[index];
EXPECT_EQ(macro.kind, kind, current);
EXPECT_EQ(SourceConverter().toPosition(macro.loc, info.srcMgr()),
tester.pos(position),
current);
};
EXPECT_EQ(macros.size(), 9);
EXPECT_MACRO(0, MacroRef::Kind::Def, "0");
EXPECT_MACRO(1, MacroRef::Kind::Ref, "1");
EXPECT_MACRO(2, MacroRef::Kind::Ref, "2");
EXPECT_MACRO(3, MacroRef::Kind::Undef, "3");
EXPECT_MACRO(4, MacroRef::Kind::Def, "4");
EXPECT_MACRO(5, MacroRef::Kind::Ref, "5");
EXPECT_MACRO(6, MacroRef::Kind::Ref, "6");
EXPECT_MACRO(7, MacroRef::Kind::Ref, "7");
EXPECT_MACRO(8, MacroRef::Kind::Undef, "8");
}
} // namespace
} // namespace clice::testing