Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CTUApex
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Package registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Heldmann, Tim
CTUApex
Commits
a27930ff
Commit
a27930ff
authored
3 months ago
by
Heldmann, Tim
Browse files
Options
Downloads
Patches
Plain Diff
Add experimental support for templated classes
parent
b85650fc
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/CTUApexConsumer.h
+2
-0
2 additions, 0 deletions
include/CTUApexConsumer.h
include/CommandLineArgs.h
+0
-3
0 additions, 3 deletions
include/CommandLineArgs.h
src/CTUApexConsumer.cpp
+45
-19
45 additions, 19 deletions
src/CTUApexConsumer.cpp
src/main.cpp
+8
-6
8 additions, 6 deletions
src/main.cpp
with
55 additions
and
28 deletions
include/CTUApexConsumer.h
+
2
−
0
View file @
a27930ff
...
...
@@ -46,6 +46,8 @@ private:
ExtractionBlock
getNextExtractionBlock
();
void
getAvailableFunctions
(
metacg
::
Callgraph
callgraph
);
void
filterExtrationBlocks
();
};
#endif //CTUAPEX_CTUAPEXCONSUMER_H
This diff is collapsed.
Click to expand it.
include/CommandLineArgs.h
+
0
−
3
View file @
a27930ff
...
...
@@ -33,8 +33,5 @@ static cl::opt<LogLevel> LoggingLevel("log-level", cl::desc("Select log level"),
static
cl
::
opt
<
bool
>
OnlyWrapper
(
"generate-only-wrapper"
,
cl
::
desc
(
"Output only the wrapper function"
),
cl
::
cat
(
CTUApex
));
static
cl
::
opt
<
bool
>
DumpAnalysisResult
(
"dump-analysis-result"
,
cl
::
desc
(
"Dump the dependence analysis result to stdout"
),
cl
::
cat
(
CTUApex
));
#endif //CTUAPEX_COMMANDLINEARGS_H
This diff is collapsed.
Click to expand it.
src/CTUApexConsumer.cpp
+
45
−
19
View file @
a27930ff
...
...
@@ -10,32 +10,35 @@
void
CTUApexConsumer
::
outlineFunctions
()
{
for
(
const
auto
&
node
:
call_graph
->
getNodes
())
{
//check for each node in the graph, whether we found a corresponding node in the current ast
if
(
auto
md
=
node
.
second
->
checkAndGet
<
ExtractionMetadata
>
();
md
.
first
&&
md
.
second
->
get_decl_node
())
{
ExtractionBlock
eb
;
if
(
md
.
second
->
isMarkedToExtract
()){
clang
::
SourceRange
sourceRange
;
if
(
md
.
second
->
get_decl_node
()
->
isTemplateInstantiation
()){
sourceRange
=
md
.
second
->
get_decl_node
()
->
getPrimaryTemplate
()
->
getSourceRange
();
}
else
{
sourceRange
=
md
.
second
->
get_decl_node
()
->
getSourceRange
();
}
eb
.
begin
=
sourceRange
.
getBegin
();
eb
.
end
=
sourceRange
.
getEnd
();
//std::cout<<"Need to extract: "<<md.second->get_decl_node()->getNameAsString()<<"\n";
clang
::
SourceRange
sourceRange
;
//The decl will refer to the instantiated template, but we need the contents of the original template specification
if
(
md
.
second
->
get_decl_node
()
->
isTemplateInstantiation
())
{
sourceRange
=
md
.
second
->
get_decl_node
()
->
getPrimaryTemplate
()
->
getSourceRange
();
}
else
{
sourceRange
=
md
.
second
->
get_decl_node
()
->
getSourceRange
();
}
eb
.
begin
=
sourceRange
.
getBegin
();
eb
.
end
=
sourceRange
.
getEnd
();
//We only copy the contents if we are interested in them, but we do need an source-range bound extraction block for every function
//To later filter for pragmas and macros
if
(
md
.
second
->
isMarkedToExtract
())
{
eb
.
contents
=
clang
::
Lexer
::
getSourceText
(
clang
::
CharSourceRange
::
getTokenRange
(
sourceRange
),
md
.
second
->
get_decl_node
()
->
getASTContext
().
getSourceManager
(),
clang
::
LangOptions
(),
nullptr
).
str
();
}
else
{
//std::cout<<"Not extracting: "<<md.second->get_decl_node()->getNameAsString()<<"\n";
eb
.
contents
=
""
;
}
else
{
eb
.
contents
=
""
;
}
funcs
.
push_back
(
eb
);
}
}
//the callgraph nodes are unsorted, we need to sort the extraction blocks afterward
std
::
sort
(
funcs
.
begin
(),
funcs
.
end
(),[](
const
ExtractionBlock
&
a
,
const
ExtractionBlock
&
b
){
return
a
.
begin
<
b
.
begin
;});
std
::
sort
(
funcs
.
begin
(),
funcs
.
end
(),
[](
const
ExtractionBlock
&
a
,
const
ExtractionBlock
&
b
)
{
return
a
.
begin
<
b
.
begin
;
});
}
void
CTUApexConsumer
::
outlineGlobals
()
{
...
...
@@ -48,7 +51,8 @@ void CTUApexConsumer::outlineGlobals() {
assert
(
clang
::
isa
<
clang
::
FunctionDecl
>
(
md
.
second
->
get_decl_node
())
&&
"Extractionset should only contain function decls at this point"
);
GlobalsMarker
gMarker
;
auto
globalsSet
=
gMarker
.
get_nodes_to_outline
(
clang
::
cast
<
clang
::
FunctionDecl
>
(
md
.
second
->
get_decl_node
()));
auto
globalsSet
=
gMarker
.
get_nodes_to_outline
(
clang
::
cast
<
clang
::
FunctionDecl
>
(
md
.
second
->
get_decl_node
()));
for
(
const
auto
&
func
:
globalsSet
)
{
ExtractionBlock
eb
;
eb
.
begin
=
func
->
getBeginLoc
();
...
...
@@ -64,6 +68,24 @@ void CTUApexConsumer::outlineGlobals() {
}
}
void
CTUApexConsumer
::
filterExtrationBlocks
()
{
//Funcs has source-ranges for every function, but only contents for the relevant ones
//We remove all entries in the includes, macros, and pragmas that are inside ANY function
//We either get the chars by copying the function, then we do not need them
//Or we do not extract the function, then we do not want to copy the includes, macros and pragmas.
//We only want "out of function" includes, macros and pragmas
for
(
const
auto
&
func
:
funcs
)
{
clang
::
SourceRange
s
=
{
func
.
begin
,
func
.
end
};
//Cast to void to ignore return-value of remove_if
(
void
)
std
::
remove_if
(
includes
.
begin
(),
includes
.
end
(),
[
&
s
](
const
ExtractionBlock
&
e
)
{
return
s
.
fullyContains
({
e
.
begin
,
e
.
end
});
});
(
void
)
std
::
remove_if
(
macros
.
begin
(),
macros
.
end
(),
[
&
s
](
const
ExtractionBlock
&
e
)
{
return
s
.
fullyContains
({
e
.
begin
,
e
.
end
});
});
(
void
)
std
::
remove_if
(
pragmas
.
begin
(),
pragmas
.
end
(),
[
&
s
](
const
ExtractionBlock
&
e
)
{
return
s
.
fullyContains
({
e
.
begin
,
e
.
end
});
});
}
}
ExtractionBlock
CTUApexConsumer
::
getNextExtractionBlock
()
{
//find the earliest block by starting source location
//we need to do a potentially expensive copy of the full struct
...
...
@@ -143,6 +165,9 @@ void CTUApexConsumer::HandleTranslationUnit(clang::ASTContext &Context) {
SPDLOG_INFO
(
"Outlining Globals"
);
outlineGlobals
();
SPDLOG_INFO
(
"Removing duplicate extraction blocks"
);
filterExtrationBlocks
();
SPDLOG_INFO
(
"Generate code skeleton"
);
const
auto
&
sm
=
Context
.
getSourceManager
();
std
::
string
filename
=
sm
.
getFileEntryForID
(
sm
.
getMainFileID
())
->
getName
().
str
();
...
...
@@ -155,16 +180,16 @@ void CTUApexConsumer::HandleTranslationUnit(clang::ASTContext &Context) {
outFile
<<
getNextExtractionBlock
().
contents
<<
"
\n
"
;
}
SPDLOG_INFO
(
"Generate wrapper calls"
);
SPDLOG_CRITICAL
(
"WRAPPER CALLS CAN NOT YET BE IMPLEMENTED"
);
if
(
auto
md
=
call_graph
->
getMain
()
->
checkAndGet
<
ExtractionMetadata
>
();
md
.
first
&&
!
md
.
second
->
isMarkedToExtract
()){
if
(
auto
md
=
call_graph
->
getMain
()
->
checkAndGet
<
ExtractionMetadata
>
();
md
.
first
&&
!
md
.
second
->
isMarkedToExtract
())
{
//we have no main function and need to create or own
outFile
<<
"
\n
int main(){return 0;}
\n
"
;
outFile
<<
"
\n
int main(){return 0;}
\n
"
;
}
// Outline the code we want
//SPDLOG_DEBUG("Generating outline");
//assert(output.empty());
...
...
@@ -190,3 +215,4 @@ void CTUApexConsumer::HandleTranslationUnit(clang::ASTContext &Context) {
This diff is collapsed.
Click to expand it.
src/main.cpp
+
8
−
6
View file @
a27930ff
...
...
@@ -72,8 +72,11 @@ private:
void
markCalleesToExtract
(
const
size_t
nodeID
,
const
metacg
::
Callgraph
&
cg
)
{
for
(
const
auto
&
call
:
cg
.
getCallees
(
nodeID
))
{
call
->
getOrCreateMD
<
ExtractionMetadata
>
()
->
setMarkedToExtract
(
true
);
markCalleesToExtract
(
call
->
getId
(),
cg
);
//This check is probably? necessary in case of recursive functions
if
(
auto
[
h
,
v
]
=
call
->
checkAndGet
<
ExtractionMetadata
>
();
!
h
||
!
v
->
isMarkedToExtract
()){
call
->
getOrCreateMD
<
ExtractionMetadata
>
()
->
setMarkedToExtract
(
true
);
markCalleesToExtract
(
call
->
getId
(),
cg
);
}
}
}
...
...
@@ -112,14 +115,15 @@ std::vector<std::string> clangIncludeBasedArgumentAdjustor(const CommandLineArgu
std
::
string
::
size_type
pos
;
std
::
string
::
size_type
prev
=
0
;
while
((
pos
=
txt
.
find
(
'\n'
,
prev
))
!=
std
::
string
::
npos
)
{
ret
.
push_back
(
"-I"
+
txt
.
substr
(
prev
,
pos
-
prev
));
auto
t
=
std
::
prev
(
ret
.
end
(),
3
);
ret
.
insert
(
t
,{
"-I"
+
txt
.
substr
(
prev
,
pos
-
prev
)});
prev
=
pos
+
2
;
}
return
ret
;
}
std
::
vector
<
std
::
string
>
clangResourceDirBasedAdjuster
(
const
CommandLineArguments
&
cla
,
StringRef
)
{
//call the compiler specified in cla[0] with
-S and -v like so
//call the compiler specified in cla[0] with
the job to print the resource directory for compiler specific includes
std
::
string
command
=
"clang --print-resource-dir 2>1&"
;
std
::
unique_ptr
<
FILE
,
decltype
(
&
pclose
)
>
pipe
(
popen
(
command
.
c_str
(),
"r"
),
pclose
);
//then read the output of the command like so:
...
...
@@ -137,7 +141,6 @@ std::vector<std::string> clangResourceDirBasedAdjuster(const CommandLineArgument
//additional search paths need to be inserted before these 3
auto
t
=
std
::
prev
(
ret
.
end
(),
3
);
ret
.
insert
(
t
,{
"-I"
+
txt
+
"/include"
});
std
::
cout
<<
"
\n
"
;
return
ret
;
}
...
...
@@ -193,7 +196,6 @@ int main(int argc, const char **argv) {
ClangTool
tool
(
OptionsParser
.
getCompilations
(),
OptionsParser
.
getSourcePathList
());
//tool.clearArgumentsAdjusters();
tool
.
appendArgumentsAdjuster
(
clangResourceDirBasedAdjuster
);
metacg
::
io
::
FileSource
fs
(
cg_file
.
getValue
());
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment