[fidlc] Improved support for anonymous names

Since we have anonymous names which do not come from source files, e.g.
the name of the built-in uint32 type, we must handle absence of location
all the way down to how we report errors.

One benefit is the removal of the is_anonymous() method on Name:
callers should always assume that names could be anonymous, and this
should be hidden by the Name object model.

Change-Id: Ib47d23c93d893c3fefc6093d9162264ec492e3ef
diff --git a/zircon/system/host/fidl/include/fidl/error_reporter.h b/zircon/system/host/fidl/include/fidl/error_reporter.h
index bfac003..4e8b3a6 100644
--- a/zircon/system/host/fidl/include/fidl/error_reporter.h
+++ b/zircon/system/host/fidl/include/fidl/error_reporter.h
@@ -36,12 +36,18 @@
 
     void ReportErrorWithSquiggle(const SourceLocation& location,
                                  StringView message);
-    void ReportError(const SourceLocation& location, StringView message);
+    void ReportError(const SourceLocation& location, StringView message) {
+        ReportError(&location, message);
+    }
+    void ReportError(const SourceLocation* maybe_location, StringView message);
     void ReportError(const Token& token, StringView message);
     void ReportError(StringView message);
     void ReportWarningWithSquiggle(const SourceLocation& location,
                                    StringView message);
-    void ReportWarning(const SourceLocation& location, StringView message);
+    void ReportWarning(const SourceLocation& location, StringView message) {
+        ReportWarning(&location, message);
+    }
+    void ReportWarning(const SourceLocation* maybe_location, StringView message);
     void PrintReports();
     Counts Checkpoint() const { return Counts(this); }
     const std::vector<std::string>& errors() const { return errors_; }
diff --git a/zircon/system/host/fidl/include/fidl/flat_ast.h b/zircon/system/host/fidl/include/fidl/flat_ast.h
index 2683fd6..fc2a987 100644
--- a/zircon/system/host/fidl/include/fidl/flat_ast.h
+++ b/zircon/system/host/fidl/include/fidl/flat_ast.h
@@ -65,13 +65,12 @@
     Name(Name&&) = default;
     Name& operator=(Name&&) = default;
 
-    bool is_anonymous() const { return name_from_source_ == nullptr; }
     const Library* library() const { return library_; }
-    const SourceLocation& source_location() const {
-        return *name_from_source_.get();
+    const SourceLocation* maybe_location() const {
+        return name_from_source_.get();
     }
     const StringView name_part() const {
-        if (is_anonymous())
+        if (!name_from_source_)
             return *anonymous_name_.get();
         return name_from_source_->data();
     }
@@ -892,7 +891,7 @@
 
     const Name* name() const { return &name_; }
 
-    virtual bool Create(const SourceLocation& location,
+    virtual bool Create(const SourceLocation* maybe_location,
                         const Type* arg_type,
                         const types::HandleSubtype* handle_subtype,
                         const Size* size,
@@ -900,12 +899,22 @@
                         std::unique_ptr<Type>* out_type) const = 0;
 
 protected:
-    bool MustBeParameterized(const SourceLocation& location) const { return Fail(location, "must be parametrized"); }
-    bool MustHaveSize(const SourceLocation& location) const { return Fail(location, "must have size"); }
-    bool CannotBeParameterized(const SourceLocation& location) const { return Fail(location, "cannot be parametrized"); }
-    bool CannotHaveSize(const SourceLocation& location) const { return Fail(location, "cannot have size"); }
-    bool CannotBeNullable(const SourceLocation& location) const { return Fail(location, "cannot be nullable"); }
-    bool Fail(const SourceLocation& location, const std::string& content) const;
+    bool MustBeParameterized(const SourceLocation* maybe_location) const {
+        return Fail(maybe_location, "must be parametrized");
+    }
+    bool MustHaveSize(const SourceLocation* maybe_location) const {
+        return Fail(maybe_location, "must have size");
+    }
+    bool CannotBeParameterized(const SourceLocation* maybe_location) const {
+        return Fail(maybe_location, "cannot be parametrized");
+    }
+    bool CannotHaveSize(const SourceLocation* maybe_location) const {
+        return Fail(maybe_location, "cannot have size");
+    }
+    bool CannotBeNullable(const SourceLocation* maybe_location) const {
+        return Fail(maybe_location, "cannot be nullable");
+    }
+    bool Fail(const SourceLocation* maybe_location, const std::string& content) const;
 
     Typespace* typespace_;
 
@@ -1090,12 +1099,12 @@
     friend class TypeAliasTypeTemplate;
 
     bool Fail(StringView message);
-    bool Fail(const SourceLocation& location, StringView message);
+    bool Fail(const SourceLocation& location, StringView message) {
+        return Fail(&location, message);
+    }
+    bool Fail(const SourceLocation* maybe_location, StringView message);
     bool Fail(const Name& name, StringView message) {
-        if (name.is_anonymous()) {
-            return Fail(message);
-        }
-        return Fail(name.source_location(), message);
+        return Fail(name.maybe_location(), message);
     }
     bool Fail(const Decl& decl, StringView message) { return Fail(decl.name, message); }
 
@@ -1104,8 +1113,13 @@
     void ValidateAttributesConstraints(const Decl* decl,
                                        const raw::AttributeList* attributes);
 
+    // TODO(FIDL-596): Rationalize the use of names. Here, a simple name is
+    // one that is not scoped, it is just text. An anonymous name is one that
+    // is guaranteed to be unique within the library, and a derived name is one
+    // that is library scoped but derived from the concatenated components using
+    // underscores as delimiters.
+    SourceLocation GeneratedSimpleName(const std::string& name);
     Name NextAnonymousName();
-    Name GeneratedName(const std::string& name);
     Name DerivedName(const std::vector<StringView>& components);
 
     bool CompileCompoundIdentifier(const raw::CompoundIdentifier* compound_identifier,
diff --git a/zircon/system/host/fidl/include/fidl/json_generator.h b/zircon/system/host/fidl/include/fidl/json_generator.h
index ebbb20f..cd3287f 100644
--- a/zircon/system/host/fidl/include/fidl/json_generator.h
+++ b/zircon/system/host/fidl/include/fidl/json_generator.h
@@ -16,11 +16,16 @@
 namespace fidl {
 
 struct NameLocation {
-    explicit NameLocation(const SourceLocation& source_location)
-        : filename(source_location.source_file().filename()) {
-      source_location.SourceLine(&position);
+    explicit NameLocation(const SourceLocation& location)
+        : filename(location.source_file().filename()) {
+      location.SourceLine(&position);
     }
-    explicit NameLocation(const flat::Name& name) : NameLocation(name.source_location()) {}
+
+    // TODO(FIDL-596): We are incorrectly assuming that the provided name is not
+    // anonymous, and relying on callers to avoid derefencing a nullptr
+    // location.
+    explicit NameLocation(const flat::Name& name) : NameLocation(*name.maybe_location()) {}
+
     const std::string filename;
     SourceFile::Position position;
 };
diff --git a/zircon/system/host/fidl/include/fidl/token.h b/zircon/system/host/fidl/include/fidl/token.h
index 42142ec..bfb7d5c 100644
--- a/zircon/system/host/fidl/include/fidl/token.h
+++ b/zircon/system/host/fidl/include/fidl/token.h
@@ -69,7 +69,7 @@
     }
 
     StringView data() const { return location_.data(); }
-    SourceLocation location() const { return location_; }
+    const SourceLocation& location() const { return location_; }
     void set_previous_end(SourceLocation location) { previous_end_ = location; }
     SourceLocation previous_end() const { return previous_end_; }
     Kind kind() const { return kind_and_subkind_.kind(); }
diff --git a/zircon/system/host/fidl/lib/error_reporter.cpp b/zircon/system/host/fidl/lib/error_reporter.cpp
index 28d56d6..5fcc421 100644
--- a/zircon/system/host/fidl/lib/error_reporter.cpp
+++ b/zircon/system/host/fidl/lib/error_reporter.cpp
@@ -24,8 +24,16 @@
     return squiggle;
 }
 
-std::string Format(std::string qualifier, const SourceLocation& location,
+std::string Format(std::string qualifier, const SourceLocation* maybe_location,
                    StringView message, size_t squiggle_size = 0u) {
+    if (!maybe_location) {
+        std::string error = qualifier;
+        error.append(": ");
+        error.append(message);
+        return error;
+    }
+
+    const auto& location = *maybe_location;
     SourceFile::Position position;
     std::string surrounding_line = location.SourceLine(&position);
 
@@ -53,7 +61,6 @@
     error.push_back('\n');
     error.append(surrounding_line);
     error.append(squiggle);
-
     return error;
 }
 
@@ -75,8 +82,8 @@
 //     filename:line:col: error: message
 //     sourceline
 //        ^
-void ErrorReporter::ReportError(const SourceLocation& location, StringView message) {
-    auto error = Format("error", location, message);
+void ErrorReporter::ReportError(const SourceLocation* maybe_location, StringView message) {
+    auto error = Format("error", maybe_location, message);
     AddError(std::move(error));
 }
 
@@ -89,7 +96,7 @@
 void ErrorReporter::ReportErrorWithSquiggle(
     const SourceLocation& location, StringView message) {
     auto token_data = location.data();
-    auto error = Format("error", location, message, token_data.size());
+    auto error = Format("error", &location, message, token_data.size());
     AddError(std::move(error));
 }
 
@@ -118,8 +125,8 @@
 //     filename:line:col: warning: message
 //     sourceline
 //        ^
-void ErrorReporter::ReportWarning(const SourceLocation& location, StringView message) {
-    auto warning = Format("warning", location, message);
+void ErrorReporter::ReportWarning(const SourceLocation* maybe_location, StringView message) {
+    auto warning = Format("warning", maybe_location, message);
     AddWarning(std::move(warning));
 }
 
@@ -132,7 +139,7 @@
 void ErrorReporter::ReportWarningWithSquiggle(
     const SourceLocation& location, StringView message) {
     auto token_data = location.data();
-    auto warning = Format("warning", location, message, token_data.size());
+    auto warning = Format("warning", &location, message, token_data.size());
     AddWarning(std::move(warning));
 }
 
diff --git a/zircon/system/host/fidl/lib/flat_ast.cpp b/zircon/system/host/fidl/lib/flat_ast.cpp
index 481dd7a..9ce526a9 100644
--- a/zircon/system/host/fidl/lib/flat_ast.cpp
+++ b/zircon/system/host/fidl/lib/flat_ast.cpp
@@ -400,15 +400,16 @@
     // return it rather than create a new one. Lookup must be by name,
     // arg_type, size, and nullability.
 
-    auto const& location = name.source_location();
+    auto maybe_location = name.maybe_location();
     auto type_template = LookupTemplate(name);
     if (type_template == nullptr) {
         std::string message("unknown type ");
         message.append(name.name_part());
-        error_reporter_->ReportError(location, message);
+        error_reporter_->ReportError(maybe_location, message);
         return false;
     }
-    return type_template->Create(location, arg_type, handle_subtype, size, nullability, out_type);
+    return type_template->Create(maybe_location, arg_type, handle_subtype, size,
+                                 nullability, out_type);
 
 }
 
@@ -429,11 +430,11 @@
     return nullptr;
 }
 
-bool TypeTemplate::Fail(const SourceLocation& location, const std::string& content) const {
+bool TypeTemplate::Fail(const SourceLocation* maybe_location, const std::string& content) const {
     std::string message(NameName(name_, ".", "/"));
     message.append(" ");
     message.append(content);
-    error_reporter_->ReportError(location, message);
+    error_reporter_->ReportError(maybe_location, message);
     return false;
 }
 
@@ -444,18 +445,18 @@
         : TypeTemplate(Name(nullptr, name), typespace, error_reporter),
           subtype_(subtype) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* maybe_arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* maybe_size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (maybe_arg_type != nullptr)
-            return CannotBeParameterized(location);
+            return CannotBeParameterized(maybe_location);
         if (maybe_size != nullptr)
-            return CannotHaveSize(location);
+            return CannotHaveSize(maybe_location);
         if (nullability == types::Nullability::kNullable)
-            return CannotBeNullable(location);
+            return CannotBeNullable(maybe_location);
 
         *out_type = std::make_unique<PrimitiveType>(subtype_);
         return true;
@@ -471,14 +472,14 @@
         : TypeTemplate(Name(nullptr, "bytes"), typespace, error_reporter),
           uint8_type_(types::PrimitiveSubtype::kUint8) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* maybe_arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (maybe_arg_type != nullptr)
-            return CannotBeParameterized(location);
+            return CannotBeParameterized(maybe_location);
         if (size == nullptr)
             size = &max_size;
 
@@ -496,18 +497,18 @@
     ArrayTypeTemplate(Typespace* typespace, ErrorReporter* error_reporter)
         : TypeTemplate(Name(nullptr, "array"), typespace, error_reporter) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (arg_type == nullptr)
-            return MustBeParameterized(location);
+            return MustBeParameterized(maybe_location);
         if (size == nullptr)
-            return MustHaveSize(location);
+            return MustHaveSize(maybe_location);
         if (nullability == types::Nullability::kNullable)
-            return CannotBeNullable(location);
+            return CannotBeNullable(maybe_location);
 
         *out_type = std::make_unique<ArrayType>(arg_type, size);
         return true;
@@ -519,14 +520,14 @@
     VectorTypeTemplate(Typespace* typespace, ErrorReporter* error_reporter)
         : TypeTemplate(Name(nullptr, "vector"), typespace, error_reporter) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (arg_type == nullptr)
-            return MustBeParameterized(location);
+            return MustBeParameterized(maybe_location);
         if (size == nullptr)
             size = &max_size;
 
@@ -543,14 +544,14 @@
     StringTypeTemplate(Typespace* typespace, ErrorReporter* error_reporter)
         : TypeTemplate(Name(nullptr, "string"), typespace, error_reporter) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (arg_type != nullptr)
-            return CannotBeParameterized(location);
+            return CannotBeParameterized(maybe_location);
         if (size == nullptr)
             size = &max_size;
 
@@ -567,7 +568,7 @@
     HandleTypeTemplate(Typespace* typespace, ErrorReporter* error_reporter)
         : TypeTemplate(Name(nullptr, "handle"), typespace, error_reporter) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* maybe_arg_type,
                 const types::HandleSubtype* maybe_handle_subtype,
                 const Size* maybe_size,
@@ -576,7 +577,7 @@
         assert(maybe_arg_type == nullptr);
 
         if (maybe_size != nullptr)
-            return CannotHaveSize(location);
+            return CannotHaveSize(maybe_location);
 
         auto handle_subtype = types::HandleSubtype::kHandle;
         if (maybe_handle_subtype != nullptr)
@@ -592,21 +593,21 @@
     RequestTypeTemplate(Typespace* typespace, ErrorReporter* error_reporter)
         : TypeTemplate(Name(nullptr, "request"), typespace, error_reporter) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* maybe_size,
                 types::Nullability nullability,
                 std::unique_ptr<Type>* out_type) const {
         if (arg_type == nullptr)
-            return MustBeParameterized(location);
+            return MustBeParameterized(maybe_location);
         if (arg_type->kind != Type::Kind::kIdentifier)
-            return Fail(location, "must be an interface");
+            return Fail(maybe_location, "must be an interface");
         auto interface_type = static_cast<const IdentifierType*>(arg_type);
         if (interface_type->type_decl->kind != Decl::Kind::kInterface)
-            return Fail(location, "must be an interface");
+            return Fail(maybe_location, "must be an interface");
         if (maybe_size != nullptr)
-            return CannotHaveSize(location);
+            return CannotHaveSize(maybe_location);
 
         *out_type = std::make_unique<RequestHandleType>(interface_type, nullability);
         return true;
@@ -625,7 +626,7 @@
         : TypeTemplate(std::move(name), typespace, error_reporter),
           library_(library), type_decl_(type_decl) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* arg_type,
                 const types::HandleSubtype* handle_subtype,
                 const Size* size,
@@ -654,7 +655,7 @@
 
         case Decl::Kind::kTable:
             if (nullability == types::Nullability::kNullable)
-                return CannotBeNullable(location);
+                return CannotBeNullable(maybe_location);
             break;
 
         default:
@@ -684,7 +685,7 @@
         : TypeTemplate(std::move(name), typespace, error_reporter),
           library_(library), partial_type_ctor_(std::move(partial_type_ctor)) {}
 
-    bool Create(const SourceLocation& location,
+    bool Create(const SourceLocation* maybe_location,
                 const Type* maybe_arg_type,
                 const types::HandleSubtype* no_handle_subtype,
                 const Size* maybe_size,
@@ -695,7 +696,7 @@
         const Type* arg_type = nullptr;
         if (partial_type_ctor_->maybe_arg_type_ctor) {
             if (maybe_arg_type) {
-                return Fail(location, "cannot parametrize twice");
+                return Fail(maybe_location, "cannot parametrize twice");
             }
             if (!partial_type_ctor_->maybe_arg_type_ctor->type) {
                 if (!library_->CompileTypeConstructor(
@@ -711,10 +712,10 @@
         const Size* size = nullptr;
         if (partial_type_ctor_->maybe_size) {
             if (maybe_size) {
-                return Fail(location, "cannot bound twice");
+                return Fail(maybe_location, "cannot bound twice");
             }
             if (!library_->ResolveConstant(partial_type_ctor_->maybe_size.get(), &library_->kSizeType))
-                return Fail(location, "unable to parse size bound");
+                return Fail(maybe_location, "unable to parse size bound");
             size = static_cast<const Size*>(&partial_type_ctor_->maybe_size->Value());
         } else {
             size = maybe_size;
@@ -723,7 +724,7 @@
         types::Nullability nullability;
         if (partial_type_ctor_->nullability == types::Nullability::kNullable) {
             if (maybe_nullability == types::Nullability::kNullable) {
-                return Fail(location, "cannot indicate nullability twice");
+                return Fail(maybe_location, "cannot indicate nullability twice");
             }
             nullability = types::Nullability::kNullable;
         } else {
@@ -1000,7 +1001,7 @@
         (error_primitive->subtype != types::PrimitiveSubtype::kInt32 &&
          error_primitive->subtype != types::PrimitiveSubtype::kUint32)) {
         error_reporter->ReportError(
-            decl->name.source_location(),
+            decl->name.maybe_location(),
             "invalid error type: must be int32, uint32 or an enum therof");
         return false;
     }
@@ -1053,7 +1054,7 @@
                 first = false;
                 out << t;
             }
-            error_reporter->ReportError(decl->name.source_location(), out.str());
+            error_reporter->ReportError(decl->name.maybe_location(), out.str());
             return false;
         }
     }
@@ -1262,8 +1263,8 @@
     return false;
 }
 
-bool Library::Fail(const SourceLocation& location, StringView message) {
-    error_reporter_->ReportError(location, message);
+bool Library::Fail(const SourceLocation* maybe_location, StringView message) {
+    error_reporter_->ReportError(maybe_location, message);
     return false;
 }
 
@@ -1291,22 +1292,22 @@
     }
 }
 
+SourceLocation Library::GeneratedSimpleName(const std::string& name) {
+    return generated_source_file_.AddLine(name);
+}
+
 Name Library::NextAnonymousName() {
-    // TODO(pascallouis): Improve anonymous name generation. We want to be
+    // TODO(FIDL-596): Improve anonymous name generation. We want to be
     // specific about how these names are generated once they appear in the
     // JSON IR, and are exposed to the backends.
     std::ostringstream data;
     data << "SomeLongAnonymousPrefix";
     data << anon_counter_++;
-    return GeneratedName(data.str());
-}
-
-Name Library::GeneratedName(const std::string& name) {
-    return Name(this, generated_source_file_.AddLine(name));
+    return Name(this, GeneratedSimpleName(data.str()));
 }
 
 Name Library::DerivedName(const std::vector<StringView>& components) {
-    return GeneratedName(StringJoin(components, "_"));
+    return Name(this, GeneratedSimpleName(StringJoin(components, "_")));
 }
 
 bool Library::CompileCompoundIdentifier(const raw::CompoundIdentifier* compound_identifier,
@@ -1581,11 +1582,11 @@
     // error type.
     Union::Member response_member{
         IdentifierTypeForDecl(in_response, types::Nullability::kNonnullable),
-        GeneratedName("response").source_location(),
+        GeneratedSimpleName("response"),
         nullptr};
     Union::Member error_member{
         std::move(error_type_ctor),
-        GeneratedName("err").source_location(),
+        GeneratedSimpleName("err"),
         nullptr};
     SourceLocation method_name = method->identifier->location();
     Name result_name = DerivedName({interface_name.name_part(), method_name.data(), "Result"});
@@ -1607,7 +1608,7 @@
     // result union.
     std::vector<Struct::Member> response_members;
     response_members.push_back(Struct::Member(IdentifierTypeForDecl(result_decl, types::Nullability::kNonnullable),
-                                              GeneratedName("result").source_location(), nullptr, nullptr));
+                                              GeneratedSimpleName("result"), nullptr, nullptr));
     struct_declarations_.push_back(std::make_unique<Struct>(nullptr, NextAnonymousName(), std::move(response_members), true));
     *out_response = struct_declarations_.back().get();
     if (!RegisterDecl(*out_response))
@@ -2843,8 +2844,9 @@
                 return Fail(name, message);
             }
             auto superinterface = static_cast<const Interface*>(decl);
-            assert(!superinterface->name.is_anonymous());
-            if (method_scope.interfaces.Insert(superinterface, superinterface->name.source_location()).ok()) {
+            auto maybe_location = superinterface->name.maybe_location();
+            assert(maybe_location);
+            if (method_scope.interfaces.Insert(superinterface, *maybe_location).ok()) {
                 if (!Visitor(superinterface, Visitor))
                     return false;
             } else {
@@ -3117,7 +3119,6 @@
 }
 
 bool Library::CompileTypeConstructor(TypeConstructor* type_ctor, TypeShape* out_typeshape) {
-    auto const& location = type_ctor->name.source_location();
     const Type* maybe_arg_type = nullptr;
     if (type_ctor->maybe_arg_type_ctor != nullptr) {
         if (!CompileTypeConstructor(type_ctor->maybe_arg_type_ctor.get(), nullptr))
@@ -3127,7 +3128,7 @@
     const Size* size = nullptr;
     if (type_ctor->maybe_size != nullptr) {
         if (!ResolveConstant(type_ctor->maybe_size.get(), &kSizeType))
-            return Fail(location, "unable to parse size bound");
+            return Fail(type_ctor->name.maybe_location(), "unable to parse size bound");
         size = static_cast<const Size*>(&type_ctor->maybe_size->Value());
     }
     if (!typespace_->Create(type_ctor->name, maybe_arg_type, type_ctor->maybe_handle_subtype.get(),
diff --git a/zircon/system/host/fidl/lib/lexer.cpp b/zircon/system/host/fidl/lib/lexer.cpp
index d34462b..0e9ea9e 100644
--- a/zircon/system/host/fidl/lib/lexer.cpp
+++ b/zircon/system/host/fidl/lib/lexer.cpp
@@ -182,7 +182,7 @@
         std::string msg("invalid identifier '");
         msg.append(identifier_data);
         msg.append("'");
-        error_reporter_->ReportError(location, msg);
+        error_reporter_->ReportError(&location, msg);
     }
     auto subkind = Token::Subkind::kNone;
     auto lookup = keyword_table_.find(identifier_data);
@@ -368,7 +368,7 @@
                 std::string msg("invalid character '");
                 msg.append(location.data());
                 msg.append("'");
-                error_reporter_->ReportError(location, msg);
+                error_reporter_->ReportError(&location, msg);
                 continue;
             }
             } // switch
@@ -410,7 +410,7 @@
             std::string msg("invalid character '");
             msg.append(location.data());
             msg.append("'");
-            error_reporter_->ReportError(location, msg);
+            error_reporter_->ReportError(&location, msg);
             continue;
         }
         } // switch