}
/// Stream operator for new diagnostic arguments.
+ template <typename Arg> InFlightDiagnostic &operator<<(Arg &&arg) & {
+ return append(std::forward<Arg>(arg));
+ }
template <typename Arg> InFlightDiagnostic &&operator<<(Arg &&arg) && {
- appendArgument(std::forward<Arg>(arg));
- return std::move(*this);
+ return std::move(append(std::forward<Arg>(arg)));
}
- template <typename Arg> InFlightDiagnostic &operator<<(Arg &&arg) & {
- appendArgument(std::forward<Arg>(arg));
+
+ /// Append arguments to the diagnostic.
+ template <typename... Args> InFlightDiagnostic &append(Args &&... args) & {
+ assert(isActive() && "diagnostic not active");
+ if (isInFlight())
+ impl->append(std::forward<Args>(args)...);
return *this;
}
+ template <typename... Args> InFlightDiagnostic &&append(Args &&... args) && {
+ return std::move(append(std::forward<Args>(args)...));
+ }
/// Attaches a note to this diagnostic.
Diagnostic &attachNote(llvm::Optional<Location> noteLoc = llvm::None) {
InFlightDiagnostic(DiagnosticEngine *owner, Diagnostic &&rhs)
: owner(owner), impl(std::move(rhs)) {}
- /// Add an argument to the internal diagnostic.
- template <typename Arg> void appendArgument(Arg &&arg) {
- assert(isActive() && "diagnostic not active");
- if (isInFlight())
- *impl << std::forward<Arg>(arg);
- }
-
/// Returns if the diagnostic is still active, i.e. it has a live diagnostic.
bool isActive() const { return impl.hasValue(); }
if (result->getType() == type)
return result;
- emitError(useInfo.loc, "use of value '" + useInfo.name.str() +
- "' expects different type than prior uses");
- emitError(entries[useInfo.number].second, "prior use here");
+ emitError(useInfo.loc, "use of value '")
+ .append(useInfo.name, "' expects different type than prior uses")
+ .attachNote(getEncodedSourceLocation(entries[useInfo.number].second))
+ .append("prior use here");
return nullptr;
}
// or a forward reference.
if (auto *existing = entries[useInfo.number].first) {
if (!isForwardReferencePlaceholder(existing)) {
- emitError(useInfo.loc,
- "redefinition of SSA value '" + useInfo.name + "'");
- return emitError(entries[useInfo.number].second,
- "previously defined here");
+ emitError(useInfo.loc)
+ .append("redefinition of SSA value '", useInfo.name, "'")
+ .attachNote(getEncodedSourceLocation(entries[useInfo.number].second))
+ .append("previously defined here");
+ return failure();
}
// If it was a forward reference, update everything that used it to use
// Comparison are defined for arguments of the same type.
func @func_with_ops(i32, i64) {
-^bb0(%a : i32, %b : i64): // expected-error {{prior use here}}
+^bb0(%a : i32, %b : i64): // expected-note {{prior use here}}
%r = cmpi "eq", %a, %b : i32 // expected-error {{use of value '%b' expects different type than prior uses}}
}
func @func_with_ops(i32, i32, i32) {
^bb0(%cond : i32, %t : i32, %f : i32):
// expected-error@+2 {{different type than prior uses}}
- // expected-error@-2 {{prior use here}}
+ // expected-note@-2 {{prior use here}}
%r = select %cond, %t, %f : i32
}
// -----
func @cmpf_canonical_wrong_result_type(%a : f32, %b : f32) -> f32 {
- %r = cmpf "oeq", %a, %b : f32 // expected-error {{prior use here}}
+ %r = cmpf "oeq", %a, %b : f32 // expected-note {{prior use here}}
// expected-error@+1 {{use of value '%r' expects different type than prior uses}}
return %r : f32
}
// -----
-func @cmpf_canonical_type_mismatch(%a : f32, %b : f64) { // expected-error {{prior use here}}
+func @cmpf_canonical_type_mismatch(%a : f32, %b : f64) { // expected-note {{prior use here}}
// expected-error@+1 {{use of value '%b' expects different type than prior uses}}
%r = cmpf "oeq", %a, %b : f32
}
func @redef() {
^bb42:
- %x = "xxx"(){index: 0} : ()->i32 // expected-error {{previously defined here}}
+ %x = "xxx"(){index: 0} : ()->i32 // expected-note {{previously defined here}}
%x = "xxx"(){index: 0} : ()->i32 // expected-error {{redefinition of SSA value '%x'}}
return
}
// -----
func @argError() {
-^bb1(%a: i64): // expected-error {{previously defined here}}
+^bb1(%a: i64): // expected-note {{previously defined here}}
br ^bb2
^bb2(%a: i64): // expected-error{{redefinition of SSA value '%a'}}
return
func @condbr_notbool() {
^bb0:
- %a = "foo"() : () -> i32 // expected-error {{prior use here}}
+ %a = "foo"() : () -> i32 // expected-note {{prior use here}}
cond_br %a, ^bb0, ^bb0 // expected-error {{use of value '%a' expects different type than prior uses}}
// expected-error@-1 {{expected condition type was boolean (i1)}}
}
// -----
func @conflicting_names() {
- // expected-error@+1 {{previously defined here}}
+ // expected-note@+1 {{previously defined here}}
%foo, %bar = "foo" () : () -> (i32, i32)
// expected-error@+1 {{redefinition of SSA value '%bar'}}