Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/3C/3C.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class _3CInterface {
// Mutex for this interface.
std::mutex InterfaceMutex;

// saved ASTs
std::vector< std::unique_ptr< ASTUnit >> ASTs;

// If the parameters are invalid, this function prints an error message to
// stderr and returns null.
//
Expand Down
195 changes: 118 additions & 77 deletions clang/lib/3C/3C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,18 +351,29 @@ bool _3CInterface::addVariables() {

std::lock_guard<std::mutex> Lock(InterfaceMutex);

// first step, so load the ASTs
ClangTool &Tool = getGlobalClangTool();
if (Tool.buildASTs(ASTs)) return false;
// Enable Diagnostics
for (auto &TU :ASTs) {
TU->enableSourceFileDiagnostics();
}

// 1a. Add Variables.
std::unique_ptr<ToolAction> AdderTool = newFrontendActionFactoryA<
GenericAction<VariableAdderConsumer, ProgramInfo>>(GlobalProgramInfo);
VariableAdderConsumer VA = VariableAdderConsumer(GlobalProgramInfo, nullptr);
for (auto &TU : ASTs) {
VA.HandleTranslationUnit(TU->getASTContext());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No return code form this call? Tool.run() below returns an exit code that could cause a return value of false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Same question for the passes below.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep. fixed.

}

if (AdderTool) {
int ToolExitCode = Tool.run(AdderTool.get());
if (ToolExitCode != 0)
return false;
} else
llvm_unreachable("No action");
// // 1a. Add Variables.
// std::unique_ptr<ToolAction> AdderTool = newFrontendActionFactoryA<
// GenericAction<VariableAdderConsumer, ProgramInfo>>(GlobalProgramInfo);
//
// if (AdderTool) {
// int ToolExitCode = Tool.run(AdderTool.get());
// if (ToolExitCode != 0)
// return false;
// } else
// llvm_unreachable("No action");

return true;
}
Expand All @@ -371,18 +382,23 @@ bool _3CInterface::buildInitialConstraints() {

std::lock_guard<std::mutex> Lock(InterfaceMutex);

ClangTool &Tool = getGlobalClangTool();
// ClangTool &Tool = getGlobalClangTool();

// 1b. Gather constraints.
std::unique_ptr<ToolAction> ConstraintTool = newFrontendActionFactoryA<
GenericAction<ConstraintBuilderConsumer, ProgramInfo>>(GlobalProgramInfo);
ConstraintBuilderConsumer CB = ConstraintBuilderConsumer(GlobalProgramInfo, nullptr);
for (auto &TU : ASTs) {
CB.HandleTranslationUnit(TU->getASTContext());
}

if (ConstraintTool) {
int ToolExitCode = Tool.run(ConstraintTool.get());
if (ToolExitCode != 0)
return false;
} else
llvm_unreachable("No action");
// // 1b. Gather constraints.
// std::unique_ptr<ToolAction> ConstraintTool = newFrontendActionFactoryA<
// GenericAction<ConstraintBuilderConsumer, ProgramInfo>>(GlobalProgramInfo);
//
// if (ConstraintTool) {
// int ToolExitCode = Tool.run(ConstraintTool.get());
// if (ToolExitCode != 0)
// return false;
// } else
// llvm_unreachable("No action");

if (!GlobalProgramInfo.link()) {
errs() << "Linking failed!\n";
Expand Down Expand Up @@ -420,7 +436,8 @@ bool _3CInterface::solveConstraints() {
if (DumpIntermediate)
dumpConstraintOutputJson(FINAL_OUTPUT_SUFFIX, GlobalProgramInfo);

ClangTool &Tool = getGlobalClangTool();
// ClangTool &Tool = getGlobalClangTool();

if (AllTypes) {
if (DebugArrSolver)
GlobalProgramInfo.getABoundsInfo().dumpAVarGraph(
Expand All @@ -430,31 +447,42 @@ bool _3CInterface::solveConstraints() {
// bounds declarations.
GlobalProgramInfo.getABoundsInfo().performFlowAnalysis(&GlobalProgramInfo);

// 3. Infer the bounds based on calls to malloc and calloc
std::unique_ptr<ToolAction> ABInfTool = newFrontendActionFactoryA<
GenericAction<AllocBasedBoundsInference, ProgramInfo>>(
GlobalProgramInfo);
if (ABInfTool) {
int ToolExitCode = Tool.run(ABInfTool.get());
if (ToolExitCode != 0)
return false;
} else
llvm_unreachable("No Action");
AllocBasedBoundsInference ABBI = AllocBasedBoundsInference(GlobalProgramInfo, nullptr);
for (auto &TU : ASTs) {
ABBI.HandleTranslationUnit(TU->getASTContext());
}


// // 3. Infer the bounds based on calls to malloc and calloc
// std::unique_ptr<ToolAction> ABInfTool = newFrontendActionFactoryA<
// GenericAction<AllocBasedBoundsInference, ProgramInfo>>(
// GlobalProgramInfo);
// if (ABInfTool) {
// int ToolExitCode = Tool.run(ABInfTool.get());
// if (ToolExitCode != 0)
// return false;
// } else
// llvm_unreachable("No Action");

// Propagate the information from allocator bounds.
GlobalProgramInfo.getABoundsInfo().performFlowAnalysis(&GlobalProgramInfo);
}

// 4. Run intermediate tool hook to run visitors that need to be executed
// after constraint solving but before rewriting.
std::unique_ptr<ToolAction> IMTool = newFrontendActionFactoryA<
GenericAction<IntermediateToolHook, ProgramInfo>>(GlobalProgramInfo);
if (IMTool) {
int ToolExitCode = Tool.run(IMTool.get());
if (ToolExitCode != 0)
return false;
} else
llvm_unreachable("No Action");
IntermediateToolHook ITH = IntermediateToolHook(GlobalProgramInfo, nullptr);
for (auto &TU : ASTs) {
ITH.HandleTranslationUnit(TU->getASTContext());
}

// // 4. Run intermediate tool hook to run visitors that need to be executed
// // after constraint solving but before rewriting.
// std::unique_ptr<ToolAction> IMTool = newFrontendActionFactoryA<
// GenericAction<IntermediateToolHook, ProgramInfo>>(GlobalProgramInfo);
// if (IMTool) {
// int ToolExitCode = Tool.run(IMTool.get());
// if (ToolExitCode != 0)
// return false;
// } else
// llvm_unreachable("No Action");

if (AllTypes) {
// Propagate data-flow information for Array pointers.
Expand Down Expand Up @@ -497,48 +525,61 @@ bool _3CInterface::solveConstraints() {
return true;
}

bool _3CInterface::writeConvertedFileToDisk(const std::string &FilePath) {
std::lock_guard<std::mutex> Lock(InterfaceMutex);
bool RetVal = false;
if (std::find(SourceFiles.begin(), SourceFiles.end(), FilePath) !=
SourceFiles.end()) {
RetVal = true;
std::vector<std::string> SourceFiles;
SourceFiles.clear();
SourceFiles.push_back(FilePath);
// Don't use global tool. Create a new tool for give single file.
ClangTool Tool(*CurrCompDB, SourceFiles);
Tool.appendArgumentsAdjuster(getIgnoreCheckedPointerAdjuster());
std::unique_ptr<ToolAction> RewriteTool =
newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
GlobalProgramInfo, VerifyDiagnosticOutput);

if (RewriteTool) {
int ToolExitCode = Tool.run(RewriteTool.get());
if (ToolExitCode != 0)
RetVal = false;
}
}
GlobalProgramInfo.getPerfStats().endTotalTime();
GlobalProgramInfo.getPerfStats().startTotalTime();
return RetVal;
}
//bool _3CInterface::writeConvertedFileToDisk(const std::string &FilePath) {
// std::lock_guard<std::mutex> Lock(InterfaceMutex);
// bool RetVal = false;
// if (std::find(SourceFiles.begin(), SourceFiles.end(), FilePath) !=
// SourceFiles.end()) {
// RetVal = true;
// std::vector<std::string> SourceFiles;
// SourceFiles.clear();
// SourceFiles.push_back(FilePath);
// // Don't use global tool. Create a new tool for give single file.
// ClangTool Tool(*CurrCompDB, SourceFiles);
// Tool.appendArgumentsAdjuster(getIgnoreCheckedPointerAdjuster());
//
// RewriteConsumer RC = RewriteConsumer(GlobalProgramInfo);
// for (auto &TU : ASTs) {
// RC.HandleTranslationUnit(TU->getASTContext());
// }
//
//
//// std::unique_ptr<ToolAction> RewriteTool =
//// newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
//// GlobalProgramInfo, VerifyDiagnosticOutput);
////
//// if (RewriteTool) {
//// int ToolExitCode = Tool.run(RewriteTool.get());
//// if (ToolExitCode != 0)
//// RetVal = false;
//// }
//
// }
// GlobalProgramInfo.getPerfStats().endTotalTime();
// GlobalProgramInfo.getPerfStats().startTotalTime();
// return RetVal;
//}

bool _3CInterface::writeAllConvertedFilesToDisk() {
std::lock_guard<std::mutex> Lock(InterfaceMutex);

ClangTool &Tool = getGlobalClangTool();
// ClangTool &Tool = getGlobalClangTool();

RewriteConsumer RC = RewriteConsumer(GlobalProgramInfo);
for (auto &TU : ASTs) {
RC.HandleTranslationUnit(TU->getASTContext());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After rewriting happens, do you need to delete/free the ASTs? Maybe add another method to free them, to complement the one I'm suggesting you add, to build them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I could tell the destructors handled everything. That might be different if we had to save/load for memory, or maintain the diagnostics for verification. If you can think of anything else, I'll check it out and add it.


// Rewrite the input files.
std::unique_ptr<ToolAction> RewriteTool =
newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
GlobalProgramInfo, VerifyDiagnosticOutput);
if (RewriteTool) {
int ToolExitCode = Tool.run(RewriteTool.get());
if (ToolExitCode != 0)
return false;
} else
llvm_unreachable("No action");
// // Rewrite the input files.
// std::unique_ptr<ToolAction> RewriteTool =
// newFrontendActionFactoryA<RewriteAction<RewriteConsumer, ProgramInfo>>(
// GlobalProgramInfo, VerifyDiagnosticOutput);
// if (RewriteTool) {
// int ToolExitCode = Tool.run(RewriteTool.get());
// if (ToolExitCode != 0)
// return false;
// } else
// llvm_unreachable("No action");

GlobalProgramInfo.getPerfStats().endTotalTime();
GlobalProgramInfo.getPerfStats().startTotalTime();
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/3C/PersistentSourceLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,16 @@ PersistentSourceLoc PersistentSourceLoc::mkPSL(clang::SourceRange SR,
if (TFSL.isValid()) {
const FileEntry *Fe = SM.getFileEntryForID(TFSL.getFileID());
std::string ToConv = Fn;
StringRef DidConv = Fn;
std::string FeAbsS = "";
if (Fe != nullptr)
if (Fe != nullptr) {
ToConv = std::string(Fe->getName());
getCanonicalFilePath(ToConv, FeAbsS);
DidConv = Fe->tryGetRealPathName();
}
if (DidConv.empty())
getCanonicalFilePath(ToConv, FeAbsS);
else
FeAbsS = DidConv.str();
Fn = std::string(sys::path::remove_leading_dotslash(FeAbsS));
}
PersistentSourceLoc PSL(Fn, FESL.getExpansionLineNumber(),
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/3C/RewriteUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,9 @@ static void emit(Rewriter &R, ASTContext &C) {
};

// Check whether we are allowed to write this file.
std::string FeAbsS = "";
getCanonicalFilePath(std::string(FE->getName()), FeAbsS);
std::string FeAbsS = FE->tryGetRealPathName().str();
if (FeAbsS == "")
getCanonicalFilePath(std::string(FE->getName()), FeAbsS);
if (!canWrite(FeAbsS)) {
DiagnosticsEngine &DE = C.getDiagnostics();
unsigned ID =
Expand Down