aboutsummaryrefslogtreecommitdiffstats
path: root/safercpp
diff options
context:
space:
mode:
authoruser1 <user1@ubuntu>2017-04-21 16:13:32 +0000
committeruser1 <user1@ubuntu>2017-04-21 16:13:32 +0000
commitce7141d73cef8142becf46d6e157a4bd40dfd29b (patch)
treedd430ef6793a7e271215b58c34c55aea4465eb75 /safercpp
parentMerge branch 'master' of https://github.com/bloodstalker/mutator (diff)
downloadmutator-ce7141d73cef8142becf46d6e157a4bd40dfd29b.tar.gz
mutator-ce7141d73cef8142becf46d6e157a4bd40dfd29b.zip
added handling of conditional initializers
Diffstat (limited to 'safercpp')
-rw-r--r--safercpp/safercpp-arr.cpp984
1 files changed, 646 insertions, 338 deletions
diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp
index 28419a1..750d393 100644
--- a/safercpp/safercpp-arr.cpp
+++ b/safercpp/safercpp-arr.cpp
@@ -214,14 +214,6 @@ static std::vector<std::string> f_declared_object_strings(const std::string& dec
return retval;
}
-class CState1;
-
-class CReplacementAction {
-public:
- virtual ~CReplacementAction() {}
- virtual void do_replacement(CState1& state1) const = 0;
-};
-
std::string tolowerstr(const std::string& a) {
std::string retval;
for (const auto& ch : a) {
@@ -230,6 +222,10 @@ std::string tolowerstr(const std::string& a) {
return retval;
}
+bool string_begins_with(const std::string& s1, const std::string& prefix) {
+ return (0 == s1.compare(0, prefix.length(), prefix));
+}
+
/* This function returns a list of individual declarations contained in the same declaration statement
* as the given declaration. (eg.: "int a, b = 3, *c;" ) */
static std::vector<const DeclaratorDecl*> IndividualDeclaratorDecls(const DeclaratorDecl* DD, Rewriter &Rewrite) {
@@ -295,197 +291,6 @@ public:
size_t m_indirection_level = 0;
};
-class CDDecl2ReplacementAction : public CReplacementAction {
-public:
- CDDecl2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR,
- const CDDeclIndirection& ddecl_indirection) : m_Rewrite(Rewrite), m_MR(MR), m_ddecl_indirection(ddecl_indirection) {}
- virtual ~CDDecl2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const = 0;
- virtual const clang::DeclaratorDecl* get_ddecl_cptr() const { return m_ddecl_indirection.m_ddecl_cptr; }
- virtual const CDDeclIndirection& ddecl_indirection_cref() const { return m_ddecl_indirection; }
-
- clang::SourceRange source_range() {
- clang::SourceRange retval = m_ddecl_indirection.m_ddecl_cptr->getSourceRange();
- return retval;
- }
- clang::SourceLocation start_location() {
- clang::SourceLocation retval = source_range().getBegin();
- return retval;
- }
- std::string get_var_name() {
- std::string retval = m_ddecl_indirection.m_ddecl_cptr->getNameAsString();
- return retval;
- }
-
- Rewriter& m_Rewrite;
- const MatchFinder::MatchResult m_MR;
- CDDeclIndirection m_ddecl_indirection;
-};
-
-class CArray2ReplacementAction : public CDDecl2ReplacementAction {
-public:
- using CDDecl2ReplacementAction::CDDecl2ReplacementAction;
- virtual ~CArray2ReplacementAction() {}
-};
-
-class CMemsetArray2ReplacementAction : public CArray2ReplacementAction {
-public:
- CMemsetArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const CallExpr* CE, const std::string& ce_replacement_code) :
- CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_ce_replacement_code(ce_replacement_code) {}
- virtual ~CMemsetArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const CallExpr* m_CE = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_ce_replacement_code;
-};
-
-class CMemcpyArray2ReplacementAction : public CArray2ReplacementAction {
-public:
- CMemcpyArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const CallExpr* CE, const std::string& ce_replacement_code) :
- CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_ce_replacement_code(ce_replacement_code) {}
- virtual ~CMemcpyArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const CallExpr* m_CE = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_ce_replacement_code;
-};
-
-class CAssignedFromArray2ReplacementAction : public CArray2ReplacementAction {
-public:
- CAssignedFromArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const CDDeclIndirection& ddecl_indirection2) :
- CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_ddecl_indirection2(ddecl_indirection2) {}
- virtual ~CAssignedFromArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const CDDeclIndirection m_ddecl_indirection2;
-};
-
-class CDDecl2ReplacementActionMap : public std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> {
-public:
- typedef std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> base_class;
- iterator insert( const std::shared_ptr<CDDecl2ReplacementAction>& cr_shptr ) {
- iterator retval(end());
- if (!cr_shptr) { assert(false); } else {
- value_type val((*cr_shptr).ddecl_indirection_cref(), cr_shptr);
- retval = base_class::insert(val);
- }
- return retval;
- }
- void do_and_dispose_matching_replacements(CState1& state1, const CDDeclIndirection& ddecl_indirection) {
- /* The base class map may be modified during loop iterations. Maybe. */
- auto iter = base_class::find(ddecl_indirection);
- while (base_class::end() != iter) {
- (*((*iter).second)).do_replacement(state1);
- base_class::erase(iter);
-
- iter = base_class::find(ddecl_indirection);
- }
- }
-};
-
-class CDynamicArray2ReplacementAction : public CArray2ReplacementAction {
-public:
- using CArray2ReplacementAction::CArray2ReplacementAction;
- virtual ~CDynamicArray2ReplacementAction() {}
-};
-
-class CMallocArray2ReplacementAction : public CDynamicArray2ReplacementAction {
-public:
- CMallocArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const BinaryOperator* BO, const std::string& bo_replacement_code) :
- CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_BO(BO), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_bo_replacement_code(bo_replacement_code) {}
- virtual ~CMallocArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const BinaryOperator* m_BO = nullptr;
- //const CallExpr* m_CE = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_bo_replacement_code;
-};
-
-class CMallocInitializerArray2ReplacementAction : public CDynamicArray2ReplacementAction {
-public:
- CMallocInitializerArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const DeclStmt* DS, const std::string& initializer_info_str) :
- CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_DS(DS), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_initializer_info_str(initializer_info_str) {}
- virtual ~CMallocInitializerArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const DeclStmt* m_DS = nullptr;
- //const CallExpr* m_CE = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_initializer_info_str;
-};
-
-class CFreeDynamicArray2ReplacementAction : public CDynamicArray2ReplacementAction {
-public:
- CFreeDynamicArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const CallExpr* CE, const std::string& ce_replacement_code) :
- CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_ce_replacement_code(ce_replacement_code) {}
- virtual ~CFreeDynamicArray2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const CallExpr* m_CE = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_ce_replacement_code;
-};
-
-class CSetArrayPointerToNull2ReplacementAction : public CDynamicArray2ReplacementAction {
-public:
- CSetArrayPointerToNull2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const BinaryOperator* BO, const std::string& bo_replacement_code) :
- CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_BO(BO), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_bo_replacement_code(bo_replacement_code) {}
- virtual ~CSetArrayPointerToNull2ReplacementAction() {}
-
- virtual void do_replacement(CState1& state1) const;
-
- const BinaryOperator* m_BO = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_bo_replacement_code;
-};
-
-class CDynamicArray2ReplacementActionMap : public CDDecl2ReplacementActionMap {
-public:
- iterator insert( const std::shared_ptr<CDynamicArray2ReplacementAction>& cr_shptr ) {
- return CDDecl2ReplacementActionMap::insert(static_cast<std::shared_ptr<CDDecl2ReplacementAction> >(cr_shptr));
- }
-};
-
-class CArray2ReplacementActionMap : public CDDecl2ReplacementActionMap {
-public:
- iterator insert( const std::shared_ptr<CArray2ReplacementAction>& cr_shptr ) {
- return CDDecl2ReplacementActionMap::insert(static_cast<std::shared_ptr<CDDecl2ReplacementAction> >(cr_shptr));
- }
-};
-
class CIndirectionState {
public:
CIndirectionState(std::string original, std::string current)
@@ -740,6 +545,8 @@ public:
std::string m_initializer_info_str;
bool m_original_initialization_has_been_noted = false;
std::string m_original_initialization_expr_str;
+ bool m_original_source_text_has_been_noted = false;
+ std::string m_original_source_text_str;
};
class CDDeclConversionStateMap : public std::map<const clang::DeclaratorDecl*, CDDeclConversionState> {
@@ -750,6 +557,223 @@ public:
}
};
+
+class CState1;
+
+class CReplacementAction {
+public:
+ virtual ~CReplacementAction() {}
+ virtual void do_replacement(CState1& state1) const = 0;
+};
+
+class CDDecl2ReplacementAction : public CReplacementAction {
+public:
+ CDDecl2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR,
+ const CDDeclIndirection& ddecl_indirection) : m_Rewrite(Rewrite), m_MR(MR), m_ddecl_indirection(ddecl_indirection) {}
+ virtual ~CDDecl2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const = 0;
+ virtual const clang::DeclaratorDecl* get_ddecl_cptr() const { return m_ddecl_indirection.m_ddecl_cptr; }
+ virtual const CDDeclIndirection& ddecl_indirection_cref() const { return m_ddecl_indirection; }
+
+ clang::SourceRange source_range() {
+ clang::SourceRange retval = m_ddecl_indirection.m_ddecl_cptr->getSourceRange();
+ return retval;
+ }
+ clang::SourceLocation start_location() {
+ clang::SourceLocation retval = source_range().getBegin();
+ return retval;
+ }
+ std::string get_var_name() {
+ std::string retval = m_ddecl_indirection.m_ddecl_cptr->getNameAsString();
+ return retval;
+ }
+
+ Rewriter& m_Rewrite;
+ const MatchFinder::MatchResult m_MR;
+ CDDeclIndirection m_ddecl_indirection;
+};
+
+class CArray2ReplacementAction : public CDDecl2ReplacementAction {
+public:
+ using CDDecl2ReplacementAction::CDDecl2ReplacementAction;
+ virtual ~CArray2ReplacementAction() {}
+};
+
+class CMemsetArray2ReplacementAction : public CArray2ReplacementAction {
+public:
+ CMemsetArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const CallExpr* CE, const std::string& ce_replacement_code) :
+ CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_ce_replacement_code(ce_replacement_code) {}
+ virtual ~CMemsetArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const CallExpr* m_CE = nullptr;
+ //const DeclRefExpr* m_DRE = nullptr;
+ //const MemberExpr* m_ME = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_ce_replacement_code;
+};
+
+class CMemcpyArray2ReplacementAction : public CArray2ReplacementAction {
+public:
+ CMemcpyArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const CallExpr* CE, const std::string& ce_replacement_code) :
+ CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_ce_replacement_code(ce_replacement_code) {}
+ virtual ~CMemcpyArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const CallExpr* m_CE = nullptr;
+ //const DeclRefExpr* m_DRE = nullptr;
+ //const MemberExpr* m_ME = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_ce_replacement_code;
+};
+
+class CAssignedFromArray2ReplacementAction : public CArray2ReplacementAction {
+public:
+ CAssignedFromArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const CDDeclIndirection& ddecl_indirection2) :
+ CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_ddecl_indirection2(ddecl_indirection2) {}
+ virtual ~CAssignedFromArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const CDDeclIndirection m_ddecl_indirection2;
+};
+
+class CDDecl2ReplacementActionMap : public std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> {
+public:
+ typedef std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> base_class;
+ iterator insert( const std::shared_ptr<CDDecl2ReplacementAction>& cr_shptr ) {
+ iterator retval(end());
+ if (!cr_shptr) { assert(false); } else {
+ value_type val((*cr_shptr).ddecl_indirection_cref(), cr_shptr);
+ retval = base_class::insert(val);
+ }
+ return retval;
+ }
+ void do_and_dispose_matching_replacements(CState1& state1, const CDDeclIndirection& ddecl_indirection) {
+ /* The base class map may be modified during loop iterations. Maybe. */
+ auto iter = base_class::find(ddecl_indirection);
+ while (base_class::end() != iter) {
+ (*((*iter).second)).do_replacement(state1);
+ base_class::erase(iter);
+
+ iter = base_class::find(ddecl_indirection);
+ }
+ }
+};
+
+class CDynamicArray2ReplacementAction : public CArray2ReplacementAction {
+public:
+ using CArray2ReplacementAction::CArray2ReplacementAction;
+ virtual ~CDynamicArray2ReplacementAction() {}
+};
+
+class CMallocArray2ReplacementAction : public CDynamicArray2ReplacementAction {
+public:
+ CMallocArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const BinaryOperator* BO, const std::string& bo_replacement_code) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_BO(BO), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_bo_replacement_code(bo_replacement_code) {}
+ virtual ~CMallocArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const BinaryOperator* m_BO = nullptr;
+ //const CallExpr* m_CE = nullptr;
+ //const DeclRefExpr* m_DRE = nullptr;
+ //const MemberExpr* m_ME = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_bo_replacement_code;
+};
+
+class CMallocInitializerArray2ReplacementAction : public CDynamicArray2ReplacementAction {
+public:
+ CMallocInitializerArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const DeclStmt* DS, const std::string& initializer_info_str) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_DS(DS), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_initializer_info_str(initializer_info_str) {}
+ virtual ~CMallocInitializerArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const DeclStmt* m_DS = nullptr;
+ //const CallExpr* m_CE = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_initializer_info_str;
+};
+
+class CFreeDynamicArray2ReplacementAction : public CDynamicArray2ReplacementAction {
+public:
+ CFreeDynamicArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const CallExpr* CE, const std::string& ce_replacement_code) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CE(CE), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_ce_replacement_code(ce_replacement_code) {}
+ virtual ~CFreeDynamicArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const CallExpr* m_CE = nullptr;
+ //const DeclRefExpr* m_DRE = nullptr;
+ //const MemberExpr* m_ME = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_ce_replacement_code;
+};
+
+class CSetArrayPointerToNull2ReplacementAction : public CDynamicArray2ReplacementAction {
+public:
+ CSetArrayPointerToNull2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const BinaryOperator* BO, const std::string& bo_replacement_code) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_BO(BO), m_DD(ddecl_indirection.m_ddecl_cptr),
+ m_bo_replacement_code(bo_replacement_code) {}
+ virtual ~CSetArrayPointerToNull2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const BinaryOperator* m_BO = nullptr;
+ //const DeclRefExpr* m_DRE = nullptr;
+ //const MemberExpr* m_ME = nullptr;
+ const DeclaratorDecl* m_DD = nullptr;
+ std::string m_bo_replacement_code;
+};
+
+/* This class represents and "enforces" the constraint that the lhs and rhs
+ * values of a conditional operator must be the same type. */
+class CConditionalOperatorReconciliation2ReplacementAction : public CDynamicArray2ReplacementAction {
+public:
+ CConditionalOperatorReconciliation2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const clang::ConditionalOperator* CO, const DeclaratorDecl* lhs_DD, const DeclaratorDecl* rhs_DD, const DeclaratorDecl* var_DD = nullptr) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_CO(CO), m_lhs_DD(lhs_DD), m_rhs_DD(rhs_DD), m_var_DD(var_DD) {}
+ virtual ~CConditionalOperatorReconciliation2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const clang::ConditionalOperator* m_CO = nullptr;
+ const DeclaratorDecl* m_lhs_DD = nullptr;
+ const DeclaratorDecl* m_rhs_DD = nullptr;
+ const DeclaratorDecl* m_var_DD = nullptr;
+};
+
+class CDynamicArray2ReplacementActionMap : public CDDecl2ReplacementActionMap {
+public:
+ iterator insert( const std::shared_ptr<CDynamicArray2ReplacementAction>& cr_shptr ) {
+ return CDDecl2ReplacementActionMap::insert(static_cast<std::shared_ptr<CDDecl2ReplacementAction> >(cr_shptr));
+ }
+};
+
+class CArray2ReplacementActionMap : public CDDecl2ReplacementActionMap {
+public:
+ iterator insert( const std::shared_ptr<CArray2ReplacementAction>& cr_shptr ) {
+ return CDDecl2ReplacementActionMap::insert(static_cast<std::shared_ptr<CDDecl2ReplacementAction> >(cr_shptr));
+ }
+};
+
class CState1 {
public:
/* This container holds (potential) actions that are meant to be executed if/when
@@ -773,6 +797,14 @@ public:
static CDeclarationReplacementCodeItem generate_declaration_replacement_code(const DeclaratorDecl* DD, Rewriter &Rewrite, CDDeclConversionStateMap& ddecl_conversion_state_map, std::string options_str = "") {
CDeclarationReplacementCodeItem retval;
+ if (!DD) {
+ return retval;
+ }
+ auto decl_source_range = nice_source_range(DD->getSourceRange(), Rewrite);
+ if (!(decl_source_range.isValid())) {
+ return retval;
+ }
+
auto res1 = ddecl_conversion_state_map.insert(*DD);
auto ddcs_map_iter = res1.first;
auto& ddcs_ref = (*ddcs_map_iter).second;
@@ -786,6 +818,11 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
} else if ("const _Bool" == direct_qtype_str) {
direct_qtype_str = "const bool";
}
+ auto direct_TP = ddcs_ref.m_direct_qtype.getTypePtr();
+ if (!direct_TP) {
+ return retval;
+ }
+ bool direct_type_is_function_type = direct_TP->isFunctionType();
std::string variable_name = DD->getNameAsString();
std::string identifier_name_str;
@@ -797,6 +834,13 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
int q = 7;
}
+ if (!(ddcs_ref.m_original_source_text_has_been_noted)) {
+ ddcs_ref.m_original_source_text_str = Rewrite.getRewrittenText(decl_source_range);
+ ddcs_ref.m_original_source_text_has_been_noted = true;
+ }
+
+ clang::StorageClass storage_class = clang::StorageClass::SC_None;
+ bool is_extern = false;
clang::StorageDuration storage_duration = clang::StorageDuration::SD_Automatic;
bool has_dynamic_storage_duration = false;
bool is_a_temporary = false;
@@ -805,14 +849,21 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
bool is_member = false;
bool is_vardecl = false;
std::string initialization_expr_str;
+ bool is_function = DD->isFunctionOrFunctionTemplate();
auto VD = dynamic_cast<const clang::VarDecl *>(DD);
if (VD) {
is_vardecl = true;
+ storage_class = VD->getStorageClass();
+ is_extern = (clang::StorageClass::SC_Extern == storage_class);
storage_duration = VD->getStorageDuration();
has_dynamic_storage_duration = (clang::StorageDuration::SD_Dynamic == storage_duration);
is_a_temporary = (clang::StorageDuration::SD_FullExpression == storage_duration);
- is_static = (clang::StorageDuration::SD_Static == storage_duration);
+ //is_static = (clang::StorageDuration::SD_Static == storage_duration);
+ is_static = (clang::StorageClass::SC_Static == storage_class);
+ if ((clang::StorageDuration::SD_Static == storage_duration) && (!is_static)) {
+ int q = 5;
+ }
is_a_function_parameter = (VD->isLocalVarDeclOrParm() && (!VD->isLocalVarDecl()));
if (ddcs_ref.m_original_initialization_has_been_noted) {
@@ -880,142 +931,177 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
}
ddcs_ref.m_original_initialization_has_been_noted = true;
+ bool changed_from_original = false;
std::string replacement_code;
std::string prefix_str;
std::string suffix_str;
- for (size_t i = 0; i < ddcs_ref.m_indirection_state_stack.size(); i += 1) {
- bool is_char_star = false;
- bool is_last_indirection = (ddcs_ref.m_indirection_state_stack.size() == (i+1));
- if (is_last_indirection && (("char" == direct_qtype_str) || ("const char" == direct_qtype_str))) {
- is_char_star = true;
- }
- if ("inferred array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else {
- prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TNullableAnyRandomAccessIterator";
- }
- } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else {
- prefix_str = prefix_str + "mse::TIPointerWithBundledVector<";
- if (is_a_function_parameter) {
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer parameter to TIPointerWithBundledVector";
+ if (true) {
+ for (size_t i = 0; i < ddcs_ref.m_indirection_state_stack.size(); i += 1) {
+ bool is_char_star = false;
+ bool is_function_pointer = false;
+ bool is_last_indirection = (ddcs_ref.m_indirection_state_stack.size() == (i+1));
+ if (is_last_indirection && (("char" == direct_qtype_str) || ("const char" == direct_qtype_str))) {
+ is_char_star = true;
+ } else if (is_last_indirection && direct_type_is_function_type) {
+ is_function_pointer = true;
+ }
+ if ("inferred array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "char*";
} else {
+ prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TIPointerWithBundledVector";
+ retval.m_action_species = "native pointer to TNullableAnyRandomAccessIterator";
}
- }
- } else if ("native array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- std::string size_text;
- if (TP->isVariableArrayType()) {
- auto VATP = llvm::cast<const clang::VariableArrayType>(TP);
- if (!VATP) {
- assert(false);
+ } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "char*";
} else {
- auto size_expr = VATP->getSizeExpr();
- auto SR = nice_source_range(size_expr->getSourceRange(), Rewrite);
- size_text = Rewrite.getRewrittenText(SR);
+ prefix_str = prefix_str + "mse::TIPointerWithBundledVector<";
+ if (is_a_function_parameter) {
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer parameter to TIPointerWithBundledVector";
+ } else {
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer to TIPointerWithBundledVector";
+ }
}
- } else if (TP->isConstantArrayType()) {
- auto CATP = llvm::cast<const clang::ConstantArrayType>(TP);
- if (!CATP) {
- assert(false);
- } else {
- auto array_size = CATP->getSize();
- size_text = array_size.toString(10, false);/*check this*/
-
- if (false) {
- auto DDSR = nice_source_range(DD->getSourceRange(), Rewrite);
- std::string array_size_expression_text;
- std::string source_text;
- if (DDSR.isValid()) {
- source_text = Rewrite.getRewrittenText(DDSR);
-
- auto left_bracket_pos = source_text.find('[');
- auto right_bracket_pos = source_text.find(']');
- if ((std::string::npos != left_bracket_pos) && (std::string::npos != right_bracket_pos)
- && (left_bracket_pos + 1 < right_bracket_pos)) {
- auto array_size_expression_text = source_text.substr(left_bracket_pos + 1, right_bracket_pos - (left_bracket_pos + 1));
- int q = 3;
+ } else if ("native array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ std::string size_text;
+ if (TP->isVariableArrayType()) {
+ auto VATP = llvm::cast<const clang::VariableArrayType>(TP);
+ if (!VATP) {
+ assert(false);
+ } else {
+ auto size_expr = VATP->getSizeExpr();
+ auto SR = nice_source_range(size_expr->getSourceRange(), Rewrite);
+ size_text = Rewrite.getRewrittenText(SR);
+ }
+ } else if (TP->isConstantArrayType()) {
+ auto CATP = llvm::cast<const clang::ConstantArrayType>(TP);
+ if (!CATP) {
+ assert(false);
+ } else {
+ auto array_size = CATP->getSize();
+ size_text = array_size.toString(10, false);/*check this*/
+
+ if (false) {
+ auto DDSR = nice_source_range(DD->getSourceRange(), Rewrite);
+ std::string array_size_expression_text;
+ std::string source_text;
+ if (DDSR.isValid()) {
+ source_text = Rewrite.getRewrittenText(DDSR);
+
+ auto left_bracket_pos = source_text.find('[');
+ auto right_bracket_pos = source_text.find(']');
+ if ((std::string::npos != left_bracket_pos) && (std::string::npos != right_bracket_pos)
+ && (left_bracket_pos + 1 < right_bracket_pos)) {
+ auto array_size_expression_text = source_text.substr(left_bracket_pos + 1, right_bracket_pos - (left_bracket_pos + 1));
+ int q = 3;
+ } else {
+ int q = 7;
+ }
} else {
- int q = 7;
+ int q = 5;
}
- } else {
- int q = 5;
}
}
}
- }
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char[] for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "[" + size_text + "]" + suffix_str;
- } else {
- if (is_a_function_parameter) {
- prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
- suffix_str = ", " + size_text + "> " + suffix_str;
- retval.m_action_species = "native array parameter to TNullableAnyRandomAccessIterator";
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char[] for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "[" + size_text + "]" + suffix_str;
} else {
- prefix_str = prefix_str + "mse::TIteratorWithBundledArray<";
- suffix_str = ", " + size_text + "> " + suffix_str;
- retval.m_action_species = "native array to TIteratorWithBundledArray";
+ if (is_a_function_parameter) {
+ prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
+ suffix_str = ", " + size_text + "> " + suffix_str;
+ retval.m_action_species = "native array parameter to TNullableAnyRandomAccessIterator";
+ } else {
+ prefix_str = prefix_str + "mse::TIteratorWithBundledArray<";
+ suffix_str = ", " + size_text + "> " + suffix_str;
+ retval.m_action_species = "native array to TIteratorWithBundledArray";
+ }
}
- }
- } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else {
- if (false/*for now*/) {
- prefix_str = prefix_str + "mse::TAnyPointer<";
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TAnyPointer";
- } else {
+ } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
//prefix_str = prefix_str + "";
suffix_str = "* " + suffix_str;
- retval.m_action_species = "native pointer";
+ retval.m_action_species = "char*";
+ } else if (is_function_pointer) {
+ prefix_str = prefix_str + "std::function<";
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "function pointer to std::function";
+ } else {
+ if (false/*for now*/) {
+ prefix_str = prefix_str + "mse::TAnyPointer<";
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer to TAnyPointer";
+ } else {
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "native pointer";
+ }
}
+ } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ /* We'll just leaving it as a native pointer for now. Ultimately, this won't be the case. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "malloc target";
}
- } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- /* We'll just leaving it as a native pointer for now. Ultimately, this won't be the case. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "malloc target";
}
}
- if (is_static) {
- replacement_code += "static ";
- }
- replacement_code += prefix_str + direct_qtype_str + suffix_str;
- replacement_code += " ";
- replacement_code += variable_name;
- if (std::string::npos == options_str.find("[no-initializer]")) {
- std::string initializer_append_str = ddcs_ref.m_initializer_info_str;
+ bool discard_initializer_option_flag = (std::string::npos != options_str.find("[discard-initializer]"));
+ std::string initializer_append_str;
+ if (!discard_initializer_option_flag) {
+ initializer_append_str = ddcs_ref.m_initializer_info_str;
if (("" == initializer_append_str) && ("" != initialization_expr_str)) {
initializer_append_str = " = " + initialization_expr_str;
}
+ }
+
+ if (("" != prefix_str) || ("" != suffix_str)) {
+ changed_from_original = true;
+ } else if (("" != ddcs_ref.m_initializer_info_str) ||
+ (discard_initializer_option_flag)) {
+ changed_from_original = true;
+ } else if (2 <= IndividualDeclaratorDecls(DD, Rewrite).size()) {
+ /* There is more than one declaration in the declaration statement. We split
+ * them so that each has their own separate declaration statement. This counts
+ * as a change from the original source code. */
+ changed_from_original = true;
+ }
+
+ if (changed_from_original) {
+ if (is_extern) {
+ if ("" == ddcs_ref.m_original_initialization_expr_str) {
+ replacement_code += "extern ";
+ }
+ } else if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += prefix_str + direct_qtype_str + suffix_str;
+ replacement_code += " ";
+ replacement_code += variable_name;
+
replacement_code += initializer_append_str;
+ } else {
+ replacement_code = ddcs_ref.m_original_source_text_str;
}
+
retval.m_replacement_code = replacement_code;
return retval;
}
@@ -1294,16 +1380,21 @@ void CAssignedFromArray2ReplacementAction::do_replacement(CState1& state1) const
auto& ddcs_ref = (*ddcs_map_iter).second;
bool update_declaration_flag = res1.second;
- if ("native pointer" == ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current) {
- ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current = "inferred array";
- update_declaration_flag = true;
- state1.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
- } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current) {
- ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current = "dynamic array";
- update_declaration_flag = true;
- state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
+ if (ddcs_ref.m_indirection_state_stack.size() >= m_ddecl_indirection2.m_indirection_level) {
+ if ("native pointer" == ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current) {
+ ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current = "inferred array";
+ update_declaration_flag = true;
+ state1.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
+ } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current) {
+ ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current = "dynamic array";
+ update_declaration_flag = true;
+ state1.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
+ state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
+ } else {
+ int q = 3;
+ }
} else {
- int q = 3;
+ int q = 7;
}
if (update_declaration_flag) {
@@ -1311,6 +1402,136 @@ void CAssignedFromArray2ReplacementAction::do_replacement(CState1& state1) const
}
}
+void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState1& state1) const {
+ const clang::ConditionalOperator* CO = m_CO;
+ const Expr* COND = nullptr;
+ const Expr* LHS = nullptr;
+ const Expr* RHS = nullptr;
+ if (CO) {
+ COND = CO->getCond();
+ LHS = CO->getLHS();
+ RHS = CO->getRHS();
+ }
+ const DeclaratorDecl* lhs_DD = m_lhs_DD;
+ const DeclaratorDecl* rhs_DD = m_rhs_DD;
+ if ((COND != nullptr) && (LHS != nullptr) && (RHS != nullptr) && (lhs_DD != nullptr) && (rhs_DD != nullptr)) {
+ bool lhs_is_array = false;
+ bool lhs_is_dynamic_array = false;
+ bool lhs_is_native_array = false;
+
+ auto COSR = nice_source_range(CO->getSourceRange(), (*this).m_Rewrite);
+ auto cond_SR = nice_source_range(COND->getSourceRange(), (*this).m_Rewrite);
+ auto lhs_SR = nice_source_range(LHS->getSourceRange(), (*this).m_Rewrite);
+ auto rhs_SR = nice_source_range(RHS->getSourceRange(), (*this).m_Rewrite);
+ if ((COSR.isValid()) && (cond_SR.isValid()) && (lhs_SR.isValid()) && (rhs_SR.isValid())) {
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*lhs_DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ if (1 <= ddcs_ref.m_indirection_state_stack.size()) {
+ if ("dynamic array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ lhs_is_dynamic_array = true;
+ lhs_is_array = true;
+ } else if ("native array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ lhs_is_native_array = true;
+ lhs_is_array = true;
+ } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ lhs_is_array = true;
+ }
+ } else {
+ int q = 3;
+ }
+ }
+
+ bool rhs_is_array = false;
+ bool rhs_is_dynamic_array = false;
+ bool rhs_is_native_array = false;
+ {
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*rhs_DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ if (1 <= ddcs_ref.m_indirection_state_stack.size()) {
+ if ("dynamic array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ rhs_is_dynamic_array = true;
+ rhs_is_array = true;
+ } else if ("native array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ rhs_is_native_array = true;
+ rhs_is_array = true;
+ } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ rhs_is_array = true;
+ }
+ } else {
+ int q = 3;
+ }
+ }
+ if (lhs_is_array && rhs_is_array) {
+ if (m_var_DD) {
+ update_declaration(*m_var_DD, (*this).m_Rewrite, state1);
+ }
+
+ std::string CO_prior_text = (*this).m_Rewrite.getRewrittenText(COSR);
+ std::string CO_replacement_text;
+
+ std::string cond_prior_text = (*this).m_Rewrite.getRewrittenText(cond_SR);
+ std::string cond_replacement_text = cond_prior_text;
+
+ std::string lhs_prior_text = (*this).m_Rewrite.getRewrittenText(lhs_SR);
+ std::string lhs_replacement_text = lhs_prior_text;
+
+ std::string rhs_prior_text = (*this).m_Rewrite.getRewrittenText(rhs_SR);
+ std::string rhs_replacement_text = rhs_prior_text;
+ static const std::string ara_iter_prefix = "mse::TAnyRandomAccessIterator<";
+
+ bool lhs_needs_to_be_wrapped = false;
+ if ((lhs_is_dynamic_array && (!rhs_is_dynamic_array)) || (lhs_is_native_array && (!rhs_is_native_array))) {
+ lhs_needs_to_be_wrapped = true;
+ }
+ if (lhs_needs_to_be_wrapped) {
+ if (!string_begins_with(lhs_prior_text, ara_iter_prefix)) {
+ std::string lhs_base_type_str = lhs_DD->getType().getAsString();
+ std::string lhs_replacement_text = ara_iter_prefix + lhs_base_type_str + " >(" + lhs_prior_text + ")";
+ if (ConvertToSCPP) {
+ auto res2 = (*this).m_Rewrite.ReplaceText(lhs_SR, lhs_replacement_text);
+
+ CO_replacement_text = (*this).m_Rewrite.getRewrittenText(COSR);
+ int q = 3;
+ }
+ }
+ }
+
+ bool rhs_needs_to_be_wrapped = false;
+ if ((rhs_is_dynamic_array && (!lhs_is_dynamic_array)) || (rhs_is_native_array && (!lhs_is_native_array))) {
+ rhs_needs_to_be_wrapped = true;
+ }
+ if (rhs_needs_to_be_wrapped) {
+ if (!string_begins_with(rhs_prior_text, ara_iter_prefix)) {
+ std::string rhs_base_type_str = rhs_DD->getType().getAsString();
+ std::string rhs_replacement_text = ara_iter_prefix + rhs_base_type_str + " >(" + rhs_prior_text + ")";
+ if (ConvertToSCPP) {
+ auto res2 = (*this).m_Rewrite.ReplaceText(rhs_SR, rhs_replacement_text);
+
+ auto possibly_truncated_CO_replacement_text = (*this).m_Rewrite.getRewrittenText(COSR);
+ std::string cond_text = (*this).m_Rewrite.getRewrittenText(cond_SR);
+ std::string CO_replacement_text2 = cond_text + " ? " + lhs_replacement_text + " : " + rhs_replacement_text;
+
+ CO_replacement_text = possibly_truncated_CO_replacement_text;
+ int q = 3;
+ }
+ }
+ }
+
+ if (m_var_DD && ("" != CO_replacement_text)) {
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*m_var_DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+
+ ddcs_ref.m_initializer_info_str = " = " + CO_replacement_text;
+ }
+
+ }
+ }
+}
+
+
struct CArrayInferenceInfo {
bool update_declaration_flag = false;
bool has_been_determined_to_be_an_array = false;
@@ -1326,7 +1547,11 @@ CArrayInferenceInfo infer_array_type_info_from_stmt_indirection_stack(CDDeclConv
if (!DD) { assert(false); return retval; }
for (size_t i = 0; ((i < ddcs_ref.m_indirection_state_stack.size())
&& (i < stmt_indirection_stack.size())); i += 1) {
- if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (("" == stmt_indirection_stack[i])) {
+ /* We're using the empty string as a generic state for the "terminal level of indirection"
+ * when we don't want to bother specifying a specific state. */
+ retval.indirection_level = i;
+ } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
if (("ArraySubscriptExpr" == stmt_indirection_stack[i])
|| ("pointer arithmetic" == stmt_indirection_stack[i])) {
ddcs_ref.m_indirection_state_stack[i].m_current = "inferred array";
@@ -2780,6 +3005,7 @@ private:
CState1& m_state1;
};
+/* This class addresses the initialized declarations in the form "type var = cond ? lhs : rhs;". */
class MCSSSConditionalInitializer : public MatchFinder::MatchCallback
{
public:
@@ -2821,11 +3047,6 @@ public:
return void();
}
- if (std::string::npos != source_location_str.find("73")) {
- walkTheAST1(*LHS);
- int q = 5;
- }
-
auto decl_source_range = nice_source_range(DD->getSourceRange(), Rewrite);
auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
std::string decl_source_text;
@@ -2845,52 +3066,139 @@ public:
return;
}
- auto res1 = (*this).m_state1.m_ddecl_conversion_state_map.insert(*DD);
- auto ddcs_map_iter = res1.first;
- auto& ddcs_ref = (*ddcs_map_iter).second;
- bool update_declaration_flag = res1.second;
+ std::string var_current_state_str;
+ {
+ auto res1 = m_state1.m_ddecl_conversion_state_map.insert(*DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ if (1 <= ddcs_ref.m_indirection_state_stack.size()) {
+ var_current_state_str = ddcs_ref.m_indirection_state_stack[0].m_current;
+ } else {
+ int q = 7;
+ }
+ }
+ bool var_has_been_determined_to_be_an_array = false;
+ if (("inferred array" == var_current_state_str) ||
+ ("dynamic array" == var_current_state_str) ||
+ ("native array" == var_current_state_str)) {
+ if ("native array" == var_current_state_str) {
+ assert(false); /* right? */
+ }
+ var_has_been_determined_to_be_an_array = true;
+ }
+
+ auto lhs_res2 = infer_array_type_info_from_stmt(*LHS, "", (*this).m_state1);
+ auto rhs_res2 = infer_array_type_info_from_stmt(*RHS, "", (*this).m_state1);
+ bool lhs_qualifies = false;
+ bool rhs_qualifies = false;
{
- auto res2 = infer_array_type_info_from_stmt(*LHS, "", (*this).m_state1);
+ auto& res2 = lhs_res2;
if (res2.ddecl_cptr && res2.declaration_expr_cptr) {
std::string variable_name = res2.ddecl_cptr->getNameAsString();
auto QT = res2.ddecl_cptr->getType();
auto LHS_QT = LHS->getType();
- if (QT == LHS_QT) {
-
- if (ConvertToSCPP && decl_source_range.isValid()) {
+ /* Currently we only support the case where the value expressions are direct
+ * references to declared variables. */
+ if ((QT == LHS_QT)/* && (1 == res2.indirection_level)*/) {
+ lhs_qualifies = true;
+ if (ConvertToSCPP) {
+ /* Here we're establishing and "enforcing" the constraint that the lhs value must
+ * be of an (array) type that can be assigned to the target variable. */
auto cr_shptr = std::make_shared<CAssignedFromArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0), CDDeclIndirection(*(res2.ddecl_cptr) , res2.indirection_level));
- if (true || res2.has_been_determined_to_be_an_array) {
+ if (var_has_been_determined_to_be_an_array) {
(*cr_shptr).do_replacement(m_state1);
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
}
- } else {
- int q = 7;
}
}
}
}
{
- auto res2 = infer_array_type_info_from_stmt(*RHS, "", (*this).m_state1);
+ auto& res2 = rhs_res2;
if (res2.ddecl_cptr && res2.declaration_expr_cptr) {
std::string variable_name = res2.ddecl_cptr->getNameAsString();
auto QT = res2.ddecl_cptr->getType();
auto RHS_QT = RHS->getType();
+ /* Currently we only support the case where the value expressions are direct
+ * references to declared variables. */
if (QT == RHS_QT) {
-
- if (ConvertToSCPP && decl_source_range.isValid()) {
+ rhs_qualifies = true;
+ if (ConvertToSCPP) {
+ /* Here we're establishing and "enforcing" the constraint that the rhs value must
+ * be of an (array) type that can be assigned to the target variable. */
auto cr_shptr = std::make_shared<CAssignedFromArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0), CDDeclIndirection(*(res2.ddecl_cptr) , res2.indirection_level));
- if (true || res2.has_been_determined_to_be_an_array) {
+ if (var_has_been_determined_to_be_an_array) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ }
+ }
+ }
+
+ if (lhs_qualifies && rhs_qualifies) {
+ std::string lhs_current_state_str;
+ {
+ auto res1 = m_state1.m_ddecl_conversion_state_map.insert(*(lhs_res2.ddecl_cptr));
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ if (1 <= ddcs_ref.m_indirection_state_stack.size()) {
+ lhs_current_state_str = ddcs_ref.m_indirection_state_stack[0].m_current;
+ } else {
+ int q = 7;
+ }
+ }
+ std::string rhs_current_state_str;
+ {
+ auto res1 = m_state1.m_ddecl_conversion_state_map.insert(*(rhs_res2.ddecl_cptr));
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ if (1 <= ddcs_ref.m_indirection_state_stack.size()) {
+ rhs_current_state_str = ddcs_ref.m_indirection_state_stack[0].m_current;
+ } else {
+ int q = 7;
+ }
+ }
+
+ if (ConvertToSCPP) {
+ /* Here we're establishing and "enforcing" the constraint that the lhs and rhs
+ * values of the conditional operator must be the same type. */
+ {
+ auto cr_shptr = std::make_shared<CConditionalOperatorReconciliation2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*lhs_res2.ddecl_cptr, 0), CO, lhs_res2.ddecl_cptr, rhs_res2.ddecl_cptr, DD);
+
+ if ("dynamic array" == lhs_current_state_str) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else if ("native array" == lhs_current_state_str) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ if ("inferred array" == lhs_current_state_str) {
(*cr_shptr).do_replacement(m_state1);
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
}
+ }
+ }
+ {
+ auto cr_shptr = std::make_shared<CConditionalOperatorReconciliation2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*rhs_res2.ddecl_cptr, 0), CO, lhs_res2.ddecl_cptr, rhs_res2.ddecl_cptr, DD);
+
+ if ("dynamic array" == rhs_current_state_str) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else if ("native array" == rhs_current_state_str) {
+ (*cr_shptr).do_replacement(m_state1);
} else {
- int q = 7;
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ if ("inferred array" == rhs_current_state_str) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ }
}
}
}