Skip to content

Commit 7700689

Browse files
ladisginMalofeev Mikhail
andauthored
Constructor support rebase (#594)
* Add initial constructor support --------- Co-authored-by: Malofeev Mikhail <[email protected]>
1 parent 10c065d commit 7700689

29 files changed

+629
-155
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include "constructors.h"
2+
#include <cassert>
3+
4+
BigOrSmallInteger::BigOrSmallInteger(bool isBig) {
5+
if (isBig) {
6+
number = 10000;
7+
} else {
8+
number = 1;
9+
}
10+
}
11+
12+
BigOrSmallInteger::BigOrSmallInteger() {
13+
number = 0;
14+
}
15+
16+
TwoElements::TwoElements(int *first_, int *second_) {
17+
if (*first_ > *second_) {
18+
first = *first_;
19+
second = *second_;
20+
} else {
21+
first = *second_;
22+
second = *first_;
23+
}
24+
}
25+
26+
TwoElements::TwoElements() {
27+
first = 0;
28+
second = 0;
29+
}
30+
31+
Closet::Closet(const Closet &other) {
32+
length = other.length;
33+
width = other.width;
34+
height = other.height;
35+
volume = other.volume;
36+
}
37+
38+
Closet::Closet() {
39+
length = 1.5;
40+
width = 0.5;
41+
height = 2.5;
42+
volume = height * width * length;
43+
}
44+
45+
Closet::Closet(double length_, double width_, double height_, double volume_) {
46+
length = length_;
47+
width = width_;
48+
height = height_;
49+
volume = volume_;
50+
}
51+
52+
Closet2::Closet2() {
53+
length = 1.5;
54+
width = 0.5;
55+
height = 2.5;
56+
volume = height * width * length;
57+
}
58+
59+
Closet3::Closet3(Closet3 &&other) {
60+
length = other.length;
61+
width = other.width;
62+
height = other.height;
63+
volume = other.volume;
64+
}
65+
66+
Closet3::Closet3() {
67+
length = 1.5;
68+
width = 0.5;
69+
height = 2.5;
70+
volume = height * width * length;
71+
}
72+
73+
Closet3::Closet3(double length_, double width_, double height_, double volume_) {
74+
length = length_;
75+
width = width_;
76+
height = height_;
77+
volume = volume_;
78+
}
79+
80+
Closet4::Closet4(double length_, double width_, double height_) {
81+
length = length_;
82+
width = width_;
83+
height = height_;
84+
volume = height * width * length;
85+
}
86+
87+
Closet4::Closet4() {
88+
length = 1.5;
89+
width = 0.5;
90+
height = 2.5;
91+
volume = height * width * length;
92+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef UNITTESTBOT_CONSTRUCTORS_H
2+
#define UNITTESTBOT_CONSTRUCTORS_H
3+
4+
5+
struct BigOrSmallInteger {
6+
int number;
7+
8+
BigOrSmallInteger();
9+
10+
BigOrSmallInteger(bool isBig);
11+
};
12+
13+
struct TwoElements {
14+
int first;
15+
int second;
16+
17+
TwoElements();
18+
19+
TwoElements(int *first_, int *second_);
20+
};
21+
22+
struct Closet {
23+
double length;
24+
double width;
25+
double height;
26+
double volume;
27+
28+
Closet();
29+
30+
Closet(double length_, double width_, double height_, double volume_);
31+
32+
Closet(const Closet &other);
33+
};
34+
35+
struct Closet2 {
36+
double length;
37+
double width;
38+
double height;
39+
double volume;
40+
41+
Closet2();
42+
};
43+
44+
struct Closet3 {
45+
double length;
46+
double width;
47+
double height;
48+
double volume;
49+
50+
Closet3();
51+
52+
Closet3(double length_, double width_, double height_, double volume_);
53+
54+
Closet3(Closet3 &&other);
55+
};
56+
57+
struct Closet4 {
58+
double length;
59+
double width;
60+
double height;
61+
double volume;
62+
63+
Closet4();
64+
65+
Closet4(double length_, double width_, double height_);
66+
};
67+
68+
69+
#endif // UNITTESTBOT_CONSTRUCTORS_H

server/src/BordersFinder.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "clang-utils/Matchers.h"
66
#include "utils/CollectionUtils.h"
77
#include "utils/CompilationUtils.h"
8+
#include "clang-utils/ClangUtils.h"
89

910
#include "loguru.h"
1011

@@ -38,9 +39,8 @@ void BordersFinder::run(const MatchFinder::MatchResult &Result) {
3839
lineInfo.initialized = true;
3940
LOG_S(MAX) << "Class name: " << ST->getNameAsString();
4041
LOG_S(MAX) << "Class's borders: " << lineInfo.begin << ' ' << lineInfo.end;
41-
} else if (const auto *FS = Result.Nodes.getNodeAs<FunctionDecl>(Matchers::FUNCTION_DEF)) {
42+
} else if (const FunctionDecl *FS = ClangUtils::getFunctionOrConstructor(Result)) {
4243
SourceManager &sourceManager = Result.Context->getSourceManager();
43-
4444
fs::path path = sourceManager.getFileEntryForID(sourceManager.getMainFileID())
4545
->tryGetRealPathName()
4646
.str();
@@ -84,7 +84,7 @@ void BordersFinder::run(const MatchFinder::MatchResult &Result) {
8484
lineInfo.scopeName = path.stem().string();
8585
}
8686
lineInfo.methodName = FS->getNameAsString();
87-
const clang::QualType realReturnType = FS->getReturnType().getCanonicalType();
87+
clang::QualType realReturnType = ClangUtils::getReturnType(FS, Result);
8888
lineInfo.functionReturnType = ParamsHandler::getType(realReturnType, realReturnType, sourceManager);
8989
lineInfo.initialized = true;
9090

@@ -147,6 +147,8 @@ bool BordersFinder::containsLine(BordersFinder::Borders b) const {
147147
void BordersFinder::findFunction() {
148148
MatchFinder finder;
149149
finder.addMatcher(Matchers::functionDefinitionMatcher, this);
150+
finder.addMatcher(Matchers::constructorDefinitionMatcher, this);
151+
finder.addMatcher(Matchers::memberConstructorDefinitionMatcher, this);
150152
auto factory = clang::tooling::newFrontendActionFactory(&finder);
151153
clangToolRunner.run(lineInfo.filePath, factory.get());
152154
}

server/src/Tests.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,5 +1275,4 @@ bool Tests::MethodTestCase::isError() const {
12751275
bool Tests::TypeAndVarName::operator<(const Tests::TypeAndVarName &other) const {
12761276
return varName < other.varName || (varName == other.varName && type.mTypeName() < other.type.mTypeName());
12771277
}
1278-
1279-
}
1278+
} // tests

server/src/Tests.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,12 @@ namespace tests {
482482
bool isInline;
483483
};
484484

485+
enum ConstructorInfo {
486+
NOT_A_CONSTRUCTOR = 0,
487+
CONSTRUCTOR = 1,
488+
MOVE_CONSTRUCTOR = 2
489+
};
490+
485491
struct MethodDescription {
486492
std::optional<MethodParam> classObj;
487493
std::string name;
@@ -508,6 +514,8 @@ namespace tests {
508514
typedef std::unordered_map<std::string, std::vector<int>> SuiteNameToTestCasesMap;
509515
SuiteNameToTestCasesMap suiteTestCases;
510516

517+
ConstructorInfo constructorInfo = ConstructorInfo::NOT_A_CONSTRUCTOR;
518+
511519
bool operator==(const MethodDescription &other) const;
512520

513521
MethodDescription();
@@ -571,6 +579,15 @@ namespace tests {
571579
}
572580
return std::nullopt;
573581
}
582+
583+
[[nodiscard]] bool isConstructor() const {
584+
return constructorInfo == Tests::ConstructorInfo::CONSTRUCTOR ||
585+
constructorInfo == Tests::ConstructorInfo::MOVE_CONSTRUCTOR;
586+
}
587+
588+
[[nodiscard]] bool isMoveConstructor() const {
589+
return constructorInfo == Tests::ConstructorInfo::MOVE_CONSTRUCTOR;
590+
}
574591
};
575592

576593
struct MethodDescriptionToStringEqual {

server/src/clang-utils/ClangUtils.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,25 @@ namespace ClangUtils {
2323
}
2424
return false;
2525
}
26+
27+
const clang::CXXConstructorDecl *getConstructor(const clang::ast_matchers::MatchFinder::MatchResult &Result) {
28+
return Result.Nodes.getNodeAs<clang::CXXConstructorDecl>(Matchers::CONSTRUCTOR_DEF);
29+
}
30+
31+
const clang::FunctionDecl *getFunctionOrConstructor(const clang::ast_matchers::MatchFinder::MatchResult &Result) {
32+
const auto *FS = Result.Nodes.getNodeAs<clang::FunctionDecl>(Matchers::FUNCTION_DEF);
33+
if (!FS) {
34+
FS = getConstructor(Result);
35+
}
36+
return FS;
37+
}
38+
39+
40+
clang::QualType getReturnType(const clang::FunctionDecl *FS, const clang::ast_matchers::MatchFinder::MatchResult &Result) {
41+
clang::QualType realReturnType = FS->getReturnType().getCanonicalType();
42+
if (const auto *CS = getConstructor(Result)) {
43+
realReturnType = CS->getThisObjectType();
44+
}
45+
return realReturnType;
46+
}
2647
}

server/src/clang-utils/ClangUtils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#ifndef UNITTESTBOT_CLANGUTILS_H
22
#define UNITTESTBOT_CLANGUTILS_H
33

4+
#include "clang-utils/Matchers.h"
45
#include <clang/AST/Type.h>
56

67
namespace ClangUtils {
78
bool isIncomplete(clang::QualType type);
9+
const clang::CXXConstructorDecl *getConstructor(const clang::ast_matchers::MatchFinder::MatchResult &Result);
10+
const clang::FunctionDecl *getFunctionOrConstructor(const clang::ast_matchers::MatchFinder::MatchResult &Result);
11+
clang::QualType getReturnType(const clang::FunctionDecl *FS, const clang::ast_matchers::MatchFinder::MatchResult &Result);
812
};
913

1014

server/src/clang-utils/Matchers.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ namespace Matchers {
9797
functionDecl(functionDefinitionTraits)
9898
.bind(FUNCTION_DEF);
9999

100+
const DeclarationMatcher constructorDefinitionMatcher = cxxConstructorDecl(isDefinition()).bind(CONSTRUCTOR_DEF);
101+
102+
const DeclarationMatcher memberConstructorDefinitionMatcher = cxxRecordDecl(cxxConstructorDecl(isDefinition())).bind(CONSTRUCTOR_DEF);
103+
100104
const DeclarationMatcher anyTypeDeclarationMatcher =
101105
anyOf(
102106
structMatcher,
@@ -126,7 +130,9 @@ namespace Matchers {
126130

127131
const DeclarationMatcher anyToplevelDeclarationMatcher = anyOf(
128132
anyToplevelTypeDeclarationMatcher,
129-
functionDefinitionMatcher);
133+
functionDefinitionMatcher,
134+
constructorDefinitionMatcher,
135+
memberConstructorDefinitionMatcher);
130136

131137
const DeclarationMatcher globalVariableUsageMatcher = functionDecl(functionDefinitionTraits,
132138
forEachDescendant(declRefExpr(

server/src/clang-utils/Matchers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace Matchers {
2727
static inline const std::string TYPEDEF_UNION_DECL = "the_union_typedef";
2828

2929
static inline const std::string FUNCTION_DEF = "function_def";
30+
static inline const std::string CONSTRUCTOR_DEF = "constructor_def";
3031
static inline const std::string TOPLEVEL_TYPEDEF = "typedef_decl";
3132

3233
static inline const std::string TOPLEVEL_VAR_DECL = "toplevel_var_decl";
@@ -38,6 +39,8 @@ namespace Matchers {
3839
static inline const std::string RETURN = "return";
3940

4041
extern const DeclarationMatcher functionDefinitionMatcher;
42+
extern const DeclarationMatcher constructorDefinitionMatcher;
43+
extern const DeclarationMatcher memberConstructorDefinitionMatcher;
4144

4245
extern const DeclarationMatcher structMatcher;
4346
extern const DeclarationMatcher structJustDeclMatcher;

server/src/clang-utils/SourceToHeaderMatchCallback.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "SourceToHeaderRewriter.h"
66
#include "printers/Printer.h"
77
#include "utils/ExecUtils.h"
8+
#include "clang-utils/ClangUtils.h"
89

910
#include "loguru.h"
1011

@@ -80,7 +81,7 @@ void SourceToHeaderMatchCallback::checkTypedef(const MatchFinder::MatchResult &R
8081

8182
void SourceToHeaderMatchCallback::checkFunctionDecl(
8283
const ast_matchers::MatchFinder::MatchResult &Result) {
83-
if (const auto *decl = Result.Nodes.getNodeAs<FunctionDecl>(FUNCTION_DEF)) {
84+
if (const FunctionDecl *decl = ClangUtils::getFunctionOrConstructor(Result)) {
8485
if (decl->isInlined() && decl->getStorageClass() == SC_None) {
8586
LOG_S(DEBUG)
8687
<< "inline function without static or extern modifier is not supported by now";

server/src/fetchers/Fetcher.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Fetcher::Fetcher(Options options,
3636
addMatcher<TypeDeclsMatchCallback>(structJustDeclMatcher);
3737
}
3838
if (options.has(Options::Value::FUNCTION)) {
39+
addMatcher<FunctionDeclsMatchCallback>(constructorDefinitionMatcher, false, false, false);
40+
addMatcher<FunctionDeclsMatchCallback>(memberConstructorDefinitionMatcher, false, false, false);
3941
addMatcher<FunctionDeclsMatchCallback>(functionDefinitionMatcher, false, false, false);
4042
}
4143
if (options.has(Options::Value::GLOBAL_VARIABLE_USAGE)) {
@@ -50,11 +52,15 @@ Fetcher::Fetcher(Options options,
5052
sourceFileCallbacks.add(std::move(callback));
5153
}
5254
if (options.has(Options::Value::FUNCTION_NAMES_ONLY)) {
55+
addMatcher<FunctionDeclsMatchCallback>(constructorDefinitionMatcher, true, false, false);
56+
addMatcher<FunctionDeclsMatchCallback>(memberConstructorDefinitionMatcher, true, false, false);
5357
addMatcher<FunctionDeclsMatchCallback>(functionDefinitionMatcher, true, false, false);
5458
auto callback = std::make_unique<SingleFileParseModeCallback>();
5559
sourceFileCallbacks.add(std::move(callback));
5660
}
5761
if (options.has(Options::Value::RETURN_TYPE_NAMES_ONLY)) {
62+
addMatcher<FunctionDeclsMatchCallback>(constructorDefinitionMatcher, false, true, true);
63+
addMatcher<FunctionDeclsMatchCallback>(memberConstructorDefinitionMatcher, false, true, true);
5864
addMatcher<FunctionDeclsMatchCallback>(functionDefinitionMatcher, false, true, true);
5965
auto callback = std::make_unique<SingleFileParseModeCallback>();
6066
sourceFileCallbacks.add(std::move(callback));

0 commit comments

Comments
 (0)