00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_BASIC_DIAGNOSTIC_HDR_GUARD
00010 #define COMMA_BASIC_DIAGNOSTIC_HDR_GUARD
00011 
00012 #include "comma/basic/IdentifierInfo.h"
00013 #include "comma/basic/Location.h"
00014 #include "comma/basic/ParameterModes.h"
00015 
00016 #include "llvm/Support/raw_ostream.h"
00017 
00018 namespace comma {
00019 
00020 namespace diag {
00021 
00022 enum Kind {
00023 #define DIAGNOSTIC(ENUM, KIND, FORMAT) ENUM,
00024 #include "comma/basic/Diagnostic.def"
00025 #undef DIAGNOSTIC
00026 
00027     LAST_UNUSED_DIAGNOSTIC_KIND
00028 };
00029 
00031 enum Type {
00032     ERROR,             
00033     WARNING,           
00034     NOTE               
00035 };
00036 
00037 } 
00038 
00043 class DiagnosticComponent {
00044 
00045 public:
00046     virtual ~DiagnosticComponent() { }
00047 
00049     virtual void print(llvm::raw_ostream &stream) const = 0;
00050 };
00051 
00052 class DiagnosticStream {
00053 
00054 public:
00055     DiagnosticStream(llvm::raw_ostream &stream);
00056 
00057     ~DiagnosticStream();
00058 
00059     DiagnosticStream &initialize(const SourceLocation &sloc, const char *format,
00060                                  diag::Type type);
00061 
00062     DiagnosticStream &operator<<(const std::string &string);
00063 
00064     DiagnosticStream &operator<<(const char *string);
00065 
00066     DiagnosticStream &operator<<(int n);
00067 
00068     DiagnosticStream &operator<<(char c);
00069 
00070     DiagnosticStream &operator<<(const SourceLocation &sloc);
00071 
00072     DiagnosticStream &operator<<(const IdentifierInfo *idInfo);
00073 
00074     DiagnosticStream &operator<<(PM::ParameterMode mode);
00075 
00076     DiagnosticStream &operator<<(const DiagnosticComponent &component);
00077 
00078 private:
00079     void emitFormatComponent();
00080 
00081     void emitSourceLocation(const SourceLocation &sloc);
00082 
00083     void emitDiagnosticType(diag::Type type);
00084 
00085     llvm::raw_ostream &stream;
00086     unsigned position;
00087     std::string buffer;
00088     llvm::raw_string_ostream message;
00089     SourceLocation sourceLoc;
00090     const char *format;
00091     diag::Type type;
00092 };
00093 
00094 class Diagnostic {
00095 
00096 public:
00099     Diagnostic() :
00100         diagstream(llvm::errs()),
00101         errorCount(0), warningCount(0), noteCount(0) { }
00102 
00105     Diagnostic(llvm::raw_ostream &stream) : diagstream(stream) { }
00106 
00109     DiagnosticStream &report(const SourceLocation &loc, diag::Kind kind);
00110 
00112     const char *getFormat(diag::Kind kind);
00113 
00115     diag::Type getType(diag::Kind kind);
00116 
00118     bool reportsGenerated() { return numReports() != 0; }
00119 
00121     unsigned numReports() const {
00122         return errorCount + warningCount + noteCount;
00123     }
00124 
00126     unsigned numErrors() const { return errorCount; }
00127 
00129     unsigned numWarnings() const { return warningCount; }
00130 
00132     unsigned numNotes() const { return noteCount; }
00133 
00134 private:
00135     DiagnosticStream diagstream;
00136 
00137     unsigned errorCount;
00138     unsigned warningCount;
00139     unsigned noteCount;
00140 
00141     static void initializeMessages();
00142 
00143     struct DiagInfo {
00144         const char *format;
00145         diag::Type type;
00146     };
00147 
00148     static const DiagInfo diagnostics[diag::LAST_UNUSED_DIAGNOSTIC_KIND];
00149 };
00150 
00151 } 
00152 
00153 #endif