Skip to content

Commit 86d8bd9

Browse files
Andreas FertigAndreas Fertig
Andreas Fertig
authored and
Andreas Fertig
committed
Added support for expansion of class templates.
Up to now class templates ended up with just the class tag and name. This change expands the whole class, including methods and variables. There are some cases where a method has no body in the expanded version. In that case this method is unused in the instatiated version. This changes also brings support for more statements/expressions. Like the placement delete or inline variable initialization. A further simplification is the attempt to introduce a function which is responsible to adding parens or curlys.
1 parent 6de3d9c commit 86d8bd9

File tree

73 files changed

+1388
-256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1388
-256
lines changed

CodeGenerator.cpp

+395-103
Large diffs are not rendered by default.

CodeGenerator.h

+21-1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class CodeGenerator
105105

106106
virtual ~CodeGenerator() = default;
107107

108+
#define IGNORED_DECL(type) \
109+
virtual void InsertArg(const type*) {}
108110
#define IGNORED_STMT(type) \
109111
virtual void InsertArg(const type*) {}
110112
#define SUPPORTED_DECL(type) virtual void InsertArg(const type* stmt);
@@ -126,10 +128,12 @@ class CodeGenerator
126128
}
127129

128130
STRONG_BOOL(SkipConstexpr);
131+
STRONG_BOOL(SkipAccess);
129132

130133
static void InsertAccessModifierAndNameWithReturnType(OutputFormatHelper& outputFormatHelper,
131134
const CXXMethodDecl& decl,
132-
SkipConstexpr skipConstexpr = SkipConstexpr::No);
135+
const SkipConstexpr skipConstexpr = SkipConstexpr::No,
136+
const SkipAccess skipAccess = SkipAccess::No);
133137

134138
protected:
135139
void HandleCharacterLiteral(const CharacterLiteral& stmt);
@@ -160,6 +164,22 @@ class CodeGenerator
160164
void InsertTemplateArgs(const ArrayRef<TemplateArgument>& array);
161165
void InsertTemplateArg(const TemplateArgument& arg);
162166

167+
/// \brief Check whether or not this statement will add curlys or parentheses and add them only if required.
168+
void InsertCurlysIfRequired(const Stmt* stmt);
169+
170+
STRONG_BOOL(AddSpaceAtTheEnd);
171+
172+
enum class BraceKind
173+
{
174+
Parens,
175+
Curlys
176+
};
177+
178+
template<typename T>
179+
void WrapInParensOrCurlys(const BraceKind curlys,
180+
T&& lambda,
181+
const AddSpaceAtTheEnd addSpaceAtTheEnd = AddSpaceAtTheEnd::No);
182+
163183
static const char* GetKind(const UnaryExprOrTypeTraitExpr& uk);
164184
static const char* GetOpcodeName(const int kind);
165185
static const char* GetBuiltinTypeSuffix(const BuiltinType& type);

CodeGeneratorTypes.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@
1717
IGNORED_STMT(OMPOrderedDirective)
1818
IGNORED_STMT(OMPParallelForDirective)
1919

20-
IGNORED_DECL(StaticAssertDecl)
20+
IGNORED_DECL(UsingShadowDecl)
21+
IGNORED_DECL(UsingPackDecl)
2122

2223
SUPPORTED_DECL(DecompositionDecl)
2324
SUPPORTED_DECL(VarDecl)
2425
SUPPORTED_DECL(TypeAliasDecl)
2526
SUPPORTED_DECL(TypedefDecl)
27+
SUPPORTED_DECL(StaticAssertDecl)
28+
SUPPORTED_DECL(FieldDecl)
29+
SUPPORTED_DECL(AccessSpecDecl)
30+
SUPPORTED_DECL(CXXMethodDecl)
31+
SUPPORTED_DECL(UsingDecl)
32+
SUPPORTED_DECL(CXXRecordDecl)
2633

34+
SUPPORTED_STMT(CXXDeleteExpr)
35+
SUPPORTED_STMT(CXXDefaultInitExpr)
2736
SUPPORTED_STMT(MemberExpr)
2837
SUPPORTED_STMT(IntegerLiteral)
2938
SUPPORTED_STMT(StringLiteral)

InsightsBase.h

+2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ class InsightsBase
3333

3434
STRONG_BOOL(SkipConstexpr);
3535

36+
public:
3637
static void GenerateFunctionPrototype(OutputFormatHelper& outputFormatHelper, const FunctionDecl& FD);
3738

39+
protected:
3840
bool SkipIfAlreadySeen(const Stmt* stmt);
3941

4042
private:

NumberIterator.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef INSIGHTS_NUMBER_ITERATOR_H
2+
#define INSIGHTS_NUMBER_ITERATOR_H
3+
4+
template<typename T>
5+
class NumberIterator
6+
{
7+
public:
8+
NumberIterator(const T num)
9+
: mNum{num}
10+
, mCount{0}
11+
{
12+
}
13+
14+
const T& operator*() const { return mCount; }
15+
16+
NumberIterator& operator++()
17+
{
18+
++mCount;
19+
20+
return *this;
21+
}
22+
23+
bool operator!=(const NumberIterator&) const { return mCount < mNum; }
24+
25+
const NumberIterator& begin() const { return *this; }
26+
const NumberIterator& end() const { return *this; }
27+
28+
private:
29+
const T mNum;
30+
T mCount;
31+
};
32+
//-----------------------------------------------------------------------------
33+
34+
#endif /* INSIGHTS_NUMBER_ITERATOR_H */

StaticAssertHandler.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
****************************************************************************/
77

88
#include "StaticAssertHandler.h"
9+
#include "CodeGenerator.h"
910
#include "InsightsHelpers.h"
1011
#include "InsightsMatchers.h"
1112
#include "InsightsStaticStrings.h"
@@ -30,17 +31,15 @@ StaticAssertHandler::StaticAssertHandler(Rewriter& rewrite, MatchFinder& matcher
3031

3132
void StaticAssertHandler::run(const MatchFinder::MatchResult& result)
3233
{
33-
const auto* matchedDecl = result.Nodes.getNodeAs<StaticAssertDecl>("static_assert");
34-
const std::string passFailed = [&]() {
35-
if(!matchedDecl->isFailed()) {
36-
return "/* PASSED: ";
37-
}
34+
if(const auto* matchedDecl = result.Nodes.getNodeAs<StaticAssertDecl>("static_assert")) {
35+
OutputFormatHelper outputFormatHelper{};
36+
CodeGenerator codeGenerator{outputFormatHelper};
37+
codeGenerator.InsertArg(matchedDecl);
3838

39-
return "/* FAILED: ";
40-
}();
39+
const auto sr = GetSourceRangeAfterToken(matchedDecl->getSourceRange(), tok::semi, result);
4140

42-
mRewrite.InsertText(matchedDecl->getLocStart(), passFailed);
43-
mRewrite.InsertTextAfterToken(matchedDecl->getLocEnd(), "*/");
41+
mRewrite.ReplaceText(sr, outputFormatHelper.GetString());
42+
}
4443
}
4544
//-----------------------------------------------------------------------------
4645

TemplateHandler.cpp

+5-11
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ void TemplateHandler::run(const MatchFinder::MatchResult& result)
4444
InsertInstantiatedTemplate(*functionDecl, result);
4545

4646
} else if(const auto* clsTmplSpecDecl = result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("class")) {
47+
// skip classes/struct's without a definition
48+
if(!clsTmplSpecDecl->hasDefinition()) {
49+
return;
50+
}
4751

4852
OutputFormatHelper outputFormatHelper{};
4953
outputFormatHelper.AppendNewLine();
@@ -53,19 +57,9 @@ void TemplateHandler::run(const MatchFinder::MatchResult& result)
5357

5458
outputFormatHelper.AppendNewLine("#ifdef INSIGHTS_USE_TEMPLATE");
5559

56-
outputFormatHelper.Append(kwClassSpace, GetName(*clsTmplSpecDecl));
57-
5860
CodeGenerator codeGenerator{outputFormatHelper};
59-
codeGenerator.InsertTemplateArgs(*clsTmplSpecDecl);
60-
61-
outputFormatHelper.AppendNewLine();
62-
63-
outputFormatHelper.OpenScope();
61+
codeGenerator.InsertArg(clsTmplSpecDecl);
6462

65-
outputFormatHelper.CloseScopeWithSemi();
66-
outputFormatHelper.AppendNewLine();
67-
68-
outputFormatHelper.AppendNewLine();
6963
outputFormatHelper.AppendNewLine("#endif");
7064

7165
const auto* clsTmplDecl = result.Nodes.getNodeAs<ClassTemplateDecl>("decl");

scripts/travis_install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
44
export HOMEBREW_NO_AUTO_UPDATE=1
5+
brew update > /dev/null
56
brew install cmake || brew upgrade cmake
67
brew install xz || brew upgrade xz
78

tests/AutoHandler5Test.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
int foo(int a,int b){ return a+b; }
2+
3+
int main(){
4+
if(true) {
5+
int (*add)(int,int)= foo;
6+
// auto within a function pointer
7+
auto add1= foo;
8+
}
9+
}
10+

tests/AutoHandler5Test.expect

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
int foo(int a,int b){ return a+b; }
2+
3+
int main(){
4+
if(true) {
5+
using FuncPtr_5 = int (*)(int, int);
6+
FuncPtr_5 add = foo;
7+
using FuncPtr_7 = int (*)(int, int);
8+
FuncPtr_7 add1 = foo;
9+
}
10+
11+
}
12+

tests/CXXDefaultInitExprTest.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
template<typename T, bool array>
2+
class Alloc
3+
{
4+
const int z;
5+
T* data{nullptr};
6+
const bool x{false};
7+
8+
public:
9+
Alloc() : z{2}
10+
{
11+
}
12+
};
13+
14+
int main()
15+
{
16+
Alloc<int, false> a;
17+
Alloc<char, true> b;
18+
}

tests/CXXDefaultInitExprTest.expect

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
template<typename T, bool array>
2+
class Alloc
3+
{
4+
const int z;
5+
T* data{nullptr};
6+
const bool x{false};
7+
8+
public:
9+
Alloc() : z{2}
10+
{
11+
}
12+
};
13+
/* First instantiated from: CXXDefaultInitExprTest.cpp:16 */
14+
#ifdef INSIGHTS_USE_TEMPLATE
15+
class Alloc<int, 0>
16+
{
17+
const int z;
18+
int * data;
19+
const bool x;
20+
21+
public:
22+
inline Alloc()
23+
: z{2}
24+
, data{nullptr}
25+
, x{false}
26+
{
27+
}
28+
29+
inline constexpr Alloc(const Alloc<int, 0> &) = default;
30+
inline constexpr Alloc(Alloc<int, 0> &&) = default;
31+
32+
};
33+
34+
#endif
35+
36+
/* First instantiated from: CXXDefaultInitExprTest.cpp:17 */
37+
#ifdef INSIGHTS_USE_TEMPLATE
38+
class Alloc<char, 1>
39+
{
40+
const int z;
41+
char * data;
42+
const bool x;
43+
44+
public:
45+
inline Alloc()
46+
: z{2}
47+
, data{nullptr}
48+
, x{false}
49+
{
50+
}
51+
52+
inline constexpr Alloc(const Alloc<char, 1> &) = default;
53+
inline constexpr Alloc(Alloc<char, 1> &&) = default;
54+
55+
};
56+
57+
#endif
58+
59+
60+
int main()
61+
{
62+
Alloc<int, false> a;
63+
Alloc<char, true> b;
64+
}

tests/CXXDestructorTest.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
template<typename T, bool array>
2+
class Alloc
3+
{
4+
T* data;
5+
6+
public:
7+
Alloc() {
8+
if( array ) {
9+
data = new T[10];
10+
data = new T[10]{1,2,3};
11+
} else {
12+
data = new T;
13+
data = new T(2);
14+
data = new T{2};
15+
}
16+
}
17+
18+
~Alloc() {
19+
if( array ) {
20+
delete[] data;
21+
} else {
22+
delete data;
23+
}
24+
}
25+
};
26+
27+
int main()
28+
{
29+
Alloc<int, false> a;
30+
Alloc<char, true> b;
31+
}

0 commit comments

Comments
 (0)