0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Public Attributes | Private Attributes | List of all members
clanguml::sequence_diagram::visitor::call_expression_context Struct Reference

This class is used to track current context of the call expressions. More...

Detailed Description

This class is used to track current context of the call expressions.

When traversing AST for call expressions, we need to keep the state of the current context, for instance whether we are in a for loop or an if block, as well as the current parent of the call expression e.g. a class method or function.

Definition at line 41 of file call_expression_context.h.

#include <call_expression_context.h>

Public Types

using callexpr_stack_t = std::variant< std::monostate, clang::CallExpr *, clang::CXXConstructExpr * >
 

Public Member Functions

 call_expression_context ()
 
void reset ()
 Reset call expression context to the original state.
 
bool valid () const
 Verify that the context is in a valid state.
 
clang::ASTContext * get_ast_context () const
 
void update (clang::CXXRecordDecl *cls)
 Set the current context to a class.
 
void update (clang::ClassTemplateSpecializationDecl *clst)
 Set the current context to a class template specialization.
 
void update (clang::ClassTemplateDecl *clst)
 Set the current context to a class template.
 
void update (clang::CXXMethodDecl *method)
 Set the current context to a class method.
 
void update (clang::FunctionDecl *function)
 Set the current context to a function.
 
void update (clang::FunctionTemplateDecl *function_template)
 Set the current context to a function template.
 
void set_caller_id (eid_t id)
 Set current caller to id of the current participant.
 
eid_t caller_id () const
 Get current caller id.
 
std::optional< eid_tlambda_caller_id () const
 Get the id of the current lambda caller.
 
void enter_lambda_expression (eid_t id)
 Enter a lambda expression.
 
void leave_lambda_expression ()
 Leave current lambda expression.
 
clang::IfStmt * current_ifstmt () const
 Get current if statement block.
 
void enter_ifstmt (clang::IfStmt *stmt)
 Enter if statement block.
 
void leave_ifstmt ()
 Leave if statement block.
 
void enter_elseifstmt (clang::IfStmt *stmt)
 Enter else if statement block.
 
clang::IfStmt * current_elseifstmt () const
 Get current else if statement block.
 
clang::Stmt * current_loopstmt () const
 Get current loop statement block.
 
void enter_loopstmt (clang::Stmt *stmt)
 Enter loop statement block.
 
void leave_loopstmt ()
 Leave loop statement block.
 
clang::Stmt * current_trystmt () const
 Get current try statement block.
 
void enter_trystmt (clang::Stmt *stmt)
 Enter try statement block.
 
void leave_trystmt ()
 Leave try statement block.
 
clang::SwitchStmt * current_switchstmt () const
 Get current switch statement block.
 
void enter_switchstmt (clang::SwitchStmt *stmt)
 Enter switch statement block.
 
void leave_switchstmt ()
 Leave switch statement block.
 
clang::ConditionalOperator * current_conditionaloperator () const
 Get current :? statement block.
 
void enter_conditionaloperator (clang::ConditionalOperator *stmt)
 Enter :? statement block.
 
void leave_conditionaloperator ()
 Leave :? statement block.
 
callexpr_stack_t current_callexpr () const
 Get current call expression.
 
void enter_callexpr (clang::CallExpr *expr)
 Enter a call expression.
 
void enter_callexpr (clang::CXXConstructExpr *expr)
 Enter a constructor call expression.
 
void leave_callexpr ()
 Leave call expression.
 
bool is_expr_in_current_control_statement_condition (const clang::Stmt *stmt) const
 Check, if a statement is contained in a control statement.
 
void dump ()
 Print the current call expression stack for debugging.
 

Public Attributes

clang::CXXRecordDecl * current_class_decl_ {nullptr}
 
clang::ClassTemplateDecl * current_class_template_decl_ {nullptr}
 
clang::ClassTemplateSpecializationDecl * current_class_template_specialization_decl_ {nullptr}
 
clang::CXXMethodDecl * current_method_decl_ {nullptr}
 
clang::FunctionDecl * current_function_decl_ {nullptr}
 
clang::FunctionTemplateDecl * current_function_template_decl_ {nullptr}
 

Private Attributes

eid_t current_caller_id_ {}
 
std::stack< eid_tcurrent_lambda_caller_id_
 
std::stack< callexpr_stack_tcall_expr_stack_
 
std::stack< clang::IfStmt * > if_stmt_stack_
 
std::map< clang::IfStmt *, std::stack< clang::IfStmt * > > elseif_stmt_stacks_
 
std::stack< clang::Stmt * > loop_stmt_stack_
 
std::stack< clang::Stmt * > try_stmt_stack_
 
std::stack< clang::SwitchStmt * > switch_stmt_stack_
 
std::stack< clang::ConditionalOperator * > conditional_operator_stack_
 

Member Typedef Documentation

◆ callexpr_stack_t

using clanguml::sequence_diagram::visitor::call_expression_context::callexpr_stack_t = std::variant<std::monostate, clang::CallExpr *, clang::CXXConstructExpr *>

In Clang, call to a class constructor is represented by clang::CXXConstructExpr, which does inherit from clang::CallExpr. So to enable to track calls to constructors, we need to be able to add to the call stack either type.

Definition at line 48 of file call_expression_context.h.

Constructor & Destructor Documentation

◆ call_expression_context()

clanguml::sequence_diagram::visitor::call_expression_context::call_expression_context ( )
default

Member Function Documentation

◆ caller_id()

eid_t clanguml::sequence_diagram::visitor::call_expression_context::caller_id ( ) const

Get current caller id.

Returns
Id of the current caller participant

Definition at line 133 of file call_expression_context.cc.

134{
135 if (lambda_caller_id().has_value())
136 return *lambda_caller_id(); // NOLINT
137
138 return current_caller_id_;
139}

◆ current_callexpr()

call_expression_context::callexpr_stack_t clanguml::sequence_diagram::visitor::call_expression_context::current_callexpr ( ) const

Get current call expression.

Returns
Call expression

Definition at line 234 of file call_expression_context.cc.

235{
236 if (call_expr_stack_.empty())
237 return {};
238
239 return call_expr_stack_.top();
240}

◆ current_conditionaloperator()

clang::ConditionalOperator * clanguml::sequence_diagram::visitor::call_expression_context::current_conditionaloperator ( ) const

Get current :? statement block.

Returns
:? statement block.

Definition at line 298 of file call_expression_context.cc.

299{
300 if (conditional_operator_stack_.empty())
301 return nullptr;
302
303 return conditional_operator_stack_.top();
304}

◆ current_elseifstmt()

clang::IfStmt * clanguml::sequence_diagram::visitor::call_expression_context::current_elseifstmt ( ) const

Get current else if statement block.

Returns
if statement block.

Definition at line 203 of file call_expression_context.cc.

204{
205 assert(current_ifstmt() != nullptr);
206
207 if (elseif_stmt_stacks_.count(current_ifstmt()) == 0 ||
209 return nullptr;
210
211 return elseif_stmt_stacks_.at(current_ifstmt()).top();
212}

◆ current_ifstmt()

clang::IfStmt * clanguml::sequence_diagram::visitor::call_expression_context::current_ifstmt ( ) const

Get current if statement block.

Returns
if statement block.

Definition at line 175 of file call_expression_context.cc.

176{
177 if (if_stmt_stack_.empty())
178 return nullptr;
179
180 return if_stmt_stack_.top();
181}

◆ current_loopstmt()

clang::Stmt * clanguml::sequence_diagram::visitor::call_expression_context::current_loopstmt ( ) const

Get current loop statement block.

Returns
Loop statement block.

Definition at line 214 of file call_expression_context.cc.

215{
216 if (loop_stmt_stack_.empty())
217 return nullptr;
218
219 return loop_stmt_stack_.top();
220}

◆ current_switchstmt()

clang::SwitchStmt * clanguml::sequence_diagram::visitor::call_expression_context::current_switchstmt ( ) const

Get current switch statement block.

Returns
switch statement block.

Definition at line 278 of file call_expression_context.cc.

279{
280 if (switch_stmt_stack_.empty())
281 return nullptr;
282
283 return switch_stmt_stack_.top();
284}

◆ current_trystmt()

clang::Stmt * clanguml::sequence_diagram::visitor::call_expression_context::current_trystmt ( ) const

Get current try statement block.

Returns
try statement block.

Definition at line 259 of file call_expression_context.cc.

260{
261 if (try_stmt_stack_.empty())
262 return nullptr;
263
264 return try_stmt_stack_.top();
265}

◆ dump()

void clanguml::sequence_diagram::visitor::call_expression_context::dump ( )

Print the current call expression stack for debugging.

Definition at line 36 of file call_expression_context.cc.

37{
38 LOG_DBG("current_caller_id_ = {}", current_caller_id_);
39 LOG_DBG("current_class_decl_ = {}", (void *)current_class_decl_);
40 LOG_DBG("current_class_template_decl_ = {}",
42 LOG_DBG("current_class_template_specialization_decl_ = {}",
44 LOG_DBG("current_method_decl_ = {}", (void *)current_method_decl_);
45 LOG_DBG("current_function_decl_ = {}", (void *)current_function_decl_);
46 LOG_DBG("current_function_template_decl_ = {}",
48}

◆ enter_callexpr() [1/2]

void clanguml::sequence_diagram::visitor::call_expression_context::enter_callexpr ( clang::CallExpr *  expr)

Enter a call expression.

Parameters
exprCall expression

Definition at line 242 of file call_expression_context.cc.

243{
244 call_expr_stack_.emplace(expr);
245}

◆ enter_callexpr() [2/2]

void clanguml::sequence_diagram::visitor::call_expression_context::enter_callexpr ( clang::CXXConstructExpr *  expr)

Enter a constructor call expression.

Parameters
exprConstructor call expression

Definition at line 247 of file call_expression_context.cc.

248{
249 call_expr_stack_.emplace(expr);
250}

◆ enter_conditionaloperator()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_conditionaloperator ( clang::ConditionalOperator *  stmt)

Enter :? statement block.

Parameters
stmt:? statement block

Definition at line 306 of file call_expression_context.cc.

308{
309 conditional_operator_stack_.emplace(stmt);
310}

◆ enter_elseifstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_elseifstmt ( clang::IfStmt *  stmt)

Enter else if statement block.

Parameters
stmtif statement block

Definition at line 196 of file call_expression_context.cc.

197{
198 assert(current_ifstmt() != nullptr);
199
200 elseif_stmt_stacks_[current_ifstmt()].emplace(stmt);
201}

◆ enter_ifstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_ifstmt ( clang::IfStmt *  stmt)

Enter if statement block.

Parameters
stmtif statement block

Definition at line 183 of file call_expression_context.cc.

184{
185 if_stmt_stack_.emplace(stmt);
186}

◆ enter_lambda_expression()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_lambda_expression ( eid_t  id)

Enter a lambda expression.

Parameters
idLambda id

Definition at line 155 of file call_expression_context.cc.

156{
157 LOG_DBG("Setting current lambda caller id to {}", id);
158
159 assert(id.value() != 0);
160
161 current_lambda_caller_id_.emplace(id);
162}

◆ enter_loopstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_loopstmt ( clang::Stmt *  stmt)

Enter loop statement block.

Parameters
stmtLoop statement block

Definition at line 222 of file call_expression_context.cc.

223{
224 loop_stmt_stack_.emplace(stmt);
225}

◆ enter_switchstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_switchstmt ( clang::SwitchStmt *  stmt)

Enter switch statement block.

Parameters
stmtswitch statement block

Definition at line 286 of file call_expression_context.cc.

287{
288 switch_stmt_stack_.emplace(stmt);
289}

◆ enter_trystmt()

void clanguml::sequence_diagram::visitor::call_expression_context::enter_trystmt ( clang::Stmt *  stmt)

Enter try statement block.

Parameters
stmttry statement block

Definition at line 267 of file call_expression_context.cc.

268{
269 try_stmt_stack_.emplace(stmt);
270}

◆ get_ast_context()

clang::ASTContext * clanguml::sequence_diagram::visitor::call_expression_context::get_ast_context ( ) const
Returns
Current AST context

Definition at line 60 of file call_expression_context.cc.

61{
63 return &current_class_template_specialization_decl_->getASTContext();
64
65 if (current_class_template_decl_ != nullptr)
66 return &current_class_template_decl_->getASTContext();
67
68 if (current_class_decl_ != nullptr)
69 return &current_class_decl_->getASTContext();
70
72 return &current_function_template_decl_->getASTContext();
73
74 if (current_function_decl_ != nullptr) {
75 return &current_function_decl_->getASTContext();
76 }
77
78 if (current_method_decl_ != nullptr) {
79 return &current_method_decl_->getASTContext();
80 }
81
82 return nullptr;
83}

◆ is_expr_in_current_control_statement_condition()

bool clanguml::sequence_diagram::visitor::call_expression_context::is_expr_in_current_control_statement_condition ( const clang::Stmt *  stmt) const

Check, if a statement is contained in a control statement.

This method is used to check if stmt is contained in control statement of a block, for instance:

if(a.method1()) {}

it will return true for stmt representing method1() call expression.

Parameters
stmtStatement
Returns
True, if stmt is contained in control expression of a statement block

Definition at line 318 of file call_expression_context.cc.

320{
321 if (current_ifstmt() != nullptr) {
322 if (common::is_subexpr_of(current_ifstmt()->getCond(), stmt))
323 return true;
324
325 if (const auto *condition_decl_stmt = current_ifstmt()->getInit();
326 condition_decl_stmt != nullptr) {
327 if (common::is_subexpr_of(condition_decl_stmt, stmt))
328 return true;
329 }
330
331 if (current_elseifstmt() != nullptr) {
332 if (common::is_subexpr_of(current_elseifstmt()->getCond(), stmt))
333 return true;
334 }
335 }
336
337 if (current_conditionaloperator() != nullptr) {
339 current_conditionaloperator()->getCond(), stmt))
340 return true;
341 }
342
343 if (const auto *loop_stmt = current_loopstmt(); loop_stmt != nullptr) {
344 if (const auto *for_stmt = clang::dyn_cast<clang::ForStmt>(loop_stmt);
345 for_stmt != nullptr) {
346 if (common::is_subexpr_of(for_stmt->getCond(), stmt)) {
347 return true;
348 }
349 if (common::is_subexpr_of(for_stmt->getInit(), stmt)) {
350 return true;
351 }
352 if (common::is_subexpr_of(for_stmt->getInc(), stmt)) {
353 return true;
354 }
355 }
356
357 if (const auto *range_for_stmt =
358 clang::dyn_cast<clang::CXXForRangeStmt>(loop_stmt);
359 range_for_stmt != nullptr) {
360 if (common::is_subexpr_of(range_for_stmt->getRangeInit(), stmt)) {
361 return true;
362 }
363 }
364
365 if (const auto *while_stmt =
366 clang::dyn_cast<clang::WhileStmt>(loop_stmt);
367 while_stmt != nullptr) {
368 if (common::is_subexpr_of(while_stmt->getCond(), stmt)) {
369 return true;
370 }
371 }
372
373 if (const auto *do_stmt = clang::dyn_cast<clang::DoStmt>(loop_stmt);
374 do_stmt != nullptr) {
375 if (common::is_subexpr_of(do_stmt->getCond(), stmt)) {
376 return true;
377 }
378 }
379
380 if (current_conditionaloperator() != nullptr) {
382 current_conditionaloperator()->getCond(), stmt)) {
383 return true;
384 }
385 }
386 }
387
388 return false;
389}

◆ lambda_caller_id()

std::optional< eid_t > clanguml::sequence_diagram::visitor::call_expression_context::lambda_caller_id ( ) const

Get the id of the current lambda caller.

Since lambdas can be nested within methods and functions, they have a separate caller id field.

Returns
Current lambda caller id, or 0 if current caller is not lambda.

Definition at line 141 of file call_expression_context.cc.

142{
143 if (current_lambda_caller_id_.empty())
144 return {};
145
146 return current_lambda_caller_id_.top();
147}

◆ leave_callexpr()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_callexpr ( )

Leave call expression.

Definition at line 252 of file call_expression_context.cc.

253{
254 if (!call_expr_stack_.empty()) {
255 return call_expr_stack_.pop();
256 }
257}

◆ leave_conditionaloperator()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_conditionaloperator ( )

Leave :? statement block.

Definition at line 312 of file call_expression_context.cc.

313{
314 if (!conditional_operator_stack_.empty())
316}

◆ leave_ifstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_ifstmt ( )

Leave if statement block.

Definition at line 188 of file call_expression_context.cc.

189{
190 if (!if_stmt_stack_.empty()) {
192 if_stmt_stack_.pop();
193 }
194}

◆ leave_lambda_expression()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_lambda_expression ( )

Leave current lambda expression.

Definition at line 164 of file call_expression_context.cc.

165{
166 if (current_lambda_caller_id_.empty())
167 return;
168
169 LOG_DBG("Leaving current lambda expression id to {}",
171
173}

◆ leave_loopstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_loopstmt ( )

Leave loop statement block.

Definition at line 227 of file call_expression_context.cc.

228{
229 if (!loop_stmt_stack_.empty())
230 return loop_stmt_stack_.pop();
231}

◆ leave_switchstmt()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_switchstmt ( )

Leave switch statement block.

Definition at line 291 of file call_expression_context.cc.

292{
293 if (switch_stmt_stack_.empty())
294 switch_stmt_stack_.pop();
295}

◆ leave_trystmt()

void clanguml::sequence_diagram::visitor::call_expression_context::leave_trystmt ( )

Leave try statement block.

Definition at line 272 of file call_expression_context.cc.

273{
274 if (try_stmt_stack_.empty())
275 try_stmt_stack_.pop();
276}

◆ reset()

void clanguml::sequence_diagram::visitor::call_expression_context::reset ( )

Reset call expression context to the original state.

Definition at line 25 of file call_expression_context.cc.

◆ set_caller_id()

void clanguml::sequence_diagram::visitor::call_expression_context::set_caller_id ( eid_t  id)

Set current caller to id of the current participant.

Parameters
idSet current caller id.

Definition at line 149 of file call_expression_context.cc.

150{
151 LOG_DBG("Setting current caller id to {}", id);
153}

◆ update() [1/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::ClassTemplateDecl *  clst)

Set the current context to a class template.

Parameters
clstClass template declaration.

Definition at line 96 of file call_expression_context.cc.

97{
99}

◆ update() [2/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::ClassTemplateSpecializationDecl *  clst)

Set the current context to a class template specialization.

Parameters
clstClass template specialization declaration.

Definition at line 90 of file call_expression_context.cc.

◆ update() [3/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::CXXMethodDecl *  method)

Set the current context to a class method.

Parameters
methodClass method declaration.

Definition at line 101 of file call_expression_context.cc.

102{
104}

◆ update() [4/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::CXXRecordDecl *  cls)

Set the current context to a class.

Parameters
clsClass declaration.

Definition at line 85 of file call_expression_context.cc.

86{
88}

◆ update() [5/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::FunctionDecl *  function)

Set the current context to a function.

Parameters
functionFunction declaration.

Definition at line 106 of file call_expression_context.cc.

107{
108 if (!function->isCXXClassMember())
109 reset();
110
112
113 // Check if this function is a part of template function declaration,
114 // If no - reset the current_function_template_decl_
115 if ((current_function_template_decl_ != nullptr) &&
116 current_function_template_decl_->getQualifiedNameAsString() !=
117 function->getQualifiedNameAsString()) {
119 }
120}

◆ update() [6/6]

void clanguml::sequence_diagram::visitor::call_expression_context::update ( clang::FunctionTemplateDecl *  function_template)

Set the current context to a function template.

Parameters
function_templateFunction template declaration.

Definition at line 122 of file call_expression_context.cc.

◆ valid()

bool clanguml::sequence_diagram::visitor::call_expression_context::valid ( ) const

Verify that the context is in a valid state.

Context can only be in a single state (for instance inside a function).

Returns
True, if the context is in a valid state.

Definition at line 50 of file call_expression_context.cc.

51{
52 return (current_class_decl_ != nullptr) ||
53 (current_class_template_decl_ != nullptr) ||
55 (current_method_decl_ != nullptr) ||
56 (current_function_decl_ != nullptr) ||
58}

Member Data Documentation

◆ call_expr_stack_

std::stack<callexpr_stack_t> clanguml::sequence_diagram::visitor::call_expression_context::call_expr_stack_
private

Definition at line 323 of file call_expression_context.h.

◆ conditional_operator_stack_

std::stack<clang::ConditionalOperator *> clanguml::sequence_diagram::visitor::call_expression_context::conditional_operator_stack_
private

Definition at line 331 of file call_expression_context.h.

◆ current_caller_id_

eid_t clanguml::sequence_diagram::visitor::call_expression_context::current_caller_id_ {}
private

Definition at line 320 of file call_expression_context.h.

◆ current_class_decl_

clang::CXXRecordDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_class_decl_ {nullptr}

Definition at line 311 of file call_expression_context.h.

◆ current_class_template_decl_

clang::ClassTemplateDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_class_template_decl_ {nullptr}

Definition at line 312 of file call_expression_context.h.

◆ current_class_template_specialization_decl_

clang::ClassTemplateSpecializationDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_class_template_specialization_decl_ {nullptr}

Definition at line 314 of file call_expression_context.h.

◆ current_function_decl_

clang::FunctionDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_function_decl_ {nullptr}

Definition at line 316 of file call_expression_context.h.

◆ current_function_template_decl_

clang::FunctionTemplateDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_function_template_decl_ {nullptr}

Definition at line 317 of file call_expression_context.h.

◆ current_lambda_caller_id_

std::stack<eid_t> clanguml::sequence_diagram::visitor::call_expression_context::current_lambda_caller_id_
private

Definition at line 321 of file call_expression_context.h.

◆ current_method_decl_

clang::CXXMethodDecl* clanguml::sequence_diagram::visitor::call_expression_context::current_method_decl_ {nullptr}

Definition at line 315 of file call_expression_context.h.

◆ elseif_stmt_stacks_

std::map<clang::IfStmt *, std::stack<clang::IfStmt *> > clanguml::sequence_diagram::visitor::call_expression_context::elseif_stmt_stacks_
private

Definition at line 326 of file call_expression_context.h.

◆ if_stmt_stack_

std::stack<clang::IfStmt *> clanguml::sequence_diagram::visitor::call_expression_context::if_stmt_stack_
private

Definition at line 325 of file call_expression_context.h.

◆ loop_stmt_stack_

std::stack<clang::Stmt *> clanguml::sequence_diagram::visitor::call_expression_context::loop_stmt_stack_
private

Definition at line 328 of file call_expression_context.h.

◆ switch_stmt_stack_

std::stack<clang::SwitchStmt *> clanguml::sequence_diagram::visitor::call_expression_context::switch_stmt_stack_
private

Definition at line 330 of file call_expression_context.h.

◆ try_stmt_stack_

std::stack<clang::Stmt *> clanguml::sequence_diagram::visitor::call_expression_context::try_stmt_stack_
private

Definition at line 329 of file call_expression_context.h.


The documentation for this struct was generated from the following files: