[cfe-commits] r39678 - in /cfe/cfe/trunk/Driver: DiagChecker.cpp DiagChecker.h TextDiagnosticBuffer.cpp TextDiagnosticBuffer.h clang.cpp
bwendlin at cs.uiuc.edu
bwendlin at cs.uiuc.edu
Wed Jul 11 09:47:03 PDT 2007
Author: bwendlin
Date: Wed Jul 11 11:47:03 2007
New Revision: 39678
URL: http://llvm.org/viewvc/llvm-project?rev=39678&view=rev
Log:
Submitted by: Bill Wendling
Reviewed by: Chris Lattner
- Added a new diagnostic client, TextDiagnosticBuffer. It buffers all
reported diagnostics.
- Use the new diagnostic client to check that expected diagnostics are
actually emitted. The way this is done is to put the expected
diagnostic in a comment on the line you expect it to be emitted for.
Like this:
int X = A; // expected-warning {{blah}}
- Use -parse-ast-check to use this feature.
Added:
cfe/cfe/trunk/Driver/DiagChecker.cpp (with props)
cfe/cfe/trunk/Driver/DiagChecker.h (with props)
cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp (with props)
cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h (with props)
Modified:
cfe/cfe/trunk/Driver/clang.cpp
Added: cfe/cfe/trunk/Driver/DiagChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/DiagChecker.cpp?rev=39678&view=auto
==============================================================================
--- cfe/cfe/trunk/Driver/DiagChecker.cpp (added)
+++ cfe/cfe/trunk/Driver/DiagChecker.cpp Wed Jul 11 11:47:03 2007
@@ -0,0 +1,216 @@
+//===--- LLVMDiagChecker.cpp - Diagnostic Checking Functions --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Process the input files and check that the diagnostic messages are expected.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLVMDiagChecker.h"
+#include "ASTStreamers.h"
+#include "TextDiagnosticBuffer.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+using namespace clang;
+
+// USING THE DIAGNOSTIC CHECKER:
+//
+// Indicating that a line expects an error or a warning is simple. Put a comment
+// on the line that has the diagnostic, use "expected-{error,warning}" to tag
+// if it's an expected error or warning, and place the expected text between {{
+// and }} markers. The full text doesn't have to be included, only enough to
+// ensure that the correct diagnostic was emitted.
+//
+// Here's an example:
+//
+// int A = B; // expected-error {{use of undeclared identifier 'B'}}
+//
+// You can place as many diagnostics on one line as you wish. To make the code
+// more readable, you can use slash-newline to separate out the diagnostics.
+
+static const char * const ExpectedErrStr = "expected-error";
+static const char * const ExpectedWarnStr = "expected-warning";
+
+/// FindDiagnostics - Go through the comment and see if it indicates expected
+/// diagnostics. If so, then put them in a diagnostic list.
+///
+static void FindDiagnostics(const std::string &Comment,
+ TextDiagnosticBuffer &DiagClient,
+ DiagList &ExpectedDiags,
+ SourceManager &SourceMgr,
+ SourceLocation Pos,
+ const char * const ExpectedStr) {
+ // Find all expected diagnostics
+ typedef std::string::size_type size_type;
+ size_type ColNo = std::string::npos;
+
+ for (;;) {
+ ColNo = Comment.find(ExpectedStr, ColNo);
+ if (ColNo == std::string::npos) break;
+
+ size_type OpenDiag = Comment.find_first_of("{{", ColNo);
+
+ if (OpenDiag == std::string::npos) {
+ fprintf(stderr,
+ "oops:%d: Cannot find beginning of expected error string\n",
+ SourceMgr.getLineNumber(Pos));
+ break;
+ }
+
+ OpenDiag += 2;
+ size_type CloseDiag = Comment.find_first_of("}}", OpenDiag);
+
+ if (CloseDiag == std::string::npos) {
+ fprintf(stderr,
+ "oops:%d: Cannot find end of expected error string\n",
+ SourceMgr.getLineNumber(Pos));
+ break;
+ }
+
+ std::string Msg(Comment.substr(OpenDiag, CloseDiag - OpenDiag));
+ ExpectedDiags.push_back(std::make_pair(Pos, Msg));
+ ColNo = CloseDiag + 2;
+ }
+}
+
+/// ProcessFileDiagnosticChecking - This lexes the file and finds all of the
+/// expected errors and warnings. It then does the actual parsing of the
+/// program. The parsing will report its diagnostics, and a function can be
+/// called later to report any discrepencies between the diagnostics expected
+/// and those actually seen.
+///
+void clang::ProcessFileDiagnosticChecking(TextDiagnosticBuffer &DiagClient,
+ Preprocessor &PP,
+ const std::string &InFile,
+ SourceManager &SourceMgr,
+ unsigned MainFileID,
+ DiagList &ExpectedErrors,
+ DiagList &ExpectedWarnings) {
+ LexerToken Tok;
+ PP.SetCommentRetentionState(true, true);
+
+ // Enter the cave.
+ PP.EnterSourceFile(MainFileID, 0, true);
+
+ do {
+ PP.Lex(Tok);
+
+ if (Tok.getKind() == tok::comment) {
+ std::string Comment = PP.getSpelling(Tok);
+
+ // Find all expected errors
+ FindDiagnostics(Comment, DiagClient, ExpectedErrors, SourceMgr,
+ Tok.getLocation(), ExpectedErrStr);
+
+ // Find all expected warnings
+ FindDiagnostics(Comment, DiagClient, ExpectedWarnings, SourceMgr,
+ Tok.getLocation(), ExpectedWarnStr);
+ }
+ } while (Tok.getKind() != tok::eof);
+
+ // Parsing the specified input file.
+ PP.SetCommentRetentionState(false, false);
+ BuildASTs(PP, MainFileID, false);
+}
+
+typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
+
+/// PrintProblem - This takes a diagnostic map of the delta between expected and
+/// seen diagnostics. If there's anything in it, then something unexpected
+/// happened. Print the map out in a nice format and return "true". If the map
+/// is empty and we're not going to print things, then return "false".
+///
+static bool PrintProblem(SourceManager &SourceMgr,
+ const_diag_iterator diag_begin,
+ const_diag_iterator diag_end,
+ const char *Msg) {
+ if (diag_begin == diag_end) return false;
+
+ fprintf(stderr, "%s\n", Msg);
+
+ for (; diag_begin != diag_end; ++diag_begin)
+ fprintf(stderr, " LineNo %d:\n %s\n",
+ SourceMgr.getLineNumber(diag_begin->first),
+ diag_begin->second.c_str());
+
+ return true;
+}
+
+/// CompareDiagLists - Compare two diangnostic lists and return the difference
+/// between them.
+///
+static bool CompareDiagLists(SourceManager &SourceMgr,
+ const_diag_iterator d1_begin,
+ const_diag_iterator d1_end,
+ const_diag_iterator d2_begin,
+ const_diag_iterator d2_end,
+ const char *Msg) {
+ TextDiagnosticBuffer::DiagList DiffList;
+
+ for (; d1_begin != d1_end; ++d1_begin) {
+ const std::string &Diag = d1_begin->second;
+ bool Found = false;
+
+ for (; d2_begin != d2_end; ++d2_begin) {
+ if (d2_begin->second.find(Diag) != std::string::npos ||
+ Diag.find(d2_begin->second) != std::string::npos) {
+ Found = true;
+ break;
+ }
+ }
+
+ if (!Found)
+ DiffList.push_back(std::make_pair(d1_begin->first, Diag));
+ }
+
+ return PrintProblem(SourceMgr, DiffList.begin(), DiffList.end(), Msg);
+}
+
+/// ReportCheckingResults - This compares the expected results to those that
+/// were actually reported. It emits any discrepencies. Return "true" if there
+/// were problems. Return "false" otherwise.
+///
+bool clang::ReportCheckingResults(TextDiagnosticBuffer &DiagClient,
+ const DiagList &ExpectedErrors,
+ const DiagList &ExpectedWarnings,
+ SourceManager &SourceMgr) {
+ // We want to capture the delta between what was expected and what was
+ // seen.
+ //
+ // Expected \ Seen - set expected but not seen
+ // Seen \ Expected - set seen but not expected
+ bool HadProblem = false;
+
+ // See if there were errors that were expected but not seen.
+ HadProblem |= CompareDiagLists(SourceMgr,
+ ExpectedErrors.begin(), ExpectedErrors.end(),
+ DiagClient.err_begin(), DiagClient.err_end(),
+ "Errors expected but not seen:");
+
+ // See if there were errors that were seen but not expected.
+ HadProblem |= CompareDiagLists(SourceMgr,
+ DiagClient.err_begin(), DiagClient.err_end(),
+ ExpectedErrors.begin(), ExpectedErrors.end(),
+ "Errors seen but not expected:");
+
+ // See if there were warnings that were expected but not seen.
+ HadProblem |= CompareDiagLists(SourceMgr,
+ ExpectedWarnings.begin(),
+ ExpectedWarnings.end(),
+ DiagClient.warn_begin(), DiagClient.warn_end(),
+ "Warnings expected but not seen:");
+
+ // See if there were warnings that were seen but not expected.
+ HadProblem |= CompareDiagLists(SourceMgr,
+ DiagClient.warn_begin(), DiagClient.warn_end(),
+ ExpectedWarnings.begin(),
+ ExpectedWarnings.end(),
+ "Warnings seen but not expected:");
+
+ return HadProblem;
+}
Propchange: cfe/cfe/trunk/Driver/DiagChecker.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/Driver/DiagChecker.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: cfe/cfe/trunk/Driver/DiagChecker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/DiagChecker.h?rev=39678&view=auto
==============================================================================
--- cfe/cfe/trunk/Driver/DiagChecker.h (added)
+++ cfe/cfe/trunk/Driver/DiagChecker.h Wed Jul 11 11:47:03 2007
@@ -0,0 +1,42 @@
+//===--- LLVMDiagChecker.h - Diagnostic Checking Functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Check diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DRIVER_LLVM_DIAG_CHECKER_H_
+#define DRIVER_LLVM_DIAG_CHECKER_H_
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class SourceLocation;
+class SourceManager;
+class TextDiagnosticBuffer;
+
+typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
+
+void ProcessFileDiagnosticChecking(TextDiagnosticBuffer &DiagClient,
+ Preprocessor &PP, const std::string &InFile,
+ SourceManager &SourceMgr,
+ unsigned MainFileID,
+ DiagList &ExpectedErrors,
+ DiagList &ExpectedWarnings);
+bool ReportCheckingResults(TextDiagnosticBuffer &DiagClient,
+ const DiagList &ExpectedErrors,
+ const DiagList &ExpectedWarnings,
+ SourceManager &SourceMgr);
+
+} // end clang namespace
+
+#endif
Propchange: cfe/cfe/trunk/Driver/DiagChecker.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/Driver/DiagChecker.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp?rev=39678&view=auto
==============================================================================
--- cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp (added)
+++ cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp Wed Jul 11 11:47:03 2007
@@ -0,0 +1,38 @@
+//===--- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TextDiagnosticBuffer.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+
+/// HandleDiagnostic - Store the errors & warnings that are reported.
+///
+void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level,
+ SourceLocation Pos,
+ diag::kind ID,
+ const std::string *Strs,
+ unsigned NumStrs,
+ const SourceRange *,
+ unsigned) {
+ switch (Level) {
+ default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
+ case Diagnostic::Warning:
+ Warnings.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs,
+ NumStrs)));
+ break;
+ case Diagnostic::Error:
+ Errors.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs,
+ NumStrs)));
+ break;
+ }
+}
Propchange: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h?rev=39678&view=auto
==============================================================================
--- cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h (added)
+++ cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h Wed Jul 11 11:47:03 2007
@@ -0,0 +1,57 @@
+//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
+#define DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
+
+#include "TextDiagnostics.h"
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class SourceManager;
+
+class TextDiagnosticBuffer : public TextDiagnostics {
+public:
+ typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
+ typedef DiagList::iterator iterator;
+ typedef DiagList::const_iterator const_iterator;
+private:
+ DiagList Errors;
+ DiagList Warnings;
+public:
+ TextDiagnosticBuffer(SourceManager &sourceMgr)
+ : TextDiagnostics(sourceMgr) {}
+
+ iterator err_begin() { return Errors.begin(); }
+ iterator err_end() { return Errors.end(); }
+ const_iterator err_begin() const { return Errors.begin(); }
+ const_iterator err_end() const { return Errors.end(); }
+
+ iterator warn_begin() { return Warnings.begin(); }
+ iterator warn_end() { return Warnings.end(); }
+ const_iterator warn_begin() const { return Warnings.begin(); }
+ const_iterator warn_end() const { return Warnings.end(); }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ SourceLocation Pos,
+ diag::kind ID, const std::string *Strs,
+ unsigned NumStrs,
+ const SourceRange *Ranges,
+ unsigned NumRanges);
+};
+
+} // end namspace clang
+
+#endif
Propchange: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/Driver/TextDiagnosticBuffer.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: cfe/cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/clang.cpp?rev=39678&r1=39677&r2=39678&view=diff
==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:47:03 2007
@@ -24,6 +24,8 @@
#include "clang.h"
#include "ASTStreamers.h"
+#include "LLVMDiagChecker.h"
+#include "TextDiagnosticBuffer.h"
#include "TextDiagnosticPrinter.h"
#include "clang/Parse/Parser.h"
#include "clang/Lex/HeaderSearch.h"
@@ -47,6 +49,7 @@
enum ProgActions {
EmitLLVM, // Emit a .ll file.
ParseASTPrint, // Parse ASTs and print them.
+ ParseASTCheck, // Parse ASTs and check diagnostics.
ParseAST, // Parse ASTs.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
@@ -76,6 +79,8 @@
"Run parser and build ASTs"),
clEnumValN(ParseASTPrint, "parse-ast-print",
"Run parser, build ASTs, then print ASTs"),
+ clEnumValN(ParseASTCheck, "parse-ast-check",
+ "Run parser, build ASTs, then check diagnostics"),
clEnumValN(EmitLLVM, "emit-llvm",
"Build ASTs then convert to LLVM, emit .ll file"),
clEnumValEnd));
@@ -756,6 +761,9 @@
HeaderSearch &HeaderInfo,
const LangOptions &LangInfo) {
switch (ProgAction) {
+ default:
+ fprintf(stderr, "Unexpected program action!\n");
+ return;
case DumpTokens: { // Token dump mode.
LexerToken Tok;
// Start parsing the specified input file.
@@ -807,35 +815,19 @@
HeaderInfo.PrintStats();
fprintf(stderr, "\n");
}
-
- HeaderInfo.ClearFileInfo();
}
static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
-int main(int argc, char **argv) {
- llvm::cl::ParseCommandLineOptions(argc, argv, " llvm cfe\n");
- llvm::sys::PrintStackTraceOnErrorSignal();
-
- // If no input was specified, read from stdin.
- if (InputFilenames.empty())
- InputFilenames.push_back("-");
-
- /// Create a SourceManager object. This tracks and owns all the file buffers
- /// allocated to the program.
- SourceManager SourceMgr;
-
- // Create a file manager object to provide access to and cache the filesystem.
- FileManager FileMgr;
-
- // Initialize language options, inferring file types from input filenames.
- // FIXME: This infers info from the first file, we should clump by language
- // to handle 'x.c y.c a.cpp b.cpp'.
- LangOptions LangInfo;
- InitializeBaseLanguage(LangInfo, InputFilenames[0]);
- InitializeLanguageStandard(LangInfo);
-
+/// PerformNormalFileProcessing - This processes each file in turn, printing out
+/// the diagnostic messages to stderr. It returns a pair: number of diagnostic
+/// messages, number of errors.
+///
+static std::pair<unsigned, unsigned>
+PerformNormalFileProcessing(SourceManager &SourceMgr,
+ FileManager &FileMgr,
+ LangOptions &LangInfo) {
// Print diagnostics to stderr.
TextDiagnosticPrinter OurDiagnosticClient(SourceMgr);
@@ -850,7 +842,7 @@
if (Target == 0) {
fprintf(stderr,
"Sorry, don't know what target this is, please use -arch.\n");
- return 1;
+ exit(1);
}
// Process the -I options and set them in the HeaderInfo.
@@ -870,12 +862,103 @@
ProcessInputFile(PP, MainFileID, InFile, SourceMgr,
OurDiagnosticClient, HeaderInfo, LangInfo);
+ HeaderInfo.ClearFileInfo();
}
unsigned NumDiagnostics = Diags.getNumDiagnostics();
+
if (NumDiagnostics)
fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
(NumDiagnostics == 1 ? "" : "s"));
+
+ return std::make_pair(Diags.getNumDiagnostics(), Diags.getNumErrors());
+}
+
+/// PerformDiagnosticChecking - This processes each file in turn, checking that
+/// each diagnostic message is expect.
+///
+static std::pair<unsigned, unsigned>
+PerformDiagnosticChecking(SourceManager &SourceMgr,
+ FileManager &FileMgr,
+ LangOptions &LangInfo) {
+ // Check diagnostic messages.
+ TextDiagnosticBuffer OurDiagnosticClient(SourceMgr);
+
+ // Configure our handling of diagnostics.
+ Diagnostic Diags(OurDiagnosticClient);
+ InitializeDiagnostics(Diags);
+
+ // Get information about the targets being compiled for. Note that this
+ // pointer and the TargetInfoImpl objects are never deleted by this toy
+ // driver.
+ TargetInfo *Target = CreateTargetInfo(Diags);
+ if (Target == 0) {
+ fprintf(stderr,
+ "Sorry, don't know what target this is, please use -arch.\n");
+ exit(1);
+ }
+
+ // Process the -I options and set them in the HeaderInfo.
+ HeaderSearch HeaderInfo(FileMgr);
+ OurDiagnosticClient.setHeaderSearch(HeaderInfo);
+ InitializeIncludePaths(HeaderInfo, FileMgr, Diags, LangInfo);
+
+ DiagList ExpectedErrors;
+ DiagList ExpectedWarnings;
+
+ for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
+ // Set up the preprocessor with these options.
+ Preprocessor PP(Diags, LangInfo, *Target, SourceMgr, HeaderInfo);
+ OurDiagnosticClient.setPreprocessor(PP);
+ const std::string &InFile = InputFilenames[i];
+ unsigned MainFileID = InitializePreprocessor(PP, InFile, SourceMgr,
+ HeaderInfo, LangInfo);
+
+ if (!MainFileID) continue;
+
+ ProcessFileDiagnosticChecking(OurDiagnosticClient, PP, InFile,
+ SourceMgr, MainFileID, ExpectedErrors,
+ ExpectedWarnings);
+ HeaderInfo.ClearFileInfo();
+ }
+
+ if (ReportCheckingResults(OurDiagnosticClient, ExpectedErrors,
+ ExpectedWarnings, SourceMgr))
+ // There were errors. Fake it.
+ return std::make_pair(1, 1);
+
+ return std::make_pair(0, 0);
+}
+
+int main(int argc, char **argv) {
+ llvm::cl::ParseCommandLineOptions(argc, argv, " llvm cfe\n");
+ llvm::sys::PrintStackTraceOnErrorSignal();
+
+ // If no input was specified, read from stdin.
+ if (InputFilenames.empty())
+ InputFilenames.push_back("-");
+
+ /// Create a SourceManager object. This tracks and owns all the file buffers
+ /// allocated to the program.
+ SourceManager SourceMgr;
+
+ // Create a file manager object to provide access to and cache the filesystem.
+ FileManager FileMgr;
+
+ // Initialize language options, inferring file types from input filenames.
+ // FIXME: This infers info from the first file, we should clump by language
+ // to handle 'x.c y.c a.cpp b.cpp'.
+ LangOptions LangInfo;
+ InitializeBaseLanguage(LangInfo, InputFilenames[0]);
+ InitializeLanguageStandard(LangInfo);
+
+ // Pair to represent the number of diagnostics and number of errors emitted.
+ std::pair<unsigned, unsigned> NumDiagsOutput = std::make_pair(0, 0);
+
+ if (ProgAction != ParseASTCheck)
+ NumDiagsOutput = PerformNormalFileProcessing(SourceMgr, FileMgr, LangInfo);
+ else
+ NumDiagsOutput = PerformDiagnosticChecking(SourceMgr, FileMgr, LangInfo);
if (Stats) {
// Printed from high-to-low level.
@@ -884,5 +967,5 @@
fprintf(stderr, "\n");
}
- return Diags.getNumErrors() != 0;
+ return NumDiagsOutput.second != 0;
}
More information about the cfe-commits
mailing list