diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/Driver/RewriteObjC.cpp | 5 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathDiagnostic.h | 10 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/BugReporter.h | 22 | ||||
-rw-r--r-- | clang/include/clang/Basic/Diagnostic.h | 154 | ||||
-rw-r--r-- | clang/include/clang/Driver/TextDiagnosticBuffer.h | 10 | ||||
-rw-r--r-- | clang/include/clang/Driver/TextDiagnosticPrinter.h | 12 | ||||
-rw-r--r-- | clang/lib/Analysis/BugReporter.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Analysis/PathDiagnostic.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 52 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Driver/TextDiagnosticBuffer.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Driver/TextDiagnosticPrinter.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 36 |
17 files changed, 241 insertions, 205 deletions
diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 69aedcc2dd8..804a891f6b6 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -132,9 +132,8 @@ namespace { if (!Rewrite.ReplaceStmt(Old, New) || SilenceRewriteMacroWarning) return; - SourceRange Range = Old->getSourceRange(); - Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag, - 0, 0, &Range, 1); + Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) + << Old->getSourceRange(); } void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen, diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h index 6183a7c3a68..bedc6da40f7 100644 --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -197,14 +197,8 @@ public: PathDiagnosticClient() {} virtual ~PathDiagnosticClient() {} - virtual void HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges); + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info); virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0; }; diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h index 6ab2a4e713d..71d3ccae413 100644 --- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/clang/include/clang/Analysis/PathSensitive/BugReporter.h @@ -303,26 +303,20 @@ public: virtual ~DiagCollector() {} - virtual void HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges) { + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info) { // FIXME: Use a map from diag::kind to BugType, instead of having just // one BugType. - - Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos)); + const char *Desc = Info.getDiags()->getDescription(Info.getID()); + Reports.push_back(DiagBugReport(Desc, D, Info.getLocation())); DiagBugReport& R = Reports.back(); - for ( ; NumRanges ; --NumRanges, ++Ranges) - R.addRange(*Ranges); + for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) + R.addRange(Info.getRange(i)); - for ( ; NumStrs ; --NumStrs, ++Strs) - R.addString(**Strs); + for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i) + R.addString(Info.getArgStr(i)); } // Iterators. diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index b9bbcb2831f..566b5e3d480 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -22,6 +22,7 @@ namespace clang { class DiagnosticClient; class SourceRange; class SourceManager; + class DiagnosticInfo; // Import the diagnostic enums themselves. namespace diag { @@ -150,7 +151,7 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - const char *getDescription(unsigned DiagID); + const char *getDescription(unsigned DiagID) const; /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic /// level of the specified diagnostic ID is a Note, Warning, or Extension. @@ -162,41 +163,146 @@ public: /// the DiagnosticClient. Level getDiagnosticLevel(unsigned DiagID) const; + /// Report - Issue the message to the client. DiagID is a member of the - /// diag::kind enum. - void Report(FullSourceLoc Pos, unsigned DiagID, - const std::string **Strs = 0, unsigned NumStrs = 0, - const SourceRange *Ranges = 0, unsigned NumRanges = 0) { - Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges); - } - - /// Report - Issue the message to the specified client. - /// DiagID is a member of the diag::kind enum. - void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID, - const std::string **Strs = 0, unsigned NumStrs = 0, - const SourceRange *Ranges = 0, unsigned NumRanges = 0); + /// diag::kind enum. This actually returns a new instance of DiagnosticInfo + /// which emits the diagnostics (through ProcessDiag) when it is destroyed. + inline DiagnosticInfo Report(FullSourceLoc Pos, unsigned DiagID); + +private: + // This is private state used by DiagnosticInfo. We put it here instead of + // in DiagnosticInfo in order to keep DiagnosticInfo a small light-weight + // object. This implementation choice means that we can only have one + // diagnostic "in flight" at a time, but this seems to be a reasonable + // tradeoff to keep these objects small. Assertions verify that only one + // diagnostic is in flight at a time. + friend class DiagnosticInfo; + + /// DiagArguments - The values for the various substitution positions. It + /// currently only support 10 arguments (%0-%9). + const std::string *DiagArguments[10]; + /// DiagRanges - The list of ranges added to this diagnostic. It currently + /// only support 10 ranges, could easily be extended if needed. + const SourceRange *DiagRanges[10]; + + /// NumDiagArgs - This is set to -1 when no diag is in flight. Otherwise it + /// is the number of entries in Arguments. + signed char NumDiagArgs; + /// NumRanges - This is the number of ranges in the DiagRanges array. + unsigned char NumDiagRanges; + + /// ProcessDiag - This is the method used to report a diagnostic that is + /// finally fully formed. + void ProcessDiag(const DiagnosticInfo &Info); +}; + +/// DiagnosticInfo - This is a little helper class used to produce diagnostics. +/// This is constructed with an ID and location, and then has some number of +/// arguments (for %0 substitution) and SourceRanges added to it with the +/// overloaded operator<<. Once it is destroyed, it emits the diagnostic with +/// the accumulated information. +/// +/// Note that many of these will be created as temporary objects (many call +/// sites), so we want them to be small to reduce stack space usage etc. For +/// this reason, we stick state in the Diagnostic class, see the comment there +/// for more info. +class DiagnosticInfo { + Diagnostic *DiagObj; + FullSourceLoc Loc; + unsigned DiagID; + void operator=(const DiagnosticInfo&); // DO NOT IMPLEMENT +public: + DiagnosticInfo(Diagnostic *diagObj, FullSourceLoc loc, unsigned diagID) : + DiagObj(diagObj), Loc(loc), DiagID(diagID) { + assert(DiagObj->NumDiagArgs == -1 && + "Multiple diagnostics in flight at once!"); + DiagObj->NumDiagArgs = DiagObj->NumDiagRanges = 0; + } + + /// Copy constructor. When copied, this "takes" the diagnostic info from the + /// input and neuters it. + DiagnosticInfo(DiagnosticInfo &D) { + DiagObj = D.DiagObj; + Loc = D.Loc; + DiagID = D.DiagID; + D.DiagObj = 0; + } + + /// Destructor - The dtor emits the diagnostic. + ~DiagnosticInfo() { + // If DiagObj is null, then its soul was stolen by the copy ctor. + if (!DiagObj) return; + + DiagObj->ProcessDiag(*this); + + // This diagnostic is no longer in flight. + DiagObj->NumDiagArgs = -1; + } + + const Diagnostic *getDiags() const { return DiagObj; } + unsigned getID() const { return DiagID; } + const FullSourceLoc &getLocation() const { return Loc; } + + unsigned getNumArgs() const { return DiagObj->NumDiagArgs; } + + /// getArgStr - Return the provided argument string specified by Idx. + const std::string &getArgStr(unsigned Idx) const { + assert((signed char)Idx < DiagObj->NumDiagArgs && + "Argument out of range!"); + return *DiagObj->DiagArguments[Idx]; + } + + /// getNumRanges - Return the number of source ranges associated with this + /// diagnostic. + unsigned getNumRanges() const { + return DiagObj->NumDiagRanges; + } + + const SourceRange &getRange(unsigned Idx) const { + assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!"); + return *DiagObj->DiagRanges[Idx]; + } + + DiagnosticInfo &operator<<(const std::string &S) { + assert((unsigned)DiagObj->NumDiagArgs < + sizeof(DiagObj->DiagArguments)/sizeof(DiagObj->DiagArguments[0]) && + "Too many arguments to diagnostic!"); + DiagObj->DiagArguments[DiagObj->NumDiagArgs++] = &S; + return *this; + } + + DiagnosticInfo &operator<<(const SourceRange &R) { + assert((unsigned)DiagObj->NumDiagArgs < + sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) && + "Too many arguments to diagnostic!"); + DiagObj->DiagRanges[DiagObj->NumDiagRanges++] = &R; + return *this; + } + }; + +/// Report - Issue the message to the client. DiagID is a member of the +/// diag::kind enum. This actually returns a new instance of DiagnosticInfo +/// which emits the diagnostics (through ProcessDiag) when it is destroyed. +inline DiagnosticInfo Diagnostic::Report(FullSourceLoc Pos, unsigned DiagID) { + DiagnosticInfo D(this, Pos, DiagID); + return D; +} + + /// DiagnosticClient - This is an abstract interface implemented by clients of /// the front-end, which formats and prints fully processed diagnostics. class DiagnosticClient { protected: - std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level, - diag::kind ID, - const std::string **Strs, unsigned NumStrs); + std::string FormatDiagnostic(const DiagnosticInfo &Info); public: virtual ~DiagnosticClient(); /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or /// capturing it to a log as needed. - virtual void HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges) = 0; + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info) = 0; }; } // end namespace clang diff --git a/clang/include/clang/Driver/TextDiagnosticBuffer.h b/clang/include/clang/Driver/TextDiagnosticBuffer.h index 9933308368b..e803475ae0b 100644 --- a/clang/include/clang/Driver/TextDiagnosticBuffer.h +++ b/clang/include/clang/Driver/TextDiagnosticBuffer.h @@ -39,14 +39,8 @@ public: const_iterator note_begin() const { return Notes.begin(); } const_iterator note_end() const { return Notes.end(); } - virtual void HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges); + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info); }; } // end namspace clang diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h index 7c6bce58bbb..e5ef9fca824 100644 --- a/clang/include/clang/Driver/TextDiagnosticPrinter.h +++ b/clang/include/clang/Driver/TextDiagnosticPrinter.h @@ -36,19 +36,13 @@ public: void PrintIncludeStack(FullSourceLoc Pos); void HighlightRange(const SourceRange &R, - SourceManager& SrcMgr, + const SourceManager& SrcMgr, unsigned LineNo, unsigned FileID, std::string &CaretLine, const std::string &SourceLine); - virtual void HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges); + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info); }; } // end namspace clang diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index bf99e6ba637..0074a93b5bc 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -773,21 +773,26 @@ void BugReporter::EmitWarning(BugReport& R) { D->push_back(piece); PD->HandlePathDiagnostic(D.take()); + return; } else { - std::ostringstream os; + std::string str; if (D->empty()) - os << R.getDescription(); + str = R.getDescription(); else - os << D->back()->getString(); - + str = D->back()->getString(); Diagnostic& Diag = getDiagnostic(); - unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, - os.str().c_str()); - - Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg); + unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, str.c_str()); + + switch (End-Beg) { + default: assert(0 && "Don't handle this many ranges yet!"); + case 0: Diag.Report(L, ErrorDiag); break; + case 1: Diag.Report(L, ErrorDiag) << Beg[0]; break; + case 2: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1]; break; + case 3: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1] << Beg[2]; break; + } } } @@ -807,9 +812,17 @@ void BugReporter::EmitBasicReport(const char* name, const char* category, DiagnosticClient *OldClient = Diag.getClient(); Diag.setClient(&C); - Diag.Report(getContext().getFullLoc(Loc), - Diag.getCustomDiagID(Diagnostic::Warning, str), - 0, 0, RBeg, NumRanges); + FullSourceLoc L = getContext().getFullLoc(Loc); + unsigned DiagID = Diag.getCustomDiagID(Diagnostic::Warning, str); + + switch (NumRanges) { + default: assert(0 && "Don't handle this many ranges yet!"); + case 0: Diag.Report(L, DiagID); break; + case 1: Diag.Report(L, DiagID) << RBeg[0]; break; + case 2: Diag.Report(L, DiagID) << RBeg[0] << RBeg[1]; break; + case 3: Diag.Report(L, DiagID) << RBeg[0] << RBeg[1] << RBeg[2]; break; + } + Diag.setClient(OldClient); for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp index 02cfe1e341b..aed83ea84fb 100644 --- a/clang/lib/Analysis/PathDiagnostic.cpp +++ b/clang/lib/Analysis/PathDiagnostic.cpp @@ -20,14 +20,8 @@ PathDiagnostic::~PathDiagnostic() { for (iterator I = begin(), E = end(); I != E; ++I) delete &*I; } -void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level DiagLevel, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges) { +void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info) { // Create a PathDiagnostic with a single piece. @@ -42,16 +36,13 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, case Diagnostic::Fatal: LevelStr = "fatal error: "; break; } - std::string Msg = FormatDiagnostic(Diags, DiagLevel, ID, Strs, NumStrs); + std::string Msg = FormatDiagnostic(Info); - PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, LevelStr+Msg); - - while (NumRanges) { - P->addRange(*Ranges); - --NumRanges; - ++Ranges; - } + PathDiagnosticPiece *P = + new PathDiagnosticPiece(Info.getLocation(), LevelStr+Msg); + for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) + P->addRange(Info.getRange(i)); D->push_front(P); HandlePathDiagnostic(D); diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 2076b16db08..a202a55f268 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -127,6 +127,7 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) { NumDiagnostics = 0; NumErrors = 0; CustomDiagInfo = 0; + NumDiagArgs = -1; } Diagnostic::~Diagnostic() { @@ -154,7 +155,7 @@ bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) { /// getDescription - Given a diagnostic ID, return a description of the /// issue. -const char *Diagnostic::getDescription(unsigned DiagID) { +const char *Diagnostic::getDescription(unsigned DiagID) const { if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS) return DiagnosticText[DiagID]; else @@ -210,66 +211,51 @@ Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const { } } -/// Report - Issue the message to the client. -/// DiagID is a member of the diag::kind enum. -void Diagnostic::Report(DiagnosticClient* C, - FullSourceLoc Loc, unsigned DiagID, - const std::string **Strs, unsigned NumStrs, - const SourceRange *Ranges, unsigned NumRanges) { - +/// ProcessDiag - This is the method used to report a diagnostic that is +/// finally fully formed. +void Diagnostic::ProcessDiag(const DiagnosticInfo &Info) { // Figure out the diagnostic level of this message. - Diagnostic::Level DiagLevel = getDiagnosticLevel(DiagID); + Diagnostic::Level DiagLevel = getDiagnosticLevel(Info.getID()); // If the client doesn't care about this message, don't issue it. if (DiagLevel == Diagnostic::Ignored) return; - // Set the diagnostic client if it isn't set already. - if (!C) C = Client; - // If this is not an error and we are in a system header, ignore it. We - // have to check on the original DiagID here, because we also want to + // have to check on the original Diag ID here, because we also want to // ignore extensions and warnings in -Werror and -pedantic-errors modes, // which *map* warnings/extensions to errors. if (SuppressSystemWarnings && - DiagID < diag::NUM_BUILTIN_DIAGNOSTICS && - getBuiltinDiagClass(DiagID) != ERROR && - Loc.isValid() && Loc.getPhysicalLoc().isInSystemHeader()) + Info.getID() < diag::NUM_BUILTIN_DIAGNOSTICS && + getBuiltinDiagClass(Info.getID()) != ERROR && + Info.getLocation().isValid() && + Info.getLocation().getPhysicalLoc().isInSystemHeader()) return; if (DiagLevel >= Diagnostic::Error) { ErrorOccurred = true; - if (C != 0 && C == Client) - ++NumErrors; + ++NumErrors; } // Finally, report it. - - if (C != 0) - C->HandleDiagnostic(*this, DiagLevel, Loc, (diag::kind)DiagID, - Strs, NumStrs, Ranges, NumRanges); - - if (C != 0 && C == Client) - ++NumDiagnostics; + Client->HandleDiagnostic(DiagLevel, Info); + ++NumDiagnostics; } DiagnosticClient::~DiagnosticClient() {} -std::string DiagnosticClient::FormatDiagnostic(Diagnostic &Diags, - Diagnostic::Level Level, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs) { - std::string Msg = Diags.getDescription(ID); +std::string DiagnosticClient::FormatDiagnostic(const DiagnosticInfo &Info) { + std::string Msg = Info.getDiags()->getDescription(Info.getID()); - // Replace all instances of %0 in Msg with 'Extra'. + // Replace all instances of %0 in Msg with 'Extra'. This is a pretty horrible + // and inefficient way to do this, we could improve this a lot if we care. for (unsigned i = 0; i < Msg.size() - 1; ++i) { if (Msg[i] == '%' && isdigit(Msg[i + 1])) { unsigned StrNo = Msg[i + 1] - '0'; Msg = std::string(Msg.begin(), Msg.begin() + i) + - (StrNo < NumStrs ? *Strs[StrNo] : "<<<INTERNAL ERROR>>>") + + Info.getArgStr(StrNo) + std::string(Msg.begin() + i + 2, Msg.end()); } } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 058278cfa4e..044368c6998 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -303,10 +303,9 @@ void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, S = Setter->getSelector(); } else { // FIXME: This should be diagnosed by sema. - SourceRange Range = E->getSourceRange(); CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()), - diag::err_typecheck_assign_const, 0, 0, - &Range, 1); + diag::err_typecheck_assign_const) + << E->getSourceRange(); return; } } else { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d7d732997b6..3e146215f48 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -106,11 +106,9 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, return; unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, "cannot codegen this %0 yet"); - SourceRange Range = S->getSourceRange(); std::string Msg = Type; - const std::string *Strs[] = { &Msg }; - getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID, - Strs, 1, &Range, 1); + getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID) + << Msg << S->getSourceRange(); } /// ErrorUnsupported - Print out an error that codegen doesn't support the @@ -122,8 +120,7 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, "cannot codegen this %0 yet"); std::string Msg = Type; - const std::string *Strs[] = { &Msg }; - getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID, Strs, 1); + getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg; } /// setGlobalVisibility - Set the visibility for the given LLVM diff --git a/clang/lib/Driver/TextDiagnosticBuffer.cpp b/clang/lib/Driver/TextDiagnosticBuffer.cpp index ef7ac6d408c..b138b1a24d2 100644 --- a/clang/lib/Driver/TextDiagnosticBuffer.cpp +++ b/clang/lib/Driver/TextDiagnosticBuffer.cpp @@ -17,30 +17,21 @@ using namespace clang; /// HandleDiagnostic - Store the errors, warnings, and notes that are /// reported. /// -void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level Level, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *, - unsigned) { +void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level, + const DiagnosticInfo &Info) { switch (Level) { default: assert(0 && "Diagnostic not handled during diagnostic buffering!"); case Diagnostic::Note: - Notes.push_back(std::make_pair(Pos.getLocation(), - FormatDiagnostic(Diags, Level, ID, - Strs, NumStrs))); + Notes.push_back(std::make_pair(Info.getLocation().getLocation(), + FormatDiagnostic(Info))); break; case Diagnostic::Warning: - Warnings.push_back(std::make_pair(Pos.getLocation(), - FormatDiagnostic(Diags, Level, ID, - Strs, NumStrs))); + Warnings.push_back(std::make_pair(Info.getLocation().getLocation(), + FormatDiagnostic(Info))); break; case Diagnostic::Error: - Errors.push_back(std::make_pair(Pos.getLocation(), - FormatDiagnostic(Diags, Level, ID, - Strs, NumStrs))); + Errors.push_back(std::make_pair(Info.getLocation().getLocation(), + FormatDiagnostic(Info))); break; } } diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp index e03588b9899..3b8ec10ec81 100644 --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp @@ -34,7 +34,7 @@ PrintIncludeStack(FullSourceLoc Pos) { /// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s) /// any characters in LineNo that intersect the SourceRange. void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, - SourceManager& SourceMgr, + const SourceManager& SourceMgr, unsigned LineNo, unsigned FileID, std::string &CaretLine, const std::string &SourceLine) { @@ -92,17 +92,12 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, CaretLine[i] = '~'; } -void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags, - Diagnostic::Level Level, - FullSourceLoc Pos, - diag::kind ID, - const std::string **Strs, - unsigned NumStrs, - const SourceRange *Ranges, - unsigned NumRanges) { +void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, + const DiagnosticInfo &Info) { unsigned LineNo = 0, ColNo = 0; unsigned FileID = 0; const char *LineStart = 0, *LineEnd = 0; + const FullSourceLoc &Pos = Info.getLocation(); if (Pos.isValid()) { FullSourceLoc LPos = Pos.getLogicalLoc(); @@ -146,9 +141,10 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags, break; } - OS << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n"; + OS << FormatDiagnostic(Info) << "\n"; - if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) || Ranges)) { + if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) || + Info.getNumRanges())) { // Cache the LastLoc, it allows us to omit duplicate source/caret spewage. LastLoc = Pos; @@ -160,8 +156,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags, std::string CaretLine(LineEnd-LineStart, ' '); // Highlight all of the characters covered by Ranges with ~ characters. - for (unsigned i = 0; i != NumRanges; ++i) - HighlightRange(Ranges[i], Pos.getManager(), LineNo, FileID, + for (unsigned i = 0; i != Info.getNumRanges(); ++i) + HighlightRange(Info.getRange(i), Pos.getManager(), LineNo, FileID, CaretLine, SourceLine); // Next, insert the caret itself. diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index dc4dd877b67..3357791b6cb 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -124,28 +124,24 @@ void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID) { void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) { - const std::string *Strs[] = { &Msg }; - Diags.Report(getFullLoc(Loc), DiagID, Strs, 1); + Diags.Report(getFullLoc(Loc), DiagID) << Msg; } void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, const SourceRange &R1, const SourceRange &R2) { - const std::string *Strs[] = { &Msg }; - SourceRange R[] = {R1, R2}; - Diags.Report(getFullLoc(Loc), DiagID, Strs, 1, R, 2); + Diags.Report(getFullLoc(Loc), DiagID) << Msg << R1 << R2; } void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) { - Diags.Report(getFullLoc(Loc), DiagID, 0, 0, &R, 1); + Diags.Report(getFullLoc(Loc), DiagID) << R; } void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R1, const SourceRange &R2) { - SourceRange R[] = {R1, R2}; - Diags.Report(getFullLoc(Loc), DiagID, 0, 0, R, 2); + Diags.Report(getFullLoc(Loc), DiagID) << R1 << R2; } diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 733c37cb4f9..c4971084710 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -311,7 +311,6 @@ void DeclSpec::Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr, } void DeclSpec::Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr, - unsigned DiagID, const std::string &Info) { - const std::string *Strs[] = { &Info }; - D.Report(FullSourceLoc(Loc,SrcMgr), DiagID, Strs, 1); + unsigned DiagID, const std::string &Info) { + D.Report(FullSourceLoc(Loc,SrcMgr), DiagID) << Info; } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index dfabc9b16a5..a9ce22d0470 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -43,21 +43,18 @@ Action::~Action() {} bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) { - const std::string *Strs[] = { &Msg }; - Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, Strs, 1); + Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID) << Msg; return true; } bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, const SourceRange& Range) { - const std::string *Strs[] = { &Msg }; - Diags.Report(PP.getFullLoc(Loc), DiagID, Strs, 1, &Range,1); + Diags.Report(PP.getFullLoc(Loc), DiagID) << Msg << Range; return true; } bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) { - Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, 0, 0, - &R, 1); + Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID) << R; return true; } diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 5ea27c979b1..c064e2448b2 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -18,11 +18,9 @@ #include "clang/AST/Expr.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/Diagnostic.h" - using namespace clang; -static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) -{ +static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) { if (C.getLangOptions().CPlusPlus) return CXXRecordDecl::Create(C, TagDecl::TK_struct, C.getTranslationUnitDecl(), @@ -176,66 +174,58 @@ bool Sema::Diag(SourceLocation Loc, unsigned DiagID) { } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) { - const std::string *Strs[] = { &Msg }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, const std::string &Msg2) { - const std::string *MsgArr[] = { &Msg1, &Msg2 }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg1 << Msg2; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange& Range) { - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, &Range,1); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Range; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, const SourceRange& Range) { - const std::string *Strs[] = { &Msg }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1, &Range,1); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg << Range; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, - const std::string &Msg2, const SourceRange& Range) { - const std::string *MsgArr[] = { &Msg1, &Msg2 }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2, &Range, 1); + const std::string &Msg2, const SourceRange &R) { + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg1 << Msg2 << R; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, const std::string &Msg2, const std::string &Msg3, const SourceRange &R1) { - const std::string *MsgArr[] = { &Msg1, &Msg2, &Msg3 }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 3, &R1, 1); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) + << Msg1 << Msg2 << Msg3 << R1; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange& R1, const SourceRange& R2) { - SourceRange RangeArr[] = { R1, R2 }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, RangeArr, 2); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << R1 << R2; return true; } bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg, const SourceRange& R1, const SourceRange& R2) { - SourceRange RangeArr[] = { R1, R2 }; - const std::string *Strs[] = { &Msg }; - PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1, RangeArr, 2); + PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg << R1 << R2; return true; } bool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1, const std::string &Msg2, const SourceRange& R1, const SourceRange& R2) { - const std::string *MsgArr[] = { &Msg1, &Msg2 }; - SourceRange RangeArr[] = { R1, R2 }; - PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID, MsgArr,2,RangeArr, 2); + PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID) + << Msg1 << Msg2 << R1 << R2; return true; } |