浏览代码

HPCC-11516 Extract errors from compile logs and add to workunit

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 10 年之前
父节点
当前提交
f169371fb8

+ 1 - 0
ecl/eclcc/eclcc.cpp

@@ -2193,6 +2193,7 @@ const char * const helpText[] = {
     "! -fmaxCompileThreads     Number of compiler instances to compile the c++",
     "! -fnoteRecordSizeInGraph Add estimates of record sizes to the graph",
     "! -fpickBestEngine        Allow simple thor queries to be passed to thor",
+    "! -freportCppWarnings     Report warnings from c++ compilation",
     "! -fsaveCppTempFiles      Retain the generated c++ files",
     "! -fshowActivitySizeInGraph Show estimates of generated c++ size in the graph",
     "! -fshowMetaInGraph       Add distribution/sort orders to the graph",

+ 22 - 85
ecl/hql/hqlerror.cpp

@@ -79,6 +79,8 @@ WarnErrorCategory getCategory(const char * category)
         return CategoryUnusual;
     if (strieq(category, "unexpected"))
         return CategoryUnexpected;
+    if (strieq(category, "cpp"))
+        return CategoryCpp;
     return CategoryUnknown;
 }
 
@@ -89,89 +91,24 @@ ErrorSeverity getCheckSeverity(IAtom * name)
     return severity;
 }
 
-
-//---------------------------------------------------------------------------------------------------------------------
-
-class HQL_API CECLError : public CInterfaceOf<IECLError>
-{
-public:
-    CECLError(WarnErrorCategory _category,ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position);
-
-    virtual int             errorCode() const { return no; }
-    virtual StringBuffer &  errorMessage(StringBuffer & ret) const { return ret.append(msg); }
-    virtual MessageAudience errorAudience() const { return MSGAUD_user; }
-    virtual const char* getFilename() const { return filename; }
-    virtual WarnErrorCategory getCategory() const { return category; }
-    virtual int getLine() const { return lineno; }
-    virtual int getColumn() const { return column; }
-    virtual int getPosition() const { return position; }
-    virtual StringBuffer& toString(StringBuffer&) const;
-    virtual ErrorSeverity getSeverity() const { return severity; }
-    virtual IECLError * cloneSetSeverity(ErrorSeverity _severity) const;
-
-protected:
-    ErrorSeverity severity;
-    WarnErrorCategory category;
-    int no;
-    StringAttr msg;
-    StringAttr filename;
-    int lineno;
-    int column;
-    int position;
-};
-
-CECLError::CECLError(WarnErrorCategory _category, ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position):
-  category(_category),severity(_severity), msg(_msg), filename(_filename)
-{
-    no = _no;
-    lineno = _lineno;
-    column = _column;
-    position = _position;
-}
-
-
-StringBuffer& CECLError::toString(StringBuffer& buf) const
-{
-    buf.append(filename);
-
-    if(lineno && column)
-        buf.append('(').append(lineno).append(',').append(column).append(')');
-    buf.append(" : ");
-
-    buf.append(no).append(": ").append(msg);
-    return buf;
-}
-
-IECLError * CECLError::cloneSetSeverity(ErrorSeverity newSeverity) const
-{
-    return new CECLError(category, newSeverity,
-                         errorCode(), msg, filename,
-                         getLine(), getColumn(), getPosition());
-}
-
-extern HQL_API IECLError *createECLError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char * filename, int lineno, int column, int pos)
-{
-    return new CECLError(category,severity,errNo,msg,filename,lineno,column,pos);
-}
-
 //---------------------------------------------------------------------------------------------------------------------
 
 void IErrorReceiver::reportError(int errNo, const char *msg, const char *filename, int lineno, int column, int position)
 {
-    Owned<IECLError> err = createECLError(errNo,msg,filename,lineno,column,position);
+    Owned<IError> err = createError(errNo,msg,filename,lineno,column,position);
     report(err);
 }
 
 void IErrorReceiver::reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int position)
 {
     ErrorSeverity severity = queryDefaultSeverity(category);
-    Owned<IECLError> warn = createECLError(category, severity,warnNo,msg,filename,lineno,column,position);
+    Owned<IError> warn = createError(category, severity,warnNo,msg,filename,lineno,column,position);
     report(warn);
 }
 
 //---------------------------------------------------------------------------------------------------------------------
 
-void ErrorReceiverSink::report(IECLError* error)
+void ErrorReceiverSink::report(IError* error)
 {
     switch (error->getSeverity())
     {
@@ -189,7 +126,7 @@ void ErrorReceiverSink::report(IECLError* error)
 
 
 
-void MultiErrorReceiver::report(IECLError* error)
+void MultiErrorReceiver::report(IError* error)
 {
     ErrorReceiverSink::report(error);
 
@@ -203,25 +140,25 @@ StringBuffer& MultiErrorReceiver::toString(StringBuffer& buf)
 {
     ForEachItemIn(i, msgs)
     {
-        IECLError* error=item(i);
+        IError* error=item(i);
         error->toString(buf);
         buf.append('\n');
     }
     return buf;
 }
 
-IECLError *MultiErrorReceiver::firstError()
+IError *MultiErrorReceiver::firstError()
 {
     ForEachItemIn(i, msgs)
     {
-        IECLError* error = item(i);
+        IError* error = item(i);
         if (isError(error->getSeverity()))
             return error;
     }
     return NULL;
 }
 
-extern HQL_API void reportErrors(IErrorReceiver & receiver, IECLErrorArray & errors)
+extern HQL_API void reportErrors(IErrorReceiver & receiver, IErrorArray & errors)
 {
     ForEachItemIn(i, errors)
         receiver.report(&errors.item(i));
@@ -237,7 +174,7 @@ public:
         f = _f;
     }
 
-    virtual void report(IECLError* error)
+    virtual void report(IError* error)
     {
         ErrorReceiverSink::report(error);
 
@@ -286,10 +223,10 @@ extern HQL_API IErrorReceiver *createFileErrorReceiver(FILE *f)
 
 class HQL_API ThrowingErrorReceiver : public ErrorReceiverSink
 {
-    virtual void report(IECLError* error);
+    virtual void report(IError* error);
 };
 
-void ThrowingErrorReceiver::report(IECLError* error)
+void ThrowingErrorReceiver::report(IError* error)
 {
     throw error;
 }
@@ -320,7 +257,7 @@ void reportErrorVa(IErrorReceiver * errors, int errNo, const ECLlocation & loc,
     if (errors)
         errors->reportError(errNo, msg.str(), loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
     else
-        throw createECLError(errNo, msg.str(), loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
+        throw createError(errNo, msg.str(), loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
 }
 
 void reportError(IErrorReceiver * errors, int errNo, const ECLlocation & loc, const char * format, ...)
@@ -335,9 +272,9 @@ void reportError(IErrorReceiver * errors, int errNo, const ECLlocation & loc, co
 class ErrorInserter : public IndirectErrorReceiver
 {
 public:
-    ErrorInserter(IErrorReceiver & _prev, IECLError * _error) : IndirectErrorReceiver(_prev), error(_error) {}
+    ErrorInserter(IErrorReceiver & _prev, IError * _error) : IndirectErrorReceiver(_prev), error(_error) {}
 
-    virtual void report(IECLError* error)
+    virtual void report(IError* error)
     {
         if (isError(error->getSeverity()))
             flush();
@@ -355,7 +292,7 @@ protected:
     }
 
 protected:
-    Linked<IECLError> error;
+    Linked<IError> error;
 };
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -365,9 +302,9 @@ class AbortingErrorReceiver : public IndirectErrorReceiver
 public:
     AbortingErrorReceiver(IErrorReceiver & _prev) : IndirectErrorReceiver(_prev) {}
 
-    virtual void report(IECLError* error)
+    virtual void report(IError* error)
     {
-        Owned<IECLError> mappedError = prevErrorProcessor->mapError(error);
+        Owned<IError> mappedError = prevErrorProcessor->mapError(error);
         prevErrorProcessor->report(mappedError);
         if (isError(mappedError->getSeverity()))
             throw MakeStringExceptionDirect(HQLERR_ErrorAlreadyReported, "");
@@ -386,7 +323,7 @@ class DedupingErrorReceiver : public IndirectErrorReceiver
 public:
     DedupingErrorReceiver(IErrorReceiver & _prev) : IndirectErrorReceiver(_prev) {}
 
-    virtual void report(IECLError* error)
+    virtual void report(IError* error)
     {
         if (errors.contains(*error))
             return;
@@ -420,14 +357,14 @@ void checkEclVersionCompatible(Shared<IErrorReceiver> & errors, const char * ecl
             else if (minor != LANGUAGE_VERSION_MINOR)
             {
                 VStringBuffer msg("Mismatch in minor version number (%s v %s)", eclVersion, LANGUAGE_VERSION);
-                Owned<IECLError> warning = createECLError(CategoryUnexpected, SeverityInfo, HQLERR_VersionMismatch, msg.str(), NULL, 0, 0);
+                Owned<IError> warning = createError(CategoryUnexpected, SeverityInfo, HQLERR_VersionMismatch, msg.str(), NULL, 0, 0);
                 errors.setown(new ErrorInserter(*errors, warning));
             }
             else if (subminor != LANGUAGE_VERSION_SUB)
             {
                 //This adds the warning if any other warnings occur.
                 VStringBuffer msg("Mismatch in subminor version number (%s v %s)", eclVersion, LANGUAGE_VERSION);
-                Owned<IECLError> warning = createECLError(CategoryUnexpected, SeverityInfo, HQLERR_VersionMismatch, msg.str(), NULL, 0, 0);
+                Owned<IError> warning = createError(CategoryUnexpected, SeverityInfo, HQLERR_VersionMismatch, msg.str(), NULL, 0, 0);
                 errors.setown(new ErrorInserter(*errors, warning));
             }
         }

+ 14 - 68
ecl/hql/hqlerror.hpp

@@ -23,63 +23,10 @@
 
 #define HQLERR_ErrorAlreadyReported             4799            // special case...
 
-enum ErrorSeverity
-{
-    SeverityIgnore,
-    SeverityInfo,
-    SeverityWarning,
-    SeverityError,    // a warning treated as an error
-    SeverityFatal,      // a fatal error - can't be mapped to anything else
-    SeverityUnknown,
-};
-
-inline bool isError(ErrorSeverity severity) { return severity >= SeverityError; }
-inline bool isFatal(ErrorSeverity severity) { return severity == SeverityFatal; }
-
-//TBD in a separate commit - add support for warnings to be associated with different categories
-enum WarnErrorCategory
-{
-    CategoryInformation,// Some kind of information [default severity information]
-
-    CategoryCast,       // Suspicious casts between types or out of range values
-    CategoryConfuse,    // Likely to cause confusion
-    CategoryDeprecated, // deprecated features or syntax
-    CategoryEfficiency, // Something that is likely to be inefficient
-    CategoryFolding,    // Unusual results from constant folding
-    CategoryFuture,     // Likely to cause problems in future versions
-    CategoryIgnored,    // Something that has no effect, or is ignored
-    CategoryIndex,      // Unusual indexing of datasets or strings
-    CategoryMistake,    // Almost certainly a mistake
-    CategoryLimit,      // An operation that should really have some limits to protect data runaway
-    CategorySyntax,     // Invalid syntax which is painless to recover from
-    CategoryUnusual,    // Not strictly speaking an error, but highly unusual and likely to be a mistake
-    CategoryUnexpected, // Code that could be correct, but has the potential for unexpected behaviour
-
-    CategoryError,      // Typically severity fatal
-    CategoryAll,
-    CategoryUnknown,
-    CategoryMax,
-};
-
-interface HQL_API IECLError: public IException
-{
-public:
-    virtual const char* getFilename() const = 0;
-    virtual WarnErrorCategory getCategory() const = 0;
-    virtual int getLine() const = 0;
-    virtual int getColumn() const = 0;
-    virtual int getPosition() const = 0;
-    virtual StringBuffer& toString(StringBuffer&) const = 0;
-    virtual ErrorSeverity getSeverity() const = 0;
-    virtual IECLError * cloneSetSeverity(ErrorSeverity _severity) const = 0;
-};
-inline bool isError(IECLError * error) { return isError(error->getSeverity()); }
-inline bool isFatal(IECLError * error) { return isFatal(error->getSeverity()); }
-
 interface HQL_API IErrorReceiver : public IInterface
 {
-    virtual void report(IECLError* error) = 0;
-    virtual IECLError * mapError(IECLError * error) = 0;
+    virtual void report(IError* error) = 0;
+    virtual IError * mapError(IError * error) = 0;
     virtual size32_t errCount() = 0;
     virtual size32_t warnCount() = 0;
 
@@ -88,7 +35,7 @@ interface HQL_API IErrorReceiver : public IInterface
     void reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos);
 };
 
-typedef IArrayOf<IECLError> IECLErrorArray;
+typedef IArrayOf<IError> IErrorArray;
 
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -98,8 +45,8 @@ class HQL_API ErrorReceiverSink : public CInterfaceOf<IErrorReceiver>
 public:
     ErrorReceiverSink() { errs = warns = 0; }
 
-    virtual IECLError * mapError(IECLError * error) { return LINK(error); }
-    virtual void report(IECLError* err);
+    virtual IError * mapError(IError * error) { return LINK(error); }
+    virtual void report(IError* err);
     virtual size32_t errCount() { return errs; }
     virtual size32_t warnCount() { return warns; }
 
@@ -115,11 +62,11 @@ class IndirectErrorReceiver : public CInterfaceOf<IErrorReceiver>
 public:
     IndirectErrorReceiver(IErrorReceiver & _prev) : prevErrorProcessor(&_prev) {}
 
-    virtual void report(IECLError* error)
+    virtual void report(IError* error)
     {
         prevErrorProcessor->report(error);
     }
-    virtual IECLError * mapError(IECLError * error)
+    virtual IError * mapError(IError * error)
     {
         return prevErrorProcessor->mapError(error);
     }
@@ -143,16 +90,16 @@ class HQL_API MultiErrorReceiver : public ErrorReceiverSink
 public:
     MultiErrorReceiver() {}
 
-    virtual void report(IECLError* err);
+    virtual void report(IError* err);
 
     size32_t length() { return errCount() + warnCount();}
-    IECLError* item(size32_t index) { return &msgs.item(index); }
-    IECLError* firstError();
+    IError* item(size32_t index) { return &msgs.item(index); }
+    IError* firstError();
     StringBuffer& toString(StringBuffer& out);
     void clear() { msgs.kill(); }
 
 private:
-    IECLErrorArray msgs;
+    IErrorArray msgs;
 };
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -164,12 +111,11 @@ extern HQL_API ErrorSeverity getCheckSeverity(IAtom * name);
 
 //---------------------------------------------------------------------------------------------------------------------
 
-extern HQL_API IECLError *createECLError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0);
-inline IECLError * createECLError(int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0)
+inline IError * createError(int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0)
 {
-    return createECLError(CategoryError, SeverityFatal, errNo, msg, filename, lineno, column, pos);
+    return createError(CategoryError, SeverityFatal, errNo, msg, filename, lineno, column, pos);
 }
-extern HQL_API void reportErrors(IErrorReceiver & receiver, IECLErrorArray & errors);
+extern HQL_API void reportErrors(IErrorReceiver & receiver, IErrorArray & errors);
 void HQL_API reportErrorVa(IErrorReceiver * errors, int errNo, const ECLlocation & loc, const char* format, va_list args);
 void HQL_API reportError(IErrorReceiver * errors, int errNo, const ECLlocation & loc, const char * format, ...) __attribute__((format(printf, 4, 5)));
 

+ 2 - 0
ecl/hql/hqlerrors.hpp

@@ -429,6 +429,8 @@
 #define ERR_INDEX_DEPEND_DATASET    2396
 #define ERR_DUBIOUS_NAME            2397
 
+#define ERR_CPP_COMPILE_ERROR       2999
+
 #define ERR_ASSERTION_FAILS         100000
 
 /* general error types */

+ 8 - 8
ecl/hql/hqlexpr.cpp

@@ -7194,7 +7194,7 @@ bool isImport(IHqlExpression * expr)
     return symbol && ((symbol->getSymbolFlags() & ob_import) != 0);
 }
 
-IECLError * queryAnnotatedWarning(const IHqlExpression * expr)
+IError * queryAnnotatedWarning(const IHqlExpression * expr)
 {
     assertex(expr->getAnnotationKind() == annotate_warning);
     const CHqlWarningAnnotation * cast = static_cast<const CHqlWarningAnnotation *>(expr);
@@ -7424,7 +7424,7 @@ bool CHqlAnnotationExtraBase::equals(const IHqlExpression & other) const
 //  if (!areMatchingPTrees(doc, cast->doc))
 //      return false;
 
-CHqlWarningAnnotation::CHqlWarningAnnotation(IHqlExpression *_body, IECLError * _ownedWarning)
+CHqlWarningAnnotation::CHqlWarningAnnotation(IHqlExpression *_body, IError * _ownedWarning)
 : CHqlAnnotationExtraBase(_body, _ownedWarning)
 {
 }
@@ -7436,12 +7436,12 @@ IHqlExpression * CHqlWarningAnnotation::cloneAnnotation(IHqlExpression * newbody
     return createWarningAnnotation(LINK(newbody), LINK(queryWarning()));
 }
 
-IHqlExpression * CHqlWarningAnnotation::createWarningAnnotation(IHqlExpression * _ownedBody, IECLError * _ownedWarning)
+IHqlExpression * CHqlWarningAnnotation::createWarningAnnotation(IHqlExpression * _ownedBody, IError * _ownedWarning)
 {
     return (new CHqlWarningAnnotation(_ownedBody, _ownedWarning))->closeExpr();
 }
 
-IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IECLError * _ownedWarning)
+IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IError * _ownedWarning)
 {
     return CHqlWarningAnnotation::createWarningAnnotation(_ownedBody, _ownedWarning);
 }
@@ -7919,7 +7919,7 @@ void CHqlScope::throwRecursiveError(IIdAtom * searchName)
 
     StringBuffer msg("Definition of ");
     msg.append(*searchName).append(" contains a recursive dependency");
-    throw createECLError(ERR_RECURSIVE_DEPENDENCY, msg.toCharArray(), filename, 0, 0, 1);
+    throw createError(ERR_RECURSIVE_DEPENDENCY, msg.toCharArray(), filename, 0, 0, 1);
 }
 
 inline bool namesMatch(const char * lName, const char * rName)
@@ -8114,7 +8114,7 @@ IHqlExpression *CHqlRemoteScope::lookupSymbol(IIdAtom * searchName, unsigned loo
     {
         StringBuffer msg("Definition for ");
         msg.append(*searchName).append(" contains no text");
-        throw createECLError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, 0, 0, 1);
+        throw createError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, 0, 0, 1);
     }
 
     OwnedHqlExpr recursionGuard = createSymbol(searchName, LINK(processingMarker), ob_exported);
@@ -8140,7 +8140,7 @@ IHqlExpression *CHqlRemoteScope::lookupSymbol(IIdAtom * searchName, unsigned loo
             resolved->removeSymbol(searchName);
         StringBuffer msg("Definition must contain EXPORT or SHARED value for ");
         msg.append(*searchName);
-        throw createECLError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, 0, 0, 1);
+        throw createError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, 0, 0, 1);
     }
 
     //Preserve ob_sandbox etc. annotated on the original definition, but not on the parsed code.
@@ -9313,7 +9313,7 @@ IHqlExpression *CHqlForwardScope::lookupSymbol(IIdAtom * searchName, unsigned lo
         const char * filename = parentCtx->sourcePath->str();
         StringBuffer msg("Definition must contain EXPORT or SHARED value for ");
         msg.append(*searchName);
-        throw createECLError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, oldSymbol->getStartLine(), oldSymbol->getStartColumn(), 1);
+        throw createError(ERR_EXPORT_OR_SHARE, msg.toCharArray(), filename, oldSymbol->getStartLine(), oldSymbol->getStartColumn(), 1);
     }
 
     if (!(newSymbol->isExported() || (lookupFlags & LSFsharedOK)))

+ 3 - 3
ecl/hql/hqlexpr.hpp

@@ -910,7 +910,7 @@ public:
     Owned<IPropertyTree> nestedDependTree;
     Owned<IPropertyTree> globalDependTree;
     Owned<IPropertyTree> metaTree;
-    IECLErrorArray orphanedWarnings;
+    IErrorArray orphanedWarnings;
     HqlExprArray defaultFunctionCache;
     CIArrayOf<ForwardScopeItem> forwardLinks;
     bool expandCallsWhenBound;
@@ -1310,7 +1310,7 @@ extern HQL_API IHqlExpression * createLocationAnnotation(IHqlExpression * _owned
 extern HQL_API IHqlExpression * createLocationAnnotation(IHqlExpression * ownedBody, ISourcePath * sourcePath, int lineno, int column);
 extern HQL_API IHqlExpression * createMetaAnnotation(IHqlExpression * _ownedBody, HqlExprArray & _args);
 extern HQL_API IHqlExpression * createParseMetaAnnotation(IHqlExpression * _ownedBody, HqlExprArray & _args);
-extern HQL_API IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IECLError * _ownedWarning);
+extern HQL_API IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IError * _ownedWarning);
 extern HQL_API IHqlExpression * createJavadocAnnotation(IHqlExpression * _ownedBody, IPropertyTree * _doc);
 
 extern HQL_API IHqlExpression * createCompound(IHqlExpression * expr1, IHqlExpression * expr2);
@@ -1604,7 +1604,7 @@ extern HQL_API bool isShared(IHqlExpression * expr);
 extern HQL_API bool isImport(IHqlExpression * expr);
 extern HQL_API bool isVirtualSymbol(IHqlExpression * expr);
 
-extern HQL_API IECLError * queryAnnotatedWarning(const IHqlExpression * expr);
+extern HQL_API IError * queryAnnotatedWarning(const IHqlExpression * expr);
 
 extern HQL_API bool isPublicSymbol(IHqlExpression * expr);
 extern HQL_API ITypeInfo * getSumAggType(IHqlExpression * arg);

+ 3 - 3
ecl/hql/hqlexpr.ipp

@@ -745,14 +745,14 @@ protected:
 class HQL_API CHqlWarningAnnotation: public CHqlAnnotationExtraBase
 {
 public:
-    static IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IECLError * _ownedWarning);
+    static IHqlExpression * createWarningAnnotation(IHqlExpression * _ownedBody, IError * _ownedWarning);
     virtual annotate_kind getAnnotationKind() const { return annotate_warning; }
     virtual IHqlExpression * cloneAnnotation(IHqlExpression * body);
 
-    inline IECLError * queryWarning() const { return static_cast<IECLError *>(extra.get()); }
+    inline IError * queryWarning() const { return static_cast<IError *>(extra.get()); }
 
 protected:
-    CHqlWarningAnnotation(IHqlExpression * _expr, IECLError * _ownedWarning);
+    CHqlWarningAnnotation(IHqlExpression * _expr, IError * _ownedWarning);
 };
 
 class HQL_API CHqlJavadocAnnotation: public CHqlAnnotationExtraBase

+ 4 - 4
ecl/hql/hqlgram.hpp

@@ -574,7 +574,7 @@ public:
     void doReportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos);
     void reportError(int errNo, const attribute& a, const char* format, ...) __attribute__((format(printf, 4, 5)));
     void reportError(int errNo, const ECLlocation & pos, const char* format, ...) __attribute__((format(printf, 4, 5)));
-    void reportMacroExpansionPosition(IECLError * warning, HqlLex * lexer);
+    void reportMacroExpansionPosition(IError * warning, HqlLex * lexer);
     void reportErrorUnexpectedX(const attribute & errpos, IAtom * unexpected);
 
     // Don't use overloading: va_list is the same as char*!!
@@ -588,8 +588,8 @@ public:
 
     // interface IErrorReceiver
     virtual void reportError(int errNo, const char *msg, const char *filename=NULL, int lineno=0, int column=0, int pos=0);
-    virtual void report(IECLError * error);
-    virtual IECLError * mapError(IECLError * error);
+    virtual void report(IError * error);
+    virtual IError * mapError(IError * error);
     void reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename=NULL, int lineno=0, int column=0, int pos=0);
     virtual size32_t errCount();
     virtual size32_t warnCount();
@@ -846,7 +846,7 @@ protected:
     bool expandingMacroPosition;
     unsigned m_maxErrorsAllowed;
 
-    IECLErrorArray pendingWarnings;
+    IErrorArray pendingWarnings;
     Linked<ISourcePath> sourcePath;
     IIdAtom * moduleName;
     IIdAtom * current_id;

+ 14 - 14
ecl/hql/hqlgram2.cpp

@@ -262,11 +262,11 @@ bool HqlGramCtx::hasAnyActiveParameters()
 }
 
 
-static IECLError * createErrorVA(WarnErrorCategory category, ErrorSeverity severity, int errNo, const ECLlocation & pos, const char* format, va_list args)
+static IError * createErrorVA(WarnErrorCategory category, ErrorSeverity severity, int errNo, const ECLlocation & pos, const char* format, va_list args)
 {
     StringBuffer msg;
     msg.valist_appendf(format, args);
-    return createECLError(category, severity, errNo, msg.str(), pos.sourcePath->str(), pos.lineno, pos.column, pos.position);
+    return createError(category, severity, errNo, msg.str(), pos.sourcePath->str(), pos.lineno, pos.column, pos.position);
 }
 
 IHqlExpression * HqlGram::createSetRange(attribute & array, attribute & range)
@@ -3484,7 +3484,7 @@ IHqlExpression *HqlGram::lookupSymbol(IIdAtom * searchName, const attribute& err
         }
         return NULL;
     }
-    catch(IECLError* error)
+    catch(IError* error)
     {
         if(errorHandler && !errorDisabled)
             errorHandler->report(error);
@@ -5846,11 +5846,11 @@ void HqlGram::reportErrorUnexpectedX(const attribute& errpos, IAtom * unexpected
 
 void HqlGram::doReportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos)
 {
-    Owned<IECLError> error = createECLError(category, queryDefaultSeverity(category), warnNo, msg, filename, lineno, column, pos);
+    Owned<IError> error = createError(category, queryDefaultSeverity(category), warnNo, msg, filename, lineno, column, pos);
     report(error);
 }
 
-void HqlGram::reportMacroExpansionPosition(IECLError * warning, HqlLex * lexer)
+void HqlGram::reportMacroExpansionPosition(IError * warning, HqlLex * lexer)
 {
     if (expandingMacroPosition)
         return;
@@ -5873,7 +5873,7 @@ void HqlGram::reportMacroExpansionPosition(IECLError * warning, HqlLex * lexer)
 
 void HqlGram::reportErrorVa(int errNo, const ECLlocation & pos, const char* format, va_list args)
 {
-    Owned<IECLError> error = createErrorVA(CategoryError, SeverityFatal, errNo, pos, format, args);
+    Owned<IError> error = createErrorVA(CategoryError, SeverityFatal, errNo, pos, format, args);
     report(error);
 }
 
@@ -5881,7 +5881,7 @@ void HqlGram::reportError(int errNo, const char *msg, int lineno, int column, in
 {
     if (errorHandler && !errorDisabled)
     {
-        Owned<IECLError> error = createECLError(errNo, msg, lexObject->queryActualSourcePath()->str(), lineno, column, position);
+        Owned<IError> error = createError(errNo, msg, lexObject->queryActualSourcePath()->str(), lineno, column, position);
         report(error);
     }
 }
@@ -5892,7 +5892,7 @@ void HqlGram::reportWarning(WarnErrorCategory category, int warnNo, const ECLloc
     {
         va_list args;
         va_start(args, format);
-        Owned<IECLError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
+        Owned<IError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
         va_end(args);
 
         report(error);
@@ -5906,7 +5906,7 @@ void HqlGram::reportWarning(WarnErrorCategory category, ErrorSeverity severity,
         StringBuffer msg;
         va_list args;
         va_start(args, format);
-        Owned<IECLError> error = createErrorVA(category, severity, warnNo, pos, format, args);
+        Owned<IError> error = createErrorVA(category, severity, warnNo, pos, format, args);
         va_end(args);
 
         report(error);
@@ -5918,7 +5918,7 @@ void HqlGram::reportWarningVa(WarnErrorCategory category, int warnNo, const attr
     const ECLlocation & pos = a.pos;
     if (errorHandler && !errorDisabled)
     {
-        Owned<IECLError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
+        Owned<IError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
         report(error);
     }
 }
@@ -5933,16 +5933,16 @@ void HqlGram::reportWarning(WarnErrorCategory category, int warnNo, const char *
 //interface IErrorReceiver
 void HqlGram::reportError(int errNo, const char *msg, const char *filename, int lineno, int column, int position)
 {
-    Owned<IECLError> err = createECLError(errNo,msg,filename,lineno,column,position);
+    Owned<IError> err = createError(errNo,msg,filename,lineno,column,position);
     report(err);
 }
 
-IECLError * HqlGram::mapError(IECLError * error)
+IError * HqlGram::mapError(IError * error)
 {
     return errorHandler->mapError(error);
 }
 
-void HqlGram::report(IECLError* error)
+void HqlGram::report(IError* error)
 {
     if (errorHandler && !errorDisabled)
     {
@@ -9020,7 +9020,7 @@ IHqlExpression * HqlGram::associateSideEffects(IHqlExpression * expr, const ECLl
             {
                 if (expr->isScope())
                 {
-                    Owned<IECLError> error = createECLError(CategorySyntax, SeverityError, ERR_RESULT_IGNORED_SCOPE, "Cannot associate a side effect with a module - action will be lost", errpos.sourcePath->str(), errpos.lineno, errpos.column, errpos.position);
+                    Owned<IError> error = createError(CategorySyntax, SeverityError, ERR_RESULT_IGNORED_SCOPE, "Cannot associate a side effect with a module - action will be lost", errpos.sourcePath->str(), errpos.lineno, errpos.column, errpos.position);
                     //Unusual processing.  Create a warning and save it in the parse context
                     //The reason is that this error is reporting "the associated side-effects will be lost" - but
                     //the same will apply to the warning, and if it's lost there will be no way to report it later...

+ 2 - 2
ecl/hql/hqlir.cpp

@@ -842,7 +842,7 @@ public:
 public:
     exprid_t expr;
     const char * name;
-    IECLError * warning;
+    IError * warning;
     IPropertyTree * tree;
     unsigned value;
     unsigned line;
@@ -1327,7 +1327,7 @@ public:
             }
         case annotate_warning:
             {
-                IECLError * warning = info.warning;
+                IError * warning = info.warning;
                 StringBuffer msg;
                 warning->errorMessage(msg);
                 const char * filename = warning->getFilename();

+ 9 - 9
ecl/hql/hqlutil.cpp

@@ -5756,7 +5756,7 @@ void TempTableTransformer::reportError(IHqlExpression * location, int code,const
     va_start(args, format);
     errorMsg.valist_appendf(format, args);
     va_end(args);
-    Owned<IECLError> err = createECLError(code, errorMsg.str(), where->sourcePath->str(), where->lineno, where->column, where->position);
+    Owned<IError> err = createError(code, errorMsg.str(), where->sourcePath->str(), where->lineno, where->column, where->position);
     errorProcessor.report(err);
 }
 
@@ -6618,10 +6618,10 @@ void ErrorSeverityMapper::restoreState(const ErrorSeverityMapperState & saved)
     activeSymbol = saved.symbol;
 }
 
-IECLError * ErrorSeverityMapper::mapError(IECLError * error)
+IError * ErrorSeverityMapper::mapError(IError * error)
 {
     //An error that is fatal cannot be mapped.
-    Owned<IECLError> mappedError = IndirectErrorReceiver::mapError(error);
+    Owned<IError> mappedError = IndirectErrorReceiver::mapError(error);
     if (!isFatal(mappedError))
     {
         //This takes precedence over mappings in the parent
@@ -6697,8 +6697,8 @@ public:
             }
         case annotate_warning:
             {
-                IECLError * error = static_cast<CHqlWarningAnnotation *>(expr)->queryWarning();
-                Owned<IECLError> mappedError = mapper.mapError(error);
+                IError * error = static_cast<CHqlWarningAnnotation *>(expr)->queryWarning();
+                Owned<IError> mappedError = mapper.mapError(error);
                 mapper.report(mappedError);
                 break;
             }
@@ -6717,7 +6717,7 @@ protected:
 };
 
 
-void gatherParseWarnings(IErrorReceiver * errs, IHqlExpression * expr, IECLErrorArray & orphanedWarnings)
+void gatherParseWarnings(IErrorReceiver * errs, IHqlExpression * expr, IErrorArray & orphanedWarnings)
 {
     if (!errs || !expr)
         return;
@@ -6735,7 +6735,7 @@ void gatherParseWarnings(IErrorReceiver * errs, IHqlExpression * expr, IECLError
 
     ForEachItemIn(i, orphanedWarnings)
     {
-        Owned<IECLError> mappedError = globalOnWarning->mapError(&orphanedWarnings.item(i));
+        Owned<IError> mappedError = globalOnWarning->mapError(&orphanedWarnings.item(i));
         globalOnWarning->report(mappedError);
     }
 }
@@ -8257,12 +8257,12 @@ IHqlExpression * ensureOwned(IHqlExpression * expr)
 }
 
 
-IECLError * annotateExceptionWithLocation(IException * e, IHqlExpression * location)
+IError * annotateExceptionWithLocation(IException * e, IHqlExpression * location)
 {
     StringBuffer errorMsg;
     e->errorMessage(errorMsg);
     unsigned code = e->errorCode();
-    return createECLError(code, errorMsg.str(), location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0);
+    return createError(code, errorMsg.str(), location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0);
 }
 
 StringBuffer & appendLocation(StringBuffer & s, IHqlExpression * location, const char * suffix)

+ 3 - 3
ecl/hql/hqlutil.hpp

@@ -554,7 +554,7 @@ public:
 public:
     ErrorSeverityMapper(IErrorReceiver & errorProcessor);
 
-    virtual IECLError * mapError(IECLError * error);
+    virtual IError * mapError(IError * error);
 
     bool addCommandLineMapping(const char * mapping);
     bool addMapping(const char * category, const char * value);
@@ -668,7 +668,7 @@ extern HQL_API IPropertyTree * queryEnsureArchiveModule(IPropertyTree * archive,
 extern HQL_API IPropertyTree * queryArchiveAttribute(IPropertyTree * module, const char * name);
 extern HQL_API IPropertyTree * createArchiveAttribute(IPropertyTree * module, const char * name);
 
-extern HQL_API IECLError * annotateExceptionWithLocation(IException * e, IHqlExpression * location);
+extern HQL_API IError * annotateExceptionWithLocation(IException * e, IHqlExpression * location);
 extern HQL_API IHqlExpression * expandMacroDefinition(IHqlExpression * expr, HqlLookupContext & ctx, bool reportError);
 extern HQL_API IHqlExpression * convertAttributeToQuery(IHqlExpression * expr, HqlLookupContext & ctx);
 extern HQL_API StringBuffer & appendLocation(StringBuffer & s, IHqlExpression * location, const char * suffix = NULL);
@@ -733,6 +733,6 @@ protected:
 };
 
 extern HQL_API bool joinHasRightOnlyHardMatch(IHqlExpression * expr, bool allowSlidingMatch);
-extern HQL_API void gatherParseWarnings(IErrorReceiver * errs, IHqlExpression * expr, IECLErrorArray & warnings);
+extern HQL_API void gatherParseWarnings(IErrorReceiver * errs, IHqlExpression * expr, IErrorArray & warnings);
 
 #endif

+ 5 - 5
ecl/hql/hqlwuerr.cpp

@@ -43,12 +43,12 @@ void WorkUnitErrorReceiver::initializeError(IWUException * exception, int errNo,
     exception->setTimeStamp(NULL);
 }
 
-IECLError * WorkUnitErrorReceiver::mapError(IECLError * error)
+IError * WorkUnitErrorReceiver::mapError(IError * error)
 {
     return LINK(error);
 }
 
-void WorkUnitErrorReceiver::report(IECLError* eclError)
+void WorkUnitErrorReceiver::report(IError* eclError)
 {
     WUExceptionSeverity wuSeverity = ExceptionSeverityInformation;
     ErrorSeverity severity = eclError->getSeverity();
@@ -103,13 +103,13 @@ public:
     CompoundErrorReceiver(IErrorReceiver * _primary, IErrorReceiver * _secondary) { primary.set(_primary); secondary.set(_secondary); }
     IMPLEMENT_IINTERFACE;
 
-    virtual IECLError * mapError(IECLError * error)
+    virtual IError * mapError(IError * error)
     {
-        Owned<IECLError> mappedError = primary->mapError(error);
+        Owned<IError> mappedError = primary->mapError(error);
         assertex(mappedError == error); // should not expect any mapping below a compound.
         return mappedError.getClear();
     }
-    virtual void report(IECLError* err)
+    virtual void report(IError* err)
     {
         primary->report(err);
         secondary->report(err);

+ 2 - 2
ecl/hql/hqlwuerr.hpp

@@ -26,8 +26,8 @@ public:
     WorkUnitErrorReceiver(IWorkUnit * _wu, const char * _component) { wu.set(_wu); component.set(_component); }
     IMPLEMENT_IINTERFACE;
 
-    virtual IECLError * mapError(IECLError * error);
-    virtual void report(IECLError*);
+    virtual IError * mapError(IError * error);
+    virtual void report(IError*);
     virtual size32_t errCount();
     virtual size32_t warnCount();
 

+ 6 - 6
ecl/hqlcpp/hqlcpp.cpp

@@ -1371,7 +1371,7 @@ HqlCppTranslator::HqlCppTranslator(IErrorReceiver * _errors, const char * _soNam
             if (errs.errCount())
             {
                 StringBuffer errtext;
-                IECLError *first = errs.firstError();
+                IError *first = errs.firstError();
                 first->toString(errtext);
                 throw MakeStringException(HQLERR_FailedToLoadSystemModule, "%s @ %d:%d", errtext.str(), first->getColumn(), first->getLine());
             } 
@@ -2037,14 +2037,14 @@ bool HqlCppTranslator::getDebugFlag(const char * name, bool defValue)
 
 void HqlCppTranslator::doReportWarning(WarnErrorCategory category, ErrorSeverity explicitSeverity, IHqlExpression * location, unsigned id, const char * msg)
 {
-    Owned<IECLError> warnError;
+    Owned<IError> warnError;
     if (!location)
         location = queryActiveActivityLocation();
     ErrorSeverity severity = (explicitSeverity == SeverityUnknown) ? queryDefaultSeverity(category) : explicitSeverity;
     if (location)
-        warnError.setown(createECLError(category, severity, id, msg, location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0));
+        warnError.setown(createError(category, severity, id, msg, location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0));
     else
-        warnError.setown(createECLError(category, severity, id, msg, NULL, 0, 0, 0));
+        warnError.setown(createError(category, severity, id, msg, NULL, 0, 0, 0));
 
     errorProcessor->report(warnError);
 }
@@ -2136,7 +2136,7 @@ void HqlCppTranslator::ThrowStringException(int code,const char *format, ...)
         va_start(args, format);
         errorMsg.valist_appendf(format, args);
         va_end(args);
-        throw createECLError(code, errorMsg.str(), location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0);
+        throw createError(code, errorMsg.str(), location->querySourcePath()->str(), location->getStartLine(), location->getStartColumn(), 0);
     }
 
     va_list args;
@@ -2153,7 +2153,7 @@ void HqlCppTranslator::reportErrorDirect(IHqlExpression * location, int code,con
         ECLlocation loc;
         loc.extractLocationAttr(location);
         if (alwaysAbort)
-            throw createECLError(code, msg, loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
+            throw createError(code, msg, loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
         errorProcessor->reportError(code, msg, loc.sourcePath->str(), loc.lineno, loc.column, loc.position);
     }
     else

+ 11 - 1
ecl/hqlcpp/hqlecl.cpp

@@ -393,7 +393,7 @@ bool HqlDllGenerator::generateCode(HqlQueryContext & query)
             translator.finalizeResources();
             translator.expandFunctions(true);
         }
-        catch (IECLError * e)
+        catch (IError * e)
         {
             if (e->errorCode() != HQLERR_ErrorAlreadyReported)
             {
@@ -554,6 +554,16 @@ bool HqlDllGenerator::doCompile(ICppCompiler * compiler)
     else
         PrintLog("Failed to compile %s", wuname);
 
+    bool reportCppWarnings = wu->getDebugValueBool("reportCppWarnings", false);
+    IArrayOf<IError> errors;
+    compiler->extractErrors(errors);
+    ForEachItemIn(iErr, errors)
+    {
+        IError & cur = errors.item(iErr);
+        if (isError(&cur) || reportCppWarnings)
+            errs->report(&cur);
+    }
+
     cycle_t elapsedCycles = get_cycles_now() - startCycles;
     //For eclcc the workunit has been written to the resource - so any further timings will not be preserved -> need to report differently
     queryActiveTimer()->addTiming("compile:compile c++", elapsedCycles);

+ 2 - 2
ecl/hqlcpp/hqlhtcpp.cpp

@@ -6795,12 +6795,12 @@ ABoundActivity * HqlCppTranslator::buildActivity(BuildCtx & ctx, IHqlExpression
     }
     catch (IException * e)
     {
-        if (dynamic_cast<IECLError *>(e))
+        if (dynamic_cast<IError *>(e))
             throw;
         IHqlExpression * location = queryActiveActivityLocation();
         if (location)
         {
-            IECLError * error = annotateExceptionWithLocation(e, location);
+            IError * error = annotateExceptionWithLocation(e, location);
             e->Release();
             throw error;
         }

+ 3 - 3
ecl/hqlcpp/hqlttcpp.cpp

@@ -9511,7 +9511,7 @@ void HqlScopeTagger::reportError(WarnErrorCategory category, const char * msg)
     int startColumn = location ? location->getStartColumn() : 0;
     ISourcePath * sourcePath = location ? location->querySourcePath() : NULL;
     ErrorSeverity severity = queryDefaultSeverity(category);
-    Owned<IECLError> err = createECLError(category, severity, ERR_ASSERT_WRONGSCOPING, msg, sourcePath->str(), startLine, startColumn, 0);
+    Owned<IError> err = createError(category, severity, ERR_ASSERT_WRONGSCOPING, msg, sourcePath->str(), startLine, startColumn, 0);
     errors.report(err);        // will throw immediately if it is an error.
 }
 
@@ -11529,12 +11529,12 @@ IHqlExpression * HqlTreeNormalizer::createTransformed(IHqlExpression * expr)
         }
         catch (IException * e)
         {
-            if (dynamic_cast<IECLError *>(e))
+            if (dynamic_cast<IError *>(e))
                 throw;
             IHqlExpression * location = queryLocation(expr);
             if (location)
             {
-                IECLError * error = annotateExceptionWithLocation(e, location);
+                IError * error = annotateExceptionWithLocation(e, location);
                 e->Release();
                 throw error;
             }

+ 14 - 0
ecl/regress/cpperr.ecl

@@ -0,0 +1,14 @@
+
+boolean MyFunc() := BEGINC++
+
+    char * temp = "Invalid const string assignment";
+    
+    char * x = strdup(temp);
+    iff (syntaxError);
+    
+    return false;
+
+ENDC++;
+
+output(MyFunc());
+

+ 11 - 0
ecl/regress/cpperr2.ecl

@@ -0,0 +1,11 @@
+
+boolean MyFunc() := BEGINC++
+
+extern bool doesNotExist();
+#body
+    return doesNotExist();
+
+ENDC++;
+
+output(MyFunc());
+

+ 1 - 1
esp/services/ws_dfu/ws_dfuService.cpp

@@ -1496,7 +1496,7 @@ void CWsDfuEx::getDefFile(IUserDescriptor* udesc, const char* FileName,StringBuf
     if (errs.errCount())
     {
         StringBuffer errtext;
-        IECLError *first = errs.firstError();
+        IError *first = errs.firstError();
         first->toString(errtext);
         throw MakeStringException(ECLWATCH_CANNOT_PARSE_ECL_QUERY, "Failed in parsing ECL query: %s @ %d:%d.", errtext.str(), first->getColumn(), first->getLine());
     } 

+ 95 - 0
system/jlib/jcomp.cpp

@@ -22,6 +22,7 @@
 #include "jcomp.hpp"
 #include "jsem.hpp"
 #include "jexcept.hpp"
+#include "jregexp.hpp"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -507,6 +508,100 @@ bool CppCompiler::compileFile(IThreadPool * pool, const char * filename, Semapho
     return true;
 }
 
+void CppCompiler::extractErrors(IArrayOf<IError> & errors)
+{
+    const char* cclog = ccLogPath.get();
+    if(!cclog||!*cclog)
+        cclog = queryCcLogName();
+    Owned <IFile> logfile = createIFile(cclog);
+    if (!logfile->exists())
+        return;
+
+    try
+    {
+        StringBuffer file;
+        file.loadFile(logfile);
+
+        RegExpr vsErrorPattern("^{.+}({[0-9]+}) : error {.*$}");
+        RegExpr vsLinkErrorPattern("^{.+} : error {.*$}");
+
+        //cpperr.ecl:7:10: error: ‘syntaxError’ was not declared in this scope
+        RegExpr gccErrorPattern("^{.+}:{[0-9]+}:{[0-9]+}: {[a-z]+}: {.*$}");
+        RegExpr gccLinkErrorPattern("^{.+}:[^:]+: {.*$}"); // undefined reference
+        RegExpr gccLinkErrorPattern2("^.+ld: {.*$}"); // fail to find library etc.
+        RegExpr gccExitStatusPattern("^.*exit status$"); // collect2: error: ld returned 1 exit status
+        const char * cur = file.str();
+        do
+        {
+            const char * newline = strchr(cur, '\n');
+            StringAttr next;
+            if (newline)
+            {
+                next.set(cur, newline-cur);
+                cur = newline+1;
+                if (*cur == '\r')
+                    cur++;
+            }
+            else
+            {
+                next.set(cur);
+                cur = NULL;
+            }
+
+            if (gccExitStatusPattern.find(next))
+            {
+                //ignore
+            }
+            else if (gccErrorPattern.find(next))
+            {
+                StringBuffer filename, line, column, kind, msg;
+                gccErrorPattern.findstr(filename, 1);
+                gccErrorPattern.findstr(line, 2);
+                gccErrorPattern.findstr(column, 3);
+                gccErrorPattern.findstr(kind, 4);
+                gccErrorPattern.findstr(msg, 5);
+
+                if (streq(kind, "warning"))
+                    errors.append(*createError(CategoryCpp, SeverityWarning, 2999, msg.str(), filename.str(), atoi(line), atoi(column), 0));
+                else
+                    errors.append(*createError(CategoryError, SeverityError, 2999, msg.str(), filename.str(), atoi(line), atoi(column), 0));
+            }
+            else if (gccLinkErrorPattern.find(next))
+            {
+                StringBuffer filename, msg;
+                gccLinkErrorPattern.findstr(filename, 1);
+                gccLinkErrorPattern.findstr(msg, 2);
+                errors.append(*createError(CategoryError, SeverityError, 2999, msg.str(), filename.str(), 0, 0, 0));
+            }
+            else if (gccLinkErrorPattern2.find(next))
+            {
+                StringBuffer msg("C++ link error: ");
+                gccLinkErrorPattern2.findstr(msg, 1);
+                errors.append(*createError(CategoryError, SeverityError, 2999, msg.str(), NULL, 0, 0, 0));
+            }
+            else if (vsErrorPattern.find(next))
+            {
+                StringBuffer filename, line, msg("C++ compiler error: ");
+                vsErrorPattern.findstr(filename, 1);
+                vsErrorPattern.findstr(line, 2);
+                vsErrorPattern.findstr(msg, 3);
+                errors.append(*createError(CategoryError, SeverityError, 2999, msg.str(), filename.str(), atoi(line), 0, 0));
+            }
+            else if (vsLinkErrorPattern.find(next))
+            {
+                StringBuffer filename, msg("C++ link error: ");
+                vsLinkErrorPattern.findstr(filename, 1);
+                vsLinkErrorPattern.findstr(msg, 2);
+                errors.append(*createError(CategoryError, SeverityError, 2999, msg.str(), filename.str(), 0, 0, 0));
+            }
+        } while (cur);
+    }
+    catch (IException * e)
+    {
+        e->Release();
+    }
+}
+
 void CppCompiler::expandCompileOptions(StringBuffer & target)
 {
     target.append(" ").append(CC_OPTION_CORE[targetCompiler]).append(" ");

+ 1 - 0
system/jlib/jcomp.hpp

@@ -52,6 +52,7 @@ public:
     virtual void addLinkOption(const char * option) = 0;
     virtual void addSourceFile(const char * filename) = 0;
     virtual bool compile() = 0;
+    virtual void extractErrors(IArrayOf<IError> & errors) = 0;
     virtual void setDebug(bool _debug) = 0;
     virtual void setDebugLibrary(bool _debug) = 0;
     virtual void setOnlyCompile(bool _onlyCompile) = 0;

+ 1 - 0
system/jlib/jcomp.ipp

@@ -36,6 +36,7 @@ public:
     virtual void addInclude(const char * includePath);
     virtual void addSourceFile(const char * filename);
     virtual bool compile();
+    virtual void extractErrors(IArrayOf<IError> & errors);
     virtual void setDebug(bool _debug);
     virtual void setDebugLibrary(bool _debug);
     virtual void setOnlyCompile(bool _onlyCompile) { onlyCompile = _onlyCompile; }

+ 65 - 0
system/jlib/jexcept.cpp

@@ -1356,3 +1356,68 @@ void printStackReport()
 #endif
     queryLogMsgManager()->flushQueue(10*1000);
 }
+
+//---------------------------------------------------------------------------------------------------------------------
+
+class jlib_decl CError : public CInterfaceOf<IError>
+{
+public:
+    CError(WarnErrorCategory _category,ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position);
+
+    virtual int             errorCode() const { return no; }
+    virtual StringBuffer &  errorMessage(StringBuffer & ret) const { return ret.append(msg); }
+    virtual MessageAudience errorAudience() const { return MSGAUD_user; }
+    virtual const char* getFilename() const { return filename; }
+    virtual WarnErrorCategory getCategory() const { return category; }
+    virtual int getLine() const { return lineno; }
+    virtual int getColumn() const { return column; }
+    virtual int getPosition() const { return position; }
+    virtual StringBuffer& toString(StringBuffer&) const;
+    virtual ErrorSeverity getSeverity() const { return severity; }
+    virtual IError * cloneSetSeverity(ErrorSeverity _severity) const;
+
+protected:
+    ErrorSeverity severity;
+    WarnErrorCategory category;
+    int no;
+    StringAttr msg;
+    StringAttr filename;
+    int lineno;
+    int column;
+    int position;
+};
+
+CError::CError(WarnErrorCategory _category, ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position):
+  category(_category),severity(_severity), msg(_msg), filename(_filename)
+{
+    no = _no;
+    lineno = _lineno;
+    column = _column;
+    position = _position;
+}
+
+
+StringBuffer& CError::toString(StringBuffer& buf) const
+{
+    buf.append(filename);
+
+    if(lineno && column)
+        buf.append('(').append(lineno).append(',').append(column).append(')');
+    buf.append(" : ");
+
+    buf.append(no).append(": ").append(msg);
+    return buf;
+}
+
+IError * CError::cloneSetSeverity(ErrorSeverity newSeverity) const
+{
+    return new CError(category, newSeverity,
+                         errorCode(), msg, filename,
+                         getLine(), getColumn(), getPosition());
+}
+
+IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char * filename, int lineno, int column, int pos)
+{
+    return new CError(category,severity,errNo,msg,filename,lineno,column,pos);
+}
+

+ 59 - 0
system/jlib/jexcept.hpp

@@ -160,5 +160,64 @@ void  jlib_decl printStackReport();
 #define throwError3(x,a,b,c)                    throwStringExceptionV(x, (x ## _Text), a, b, c)
 #define throwError4(x,a,b,c,d)                  throwStringExceptionV(x, (x ## _Text), a, b, c, d)
 
+//---------------------------------------------------------------------------------------------------------------------
+
+enum ErrorSeverity
+{
+    SeverityIgnore,
+    SeverityInfo,
+    SeverityWarning,
+    SeverityError,    // a warning treated as an error
+    SeverityFatal,      // a fatal error - can't be mapped to anything else
+    SeverityUnknown,
+};
+
+inline bool isError(ErrorSeverity severity) { return severity >= SeverityError; }
+inline bool isFatal(ErrorSeverity severity) { return severity == SeverityFatal; }
+
+//TBD in a separate commit - add support for warnings to be associated with different categories
+enum WarnErrorCategory
+{
+    CategoryInformation,// Some kind of information [default severity information]
+
+    CategoryCast,       // Suspicious casts between types or out of range values
+    CategoryConfuse,    // Likely to cause confusion
+    CategoryDeprecated, // deprecated features or syntax
+    CategoryEfficiency, // Something that is likely to be inefficient
+    CategoryFolding,    // Unusual results from constant folding
+    CategoryFuture,     // Likely to cause problems in future versions
+    CategoryIgnored,    // Something that has no effect, or is ignored
+    CategoryIndex,      // Unusual indexing of datasets or strings
+    CategoryMistake,    // Almost certainly a mistake
+    CategoryLimit,      // An operation that should really have some limits to protect data runaway
+    CategorySyntax,     // Invalid syntax which is painless to recover from
+    CategoryUnusual,    // Not strictly speaking an error, but highly unusual and likely to be a mistake
+    CategoryUnexpected, // Code that could be correct, but has the potential for unexpected behaviour
+    CategoryCpp,        // Warning passed through from C++ compiler
+
+    CategoryError,      // Typically severity fatal
+    CategoryAll,
+    CategoryUnknown,
+    CategoryMax,
+};
+
+interface jlib_thrown_decl IError : public IException
+{
+public:
+    virtual const char* getFilename() const = 0;
+    virtual WarnErrorCategory getCategory() const = 0;
+    virtual int getLine() const = 0;
+    virtual int getColumn() const = 0;
+    virtual int getPosition() const = 0;
+    virtual StringBuffer& toString(StringBuffer&) const = 0;
+    virtual ErrorSeverity getSeverity() const = 0;
+    virtual IError * cloneSetSeverity(ErrorSeverity _severity) const = 0;
+};
+
+inline bool isError(IError * error) { return isError(error->getSeverity()); }
+inline bool isFatal(IError * error) { return isFatal(error->getSeverity()); }
+
+extern jlib_decl IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0);
+
 #endif
 

+ 1 - 1
system/jlib/jstats.h

@@ -121,7 +121,7 @@ enum StatisticKind
 
     StSizeGeneratedCpp,
     StSizePeakMemory,
-    StSizeMaxRowSize,                   // Is measurement in K appropriate?
+    StSizeMaxRowSize,
 
     StNumRowsProcessed,                 // on edge
     StNumSlaves,                        // on edge