Skip to content

Commit

Permalink
[Clang] Add native language support via std::messages.
Browse files Browse the repository at this point in the history
This implementation must be built with libstdc++, and uses GNU Gettext
as translation database.
  • Loading branch information
Mosklia committed Jan 9, 2024
1 parent 2b3baff commit 5bfaff3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticIDs.h
Expand Up @@ -19,6 +19,8 @@
#include "llvm/ADT/StringRef.h"
#include <optional>
#include <vector>
#include <cstdlib>
#include <locale>

namespace clang {
class DiagnosticsEngine;
Expand Down Expand Up @@ -185,6 +187,9 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Information for uniquing and looking up custom diags.
std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;

const std::messages<char> &msg;
std::messages<char>::catalog msg_catalog;

public:
DiagnosticIDs();
~DiagnosticIDs();
Expand Down
34 changes: 29 additions & 5 deletions clang/lib/Basic/DiagnosticIDs.cpp
Expand Up @@ -17,6 +17,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstring>
#include <map>
#include <optional>
using namespace clang;
Expand Down Expand Up @@ -389,9 +390,15 @@ namespace clang {
// Common Diagnostic implementation
//===----------------------------------------------------------------------===//

DiagnosticIDs::DiagnosticIDs() {}
static std::locale locale(std::getenv("LANG"));
DiagnosticIDs::DiagnosticIDs()
: msg(std::use_facet<std::messages<char>>(locale)),
msg_catalog(msg.open("clang", locale)) {
}

DiagnosticIDs::~DiagnosticIDs() {}
DiagnosticIDs::~DiagnosticIDs() {
msg.close(msg_catalog);
}

/// getCustomDiagID - Return an ID for a diagnostic with the specified message
/// and level. If this is the first request for this diagnostic, it is
Expand Down Expand Up @@ -447,11 +454,28 @@ bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {

/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
static std::map<unsigned, std::string> descriptions;
StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
StringRef ref;

if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getDescription();
assert(CustomDiagInfo && "Invalid CustomDiagInfo");
return CustomDiagInfo->getDescription(DiagID);
{
ref = Info->getDescription();
}
else
{
assert(CustomDiagInfo && "Invalid CustomDiagInfo");
ref = CustomDiagInfo->getDescription(DiagID);
}

if (descriptions.count(DiagID) == 0) {
std::string s;
s = msg.get(msg_catalog, 0, 0, ref.data());
descriptions[DiagID] = s;
// std::strcpy(descriptions[DiagID], s.data());
// descriptions[DiagID] = ref.data();
}
return StringRef(descriptions[DiagID]);
}

static DiagnosticIDs::Level toLevel(diag::Severity SV) {
Expand Down

0 comments on commit 5bfaff3

Please sign in to comment.