1 /** 2 * Copyright: Copyright (c) 2011 Jacob Carlborg. All rights reserved. 3 * Authors: Jacob Carlborg 4 * Version: Initial created: Oct 6, 2011 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module clang.Diagnostic; 8 9 import std.typecons : RefCounted; 10 11 import clang.c.Index; 12 import clang.Util; 13 14 struct Diagnostic 15 { 16 mixin CX; 17 18 string format (uint options = clang_defaultDiagnosticDisplayOptions) 19 { 20 return toD(clang_formatDiagnostic(cx, options)); 21 } 22 23 @property CXDiagnosticSeverity severity () 24 { 25 return clang_getDiagnosticSeverity(cx); 26 } 27 28 @property toString() 29 { 30 return format; 31 } 32 } 33 34 struct DiagnosticSet 35 { 36 private struct Container 37 { 38 CXDiagnosticSet set; 39 40 ~this() 41 { 42 if (set != null) 43 { 44 clang_disposeDiagnosticSet(set); 45 } 46 } 47 } 48 49 private RefCounted!Container container; 50 private size_t begin; 51 private size_t end; 52 53 private static RefCounted!Container makeContainer( 54 CXDiagnosticSet set) 55 { 56 RefCounted!Container result; 57 result.set = set; 58 return result; 59 } 60 61 private this( 62 RefCounted!Container container, 63 size_t begin, 64 size_t end) 65 { 66 this.container = container; 67 this.begin = begin; 68 this.end = end; 69 } 70 71 this(CXDiagnosticSet set) 72 { 73 container = makeContainer(set); 74 begin = 0; 75 end = clang_getNumDiagnosticsInSet(container.set); 76 } 77 78 @property bool empty() const 79 { 80 return begin >= end; 81 } 82 83 @property Diagnostic front() 84 { 85 return Diagnostic(clang_getDiagnosticInSet(container.set, cast(uint) begin)); 86 } 87 88 @property Diagnostic back() 89 { 90 return Diagnostic(clang_getDiagnosticInSet(container.set, cast(uint) (end - 1))); 91 } 92 93 @property void popFront() 94 { 95 ++begin; 96 } 97 98 @property void popBack() 99 { 100 --end; 101 } 102 103 @property DiagnosticSet save() 104 { 105 return this; 106 } 107 108 @property size_t length() const 109 { 110 return end - begin; 111 } 112 113 Diagnostic opIndex(size_t index) 114 { 115 return Diagnostic(clang_getDiagnosticInSet(container.set, cast(uint) (begin + index))); 116 } 117 118 DiagnosticSet opSlice(size_t begin, size_t end) 119 { 120 return DiagnosticSet(container, this.begin + begin, this.begin + end); 121 } 122 123 size_t opDollar() const 124 { 125 return length; 126 } 127 } 128 129 CXDiagnosticSeverity severity(DiagnosticSet diagnostics) 130 { 131 import std.algorithm.searching : minPos; 132 import std.algorithm.iteration : map; 133 134 alias less = (a, b) => cast(uint) a > cast(uint) b; 135 136 if (diagnostics.empty) 137 return CXDiagnosticSeverity.ignored; 138 else 139 return diagnostics.map!(diagnostic => diagnostic.severity).minPos!less.front; 140 } 141 142 bool hasError(DiagnosticSet diagnostics) 143 { 144 auto severity = diagnostics.severity; 145 146 return severity == CXDiagnosticSeverity.error || 147 severity == CXDiagnosticSeverity.fatal; 148 }