1- /* *
1+ /* *
22 * @file test_type_correct.cpp
3- * @brief Integration tests for TypeCorrect.
4- *
5- * Runs the tool on string snippets.
6- * Covers: Rewriting, Back-Tracking, Casting, Widest Type, Template Args, Macro Expansion, and ABI Safety.
7- *
3+ * @brief Integration tests for TypeCorrect.
4+ *
5+ * Runs the tool on string snippets.
6+ * Covers: Rewriting, Back-Tracking, Casting, Widest Type, Template Args, Macro Expansion, and ABI Safety.
7+ *
88 * @author SamuelMarks
99 * @license CC0
10- */
10+ */
1111
12+ #include < clang/Frontend/CompilerInstance.h>
1213#include < clang/Tooling/Tooling.h>
1314#include < gtest/gtest.h>
1415#include < gmock/gmock.h>
1516#include < type_correct/TypeCorrect.h>
1617
17- using namespace clang ;
18- using namespace clang ::tooling;
18+ using namespace clang ;
19+ using namespace clang ::tooling;
1920
20- /* *
21+ /* *
2122 * @class TestTypeCorrectAction
22- * @brief Helper action for running TypeCorrect in a test environment.
23- *
24- * Configures the ASTConsumer with test-specific toggles (e.g. enabling ABI changes).
25- */
26- class TestTypeCorrectAction : public clang ::ASTFrontendAction {
27- public:
28- /* *
29- * @brief Constructor for the test action.
30- *
31- * @param UseDecltype Toggle decltype syntax.
32- * @param ExpandAuto Toggle auto expansion.
33- * @param Exclude Exclusion regex pattern.
34- * @param InPlace Toggle in-place rewrite (simulated).
35- * @param EnableAbi Enable structural/ABI-breaking changes.
36- */
37- explicit TestTypeCorrectAction (bool UseDecltype = false ,
38- bool ExpandAuto = false ,
39- std::string Exclude = " " ,
40- bool InPlace = false ,
41- bool EnableAbi = false )
42- : UseDecltype(UseDecltype), ExpandAuto(ExpandAuto),
43- Exclude(Exclude), InPlace(InPlace), EnableAbi(EnableAbi) {}
44-
45- /* *
46- * @brief Factory method for the AST Consumer.
47- *
48- * @param CI Compiler Instance.
49- * @param Param Unused file param.
50- * @return std::unique_ptr<clang::ASTConsumer> The TypeCorrect consumer.
51- */
52- std::unique_ptr<clang::ASTConsumer> CreateASTConsumer (clang::CompilerInstance &CI, llvm::StringRef) override {
53- Rewriter.setSourceMgr (CI.getSourceManager (), CI.getLangOpts ());
23+ * @brief Helper action for running TypeCorrect in a test environment.
24+ *
25+ * Configures the ASTConsumer with test-specific toggles (e.g. enabling ABI changes).
26+ */
27+ class TestTypeCorrectAction : public clang ::ASTFrontendAction {
28+ public:
29+ /* *
30+ * @brief Constructor for the test action.
31+ *
32+ * @param UseDecltype Toggle decltype syntax.
33+ * @param ExpandAuto Toggle auto expansion.
34+ * @param Exclude Exclusion regex pattern.
35+ * @param InPlace Toggle in-place rewrite (simulated).
36+ * @param EnableAbi Enable structural/ABI-breaking changes.
37+ */
38+ explicit TestTypeCorrectAction (bool UseDecltype = false ,
39+ bool ExpandAuto = false ,
40+ std::string Exclude = " " ,
41+ bool InPlace = false ,
42+ bool EnableAbi = false )
43+ : UseDecltype(UseDecltype), ExpandAuto(ExpandAuto),
44+ Exclude(Exclude), InPlace(InPlace), EnableAbi(EnableAbi) {}
45+
46+ /* *
47+ * @brief Factory method for the AST Consumer.
48+ *
49+ * @param CI Compiler Instance.
50+ * @param Param Unused file param.
51+ * @return std::unique_ptr<clang::ASTConsumer> The TypeCorrect consumer.
52+ */
53+ std::unique_ptr<clang::ASTConsumer> CreateASTConsumer (clang::CompilerInstance &CI, llvm::StringRef) override {
54+ Rewriter.setSourceMgr (CI.getSourceManager (), CI.getLangOpts ());
5455 // Inject test parameters into Consumer with arguments for Audit/Report set to defaults
55- return std::make_unique<TypeCorrectASTConsumer>(
56- Rewriter,
57- UseDecltype,
58- ExpandAuto,
59- " " , /* ProjectRoot */
60- Exclude,
61- InPlace,
62- EnableAbi, /* EnableAbiBreakingChanges */
63- false , /* AuditMode */
64- type_correct::Phase::Standalone,
65- " " , /* FactsOutputDir */
66- " " /* ReportFile */
67- );
68- }
69- private:
70- clang::Rewriter Rewriter;
71- bool UseDecltype;
72- bool ExpandAuto;
73- std::string Exclude;
74- bool InPlace;
75- bool EnableAbi;
76- };
77-
78- /* *
79- * @brief Helper to execute the tool on a string snippet.
80- *
81- * @param Code The C++ source code snippet.
82- * @param UseDecltype Enable decltype preference.
83- * @param ExpandAuto Enable auto expansion.
84- * @param Exclude Constraints on path exclusion (regex).
85- * @param InPlace Simulate reuse.
86- * @param EnableAbi Enable struct field rewriting.
87- * @return std::string The rewritten source code intercepted from stdout.
88- */
89- static std::string runToolOnString (llvm::StringRef Code, bool UseDecltype = false , bool ExpandAuto = false , std::string Exclude = " " , bool InPlace = false , bool EnableAbi = false ) {
90- testing::internal::CaptureStdout ();
91- runToolOnCode (std::make_unique<TestTypeCorrectAction>(UseDecltype, ExpandAuto, Exclude, InPlace, EnableAbi), Code);
92- return testing::internal::GetCapturedStdout ();
93- }
94-
95- /* *
56+ return std::make_unique<TypeCorrectASTConsumer>(
57+ Rewriter,
58+ UseDecltype,
59+ ExpandAuto,
60+ " " , /* ProjectRoot */
61+ Exclude,
62+ InPlace,
63+ EnableAbi, /* EnableAbiBreakingChanges */
64+ false , /* AuditMode */
65+ type_correct::Phase::Standalone,
66+ " " , /* FactsOutputDir */
67+ " " /* ReportFile */
68+ );
69+ }
70+ private:
71+ clang::Rewriter Rewriter;
72+ bool UseDecltype;
73+ bool ExpandAuto;
74+ std::string Exclude;
75+ bool InPlace;
76+ bool EnableAbi;
77+ };
78+
79+ /* *
80+ * @brief Helper to execute the tool on a string snippet.
81+ *
82+ * @param Code The C++ source code snippet.
83+ * @param UseDecltype Enable decltype preference.
84+ * @param ExpandAuto Enable auto expansion.
85+ * @param Exclude Constraints on path exclusion (regex).
86+ * @param InPlace Simulate reuse.
87+ * @param EnableAbi Enable struct field rewriting.
88+ * @return std::string The rewritten source code intercepted from stdout.
89+ */
90+ static std::string runToolOnString (llvm::StringRef Code, bool UseDecltype = false , bool ExpandAuto = false , std::string Exclude = " " , bool InPlace = false , bool EnableAbi = false ) {
91+ testing::internal::CaptureStdout ();
92+ runToolOnCode (std::make_unique<TestTypeCorrectAction>(UseDecltype, ExpandAuto, Exclude, InPlace, EnableAbi), Code);
93+ return testing::internal::GetCapturedStdout ();
94+ }
95+
96+ /* *
9697 * @test WidestTypeResolution
97- * @brief Verifies that the tool picks the 'widest' type when conflicting assignments exist.
98- */
99- GTEST_TEST (TypeCorrect, WidestTypeResolution) {
98+ * @brief Verifies that the tool picks the 'widest' type when conflicting assignments exist.
99+ */
100+ GTEST_TEST (TypeCorrect, WidestTypeResolution) {
100101 static const char *const Code =
101- " typedef unsigned long size_t;"
102- " size_t get_size();"
103- " int get_int();"
104- " int main(void) {"
105- " int i;"
106- " i = get_int();"
107- " i = get_size();"
108- " }" ;
109-
110- std::string Output = runToolOnString (Code);
111- EXPECT_THAT (Output, ::testing::HasSubstr (" size_t i;" ));
112- }
113-
114- /* *
102+ " typedef unsigned long size_t;"
103+ " size_t get_size();"
104+ " int get_int();"
105+ " int main(void) {"
106+ " int i;"
107+ " i = get_int();"
108+ " i = get_size();"
109+ " }" ;
110+
111+ std::string Output = runToolOnString (Code);
112+ EXPECT_THAT (Output, ::testing::HasSubstr (" size_t i;" ));
113+ }
114+
115+ /* *
115116 * @test TemplateArgumentRewriting
116- * @brief Verifies rewriting of vector<int> to vector<size_t>.
117- */
118- GTEST_TEST (TypeCorrect, TemplateArgumentRewriting) {
117+ * @brief Verifies rewriting of vector<int> to vector<size_t>.
118+ */
119+ GTEST_TEST (TypeCorrect, TemplateArgumentRewriting) {
119120 static const char *const Code =
120- " template<typename T> class vector { public: void push_back(T t) {} };"
121- " typedef unsigned long size_t;"
122- " size_t get_size();"
123- " int main() {"
124- " vector<int> v;"
125- " v.push_back(get_size());"
126- " }" ;
127-
128- std::string Output = runToolOnString (Code);
129- EXPECT_THAT (Output, ::testing::HasSubstr (" vector<size_t> v;" ));
130- }
131-
132- /* *
121+ " template<typename T> class vector { public: void push_back(T t) {} };"
122+ " typedef unsigned long size_t;"
123+ " size_t get_size();"
124+ " int main() {"
125+ " vector<int> v;"
126+ " v.push_back(get_size());"
127+ " }" ;
128+
129+ std::string Output = runToolOnString (Code);
130+ EXPECT_THAT (Output, ::testing::HasSubstr (" vector<size_t> v;" ));
131+ }
132+
133+ /* *
133134 * @test MacroRewriting
134- * @brief Verifies rewriting of type within a macro definition.
135- */
136- GTEST_TEST (TypeCorrect, MacroRewriting) {
135+ * @brief Verifies rewriting of type within a macro definition.
136+ */
137+ GTEST_TEST (TypeCorrect, MacroRewriting) {
137138 // NOTE: In-memory string tests often fail to emulate "File modifiability" logic
138- // for macros properly because they don't have a backing file.
139- // However, we test the matching logic here.
140- // The system defaults "IsModifiable" to true for Main File.
139+ // for macros properly because they don't have a backing file.
140+ // However, we test the matching logic here.
141+ // The system defaults "IsModifiable" to true for Main File.
141142 static const char *const Code =
142- " #define INIT_VAR int \n "
143- " typedef unsigned long size_t;"
144- " size_t get_size();"
145- " int main() {"
146- " INIT_VAR x = get_size();"
147- " }" ;
148-
149- std::string Output = runToolOnString (Code);
150- EXPECT_THAT (Output, ::testing::HasSubstr (" #define INIT_VAR size_t" ));
151- }
152-
153- /* *
143+ " #define INIT_VAR int \n "
144+ " typedef unsigned long size_t;"
145+ " size_t get_size();"
146+ " int main() {"
147+ " INIT_VAR x = get_size();"
148+ " }" ;
149+
150+ std::string Output = runToolOnString (Code);
151+ EXPECT_THAT (Output, ::testing::HasSubstr (" #define INIT_VAR size_t" ));
152+ }
153+
154+ /* *
154155 * @test StructFieldRewritingDisabled
155- * @brief Verifies that struct fields are NOT rewritten by default (ABI safety).
156- */
157- GTEST_TEST (TypeCorrect, StructFieldRewritingDisabled) {
156+ * @brief Verifies that struct fields are NOT rewritten by default (ABI safety).
157+ */
158+ GTEST_TEST (TypeCorrect, StructFieldRewritingDisabled) {
158159 static const char *const Code =
159- " typedef unsigned long size_t;"
160- " size_t get_size();"
161- " struct MyData { int x; };"
162- " void f() {"
163- " MyData d;"
164- " d.x = get_size();"
165- " }" ;
160+ " typedef unsigned long size_t;"
161+ " size_t get_size();"
162+ " struct MyData { int x; };"
163+ " void f() {"
164+ " MyData d;"
165+ " d.x = get_size();"
166+ " }" ;
166167
167168 // Default: EnableAbi = false
168- std::string Output = runToolOnString (Code, false , false , " " , false , /* EnableAbi=*/ false );
169+ std::string Output = runToolOnString (Code, false , false , " " , false , /* EnableAbi=*/ false );
169170
170171 // Should NOT verify change
171- EXPECT_THAT (Output, ::testing::HasSubstr (" int x;" ));
172- EXPECT_THAT (Output, ::testing::Not (::testing::HasSubstr (" size_t x;" )));
173- }
172+ EXPECT_THAT (Output, ::testing::HasSubstr (" int x;" ));
173+ EXPECT_THAT (Output, ::testing::Not (::testing::HasSubstr (" size_t x;" )));
174+ }
174175
175- /* *
176+ /* *
176177 * @test StructFieldRewritingEnabled
177- * @brief Verifies that struct fields ARE rewritten when the CLI flag is enabled.
178- */
179- GTEST_TEST (TypeCorrect, StructFieldRewritingEnabled) {
178+ * @brief Verifies that struct fields ARE rewritten when the CLI flag is enabled.
179+ */
180+ GTEST_TEST (TypeCorrect, StructFieldRewritingEnabled) {
180181 static const char *const Code =
181- " typedef unsigned long size_t;"
182- " size_t get_size();"
183- " struct MyData { int x; };"
184- " void f() {"
185- " MyData d;"
186- " d.x = get_size();"
187- " }" ;
182+ " typedef unsigned long size_t;"
183+ " size_t get_size();"
184+ " struct MyData { int x; };"
185+ " void f() {"
186+ " MyData d;"
187+ " d.x = get_size();"
188+ " }" ;
188189
189190 // EnableAbi = true
190- std::string Output = runToolOnString (Code, false , false , " " , false , /* EnableAbi=*/ true );
191+ std::string Output = runToolOnString (Code, false , false , " " , false , /* EnableAbi=*/ true );
191192
192193 // Should verify change
193- EXPECT_THAT (Output, ::testing::HasSubstr (" size_t x;" ));
194+ EXPECT_THAT (Output, ::testing::HasSubstr (" size_t x;" ));
194195}
0 commit comments