Home | History | Annotate | Download | only in Basic
      1 //===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file implements the Diagnostic-related interfaces.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Basic/CharInfo.h"
     15 #include "clang/Basic/Diagnostic.h"
     16 #include "clang/Basic/DiagnosticOptions.h"
     17 #include "clang/Basic/IdentifierTable.h"
     18 #include "clang/Basic/PartialDiagnostic.h"
     19 #include "llvm/ADT/SmallString.h"
     20 #include "llvm/ADT/StringExtras.h"
     21 #include "llvm/Support/CrashRecoveryContext.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 
     24 using namespace clang;
     25 
     26 static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
     27                                const char *Modifier, unsigned ML,
     28                                const char *Argument, unsigned ArgLen,
     29                                const DiagnosticsEngine::ArgumentValue *PrevArgs,
     30                                unsigned NumPrevArgs,
     31                                SmallVectorImpl<char> &Output,
     32                                void *Cookie,
     33                                ArrayRef<intptr_t> QualTypeVals) {
     34   const char *Str = "<can't format argument>";
     35   Output.append(Str, Str+strlen(Str));
     36 }
     37 
     38 
     39 DiagnosticsEngine::DiagnosticsEngine(
     40                        const IntrusiveRefCntPtr<DiagnosticIDs> &diags,
     41                        DiagnosticOptions *DiagOpts,
     42                        DiagnosticConsumer *client, bool ShouldOwnClient)
     43   : Diags(diags), DiagOpts(DiagOpts), Client(client),
     44     OwnsDiagClient(ShouldOwnClient), SourceMgr(0) {
     45   ArgToStringFn = DummyArgToStringFn;
     46   ArgToStringCookie = 0;
     47 
     48   AllExtensionsSilenced = 0;
     49   IgnoreAllWarnings = false;
     50   WarningsAsErrors = false;
     51   EnableAllWarnings = false;
     52   ErrorsAsFatal = false;
     53   SuppressSystemWarnings = false;
     54   SuppressAllDiagnostics = false;
     55   ElideType = true;
     56   PrintTemplateTree = false;
     57   ShowColors = false;
     58   ShowOverloads = Ovl_All;
     59   ExtBehavior = Ext_Ignore;
     60 
     61   ErrorLimit = 0;
     62   TemplateBacktraceLimit = 0;
     63   ConstexprBacktraceLimit = 0;
     64 
     65   Reset();
     66 }
     67 
     68 DiagnosticsEngine::~DiagnosticsEngine() {
     69   if (OwnsDiagClient)
     70     delete Client;
     71 }
     72 
     73 void DiagnosticsEngine::setClient(DiagnosticConsumer *client,
     74                                   bool ShouldOwnClient) {
     75   if (OwnsDiagClient && Client)
     76     delete Client;
     77 
     78   Client = client;
     79   OwnsDiagClient = ShouldOwnClient;
     80 }
     81 
     82 void DiagnosticsEngine::pushMappings(SourceLocation Loc) {
     83   DiagStateOnPushStack.push_back(GetCurDiagState());
     84 }
     85 
     86 bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
     87   if (DiagStateOnPushStack.empty())
     88     return false;
     89 
     90   if (DiagStateOnPushStack.back() != GetCurDiagState()) {
     91     // State changed at some point between push/pop.
     92     PushDiagStatePoint(DiagStateOnPushStack.back(), Loc);
     93   }
     94   DiagStateOnPushStack.pop_back();
     95   return true;
     96 }
     97 
     98 void DiagnosticsEngine::Reset() {
     99   ErrorOccurred = false;
    100   UncompilableErrorOccurred = false;
    101   FatalErrorOccurred = false;
    102   UnrecoverableErrorOccurred = false;
    103 
    104   NumWarnings = 0;
    105   NumErrors = 0;
    106   NumErrorsSuppressed = 0;
    107   TrapNumErrorsOccurred = 0;
    108   TrapNumUnrecoverableErrorsOccurred = 0;
    109 
    110   CurDiagID = ~0U;
    111   LastDiagLevel = DiagnosticIDs::Ignored;
    112   DelayedDiagID = 0;
    113 
    114   // Clear state related to #pragma diagnostic.
    115   DiagStates.clear();
    116   DiagStatePoints.clear();
    117   DiagStateOnPushStack.clear();
    118 
    119   // Create a DiagState and DiagStatePoint representing diagnostic changes
    120   // through command-line.
    121   DiagStates.push_back(DiagState());
    122   DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
    123 }
    124 
    125 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
    126                                              StringRef Arg2) {
    127   if (DelayedDiagID)
    128     return;
    129 
    130   DelayedDiagID = DiagID;
    131   DelayedDiagArg1 = Arg1.str();
    132   DelayedDiagArg2 = Arg2.str();
    133 }
    134 
    135 void DiagnosticsEngine::ReportDelayed() {
    136   Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2;
    137   DelayedDiagID = 0;
    138   DelayedDiagArg1.clear();
    139   DelayedDiagArg2.clear();
    140 }
    141 
    142 DiagnosticsEngine::DiagStatePointsTy::iterator
    143 DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const {
    144   assert(!DiagStatePoints.empty());
    145   assert(DiagStatePoints.front().Loc.isInvalid() &&
    146          "Should have created a DiagStatePoint for command-line");
    147 
    148   if (!SourceMgr)
    149     return DiagStatePoints.end() - 1;
    150 
    151   FullSourceLoc Loc(L, *SourceMgr);
    152   if (Loc.isInvalid())
    153     return DiagStatePoints.end() - 1;
    154 
    155   DiagStatePointsTy::iterator Pos = DiagStatePoints.end();
    156   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
    157   if (LastStateChangePos.isValid() &&
    158       Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
    159     Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
    160                            DiagStatePoint(0, Loc));
    161   --Pos;
    162   return Pos;
    163 }
    164 
    165 void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
    166                                              SourceLocation L) {
    167   assert(Diag < diag::DIAG_UPPER_LIMIT &&
    168          "Can only map builtin diagnostics");
    169   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
    170           (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
    171          "Cannot map errors into warnings!");
    172   assert(!DiagStatePoints.empty());
    173   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
    174 
    175   FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
    176   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
    177   // Don't allow a mapping to a warning override an error/fatal mapping.
    178   if (Map == diag::MAP_WARNING) {
    179     DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
    180     if (Info.getMapping() == diag::MAP_ERROR ||
    181         Info.getMapping() == diag::MAP_FATAL)
    182       Map = Info.getMapping();
    183   }
    184   DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L);
    185 
    186   // Common case; setting all the diagnostics of a group in one place.
    187   if (Loc.isInvalid() || Loc == LastStateChangePos) {
    188     GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
    189     return;
    190   }
    191 
    192   // Another common case; modifying diagnostic state in a source location
    193   // after the previous one.
    194   if ((Loc.isValid() && LastStateChangePos.isInvalid()) ||
    195       LastStateChangePos.isBeforeInTranslationUnitThan(Loc)) {
    196     // A diagnostic pragma occurred, create a new DiagState initialized with
    197     // the current one and a new DiagStatePoint to record at which location
    198     // the new state became active.
    199     DiagStates.push_back(*GetCurDiagState());
    200     PushDiagStatePoint(&DiagStates.back(), Loc);
    201     GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
    202     return;
    203   }
    204 
    205   // We allow setting the diagnostic state in random source order for
    206   // completeness but it should not be actually happening in normal practice.
    207 
    208   DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc);
    209   assert(Pos != DiagStatePoints.end());
    210 
    211   // Update all diagnostic states that are active after the given location.
    212   for (DiagStatePointsTy::iterator
    213          I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
    214     GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
    215   }
    216 
    217   // If the location corresponds to an existing point, just update its state.
    218   if (Pos->Loc == Loc) {
    219     GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
    220     return;
    221   }
    222 
    223   // Create a new state/point and fit it into the vector of DiagStatePoints
    224   // so that the vector is always ordered according to location.
    225   Pos->Loc.isBeforeInTranslationUnitThan(Loc);
    226   DiagStates.push_back(*Pos->State);
    227   DiagState *NewState = &DiagStates.back();
    228   GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
    229   DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
    230                                                FullSourceLoc(Loc, *SourceMgr)));
    231 }
    232 
    233 bool DiagnosticsEngine::setDiagnosticGroupMapping(
    234   StringRef Group, diag::Mapping Map, SourceLocation Loc)
    235 {
    236   // Get the diagnostics in this group.
    237   SmallVector<diag::kind, 8> GroupDiags;
    238   if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
    239     return true;
    240 
    241   // Set the mapping.
    242   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i)
    243     setDiagnosticMapping(GroupDiags[i], Map, Loc);
    244 
    245   return false;
    246 }
    247 
    248 void DiagnosticsEngine::setDiagnosticWarningAsError(diag::kind Diag,
    249                                                     bool Enabled) {
    250   // If we are enabling this feature, just set the diagnostic mappings to map to
    251   // errors.
    252   if (Enabled)
    253     setDiagnosticMapping(Diag, diag::MAP_ERROR, SourceLocation());
    254 
    255   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
    256   // potentially downgrade anything already mapped to be a warning.
    257   DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
    258 
    259   if (Info.getMapping() == diag::MAP_ERROR ||
    260       Info.getMapping() == diag::MAP_FATAL)
    261     Info.setMapping(diag::MAP_WARNING);
    262 
    263   Info.setNoWarningAsError(true);
    264 }
    265 
    266 bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
    267                                                          bool Enabled) {
    268   // If we are enabling this feature, just set the diagnostic mappings to map to
    269   // errors.
    270   if (Enabled)
    271     return setDiagnosticGroupMapping(Group, diag::MAP_ERROR);
    272 
    273   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
    274   // potentially downgrade anything already mapped to be a warning.
    275 
    276   // Get the diagnostics in this group.
    277   SmallVector<diag::kind, 8> GroupDiags;
    278   if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
    279     return true;
    280 
    281   // Perform the mapping change.
    282   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
    283     DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
    284       GroupDiags[i]);
    285 
    286     if (Info.getMapping() == diag::MAP_ERROR ||
    287         Info.getMapping() == diag::MAP_FATAL)
    288       Info.setMapping(diag::MAP_WARNING);
    289 
    290     Info.setNoWarningAsError(true);
    291   }
    292 
    293   return false;
    294 }
    295 
    296 void DiagnosticsEngine::setDiagnosticErrorAsFatal(diag::kind Diag,
    297                                                   bool Enabled) {
    298   // If we are enabling this feature, just set the diagnostic mappings to map to
    299   // errors.
    300   if (Enabled)
    301     setDiagnosticMapping(Diag, diag::MAP_FATAL, SourceLocation());
    302 
    303   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
    304   // potentially downgrade anything already mapped to be a warning.
    305   DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
    306 
    307   if (Info.getMapping() == diag::MAP_FATAL)
    308     Info.setMapping(diag::MAP_ERROR);
    309 
    310   Info.setNoErrorAsFatal(true);
    311 }
    312 
    313 bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
    314                                                        bool Enabled) {
    315   // If we are enabling this feature, just set the diagnostic mappings to map to
    316   // fatal errors.
    317   if (Enabled)
    318     return setDiagnosticGroupMapping(Group, diag::MAP_FATAL);
    319 
    320   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
    321   // potentially downgrade anything already mapped to be an error.
    322 
    323   // Get the diagnostics in this group.
    324   SmallVector<diag::kind, 8> GroupDiags;
    325   if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
    326     return true;
    327 
    328   // Perform the mapping change.
    329   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
    330     DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
    331       GroupDiags[i]);
    332 
    333     if (Info.getMapping() == diag::MAP_FATAL)
    334       Info.setMapping(diag::MAP_ERROR);
    335 
    336     Info.setNoErrorAsFatal(true);
    337   }
    338 
    339   return false;
    340 }
    341 
    342 void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map,
    343                                                    SourceLocation Loc) {
    344   // Get all the diagnostics.
    345   SmallVector<diag::kind, 64> AllDiags;
    346   Diags->getAllDiagnostics(AllDiags);
    347 
    348   // Set the mapping.
    349   for (unsigned i = 0, e = AllDiags.size(); i != e; ++i)
    350     if (Diags->isBuiltinWarningOrExtension(AllDiags[i]))
    351       setDiagnosticMapping(AllDiags[i], Map, Loc);
    352 }
    353 
    354 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
    355   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
    356 
    357   CurDiagLoc = storedDiag.getLocation();
    358   CurDiagID = storedDiag.getID();
    359   NumDiagArgs = 0;
    360 
    361   NumDiagRanges = storedDiag.range_size();
    362   assert(NumDiagRanges < DiagnosticsEngine::MaxRanges &&
    363          "Too many arguments to diagnostic!");
    364   unsigned i = 0;
    365   for (StoredDiagnostic::range_iterator
    366          RI = storedDiag.range_begin(),
    367          RE = storedDiag.range_end(); RI != RE; ++RI)
    368     DiagRanges[i++] = *RI;
    369 
    370   assert(NumDiagRanges < DiagnosticsEngine::MaxFixItHints &&
    371          "Too many arguments to diagnostic!");
    372   NumDiagFixItHints = 0;
    373   for (StoredDiagnostic::fixit_iterator
    374          FI = storedDiag.fixit_begin(),
    375          FE = storedDiag.fixit_end(); FI != FE; ++FI)
    376     DiagFixItHints[NumDiagFixItHints++] = *FI;
    377 
    378   assert(Client && "DiagnosticConsumer not set!");
    379   Level DiagLevel = storedDiag.getLevel();
    380   Diagnostic Info(this, storedDiag.getMessage());
    381   Client->HandleDiagnostic(DiagLevel, Info);
    382   if (Client->IncludeInDiagnosticCounts()) {
    383     if (DiagLevel == DiagnosticsEngine::Warning)
    384       ++NumWarnings;
    385   }
    386 
    387   CurDiagID = ~0U;
    388 }
    389 
    390 bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) {
    391   assert(getClient() && "DiagnosticClient not set!");
    392 
    393   bool Emitted;
    394   if (Force) {
    395     Diagnostic Info(this);
    396 
    397     // Figure out the diagnostic level of this message.
    398     DiagnosticIDs::Level DiagLevel
    399       = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
    400 
    401     Emitted = (DiagLevel != DiagnosticIDs::Ignored);
    402     if (Emitted) {
    403       // Emit the diagnostic regardless of suppression level.
    404       Diags->EmitDiag(*this, DiagLevel);
    405     }
    406   } else {
    407     // Process the diagnostic, sending the accumulated information to the
    408     // DiagnosticConsumer.
    409     Emitted = ProcessDiag();
    410   }
    411 
    412   // Clear out the current diagnostic object.
    413   unsigned DiagID = CurDiagID;
    414   Clear();
    415 
    416   // If there was a delayed diagnostic, emit it now.
    417   if (!Force && DelayedDiagID && DelayedDiagID != DiagID)
    418     ReportDelayed();
    419 
    420   return Emitted;
    421 }
    422 
    423 
    424 DiagnosticConsumer::~DiagnosticConsumer() {}
    425 
    426 void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
    427                                         const Diagnostic &Info) {
    428   if (!IncludeInDiagnosticCounts())
    429     return;
    430 
    431   if (DiagLevel == DiagnosticsEngine::Warning)
    432     ++NumWarnings;
    433   else if (DiagLevel >= DiagnosticsEngine::Error)
    434     ++NumErrors;
    435 }
    436 
    437 /// ModifierIs - Return true if the specified modifier matches specified string.
    438 template <std::size_t StrLen>
    439 static bool ModifierIs(const char *Modifier, unsigned ModifierLen,
    440                        const char (&Str)[StrLen]) {
    441   return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1);
    442 }
    443 
    444 /// ScanForward - Scans forward, looking for the given character, skipping
    445 /// nested clauses and escaped characters.
    446 static const char *ScanFormat(const char *I, const char *E, char Target) {
    447   unsigned Depth = 0;
    448 
    449   for ( ; I != E; ++I) {
    450     if (Depth == 0 && *I == Target) return I;
    451     if (Depth != 0 && *I == '}') Depth--;
    452 
    453     if (*I == '%') {
    454       I++;
    455       if (I == E) break;
    456 
    457       // Escaped characters get implicitly skipped here.
    458 
    459       // Format specifier.
    460       if (!isDigit(*I) && !isPunctuation(*I)) {
    461         for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ;
    462         if (I == E) break;
    463         if (*I == '{')
    464           Depth++;
    465       }
    466     }
    467   }
    468   return E;
    469 }
    470 
    471 /// HandleSelectModifier - Handle the integer 'select' modifier.  This is used
    472 /// like this:  %select{foo|bar|baz}2.  This means that the integer argument
    473 /// "%2" has a value from 0-2.  If the value is 0, the diagnostic prints 'foo'.
    474 /// If the value is 1, it prints 'bar'.  If it has the value 2, it prints 'baz'.
    475 /// This is very useful for certain classes of variant diagnostics.
    476 static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo,
    477                                  const char *Argument, unsigned ArgumentLen,
    478                                  SmallVectorImpl<char> &OutStr) {
    479   const char *ArgumentEnd = Argument+ArgumentLen;
    480 
    481   // Skip over 'ValNo' |'s.
    482   while (ValNo) {
    483     const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|');
    484     assert(NextVal != ArgumentEnd && "Value for integer select modifier was"
    485            " larger than the number of options in the diagnostic string!");
    486     Argument = NextVal+1;  // Skip this string.
    487     --ValNo;
    488   }
    489 
    490   // Get the end of the value.  This is either the } or the |.
    491   const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|');
    492 
    493   // Recursively format the result of the select clause into the output string.
    494   DInfo.FormatDiagnostic(Argument, EndPtr, OutStr);
    495 }
    496 
    497 /// HandleIntegerSModifier - Handle the integer 's' modifier.  This adds the
    498 /// letter 's' to the string if the value is not 1.  This is used in cases like
    499 /// this:  "you idiot, you have %4 parameter%s4!".
    500 static void HandleIntegerSModifier(unsigned ValNo,
    501                                    SmallVectorImpl<char> &OutStr) {
    502   if (ValNo != 1)
    503     OutStr.push_back('s');
    504 }
    505 
    506 /// HandleOrdinalModifier - Handle the integer 'ord' modifier.  This
    507 /// prints the ordinal form of the given integer, with 1 corresponding
    508 /// to the first ordinal.  Currently this is hard-coded to use the
    509 /// English form.
    510 static void HandleOrdinalModifier(unsigned ValNo,
    511                                   SmallVectorImpl<char> &OutStr) {
    512   assert(ValNo != 0 && "ValNo must be strictly positive!");
    513 
    514   llvm::raw_svector_ostream Out(OutStr);
    515 
    516   // We could use text forms for the first N ordinals, but the numeric
    517   // forms are actually nicer in diagnostics because they stand out.
    518   Out << ValNo << llvm::getOrdinalSuffix(ValNo);
    519 }
    520 
    521 
    522 /// PluralNumber - Parse an unsigned integer and advance Start.
    523 static unsigned PluralNumber(const char *&Start, const char *End) {
    524   // Programming 101: Parse a decimal number :-)
    525   unsigned Val = 0;
    526   while (Start != End && *Start >= '0' && *Start <= '9') {
    527     Val *= 10;
    528     Val += *Start - '0';
    529     ++Start;
    530   }
    531   return Val;
    532 }
    533 
    534 /// TestPluralRange - Test if Val is in the parsed range. Modifies Start.
    535 static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) {
    536   if (*Start != '[') {
    537     unsigned Ref = PluralNumber(Start, End);
    538     return Ref == Val;
    539   }
    540 
    541   ++Start;
    542   unsigned Low = PluralNumber(Start, End);
    543   assert(*Start == ',' && "Bad plural expression syntax: expected ,");
    544   ++Start;
    545   unsigned High = PluralNumber(Start, End);
    546   assert(*Start == ']' && "Bad plural expression syntax: expected )");
    547   ++Start;
    548   return Low <= Val && Val <= High;
    549 }
    550 
    551 /// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier.
    552 static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
    553   // Empty condition?
    554   if (*Start == ':')
    555     return true;
    556 
    557   while (1) {
    558     char C = *Start;
    559     if (C == '%') {
    560       // Modulo expression
    561       ++Start;
    562       unsigned Arg = PluralNumber(Start, End);
    563       assert(*Start == '=' && "Bad plural expression syntax: expected =");
    564       ++Start;
    565       unsigned ValMod = ValNo % Arg;
    566       if (TestPluralRange(ValMod, Start, End))
    567         return true;
    568     } else {
    569       assert((C == '[' || (C >= '0' && C <= '9')) &&
    570              "Bad plural expression syntax: unexpected character");
    571       // Range expression
    572       if (TestPluralRange(ValNo, Start, End))
    573         return true;
    574     }
    575 
    576     // Scan for next or-expr part.
    577     Start = std::find(Start, End, ',');
    578     if (Start == End)
    579       break;
    580     ++Start;
    581   }
    582   return false;
    583 }
    584 
    585 /// HandlePluralModifier - Handle the integer 'plural' modifier. This is used
    586 /// for complex plural forms, or in languages where all plurals are complex.
    587 /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are
    588 /// conditions that are tested in order, the form corresponding to the first
    589 /// that applies being emitted. The empty condition is always true, making the
    590 /// last form a default case.
    591 /// Conditions are simple boolean expressions, where n is the number argument.
    592 /// Here are the rules.
    593 /// condition  := expression | empty
    594 /// empty      :=                             -> always true
    595 /// expression := numeric [',' expression]    -> logical or
    596 /// numeric    := range                       -> true if n in range
    597 ///             | '%' number '=' range        -> true if n % number in range
    598 /// range      := number
    599 ///             | '[' number ',' number ']'   -> ranges are inclusive both ends
    600 ///
    601 /// Here are some examples from the GNU gettext manual written in this form:
    602 /// English:
    603 /// {1:form0|:form1}
    604 /// Latvian:
    605 /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0}
    606 /// Gaeilge:
    607 /// {1:form0|2:form1|:form2}
    608 /// Romanian:
    609 /// {1:form0|0,%100=[1,19]:form1|:form2}
    610 /// Lithuanian:
    611 /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1}
    612 /// Russian (requires repeated form):
    613 /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2}
    614 /// Slovak
    615 /// {1:form0|[2,4]:form1|:form2}
    616 /// Polish (requires repeated form):
    617 /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
    618 static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
    619                                  const char *Argument, unsigned ArgumentLen,
    620                                  SmallVectorImpl<char> &OutStr) {
    621   const char *ArgumentEnd = Argument + ArgumentLen;
    622   while (1) {
    623     assert(Argument < ArgumentEnd && "Plural expression didn't match.");
    624     const char *ExprEnd = Argument;
    625     while (*ExprEnd != ':') {
    626       assert(ExprEnd != ArgumentEnd && "Plural missing expression end");
    627       ++ExprEnd;
    628     }
    629     if (EvalPluralExpr(ValNo, Argument, ExprEnd)) {
    630       Argument = ExprEnd + 1;
    631       ExprEnd = ScanFormat(Argument, ArgumentEnd, '|');
    632 
    633       // Recursively format the result of the plural clause into the
    634       // output string.
    635       DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr);
    636       return;
    637     }
    638     Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1;
    639   }
    640 }
    641 
    642 
    643 /// FormatDiagnostic - Format this diagnostic into a string, substituting the
    644 /// formal arguments into the %0 slots.  The result is appended onto the Str
    645 /// array.
    646 void Diagnostic::
    647 FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
    648   if (!StoredDiagMessage.empty()) {
    649     OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
    650     return;
    651   }
    652 
    653   StringRef Diag =
    654     getDiags()->getDiagnosticIDs()->getDescription(getID());
    655 
    656   FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
    657 }
    658 
    659 void Diagnostic::
    660 FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
    661                  SmallVectorImpl<char> &OutStr) const {
    662 
    663   /// FormattedArgs - Keep track of all of the arguments formatted by
    664   /// ConvertArgToString and pass them into subsequent calls to
    665   /// ConvertArgToString, allowing the implementation to avoid redundancies in
    666   /// obvious cases.
    667   SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs;
    668 
    669   /// QualTypeVals - Pass a vector of arrays so that QualType names can be
    670   /// compared to see if more information is needed to be printed.
    671   SmallVector<intptr_t, 2> QualTypeVals;
    672   SmallVector<char, 64> Tree;
    673 
    674   for (unsigned i = 0, e = getNumArgs(); i < e; ++i)
    675     if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
    676       QualTypeVals.push_back(getRawArg(i));
    677 
    678   while (DiagStr != DiagEnd) {
    679     if (DiagStr[0] != '%') {
    680       // Append non-%0 substrings to Str if we have one.
    681       const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
    682       OutStr.append(DiagStr, StrEnd);
    683       DiagStr = StrEnd;
    684       continue;
    685     } else if (isPunctuation(DiagStr[1])) {
    686       OutStr.push_back(DiagStr[1]);  // %% -> %.
    687       DiagStr += 2;
    688       continue;
    689     }
    690 
    691     // Skip the %.
    692     ++DiagStr;
    693 
    694     // This must be a placeholder for a diagnostic argument.  The format for a
    695     // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0".
    696     // The digit is a number from 0-9 indicating which argument this comes from.
    697     // The modifier is a string of digits from the set [-a-z]+, arguments is a
    698     // brace enclosed string.
    699     const char *Modifier = 0, *Argument = 0;
    700     unsigned ModifierLen = 0, ArgumentLen = 0;
    701 
    702     // Check to see if we have a modifier.  If so eat it.
    703     if (!isDigit(DiagStr[0])) {
    704       Modifier = DiagStr;
    705       while (DiagStr[0] == '-' ||
    706              (DiagStr[0] >= 'a' && DiagStr[0] <= 'z'))
    707         ++DiagStr;
    708       ModifierLen = DiagStr-Modifier;
    709 
    710       // If we have an argument, get it next.
    711       if (DiagStr[0] == '{') {
    712         ++DiagStr; // Skip {.
    713         Argument = DiagStr;
    714 
    715         DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
    716         assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
    717         ArgumentLen = DiagStr-Argument;
    718         ++DiagStr;  // Skip }.
    719       }
    720     }
    721 
    722     assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic");
    723     unsigned ArgNo = *DiagStr++ - '0';
    724 
    725     // Only used for type diffing.
    726     unsigned ArgNo2 = ArgNo;
    727 
    728     DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
    729     if (ModifierIs(Modifier, ModifierLen, "diff")) {
    730       assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) &&
    731              "Invalid format for diff modifier");
    732       ++DiagStr;  // Comma.
    733       ArgNo2 = *DiagStr++ - '0';
    734       DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2);
    735       if (Kind == DiagnosticsEngine::ak_qualtype &&
    736           Kind2 == DiagnosticsEngine::ak_qualtype)
    737         Kind = DiagnosticsEngine::ak_qualtype_pair;
    738       else {
    739         // %diff only supports QualTypes.  For other kinds of arguments,
    740         // use the default printing.  For example, if the modifier is:
    741         //   "%diff{compare $ to $|other text}1,2"
    742         // treat it as:
    743         //   "compare %1 to %2"
    744         const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|');
    745         const char *FirstDollar = ScanFormat(Argument, Pipe, '$');
    746         const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$');
    747         const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) };
    748         const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) };
    749         FormatDiagnostic(Argument, FirstDollar, OutStr);
    750         FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr);
    751         FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
    752         FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr);
    753         FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
    754         continue;
    755       }
    756     }
    757 
    758     switch (Kind) {
    759     // ---- STRINGS ----
    760     case DiagnosticsEngine::ak_std_string: {
    761       const std::string &S = getArgStdStr(ArgNo);
    762       assert(ModifierLen == 0 && "No modifiers for strings yet");
    763       OutStr.append(S.begin(), S.end());
    764       break;
    765     }
    766     case DiagnosticsEngine::ak_c_string: {
    767       const char *S = getArgCStr(ArgNo);
    768       assert(ModifierLen == 0 && "No modifiers for strings yet");
    769 
    770       // Don't crash if get passed a null pointer by accident.
    771       if (!S)
    772         S = "(null)";
    773 
    774       OutStr.append(S, S + strlen(S));
    775       break;
    776     }
    777     // ---- INTEGERS ----
    778     case DiagnosticsEngine::ak_sint: {
    779       int Val = getArgSInt(ArgNo);
    780 
    781       if (ModifierIs(Modifier, ModifierLen, "select")) {
    782         HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen,
    783                              OutStr);
    784       } else if (ModifierIs(Modifier, ModifierLen, "s")) {
    785         HandleIntegerSModifier(Val, OutStr);
    786       } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
    787         HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
    788                              OutStr);
    789       } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
    790         HandleOrdinalModifier((unsigned)Val, OutStr);
    791       } else {
    792         assert(ModifierLen == 0 && "Unknown integer modifier");
    793         llvm::raw_svector_ostream(OutStr) << Val;
    794       }
    795       break;
    796     }
    797     case DiagnosticsEngine::ak_uint: {
    798       unsigned Val = getArgUInt(ArgNo);
    799 
    800       if (ModifierIs(Modifier, ModifierLen, "select")) {
    801         HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
    802       } else if (ModifierIs(Modifier, ModifierLen, "s")) {
    803         HandleIntegerSModifier(Val, OutStr);
    804       } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
    805         HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
    806                              OutStr);
    807       } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
    808         HandleOrdinalModifier(Val, OutStr);
    809       } else {
    810         assert(ModifierLen == 0 && "Unknown integer modifier");
    811         llvm::raw_svector_ostream(OutStr) << Val;
    812       }
    813       break;
    814     }
    815     // ---- NAMES and TYPES ----
    816     case DiagnosticsEngine::ak_identifierinfo: {
    817       const IdentifierInfo *II = getArgIdentifier(ArgNo);
    818       assert(ModifierLen == 0 && "No modifiers for strings yet");
    819 
    820       // Don't crash if get passed a null pointer by accident.
    821       if (!II) {
    822         const char *S = "(null)";
    823         OutStr.append(S, S + strlen(S));
    824         continue;
    825       }
    826 
    827       llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
    828       break;
    829     }
    830     case DiagnosticsEngine::ak_qualtype:
    831     case DiagnosticsEngine::ak_declarationname:
    832     case DiagnosticsEngine::ak_nameddecl:
    833     case DiagnosticsEngine::ak_nestednamespec:
    834     case DiagnosticsEngine::ak_declcontext:
    835       getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
    836                                      Modifier, ModifierLen,
    837                                      Argument, ArgumentLen,
    838                                      FormattedArgs.data(), FormattedArgs.size(),
    839                                      OutStr, QualTypeVals);
    840       break;
    841     case DiagnosticsEngine::ak_qualtype_pair:
    842       // Create a struct with all the info needed for printing.
    843       TemplateDiffTypes TDT;
    844       TDT.FromType = getRawArg(ArgNo);
    845       TDT.ToType = getRawArg(ArgNo2);
    846       TDT.ElideType = getDiags()->ElideType;
    847       TDT.ShowColors = getDiags()->ShowColors;
    848       TDT.TemplateDiffUsed = false;
    849       intptr_t val = reinterpret_cast<intptr_t>(&TDT);
    850 
    851       const char *ArgumentEnd = Argument + ArgumentLen;
    852       const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
    853 
    854       // Print the tree.  If this diagnostic already has a tree, skip the
    855       // second tree.
    856       if (getDiags()->PrintTemplateTree && Tree.empty()) {
    857         TDT.PrintFromType = true;
    858         TDT.PrintTree = true;
    859         getDiags()->ConvertArgToString(Kind, val,
    860                                        Modifier, ModifierLen,
    861                                        Argument, ArgumentLen,
    862                                        FormattedArgs.data(),
    863                                        FormattedArgs.size(),
    864                                        Tree, QualTypeVals);
    865         // If there is no tree information, fall back to regular printing.
    866         if (!Tree.empty()) {
    867           FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr);
    868           break;
    869         }
    870       }
    871 
    872       // Non-tree printing, also the fall-back when tree printing fails.
    873       // The fall-back is triggered when the types compared are not templates.
    874       const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
    875       const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
    876 
    877       // Append before text
    878       FormatDiagnostic(Argument, FirstDollar, OutStr);
    879 
    880       // Append first type
    881       TDT.PrintTree = false;
    882       TDT.PrintFromType = true;
    883       getDiags()->ConvertArgToString(Kind, val,
    884                                      Modifier, ModifierLen,
    885                                      Argument, ArgumentLen,
    886                                      FormattedArgs.data(), FormattedArgs.size(),
    887                                      OutStr, QualTypeVals);
    888       if (!TDT.TemplateDiffUsed)
    889         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
    890                                                TDT.FromType));
    891 
    892       // Append middle text
    893       FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
    894 
    895       // Append second type
    896       TDT.PrintFromType = false;
    897       getDiags()->ConvertArgToString(Kind, val,
    898                                      Modifier, ModifierLen,
    899                                      Argument, ArgumentLen,
    900                                      FormattedArgs.data(), FormattedArgs.size(),
    901                                      OutStr, QualTypeVals);
    902       if (!TDT.TemplateDiffUsed)
    903         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
    904                                                TDT.ToType));
    905 
    906       // Append end text
    907       FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
    908       break;
    909     }
    910 
    911     // Remember this argument info for subsequent formatting operations.  Turn
    912     // std::strings into a null terminated string to make it be the same case as
    913     // all the other ones.
    914     if (Kind == DiagnosticsEngine::ak_qualtype_pair)
    915       continue;
    916     else if (Kind != DiagnosticsEngine::ak_std_string)
    917       FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
    918     else
    919       FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string,
    920                                         (intptr_t)getArgStdStr(ArgNo).c_str()));
    921 
    922   }
    923 
    924   // Append the type tree to the end of the diagnostics.
    925   OutStr.append(Tree.begin(), Tree.end());
    926 }
    927 
    928 StoredDiagnostic::StoredDiagnostic() { }
    929 
    930 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
    931                                    StringRef Message)
    932   : ID(ID), Level(Level), Loc(), Message(Message) { }
    933 
    934 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level,
    935                                    const Diagnostic &Info)
    936   : ID(Info.getID()), Level(Level)
    937 {
    938   assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
    939        "Valid source location without setting a source manager for diagnostic");
    940   if (Info.getLocation().isValid())
    941     Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
    942   SmallString<64> Message;
    943   Info.FormatDiagnostic(Message);
    944   this->Message.assign(Message.begin(), Message.end());
    945 
    946   Ranges.reserve(Info.getNumRanges());
    947   for (unsigned I = 0, N = Info.getNumRanges(); I != N; ++I)
    948     Ranges.push_back(Info.getRange(I));
    949 
    950   FixIts.reserve(Info.getNumFixItHints());
    951   for (unsigned I = 0, N = Info.getNumFixItHints(); I != N; ++I)
    952     FixIts.push_back(Info.getFixItHint(I));
    953 }
    954 
    955 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
    956                                    StringRef Message, FullSourceLoc Loc,
    957                                    ArrayRef<CharSourceRange> Ranges,
    958                                    ArrayRef<FixItHint> FixIts)
    959   : ID(ID), Level(Level), Loc(Loc), Message(Message),
    960     Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end())
    961 {
    962 }
    963 
    964 StoredDiagnostic::~StoredDiagnostic() { }
    965 
    966 /// IncludeInDiagnosticCounts - This method (whose default implementation
    967 ///  returns true) indicates whether the diagnostics handled by this
    968 ///  DiagnosticConsumer should be included in the number of diagnostics
    969 ///  reported by DiagnosticsEngine.
    970 bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
    971 
    972 void IgnoringDiagConsumer::anchor() { }
    973 
    974 ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() {}
    975 
    976 void ForwardingDiagnosticConsumer::HandleDiagnostic(
    977        DiagnosticsEngine::Level DiagLevel,
    978        const Diagnostic &Info) {
    979   Target.HandleDiagnostic(DiagLevel, Info);
    980 }
    981 
    982 void ForwardingDiagnosticConsumer::clear() {
    983   DiagnosticConsumer::clear();
    984   Target.clear();
    985 }
    986 
    987 bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const {
    988   return Target.IncludeInDiagnosticCounts();
    989 }
    990 
    991 PartialDiagnostic::StorageAllocator::StorageAllocator() {
    992   for (unsigned I = 0; I != NumCached; ++I)
    993     FreeList[I] = Cached + I;
    994   NumFreeListEntries = NumCached;
    995 }
    996 
    997 PartialDiagnostic::StorageAllocator::~StorageAllocator() {
    998   // Don't assert if we are in a CrashRecovery context, as this invariant may
    999   // be invalidated during a crash.
   1000   assert((NumFreeListEntries == NumCached ||
   1001           llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
   1002          "A partial is on the lamb");
   1003 }
   1004