aboutsummaryrefslogtreecommitdiffstats
path: root/safercpp/safercpp-arr.cpp
diff options
context:
space:
mode:
authoruser1 <user1@ubuntu>2017-06-09 23:48:03 +0000
committeruser1 <user1@ubuntu>2017-06-09 23:48:03 +0000
commitf226eacb392047c7f8336b879e2e73dff7c64211 (patch)
tree7724245e98395ff09fdcbb162a0587ce63466eca /safercpp/safercpp-arr.cpp
parentfixed a (just introduced) bug in MCSSSParameterPassing in which only the (diff)
downloadmutator-f226eacb392047c7f8336b879e2e73dff7c64211.tar.gz
mutator-f226eacb392047c7f8336b879e2e73dff7c64211.zip
added insertion of "#include" directives
Diffstat (limited to '')
-rw-r--r--safercpp/safercpp-arr.cpp465
1 files changed, 281 insertions, 184 deletions
diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp
index 6b2c4ff..f7644a1 100644
--- a/safercpp/safercpp-arr.cpp
+++ b/safercpp/safercpp-arr.cpp
@@ -44,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Lex/Preprocessor.h"
/*LLVM Headers*/
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
@@ -80,16 +81,16 @@ SourceRange nice_source_range(const SourceRange& sr, Rewriter &Rewrite) {
}
}
-bool filtered_out_by_location(const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) {
+bool filtered_out_by_location(const SourceManager &SM, SourceLocation SL) {
bool retval = false;
- if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) {
+ if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) {
retval = true;
- } else if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) {
+ } else if (!Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) {
retval = true;
} else {
bool filename_is_invalid = false;
- std::string full_path_name = MR.SourceManager->getBufferName(SL, &filename_is_invalid);
+ std::string full_path_name = SM.getBufferName(SL, &filename_is_invalid);
std::string filename = full_path_name;
auto last_slash_pos = full_path_name.find_last_of('/');
if (std::string::npos != last_slash_pos) {
@@ -102,11 +103,19 @@ bool filtered_out_by_location(const ast_matchers::MatchFinder::MatchResult &MR,
static const std::string mse_str = "mse";
if (0 == filename.compare(0, mse_str.size(), mse_str)) {
retval = true;
+ } else if ("<built-in>" == filename) {
+ retval = true;
}
}
return retval;
}
+bool filtered_out_by_location(const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) {
+ ASTContext *const ASTC = MR.Context;
+ const SourceManager &SM = ASTC->getSourceManager();
+ return filtered_out_by_location(SM, SL);
+}
+
static std::string with_whitespace_removed(const std::string& str) {
std::string retval = str;
retval.erase(std::remove_if(retval.begin(), retval.end(), isspace), retval.end());
@@ -1791,6 +1800,14 @@ static void update_declaration(const DeclaratorDecl& ddecl, Rewriter &Rewrite, C
}
auto res = generate_declaration_replacement_code(&ddecl, Rewrite, state1.m_ddecl_conversion_state_map, options_str);
+ static const std::string const_space_str = "const ";
+ if (string_begins_with(res.m_replacement_code, const_space_str)) {
+ /* FunctionDecl::getReturnTypeSourceRange() seems to not include prefix qualifiers, like
+ * "const". Since the source range to be replaced doesn't include the "const " qualifier,
+ * if present, here we make sure it's not included in the replacement code either. */
+ res.m_replacement_code = res.m_replacement_code.substr(const_space_str.length());
+ }
+
if (ConvertToSCPP && return_type_source_range.isValid() && (1 <= res.m_replacement_code.size())) {
auto res2 = Rewrite.ReplaceText(return_type_source_range, res.m_replacement_code);
} else {
@@ -3104,6 +3121,7 @@ private:
struct CAllocFunctionInfo {
bool m_seems_to_be_some_kind_of_malloc_or_realloc = false;
+ bool m_seems_to_be_some_kind_of_realloc = false;
clang::CallExpr::const_arg_iterator m_num_bytes_arg_iter;
std::string m_num_bytes_arg_source_text;
};
@@ -3186,6 +3204,9 @@ CAllocFunctionInfo analyze_malloc_resemblance(const clang::CallExpr& call_expr,
retval.m_num_bytes_arg_iter = arg_iter;
retval.m_seems_to_be_some_kind_of_malloc_or_realloc = true;
retval.m_num_bytes_arg_source_text = arg_source_text;
+ if (ends_with_realloc) {
+ retval.m_seems_to_be_some_kind_of_realloc = true;
+ }
}
}
}
@@ -3318,18 +3339,30 @@ public:
}
}
if ("" != lhs_element_type_str) {
- num_elements_text = "(";
- num_elements_text += alloc_function_info1.m_num_bytes_arg_source_text;
- num_elements_text += ") / sizeof(";
- num_elements_text += lhs_element_type_str;
- num_elements_text += ")";
-
auto lhs_source_range = nice_source_range(LHS->getSourceRange(), Rewrite);
auto lhs_source_text = Rewrite.getRewrittenText(lhs_source_range);
- bo_replacement_code += "(" + lhs_source_text + ")";
- bo_replacement_code += ".resize(";
- bo_replacement_code += num_elements_text;
- bo_replacement_code += ")";
+
+ if (false) {
+ num_elements_text = "(";
+ num_elements_text += alloc_function_info1.m_num_bytes_arg_source_text;
+ num_elements_text += ") / sizeof(";
+ num_elements_text += lhs_element_type_str;
+ num_elements_text += ")";
+
+ bo_replacement_code += "(" + lhs_source_text + ")";
+ bo_replacement_code += ".resize(";
+ bo_replacement_code += num_elements_text;
+ bo_replacement_code += ")";
+ } else {
+ if (alloc_function_info1.m_seems_to_be_some_kind_of_realloc) {
+ bo_replacement_code = "MSE_LH_REALLOC(";
+ } else {
+ bo_replacement_code = "MSE_LH_ALLOC(";
+ }
+ bo_replacement_code += lhs_element_type_str + ", ";
+ bo_replacement_code += lhs_source_text + ", ";
+ bo_replacement_code += alloc_function_info1.m_num_bytes_arg_source_text + ")";
+ }
auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
std::string decl_source_text;
@@ -3403,189 +3436,115 @@ public:
int q = 5;
}
- auto function_decl = CE->getDirectCallee();
- auto num_args = CE->getNumArgs();
- if (function_decl && ((1 == num_args) || (2 == num_args))) {
- std::string function_name = function_decl->getNameAsString();
- static const std::string alloc_str = "alloc";
- static const std::string realloc_str = "realloc";
- auto lc_function_name = tolowerstr(function_name);
- bool ends_with_alloc = ((lc_function_name.size() >= alloc_str.size())
- && (0 == lc_function_name.compare(lc_function_name.size() - alloc_str.size(), alloc_str.size(), alloc_str)));
- bool ends_with_realloc = (ends_with_alloc && (lc_function_name.size() >= realloc_str.size())
- && (0 == lc_function_name.compare(lc_function_name.size() - realloc_str.size(), realloc_str.size(), realloc_str)));
- bool still_potentially_valid1 = (ends_with_alloc && (1 == num_args)) || (ends_with_realloc && (2 == num_args));
- if (still_potentially_valid1) {
- auto iter = CE->arg_begin();
- if (ends_with_realloc) {
- iter++;
- }
- {
- auto arg_source_range = nice_source_range((*iter)->getSourceRange(), Rewrite);
- std::string arg_source_text;
- if (arg_source_range.isValid()) {
- arg_source_text = Rewrite.getRewrittenText(arg_source_range);
- //auto arg_source_text_sans_ws = with_whitespace_removed(arg_source_text);
-
- bool asterisk_found = false;
- auto sizeof_start_index = arg_source_text.find("sizeof(");
- if (std::string::npos != sizeof_start_index) {
- auto sizeof_end_index = arg_source_text.find(")", sizeof_start_index);
- if (std::string::npos != sizeof_end_index) {
- assert(sizeof_end_index > sizeof_start_index);
- std::string before_str = arg_source_text.substr(0, sizeof_start_index);
- std::string after_str;
- if (sizeof_end_index + 1 < arg_source_text.size()) {
- after_str = arg_source_text.substr(sizeof_end_index + 1);
- }
-
- auto index = before_str.size() - 1;
- while (0 <= index) {
- if ('*' == before_str[index]) {
- asterisk_found = true;
- }
- if (!std::isspace(before_str[index])) {
- break;
- }
-
- index -= 1;
- }
- if (asterisk_found) {
- before_str = before_str.substr(0, index);
- } else {
- size_t index2 = 0;
- while (after_str.size() > index2) {
- if ('*' == after_str[index2]) {
- asterisk_found = true;
- }
- if (!std::isspace(after_str[index2])) {
- break;
- }
-
- index2 += 1;
- }
- if (asterisk_found) {
- after_str = after_str.substr(index2 + 1);
- }
- }
- }
- }
- if (true || asterisk_found) {
- /* The argument is in the form "something * sizeof(something_else)" or
- * "sizeof(something) * something_else". So we're just going to assume that
- * this is an instance of an array being allocated. */
- std::string num_elements_text/* = before_str + after_str*/;
-
- if (nullptr != DD) {
- 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;
- if (decl_source_range.isValid()) {
- decl_source_text = Rewrite.getRewrittenText(decl_source_range);
- } else {
- return;
- }
- QualType QT = DD->getType();
- auto variable_name = DD->getNameAsString();
+ auto alloc_function_info1 = analyze_malloc_resemblance(*CE, Rewrite);
+ if (alloc_function_info1.m_seems_to_be_some_kind_of_malloc_or_realloc) {
+ /* The argument is in the form "something * sizeof(something_else)" or
+ * "sizeof(something) * something_else". So we're just going to assume that
+ * this is an instance of an array being allocated. */
+ std::string num_elements_text/* = before_str + after_str*/;
- auto qualified_name = DD->getQualifiedNameAsString();
- static const std::string mse_namespace_str1 = "mse::";
- static const std::string mse_namespace_str2 = "::mse::";
- if ((0 == qualified_name.compare(0, mse_namespace_str1.size(), mse_namespace_str1))
- || (0 == qualified_name.compare(0, mse_namespace_str2.size(), mse_namespace_str2))) {
- return;
- }
+ if (nullptr != DD) {
+ 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;
+ if (decl_source_range.isValid()) {
+ decl_source_text = Rewrite.getRewrittenText(decl_source_range);
+ } else {
+ return;
+ }
+ QualType QT = DD->getType();
+ auto variable_name = DD->getNameAsString();
- if (!is_an_indirect_type(DD->getType())) {
- return;
- }
+ auto qualified_name = DD->getQualifiedNameAsString();
+ static const std::string mse_namespace_str1 = "mse::";
+ static const std::string mse_namespace_str2 = "::mse::";
+ if ((0 == qualified_name.compare(0, mse_namespace_str1.size(), mse_namespace_str1))
+ || (0 == qualified_name.compare(0, mse_namespace_str2.size(), mse_namespace_str2))) {
+ 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;
+ if (!is_an_indirect_type(DD->getType())) {
+ return;
+ }
- bool lhs_has_been_determined_to_be_an_array = false;
- if ("native pointer" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
- ddcs_ref.set_indirection_current(0, "malloc target");
- } else if ("inferred array" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
- ddcs_ref.set_indirection_current(0, "dynamic array");
- lhs_has_been_determined_to_be_an_array = true;
- //update_declaration_flag = true;
- m_state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(m_state1, CDDeclIndirection(*DD, 0));
- } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
- lhs_has_been_determined_to_be_an_array = true;
- } else {
- assert("native array" != ddcs_ref.m_indirection_state_stack.at(0).current());
- }
+ 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;
- const clang::Type* TP = QT.getTypePtr();
- auto lhs_type_str = QT.getAsString();
+ bool lhs_has_been_determined_to_be_an_array = false;
+ if ("native pointer" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
+ ddcs_ref.set_indirection_current(0, "malloc target");
+ } else if ("inferred array" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
+ ddcs_ref.set_indirection_current(0, "dynamic array");
+ lhs_has_been_determined_to_be_an_array = true;
+ //update_declaration_flag = true;
+ m_state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(m_state1, CDDeclIndirection(*DD, 0));
+ } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack.at(0).current()) {
+ lhs_has_been_determined_to_be_an_array = true;
+ } else {
+ assert("native array" != ddcs_ref.m_indirection_state_stack.at(0).current());
+ }
- std::string element_type_str;
- if (TP->isArrayType()) {
- auto ATP = llvm::cast<const clang::ArrayType>(TP);
- assert(nullptr != ATP);
- auto element_type = ATP->getElementType();
- auto type_str = element_type.getAsString();
- if (("char" != type_str) && ("const char" != type_str)) {
- element_type_str = type_str;
- }
- } else if (TP->isPointerType()) {
- auto TPP = llvm::cast<const clang::PointerType>(TP);
- assert(nullptr != TPP);
- auto target_type = TPP->getPointeeType();
- auto type_str = target_type.getAsString();
- if (("char" != type_str) && ("const char" != type_str)) {
- element_type_str = type_str;
- }
- }
- if ("" != element_type_str) {
- num_elements_text = "(";
- num_elements_text += arg_source_text;
- if (true || (("void" != element_type_str) && ("const void" != element_type_str))) {
- num_elements_text += ") / sizeof(";
- num_elements_text += element_type_str;
- } else {
- /* todo: something */
- }
- num_elements_text += ")";
+ const clang::Type* TP = QT.getTypePtr();
+ auto lhs_type_str = QT.getAsString();
- std::string initializer_info_str = "(" + num_elements_text + ")";
+ std::string element_type_str;
+ if (TP->isArrayType()) {
+ auto ATP = llvm::cast<const clang::ArrayType>(TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto type_str = element_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ element_type_str = type_str;
+ }
+ } else if (TP->isPointerType()) {
+ auto TPP = llvm::cast<const clang::PointerType>(TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto type_str = target_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ element_type_str = type_str;
+ }
+ }
+ if ("" != element_type_str) {
+ num_elements_text = "(";
+ num_elements_text += alloc_function_info1.m_num_bytes_arg_source_text;
+ if (true || (("void" != element_type_str) && ("const void" != element_type_str))) {
+ num_elements_text += ") / sizeof(";
+ num_elements_text += element_type_str;
+ } else {
+ /* todo: something */
+ }
+ num_elements_text += ")";
- auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
- std::string decl_source_text;
- if (decl_source_range.isValid()) {
- decl_source_text = Rewrite.getRewrittenText(decl_source_range);
- } else {
- return;
- }
+ std::string initializer_info_str = "(" + num_elements_text + ")";
- auto DSSR = clang::SourceRange(DSSL, DSSLE);
- if (ConvertToSCPP && decl_source_range.isValid() && (DSSR.isValid())) {
- auto cr_shptr = std::make_shared<CInitializerArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0/*indirection_level*/), DS, initializer_info_str);
+ auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
+ std::string decl_source_text;
+ if (decl_source_range.isValid()) {
+ decl_source_text = Rewrite.getRewrittenText(decl_source_range);
+ } else {
+ return;
+ }
- if (lhs_has_been_determined_to_be_an_array) {
- (*cr_shptr).do_replacement(m_state1);
- } else {
- m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
- }
+ auto DSSR = clang::SourceRange(DSSL, DSSLE);
+ if (ConvertToSCPP && decl_source_range.isValid() && (DSSR.isValid())) {
+ auto cr_shptr = std::make_shared<CInitializerArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0/*indirection_level*/), DS, initializer_info_str);
- int q = 3;
- } else {
- int q = 7;
- }
- }
- }
- int q = 5;
+ if (lhs_has_been_determined_to_be_an_array) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
+
+ int q = 3;
} else {
- int q = 5;
+ int q = 7;
}
- int q = 5;
}
}
-
+ int q = 5;
}
}
}
@@ -3635,7 +3594,7 @@ public:
}
Expr::NullPointerConstantKind kind = RHS->IgnoreParenCasts()->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
- if (clang::Expr::NPCK_NotNull != kind) {
+ if (false && clang::Expr::NPCK_NotNull != kind) {
if (true) {
{
if (true) {
@@ -3825,8 +3784,8 @@ public:
if ("" != arg_element_type_str) {
if (ConvertToSCPP && (arg_res2.ddecl_conversion_state_ptr) && arg_is_an_indirect_type) {
auto arg_source_text = Rewrite.getRewrittenText(arg_source_range);
- std::string ce_replacement_code = "(" + arg_source_text + ")";
- ce_replacement_code += ".resize(0)";
+ //std::string ce_replacement_code = "(" + arg_source_text + ").resize(0)";
+ std::string ce_replacement_code = "MSE_LH_FREE(" + arg_source_text + ")";
auto cr_shptr = std::make_shared<CFreeDynamicArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(arg_res2.ddecl_cptr), arg_res2.indirection_level), CE, ce_replacement_code);
@@ -6114,6 +6073,100 @@ private:
};
/**********************************************************************************************************************/
+
+struct CFirstIncludeInfo {
+ CFirstIncludeInfo(const SourceLocation &beginning_of_file_loc) : m_beginning_of_file_loc(beginning_of_file_loc),
+ m_beginning_of_file_loc_is_valid(true) {}
+
+ bool m_legacyhelpers_include_directive_found = false;
+
+ bool m_first_include_directive_loc_is_valid = false;
+ SourceLocation m_first_include_directive_loc;
+
+ bool m_first_macro_directive_ptr_is_valid = false;
+ const MacroDirective* m_first_macro_directive_ptr = nullptr;
+
+ SourceLocation m_beginning_of_file_loc;
+ bool m_beginning_of_file_loc_is_valid = false;
+};
+
+class MyPPCallbacks : public PPCallbacks
+{
+public:
+ MyPPCallbacks(Rewriter& Rewriter_ref) : m_Rewriter_ref(Rewriter_ref) {}
+
+ void InclusionDirective(
+ SourceLocation hash_loc,
+ const Token &include_token,
+ StringRef file_name,
+ bool is_angled,
+ CharSourceRange filename_range,
+ const FileEntry *file,
+ StringRef search_path,
+ StringRef relative_path,
+ const clang::Module *imported) override {
+
+ if (current_fii_shptr()) {
+ if (!(current_fii_shptr()->m_first_include_directive_loc_is_valid)) {
+ current_fii_shptr()->m_first_include_directive_loc = hash_loc;
+ current_fii_shptr()->m_first_include_directive_loc_is_valid = true;
+ }
+
+ std::string file_name_str = file_name;
+ if ("mselegacyhelpers.h" == file_name_str) {
+ current_fii_shptr()->m_legacyhelpers_include_directive_found = true;
+ }
+ int q = 5;
+ }
+ }
+
+ void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
+ if (current_fii_shptr()) {
+ if (!(current_fii_shptr()->m_first_macro_directive_ptr_is_valid)) {
+ if (MD) {
+ current_fii_shptr()->m_first_macro_directive_ptr = MD;
+ current_fii_shptr()->m_first_macro_directive_ptr_is_valid = true;
+ } else { assert(false); }
+ }
+ }
+ }
+
+ void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType,
+ FileID PrevFID = FileID()) override {
+
+ bool filename_is_invalid = false;
+ std::string full_path_name = m_Rewriter_ref.getSourceMgr().getBufferName(Loc, &filename_is_invalid);
+
+ if (PPCallbacks::FileChangeReason::EnterFile == Reason) {
+ auto fii_iter = m_first_include_info_map.find(Loc);
+ if (m_first_include_info_map.end() == fii_iter) {
+ std::map<SourceLocation, std::shared_ptr<CFirstIncludeInfo>>::value_type item(Loc, std::make_shared<CFirstIncludeInfo>(Loc));
+ fii_iter = (m_first_include_info_map.insert(item)).first;
+ }
+ m_current_fii_shptr_stack.push_back((*fii_iter).second);
+ } else if (PPCallbacks::FileChangeReason::ExitFile == Reason) {
+ if (1 <= m_current_fii_shptr_stack.size()) {
+ m_current_fii_shptr_stack.pop_back();
+ } else {
+ assert(false);
+ }
+ }
+ }
+
+ std::shared_ptr<CFirstIncludeInfo> current_fii_shptr() {
+ std::shared_ptr<CFirstIncludeInfo> retval = nullptr;
+ if (1 <= m_current_fii_shptr_stack.size()) {
+ retval = m_current_fii_shptr_stack.back();
+ }
+ return retval;
+ }
+
+ std::map<SourceLocation, std::shared_ptr<CFirstIncludeInfo>> m_first_include_info_map;
+ std::vector<std::shared_ptr<CFirstIncludeInfo>> m_current_fii_shptr_stack;
+ Rewriter& m_Rewriter_ref;
+};
+
class MyFrontendAction : public ASTFrontendAction
{
public:
@@ -6125,8 +6178,52 @@ public:
}
}
+ bool BeginSourceFileAction(CompilerInstance &ci, StringRef) override {
+ std::unique_ptr<MyPPCallbacks> my_pp_callbacks_ptr(new MyPPCallbacks(TheRewriter));
+
+ clang::Preprocessor &pp = ci.getPreprocessor();
+ pp.addPPCallbacks(std::move(my_pp_callbacks_ptr));
+
+ return true;
+ }
+
void EndSourceFileAction() override {
TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs());
+
+ {
+ clang::CompilerInstance &ci = getCompilerInstance();
+ clang::Preprocessor &pp = ci.getPreprocessor();
+ MyPPCallbacks *my_pp_callbacks_ptr = static_cast<MyPPCallbacks *>(pp.getPPCallbacks());
+
+ assert(my_pp_callbacks_ptr);
+ if (my_pp_callbacks_ptr) {
+ // do whatever you want with the callback now
+
+ for (auto& item_ref : my_pp_callbacks_ptr->m_first_include_info_map) {
+ auto& fii_ref = *(item_ref.second);
+ assert(fii_ref.m_beginning_of_file_loc_is_valid);
+
+ bool filename_is_invalid = false;
+ std::string full_path_name = TheRewriter.getSourceMgr().getBufferName(fii_ref.m_beginning_of_file_loc, &filename_is_invalid);
+
+ if (filtered_out_by_location(TheRewriter.getSourceMgr(), fii_ref.m_beginning_of_file_loc)) {
+ continue;
+ }
+
+ if (!(fii_ref.m_legacyhelpers_include_directive_found)) {
+ assert(fii_ref.m_first_include_directive_loc_is_valid);
+ TheRewriter.InsertTextBefore(fii_ref.m_first_include_directive_loc,
+ "#include \"mselegacyhelpers.h\"\n");
+ } else if (fii_ref.m_first_macro_directive_ptr_is_valid) {
+ TheRewriter.InsertTextAfterToken(fii_ref.m_first_macro_directive_ptr->getLocation(),
+ "#include \"mselegacyhelpers.h\"\n");
+ } else if (fii_ref.m_beginning_of_file_loc_is_valid) {
+ TheRewriter.InsertTextBefore(fii_ref.m_beginning_of_file_loc,
+ "#include \"mselegacyhelpers.h\"\n");
+ }
+ }
+ } else { assert(false); }
+ }
}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) override {