void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. if (pImpl->DiagnosticHandler) { if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); return; } if (!isDiagnosticEnabled(DI)) return; // Otherwise, print the message with a prefix based on the severity. std::string MsgStorage; raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); Stream.flush(); switch (DI.getSeverity()) { case DS_Error: errs() << "error: " << MsgStorage << "\n"; exit(1); case DS_Warning: errs() << "warning: " << MsgStorage << "\n"; break; case DS_Remark: errs() << "remark: " << MsgStorage << "\n"; break; case DS_Note: errs() << "note: " << MsgStorage << "\n"; break; } }
void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) { // Map the LLVM internal diagnostic severity to the LTO diagnostic severity. lto_codegen_diagnostic_severity_t Severity; switch (DI.getSeverity()) { case DS_Error: Severity = LTO_DS_ERROR; break; case DS_Warning: Severity = LTO_DS_WARNING; break; case DS_Remark: Severity = LTO_DS_REMARK; break; case DS_Note: Severity = LTO_DS_NOTE; break; } // Create the string that will be reported to the external diagnostic handler. std::string MsgStorage; raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); Stream.flush(); // If this method has been called it means someone has set up an external // diagnostic handler. Assert on that. assert(DiagHandler && "Invalid diagnostic handler"); (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext); }
static void diagnosticHandler(const DiagnosticInfo &DI) { DiagnosticPrinterRawOStream DP(errs()); DI.print(DP); errs() << '\n'; if (DI.getSeverity() == DS_Error) exit(1); }
static void diagnosticHandler(const DiagnosticInfo &DI) { raw_ostream &OS = errs(); OS << "llvm-lto: "; switch (DI.getSeverity()) { case DS_Error: OS << "error"; break; case DS_Warning: OS << "warning"; break; case DS_Remark: OS << "remark"; break; case DS_Note: OS << "note"; break; } if (!CurrentActivity.empty()) OS << ' ' << CurrentActivity; OS << ": "; DiagnosticPrinterRawOStream DP(OS); DI.print(DP); OS << '\n'; if (DI.getSeverity() == DS_Error) exit(1); }
void LLVMContext::diagnose(const DiagnosticInfo &DI) { if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) { yaml::Output *Out = getDiagnosticsOutputFile(); if (Out) { // For remarks the << operator takes a reference to a pointer. auto *P = const_cast<DiagnosticInfoOptimizationBase *>(OptDiagBase); *Out << P; } } // If there is a report handler, use it. if (pImpl->DiagHandler && (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && pImpl->DiagHandler->handleDiagnostics(DI)) return; if (!isDiagnosticEnabled(DI)) return; // Otherwise, print the message with a prefix based on the severity. DiagnosticPrinterRawOStream DP(errs()); errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP); errs() << "\n"; if (DI.getSeverity() == DS_Error) exit(1); }
static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) { std::error_code EC = BDI->getError(); if (EC == BitcodeError::InvalidBitcodeSignature) return; } std::string ErrStorage; { raw_string_ostream OS(ErrStorage); DiagnosticPrinterRawOStream DP(OS); DI.print(DP); } ld_plugin_level Level; switch (DI.getSeverity()) { case DS_Error: message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s", ErrStorage.c_str()); llvm_unreachable("Fatal doesn't return."); case DS_Warning: Level = LDPL_WARNING; break; case DS_Note: case DS_Remark: Level = LDPL_INFO; break; } message(Level, "LLVM gold plugin: %s", ErrStorage.c_str()); }
/// \brief This function is invoked when the backend needs /// to report something to the user. void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { unsigned DiagID = diag::err_fe_inline_asm; llvm::DiagnosticSeverity Severity = DI.getSeverity(); // Get the diagnostic ID based. switch (DI.getKind()) { case llvm::DK_InlineAsm: if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) return; ComputeDiagID(Severity, inline_asm, DiagID); break; case llvm::DK_StackSize: if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) return; ComputeDiagID(Severity, backend_frame_larger_than, DiagID); break; default: // Plugin IDs are not bound to any value as they are set dynamically. ComputeDiagRemarkID(Severity, backend_plugin, DiagID); break; } std::string MsgStorage; { raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } // Report the backend message using the usual diagnostic mechanism. FullSourceLoc Loc; Diags.Report(Loc, DiagID).AddString(MsgStorage); }
/// \brief This function is invoked when the backend needs /// to report something to the user. void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { unsigned DiagID = diag::err_fe_inline_asm; llvm::DiagnosticSeverity Severity = DI.getSeverity(); // Get the diagnostic ID based. switch (DI.getKind()) { case llvm::DK_InlineAsm: if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) return; ComputeDiagID(Severity, inline_asm, DiagID); break; case llvm::DK_StackSize: if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) return; ComputeDiagID(Severity, backend_frame_larger_than, DiagID); break; case llvm::DK_OptimizationRemark: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); return; case llvm::DK_OptimizationRemarkMissed: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI)); return; case llvm::DK_OptimizationRemarkAnalysis: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. OptimizationRemarkHandler( cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); return; case llvm::DK_OptimizationRemarkAnalysisFPCommute: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. OptimizationRemarkHandler( cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI)); return; case llvm::DK_OptimizationFailure: // Optimization failures are always handled completely by this // handler. OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); return; default: // Plugin IDs are not bound to any value as they are set dynamically. ComputeDiagRemarkID(Severity, backend_plugin, DiagID); break; } std::string MsgStorage; { raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } // Report the backend message using the usual diagnostic mechanism. FullSourceLoc Loc; Diags.Report(Loc, DiagID).AddString(MsgStorage); }
static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { assert(DI.getSeverity() == DS_Error && "Only expecting errors"); raw_ostream &OS = errs(); OS << (char *)Context << ": "; DiagnosticPrinterRawOStream DP(OS); DI.print(DP); OS << '\n'; exit(1); }
static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) { bool *HasError = static_cast<bool *>(Context); if (DI.getSeverity() == DS_Error) *HasError = true; DiagnosticPrinterRawOStream DP(errs()); errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP); errs() << "\n"; }
void BackendConsumer::linkerDiagnosticHandler(const DiagnosticInfo &DI) { if (DI.getSeverity() != DS_Error) return; std::string MsgStorage; { raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } Diags.Report(diag::err_fe_cannot_link_module) << LinkModule->getModuleIdentifier() << MsgStorage; }
static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) { bool *HasError = static_cast<bool *>(Context); if (DI.getSeverity() == DS_Error) *HasError = true; if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) if (!Remark->isEnabled()) return; DiagnosticPrinterRawOStream DP(errs()); errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP); errs() << "\n"; }
static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { if (DI.getSeverity() != DS_Error) { DiagnosticPrinterRawOStream DP(errs()); DI.print(DP); errs() << '\n'; return; } sLastErrorString = ""; { raw_string_ostream Stream(sLastErrorString); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } }
bool handleDiagnostics(const DiagnosticInfo &DI) override { if (DI.getSeverity() != DS_Error) { DiagnosticPrinterRawOStream DP(errs()); DI.print(DP); errs() << '\n'; return true; } sLastErrorString = ""; { raw_string_ostream Stream(sLastErrorString); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); } return true; }
void lld::diagnosticHandler(const DiagnosticInfo &DI) { SmallString<128> S; raw_svector_ostream OS(S); DiagnosticPrinterRawOStream DP(OS); DI.print(DP); warn(S); }
static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { // Optimization remarks are selective. They need to check whether the regexp // pattern, passed via one of the -pass-remarks* flags, matches the name of // the pass that is emitting the diagnostic. If there is no match, ignore the // diagnostic and return. switch (DI.getKind()) { case llvm::DK_OptimizationRemark: if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled()) return false; break; case llvm::DK_OptimizationRemarkMissed: if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled()) return false; break; case llvm::DK_OptimizationRemarkAnalysis: if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled()) return false; break; case llvm::DK_OptimizationRemarkAnalysisFPCommute: if (!cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI) .isEnabled()) return false; break; default: break; } return true; }
static void diagnosticHandler(const DiagnosticInfo &DI) { SmallString<128> ErrStorage; raw_svector_ostream OS(ErrStorage); DiagnosticPrinterRawOStream DP(OS); DI.print(DP); warn(ErrStorage); }
static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { raw_ostream &OS = errs(); OS << (char *)Context << ": "; switch (DI.getSeverity()) { case DS_Error: OS << "error: "; break; case DS_Warning: OS << "warning: "; break; case DS_Remark: OS << "remark: "; break; case DS_Note: OS << "note: "; break; } DiagnosticPrinterRawOStream DP(OS); DI.print(DP); OS << '\n'; if (DI.getSeverity() == DS_Error) exit(1); }
void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. if (pImpl->DiagHandler && (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && pImpl->DiagHandler->handleDiagnostics(DI)) return; if (!isDiagnosticEnabled(DI)) return; // Otherwise, print the message with a prefix based on the severity. DiagnosticPrinterRawOStream DP(errs()); errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP); errs() << "\n"; if (DI.getSeverity() == DS_Error) exit(1); }
static void diagnosticHandler(const DiagnosticInfo &DI) { unsigned Severity = DI.getSeverity(); switch (Severity) { case DS_Error: errs() << "ERROR: "; break; case DS_Warning: if (SuppressWarnings) return; errs() << "WARNING: "; break; case DS_Remark: case DS_Note: llvm_unreachable("Only expecting warnings and errors"); } DiagnosticPrinterRawOStream DP(errs()); DI.print(DP); errs() << '\n'; }
void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info) { // Create a PathDiagnostic with a single piece. PathDiagnostic* D = new PathDiagnostic(); const char *LevelStr; switch (DiagLevel) { default: case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); case Diagnostic::Note: LevelStr = "note: "; break; case Diagnostic::Warning: LevelStr = "warning: "; break; case Diagnostic::Error: LevelStr = "error: "; break; case Diagnostic::Fatal: LevelStr = "fatal error: "; break; } llvm::SmallString<100> StrC; StrC += LevelStr; Info.FormatDiagnostic(StrC); PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Info.getLocation(), StrC.str()); for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) P->addRange(Info.getRange(i)); for (unsigned i = 0, e = Info.getNumCodeModificationHints(); i != e; ++i) P->addCodeModificationHint(Info.getCodeModificationHint(i)); D->push_front(P); HandlePathDiagnostic(D); }
void LLVMContext::diagnose(const DiagnosticInfo &DI) { if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) if (RemarkStreamer *RS = getRemarkStreamer()) RS->emit(*OptDiagBase); // If there is a report handler, use it. if (pImpl->DiagHandler && (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) && pImpl->DiagHandler->handleDiagnostics(DI)) return; if (!isDiagnosticEnabled(DI)) return; // Otherwise, print the message with a prefix based on the severity. DiagnosticPrinterRawOStream DP(errs()); errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP); errs() << "\n"; if (DI.getSeverity() == DS_Error) exit(1); }
static void diagnosticHandler(const DiagnosticInfo &DI) { std::string ErrStorage; { raw_string_ostream OS(ErrStorage); DiagnosticPrinterRawOStream DP(OS); DI.print(DP); } ld_plugin_level Level; switch (DI.getSeverity()) { case DS_Error: message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s", ErrStorage.c_str()); case DS_Warning: Level = LDPL_WARNING; break; case DS_Note: case DS_Remark: Level = LDPL_INFO; break; } message(Level, "LLVM gold plugin: %s", ErrStorage.c_str()); }
StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) : Level(Level), Loc(Info.getLocation()) { llvm::SmallString<64> Message; Info.FormatDiagnostic(Message); this->Message.assign(Message.begin(), Message.end()); Ranges.reserve(Info.getNumRanges()); for (unsigned I = 0, N = Info.getNumRanges(); I != N; ++I) Ranges.push_back(Info.getRange(I)); FixIts.reserve(Info.getNumCodeModificationHints()); for (unsigned I = 0, N = Info.getNumCodeModificationHints(); I != N; ++I) FixIts.push_back(Info.getCodeModificationHint(I)); }
void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. if (pImpl->DiagnosticHandler) { pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); return; } // Optimization remarks are selective. They need to check whether // the regexp pattern, passed via -pass-remarks, matches the name // of the pass that is emitting the diagnostic. If there is no match, // ignore the diagnostic and return. if (DI.getKind() == llvm::DK_OptimizationRemark && !pImpl->optimizationRemarksEnabledFor( cast<DiagnosticInfoOptimizationRemark>(DI).getPassName())) return; // Otherwise, print the message with a prefix based on the severity. std::string MsgStorage; raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); DI.print(DP); Stream.flush(); switch (DI.getSeverity()) { case DS_Error: errs() << "error: " << MsgStorage << "\n"; exit(1); case DS_Warning: errs() << "warning: " << MsgStorage << "\n"; break; case DS_Remark: errs() << "remark: " << MsgStorage << "\n"; break; case DS_Note: errs() << "note: " << MsgStorage << "\n"; break; } }
void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) { OS << ProgName << ": "; switch (Level) { case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); case Diagnostic::Note: OS << "note: "; break; case Diagnostic::Warning: OS << "warning: "; break; case Diagnostic::Error: OS << "error: "; break; case Diagnostic::Fatal: OS << "fatal error: "; break; } llvm::SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); OS.write(OutStr.begin(), OutStr.size()); OS << '\n'; }
/// HandleSelectModifier - Handle the integer 'select' modifier. This is used /// like this: %select{foo|bar|baz}2. This means that the integer argument /// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'. /// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'. /// This is very useful for certain classes of variant diagnostics. static void HandleSelectModifier(const DiagnosticInfo &DInfo, unsigned ValNo, const char *Argument, unsigned ArgumentLen, llvm::SmallVectorImpl<char> &OutStr) { const char *ArgumentEnd = Argument+ArgumentLen; // Skip over 'ValNo' |'s. while (ValNo) { const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|'); assert(NextVal != ArgumentEnd && "Value for integer select modifier was" " larger than the number of options in the diagnostic string!"); Argument = NextVal+1; // Skip this string. --ValNo; } // Get the end of the value. This is either the } or the |. const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|'); // Recursively format the result of the select clause into the output string. DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); }
/// HandlePluralModifier - Handle the integer 'plural' modifier. This is used /// for complex plural forms, or in languages where all plurals are complex. /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are /// conditions that are tested in order, the form corresponding to the first /// that applies being emitted. The empty condition is always true, making the /// last form a default case. /// Conditions are simple boolean expressions, where n is the number argument. /// Here are the rules. /// condition := expression | empty /// empty := -> always true /// expression := numeric [',' expression] -> logical or /// numeric := range -> true if n in range /// | '%' number '=' range -> true if n % number in range /// range := number /// | '[' number ',' number ']' -> ranges are inclusive both ends /// /// Here are some examples from the GNU gettext manual written in this form: /// English: /// {1:form0|:form1} /// Latvian: /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0} /// Gaeilge: /// {1:form0|2:form1|:form2} /// Romanian: /// {1:form0|0,%100=[1,19]:form1|:form2} /// Lithuanian: /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1} /// Russian (requires repeated form): /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2} /// Slovak /// {1:form0|[2,4]:form1|:form2} /// Polish (requires repeated form): /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2} static void HandlePluralModifier(const DiagnosticInfo &DInfo, unsigned ValNo, const char *Argument, unsigned ArgumentLen, llvm::SmallVectorImpl<char> &OutStr) { const char *ArgumentEnd = Argument + ArgumentLen; while (1) { assert(Argument < ArgumentEnd && "Plural expression didn't match."); const char *ExprEnd = Argument; while (*ExprEnd != ':') { assert(ExprEnd != ArgumentEnd && "Plural missing expression end"); ++ExprEnd; } if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { Argument = ExprEnd + 1; ExprEnd = ScanFormat(Argument, ArgumentEnd, '|'); // Recursively format the result of the plural clause into the // output string. DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr); return; } Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1; } }
void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info) { Client->HandleDiagnostic(DiagLevel, Info); // Skip over any diagnostics that are ignored or notes. if (DiagLevel <= Diagnostic::Note) return; // Make sure that we can perform all of the modifications we // in this diagnostic. bool CanRewrite = Info.getNumFixItHints() > 0; for (unsigned Idx = 0, Last = Info.getNumFixItHints(); Idx < Last; ++Idx) { const FixItHint &Hint = Info.getFixItHint(Idx); if (Hint.RemoveRange.isValid() && Rewrite.getRangeSize(Hint.RemoveRange) == -1) { CanRewrite = false; break; } } if (!CanRewrite) { if (Info.getNumFixItHints() > 0) Diag(Info.getLocation(), diag::note_fixit_in_macro); // If this was an error, refuse to perform any rewriting. if (DiagLevel == Diagnostic::Error || DiagLevel == Diagnostic::Fatal) { if (++NumFailures == 1) Diag(Info.getLocation(), diag::note_fixit_unfixed_error); } return; } bool Failed = false; for (unsigned Idx = 0, Last = Info.getNumFixItHints(); Idx < Last; ++Idx) { const FixItHint &Hint = Info.getFixItHint(Idx); if (Hint.CodeToInsert.empty()) { // We're removing code. if (Rewrite.RemoveText(Hint.RemoveRange.getBegin(), Rewrite.getRangeSize(Hint.RemoveRange))) Failed = true; continue; } // We're replacing code. if (Rewrite.ReplaceText(Hint.RemoveRange.getBegin(), Rewrite.getRangeSize(Hint.RemoveRange), Hint.CodeToInsert)) Failed = true; } if (Failed) { ++NumFailures; Diag(Info.getLocation(), diag::note_fixit_failed); return; } Diag(Info.getLocation(), diag::note_fixit_applied); }
void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info) { Client->HandleDiagnostic(DiagLevel, Info); // Skip over any diagnostics that are ignored. if (DiagLevel == Diagnostic::Ignored) return; if (!FixItLocations.empty()) { // The user has specified the locations where we should perform // the various fix-it modifications. // If this diagnostic does not have any code modifications, // completely ignore it, even if it's an error: fix-it locations // are meant to perform specific fix-ups even in the presence of // other errors. if (Info.getNumCodeModificationHints() == 0) return; // See if the location of the error is one that matches what the // user requested. bool AcceptableLocation = false; const FileEntry *File = Rewrite.getSourceMgr().getFileEntryForID( Info.getLocation().getFileID()); unsigned Line = Info.getLocation().getSpellingLineNumber(); unsigned Column = Info.getLocation().getSpellingColumnNumber(); for (llvm::SmallVector<RequestedSourceLocation, 4>::iterator Loc = FixItLocations.begin(), LocEnd = FixItLocations.end(); Loc != LocEnd; ++Loc) { if (Loc->File == File && Loc->Line == Line && Loc->Column == Column) { AcceptableLocation = true; break; } } if (!AcceptableLocation) return; } // Make sure that we can perform all of the modifications we // in this diagnostic. bool CanRewrite = Info.getNumCodeModificationHints() > 0; for (unsigned Idx = 0, Last = Info.getNumCodeModificationHints(); Idx < Last; ++Idx) { const CodeModificationHint &Hint = Info.getCodeModificationHint(Idx); if (Hint.RemoveRange.isValid() && Rewrite.getRangeSize(Hint.RemoveRange) == -1) { CanRewrite = false; break; } if (Hint.InsertionLoc.isValid() && !Rewrite.isRewritable(Hint.InsertionLoc)) { CanRewrite = false; break; } } if (!CanRewrite) { if (Info.getNumCodeModificationHints() > 0) Diag(Info.getLocation(), diag::note_fixit_in_macro); // If this was an error, refuse to perform any rewriting. if (DiagLevel == Diagnostic::Error || DiagLevel == Diagnostic::Fatal) { if (++NumFailures == 1) Diag(Info.getLocation(), diag::note_fixit_unfixed_error); } return; } bool Failed = false; for (unsigned Idx = 0, Last = Info.getNumCodeModificationHints(); Idx < Last; ++Idx) { const CodeModificationHint &Hint = Info.getCodeModificationHint(Idx); if (!Hint.RemoveRange.isValid()) { // We're adding code. if (Rewrite.InsertTextBefore(Hint.InsertionLoc, Hint.CodeToInsert)) Failed = true; continue; } if (Hint.CodeToInsert.empty()) { // We're removing code. if (Rewrite.RemoveText(Hint.RemoveRange.getBegin(), Rewrite.getRangeSize(Hint.RemoveRange))) Failed = true; continue; } // We're replacing code. if (Rewrite.ReplaceText(Hint.RemoveRange.getBegin(), Rewrite.getRangeSize(Hint.RemoveRange), Hint.CodeToInsert)) Failed = true; } if (Failed) { ++NumFailures; Diag(Info.getLocation(), diag::note_fixit_failed); return; } Diag(Info.getLocation(), diag::note_fixit_applied); }