Customize clang diagnostic handling. (#1707)

* Cutomize clang diagnostic handling.

* Removed code that was commented out.
This commit is contained in:
Hong Chen 2024-05-14 10:53:11 -05:00 committed by GitHub
parent 26c18d95af
commit d72312c602
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,39 @@
#include <iostream>
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceLocation.h"
#include "ICGDiagnosticConsumer.hh"
#include "HeaderSearchDirs.hh"
#include "Utilities.hh"
ICGDiagnosticConsumer::ICGDiagnosticConsumer(llvm::raw_ostream &os, clang::DiagnosticOptions *diags, clang::CompilerInstance &in_ci, HeaderSearchDirs &in_hsd)
: clang::TextDiagnosticPrinter(os, diags), ci(in_ci), hsd(in_hsd) {
error_in_user_code = false;
};
ICGDiagnosticConsumer::~ICGDiagnosticConsumer() {
};
/**
* @details
* -# Check the diagnostic level to see if an error is from user code.
* -# Terminate the build if yes, continue otherwise.
*/
void ICGDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) {
// Use TextDiagnosticPrinter to handle diagnostic if the code is user code.
// Otherwise use base DiagnosticConsumer to handle diagnostic for system code.
if (isInUserCode(ci , Info.getLocation(), hsd)) {
// Parent class implementation for handling diagnostic
clang::TextDiagnosticPrinter::HandleDiagnostic(DiagLevel, Info);
// Flag it if an error is from user code
if (DiagLevel == clang::DiagnosticsEngine::Level::Fatal || DiagLevel == clang::DiagnosticsEngine::Level::Error) {
error_in_user_code = true;
}
} else {
// Base class implementation for handling diagnostic
clang::DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
}
}

View File

@ -0,0 +1,42 @@
#ifndef ICG_DIAGNOSTICCONSUMER_HH
#define ICG_DIAGNOSTICCONSUMER_HH
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
class HeaderSearchDirs;
/**
This class is passed to the clang parser as a DiagnosticConsumer.
It will terminate the trick build if an error found is from user code.
@date May 2024
*/
class ICGDiagnosticConsumer : public clang::TextDiagnosticPrinter {
public:
ICGDiagnosticConsumer(llvm::raw_ostream &os, clang::DiagnosticOptions *diags, clang::CompilerInstance &in_ci, HeaderSearchDirs &in_hsd);
~ICGDiagnosticConsumer() override;
void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) override;
/** Flag for if any error found in user code. */
bool error_in_user_code;
protected:
/** The compiler instance. */
clang::CompilerInstance &ci ;
/** The header search directories. */
HeaderSearchDirs &hsd ;
};
#endif

View File

@ -25,6 +25,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Parse/ParseAST.h"
#include "ICGDiagnosticConsumer.hh"
#include "ICGASTConsumer.hh"
#include "HeaderSearchDirs.hh"
#include "CommentSaver.hh"
@ -323,6 +324,8 @@ int main(int argc, char * argv[]) {
#else
ci.getSourceManager().createMainFileID(fileEntry);
#endif
ICGDiagnosticConsumer *icgDiagConsumer = new ICGDiagnosticConsumer(llvm::errs(), &ci.getDiagnosticOpts(), ci, hsd);
ci.getDiagnostics().setClient(icgDiagConsumer);
ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor());
clang::ParseAST(ci.getSema());
ci.getDiagnosticClient().EndSourceFile();
@ -337,5 +340,10 @@ int main(int argc, char * argv[]) {
// Print the list of headers that have the ICG:(No) comment
printAttributes.printICGNoFiles();
if (icgDiagConsumer->error_in_user_code) {
std::cout << color(ERROR, "Trick build was terminated due to error in user code!") << std::endl;
exit(-1);
}
return 0;
}