mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
clang_generator: Refactor frontend test utilities
This makes it easier to write tests with expected compilation/parsing failures. PiperOrigin-RevId: 485331205 Change-Id: Ia545934849d38bded9320537c71e970fb4730cb6
This commit is contained in:
parent
c3889ce379
commit
7e0f72e445
|
@ -46,13 +46,14 @@ class EmitterTest : public FrontendActionTest {};
|
|||
|
||||
TEST_F(EmitterTest, BasicFunctionality) {
|
||||
GeneratorOptions options;
|
||||
options.out_file = "input.h";
|
||||
options.set_function_names<std::initializer_list<std::string>>(
|
||||
{"ExposedFunction"});
|
||||
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(R"(extern "C" void ExposedFunction() {})",
|
||||
std::make_unique<GeneratorAction>(emitter, options));
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(R"(extern "C" void ExposedFunction() {})",
|
||||
std::make_unique<GeneratorAction>(emitter, options)),
|
||||
IsOk());
|
||||
|
||||
EXPECT_THAT(emitter.functions_, SizeIs(1));
|
||||
|
||||
|
@ -62,25 +63,25 @@ TEST_F(EmitterTest, BasicFunctionality) {
|
|||
|
||||
TEST_F(EmitterTest, RelatedTypes) {
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(
|
||||
R"(
|
||||
namespace std {
|
||||
using size_t = unsigned long;
|
||||
} // namespace std
|
||||
using std::size_t;
|
||||
typedef enum { kRed, kGreen, kBlue } Color;
|
||||
struct Channel {
|
||||
Color color;
|
||||
size_t width;
|
||||
size_t height;
|
||||
};
|
||||
struct ByValue { int value; };
|
||||
extern "C" void Colorize(Channel* chan, ByValue v) {}
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(
|
||||
R"(namespace std {
|
||||
using size_t = unsigned long;
|
||||
} // namespace std
|
||||
using std::size_t;
|
||||
typedef enum { kRed, kGreen, kBlue } Color;
|
||||
struct Channel {
|
||||
Color color;
|
||||
size_t width;
|
||||
size_t height;
|
||||
};
|
||||
struct ByValue { int value; };
|
||||
extern "C" void Colorize(Channel* chan, ByValue v);
|
||||
|
||||
typedef struct { int member; } MyStruct;
|
||||
extern "C" void Structize(MyStruct* s);
|
||||
)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions()));
|
||||
typedef struct { int member; } MyStruct;
|
||||
extern "C" void Structize(MyStruct* s);)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions())),
|
||||
IsOk());
|
||||
|
||||
// Types from "std" should be skipped
|
||||
EXPECT_THAT(emitter.rendered_types_["std"], IsEmpty());
|
||||
|
@ -97,16 +98,16 @@ TEST_F(EmitterTest, RelatedTypes) {
|
|||
|
||||
TEST_F(EmitterTest, NestedStruct) {
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(
|
||||
R"(
|
||||
struct A {
|
||||
struct B { int number; };
|
||||
B b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A* s);
|
||||
)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions()));
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(
|
||||
R"(struct A {
|
||||
struct B { int number; };
|
||||
B b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A* s);)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions())),
|
||||
IsOk());
|
||||
|
||||
EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]),
|
||||
ElementsAre("struct A {"
|
||||
|
@ -117,15 +118,15 @@ TEST_F(EmitterTest, NestedStruct) {
|
|||
|
||||
TEST_F(EmitterTest, NestedAnonymousStruct) {
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(
|
||||
R"(
|
||||
struct A {
|
||||
struct { int number; } b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A* s);
|
||||
)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions()));
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(
|
||||
R"(struct A {
|
||||
struct { int number; } b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A* s);)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions())),
|
||||
IsOk());
|
||||
|
||||
EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]),
|
||||
ElementsAre("struct A {"
|
||||
|
@ -135,16 +136,16 @@ TEST_F(EmitterTest, NestedAnonymousStruct) {
|
|||
|
||||
TEST_F(EmitterTest, ParentNotCollected) {
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(
|
||||
R"(
|
||||
struct A {
|
||||
struct B { int number; };
|
||||
B b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A::B* s);
|
||||
)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions()));
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(
|
||||
R"(struct A {
|
||||
struct B { int number; };
|
||||
B b;
|
||||
int data;
|
||||
};
|
||||
extern "C" void Structize(A::B* s);)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions())),
|
||||
IsOk());
|
||||
|
||||
EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]),
|
||||
ElementsAre("struct A {"
|
||||
|
@ -155,12 +156,12 @@ TEST_F(EmitterTest, ParentNotCollected) {
|
|||
|
||||
TEST_F(EmitterTest, RemoveQualifiers) {
|
||||
EmitterForTesting emitter;
|
||||
RunFrontendAction(
|
||||
R"(
|
||||
struct A { int data; };
|
||||
extern "C" void Structize(const A* in, A* out);
|
||||
)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions()));
|
||||
ASSERT_THAT(
|
||||
RunFrontendAction(
|
||||
R"(struct A { int data; };
|
||||
extern "C" void Structize(const A* in, A* out);)",
|
||||
std::make_unique<GeneratorAction>(emitter, GeneratorOptions())),
|
||||
IsOk());
|
||||
|
||||
EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]),
|
||||
ElementsAre("struct A { int data; }"));
|
||||
|
|
|
@ -56,21 +56,20 @@ class FrontendActionTest : public ::testing::Test {
|
|||
absl::string_view input_file);
|
||||
|
||||
// Runs the specified frontend action on in-memory source code.
|
||||
void RunFrontendAction(absl::string_view code,
|
||||
std::unique_ptr<clang::FrontendAction> action) {
|
||||
absl::Status RunFrontendAction(
|
||||
absl::string_view code, std::unique_ptr<clang::FrontendAction> action) {
|
||||
std::vector<std::string> command_line =
|
||||
GetCommandLineFlagsForTesting(input_file_);
|
||||
AddCode(input_file_, code);
|
||||
ASSERT_THAT(
|
||||
internal::RunClangTool(command_line, file_contents_, std::move(action)),
|
||||
IsOk());
|
||||
return internal::RunClangTool(command_line, file_contents_,
|
||||
std::move(action));
|
||||
}
|
||||
|
||||
// Runs the specified frontend action. Provided for compatibility with LLVM <
|
||||
// 10. Takes ownership.
|
||||
void RunFrontendAction(absl::string_view code,
|
||||
clang::FrontendAction* action) {
|
||||
RunFrontendAction(code, absl::WrapUnique(action));
|
||||
absl::Status RunFrontendAction(absl::string_view code,
|
||||
clang::FrontendAction* action) {
|
||||
return RunFrontendAction(code, absl::WrapUnique(action));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
|
@ -51,7 +49,7 @@ struct GeneratorOptions {
|
|||
std::string namespace_name; // Namespace to wrap the SAPI in
|
||||
// Output path of the generated header. Used to build the header include
|
||||
// guard.
|
||||
std::string out_file;
|
||||
std::string out_file = "out_file.cc";
|
||||
std::string embed_dir; // Directory with embedded includes
|
||||
std::string embed_name; // Identifier of the embed object
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user