1 /*===-- CXStoreDiagnostic.cpp - Diagnostics C Interface ----------*- C++ -*-===*\ 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 |* Implements part of the diagnostic functions of the Clang C interface. *| 11 |* *| 12 \*===----------------------------------------------------------------------===*/ 13 14 #include "CIndexDiagnostic.h" 15 #include "CIndexer.h" 16 #include "CXTranslationUnit.h" 17 #include "CXSourceLocation.h" 18 #include "CXString.h" 19 20 #include "clang/Frontend/ASTUnit.h" 21 #include "clang/Frontend/FrontendDiagnostic.h" 22 #include "llvm/ADT/SmallString.h" 23 #include "llvm/ADT/Twine.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 using namespace clang; 28 using namespace clang::cxloc; 29 using namespace clang::cxstring; 30 31 CXDiagnosticSeverity CXStoredDiagnostic::getSeverity() const { 32 switch (Diag.getLevel()) { 33 case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; 34 case DiagnosticsEngine::Note: return CXDiagnostic_Note; 35 case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; 36 case DiagnosticsEngine::Error: return CXDiagnostic_Error; 37 case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; 38 } 39 40 llvm_unreachable("Invalid diagnostic level"); 41 } 42 43 CXSourceLocation CXStoredDiagnostic::getLocation() const { 44 if (Diag.getLocation().isInvalid()) 45 return clang_getNullLocation(); 46 47 return translateSourceLocation(Diag.getLocation().getManager(), 48 LangOpts, Diag.getLocation()); 49 } 50 51 CXString CXStoredDiagnostic::getSpelling() const { 52 return createCXString(Diag.getMessage(), false); 53 } 54 55 CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const { 56 unsigned ID = Diag.getID(); 57 StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID); 58 if (!Option.empty()) { 59 if (Disable) 60 *Disable = createCXString((Twine("-Wno-") + Option).str()); 61 return createCXString((Twine("-W") + Option).str()); 62 } 63 64 if (ID == diag::fatal_too_many_errors) { 65 if (Disable) 66 *Disable = createCXString("-ferror-limit=0"); 67 return createCXString("-ferror-limit="); 68 } 69 70 bool EnabledByDefault; 71 if (DiagnosticIDs::isBuiltinExtensionDiag(ID, EnabledByDefault) && 72 !EnabledByDefault) 73 return createCXString("-pedantic"); 74 75 return createCXString(""); 76 } 77 78 unsigned CXStoredDiagnostic::getCategory() const { 79 return DiagnosticIDs::getCategoryNumberForDiag(Diag.getID()); 80 } 81 82 CXString CXStoredDiagnostic::getCategoryText() const { 83 unsigned catID = DiagnosticIDs::getCategoryNumberForDiag(Diag.getID()); 84 return createCXString(DiagnosticIDs::getCategoryNameFromID(catID)); 85 } 86 87 unsigned CXStoredDiagnostic::getNumRanges() const { 88 if (Diag.getLocation().isInvalid()) 89 return 0; 90 91 return Diag.range_size(); 92 } 93 94 CXSourceRange CXStoredDiagnostic::getRange(unsigned int Range) const { 95 assert(Diag.getLocation().isValid()); 96 return translateSourceRange(Diag.getLocation().getManager(), 97 LangOpts, 98 Diag.range_begin()[Range]); 99 } 100 101 unsigned CXStoredDiagnostic::getNumFixIts() const { 102 if (Diag.getLocation().isInvalid()) 103 return 0; 104 return Diag.fixit_size(); 105 } 106 107 CXString CXStoredDiagnostic::getFixIt(unsigned FixIt, 108 CXSourceRange *ReplacementRange) const { 109 const FixItHint &Hint = Diag.fixit_begin()[FixIt]; 110 if (ReplacementRange) { 111 // Create a range that covers the entire replacement (or 112 // removal) range, adjusting the end of the range to point to 113 // the end of the token. 114 *ReplacementRange = translateSourceRange(Diag.getLocation().getManager(), 115 LangOpts, Hint.RemoveRange); 116 } 117 return createCXString(Hint.CodeToInsert); 118 } 119 120