[clang] [CIR][Dialect] Add SourceLangAttr (PR #152511)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 7 18:10:31 PDT 2025
https://github.com/seven-mile updated https://github.com/llvm/llvm-project/pull/152511
>From f501e18cd33bf54d9c91dd772fb3db6f7ee52335 Mon Sep 17 00:00:00 2001
From: seven-mile <i at 7li.moe>
Date: Thu, 7 Aug 2025 14:10:08 +0000
Subject: [PATCH 1/3] [CIR][Dialect] Add SourceLangAttr
---
.../include/clang/CIR/Dialect/IR/CIRAttrs.td | 37 +++++++++++++++++++
.../clang/CIR/Dialect/IR/CIRDialect.td | 1 +
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 24 ++++++++++++
clang/lib/CIR/CodeGen/CIRGenModule.h | 3 ++
clang/test/CIR/CodeGen/lang-c.c | 8 ++++
clang/test/CIR/CodeGen/lang-cpp.cpp | 8 ++++
clang/test/CIR/IR/invalid-lang-attr.cir | 5 +++
clang/test/CIR/IR/module.cir | 12 ++++++
8 files changed, 98 insertions(+)
create mode 100644 clang/test/CIR/CodeGen/lang-c.c
create mode 100644 clang/test/CIR/CodeGen/lang-cpp.cpp
create mode 100644 clang/test/CIR/IR/invalid-lang-attr.cir
create mode 100644 clang/test/CIR/IR/module.cir
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 588fb0d74a509..2040109298ad1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -50,6 +50,43 @@ class CIR_UnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
let isOptional = 1;
}
+//===----------------------------------------------------------------------===//
+// SourceLanguageAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_SourceLanguage : CIR_I32EnumAttr<"SourceLanguage", "source language", [
+ I32EnumAttrCase<"C", 1, "c">,
+ I32EnumAttrCase<"CXX", 2, "cxx">
+]> {
+ // The enum attr class is defined in `CIR_SourceLanguageAttr` below,
+ // so that it can define extra class methods.
+ let genSpecializedAttr = 0;
+}
+
+def CIR_SourceLanguageAttr : CIR_EnumAttr<CIR_SourceLanguage, "lang"> {
+
+ let summary = "Module source language";
+ let description = [{
+ Represents the source language used to generate the module.
+
+ Example:
+ ```
+ // Module compiled from C.
+ module attributes {cir.lang = cir.lang<c>} {}
+ // Module compiled from C++.
+ module attributes {cir.lang = cir.lang<cxx>} {}
+ ```
+
+ Module source language attribute name is `cir.lang` is defined by
+ `getSourceLanguageAttrName` method in CIRDialect class.
+ }];
+
+ let extraClassDeclaration = [{
+ bool isC() const { return getValue() == SourceLanguage::C; }
+ bool isCXX() const { return getValue() == SourceLanguage::CXX; }
+ }];
+}
+
//===----------------------------------------------------------------------===//
// OptInfoAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 3fdbf65573b36..c62d63ad42725 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -35,6 +35,7 @@ def CIR_Dialect : Dialect {
let hasConstantMaterializer = 1;
let extraClassDeclaration = [{
+ static llvm::StringRef getSourceLanguageAttrName() { return "cir.lang"; }
static llvm::StringRef getTripleAttrName() { return "cir.triple"; }
static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
static llvm::StringRef getCalleeAttrName() { return "callee"; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 425250db87da6..19f4858a7848a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -102,6 +102,9 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
PtrDiffTy =
cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true);
+ theModule->setAttr(
+ cir::CIRDialect::getSourceLanguageAttrName(),
+ cir::SourceLanguageAttr::get(&mlirContext, getCIRSourceLanguage()));
theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
builder.getStringAttr(getTriple().str()));
@@ -495,6 +498,27 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
assert(!cir::MissingFeatures::setTargetAttributes());
}
+cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
+ using ClangStd = clang::LangStandard;
+ using CIRLang = cir::SourceLanguage;
+ auto opts = getLangOpts();
+
+ if (opts.OpenCL && !opts.OpenCLCPlusPlus)
+ llvm_unreachable("NYI");
+
+ if (opts.CPlusPlus || opts.CPlusPlus11 || opts.CPlusPlus14 ||
+ opts.CPlusPlus17 || opts.CPlusPlus20 || opts.CPlusPlus23 ||
+ opts.CPlusPlus26)
+ return CIRLang::CXX;
+ if (opts.C99 || opts.C11 || opts.C17 || opts.C23 ||
+ opts.LangStd == ClangStd::lang_c89 ||
+ opts.LangStd == ClangStd::lang_gnu89)
+ return CIRLang::C;
+
+ // TODO(cir): support remaining source languages.
+ llvm_unreachable("CIR does not yet support the given source language");
+}
+
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
// Set linkage and visibility in case we never see a definition.
LinkageInfo lv = nd->getLinkageAndVisibility();
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 5d07d38012318..cad5afaa92615 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -423,6 +423,9 @@ class CIRGenModule : public CIRGenTypeCache {
void replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF);
void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
+
+ /// Map source language used to a CIR attribute.
+ cir::SourceLanguage getCIRSourceLanguage() const;
};
} // namespace CIRGen
diff --git a/clang/test/CIR/CodeGen/lang-c.c b/clang/test/CIR/CodeGen/lang-c.c
new file mode 100644
index 0000000000000..cae9d23059bd9
--- /dev/null
+++ b/clang/test/CIR/CodeGen/lang-c.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// CIR: module attributes {{{.*}}cir.lang = #cir.lang<c>{{.*}}}
+
+int main() {
+ return 0;
+}
diff --git a/clang/test/CIR/CodeGen/lang-cpp.cpp b/clang/test/CIR/CodeGen/lang-cpp.cpp
new file mode 100644
index 0000000000000..561d8b66ab967
--- /dev/null
+++ b/clang/test/CIR/CodeGen/lang-cpp.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// CIR: module attributes {{{.*}}cir.lang = #cir.lang<cxx>{{.*}}}
+
+int main() {
+ return 0;
+}
diff --git a/clang/test/CIR/IR/invalid-lang-attr.cir b/clang/test/CIR/IR/invalid-lang-attr.cir
new file mode 100644
index 0000000000000..ffe523b1ad401
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-lang-attr.cir
@@ -0,0 +1,5 @@
+// RUN: cir-opt %s -verify-diagnostics
+
+// expected-error at below {{expected ::cir::SourceLanguage to be one of}}
+// expected-error at below {{failed to parse CIR_SourceLanguageAttr parameter 'value'}}
+module attributes {cir.lang = #cir.lang<dummy>} { }
diff --git a/clang/test/CIR/IR/module.cir b/clang/test/CIR/IR/module.cir
new file mode 100644
index 0000000000000..7ce2c0ba21cb0
--- /dev/null
+++ b/clang/test/CIR/IR/module.cir
@@ -0,0 +1,12 @@
+// RUN: cir-opt %s -split-input-file -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// Should parse and print C source language attribute.
+module attributes {cir.lang = #cir.lang<c>} { }
+// CHECK: module attributes {cir.lang = #cir.lang<c>}
+
+// -----
+
+// Should parse and print C++ source language attribute.
+module attributes {cir.lang = #cir.lang<cxx>} { }
+// CHECK: module attributes {cir.lang = #cir.lang<cxx>}
>From 6fe6b009b7f31a52423cd0c89dca945e3c9cb3ca Mon Sep 17 00:00:00 2001
From: seven-mile <i at 7li.moe>
Date: Fri, 8 Aug 2025 01:06:09 +0000
Subject: [PATCH 2/3] use errorNYI and add missing feature flag
---
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 2 ++
clang/include/clang/CIR/MissingFeatures.h | 1 +
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 6 ++----
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 2040109298ad1..9fcfbcf71b155 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -63,6 +63,8 @@ def CIR_SourceLanguage : CIR_I32EnumAttr<"SourceLanguage", "source language", [
let genSpecializedAttr = 0;
}
+// TODO: Add cases for other languages that Clang supports.
+
def CIR_SourceLanguageAttr : CIR_EnumAttr<CIR_SourceLanguage, "lang"> {
let summary = "Module source language";
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 27dd181f2fb37..151e2c80cca49 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -245,6 +245,7 @@ struct MissingFeatures {
static bool setNonGC() { return false; }
static bool setObjCGCLValueClass() { return false; }
static bool setTargetAttributes() { return false; }
+ static bool sourceLanguageCases() { return false; }
static bool stackBase() { return false; }
static bool stackSaveOp() { return false; }
static bool targetCIRGenInfoArch() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 19f4858a7848a..0c764ff4cf47c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -503,9 +503,6 @@ cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
using CIRLang = cir::SourceLanguage;
auto opts = getLangOpts();
- if (opts.OpenCL && !opts.OpenCLCPlusPlus)
- llvm_unreachable("NYI");
-
if (opts.CPlusPlus || opts.CPlusPlus11 || opts.CPlusPlus14 ||
opts.CPlusPlus17 || opts.CPlusPlus20 || opts.CPlusPlus23 ||
opts.CPlusPlus26)
@@ -516,7 +513,8 @@ cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
return CIRLang::C;
// TODO(cir): support remaining source languages.
- llvm_unreachable("CIR does not yet support the given source language");
+ assert(!cir::MissingFeatures::sourceLanguageCases());
+ errorNYI("CIR does not yet support the given source language");
}
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
>From 1a04b370c56d038278108114449e0dbfc9297793 Mon Sep 17 00:00:00 2001
From: seven-mile <i at 7li.moe>
Date: Fri, 8 Aug 2025 01:10:17 +0000
Subject: [PATCH 3/3] adjust todo position
---
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 9fcfbcf71b155..f54098345953f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -54,6 +54,8 @@ class CIR_UnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
// SourceLanguageAttr
//===----------------------------------------------------------------------===//
+// TODO: Add cases for other languages that Clang supports.
+
def CIR_SourceLanguage : CIR_I32EnumAttr<"SourceLanguage", "source language", [
I32EnumAttrCase<"C", 1, "c">,
I32EnumAttrCase<"CXX", 2, "cxx">
@@ -63,8 +65,6 @@ def CIR_SourceLanguage : CIR_I32EnumAttr<"SourceLanguage", "source language", [
let genSpecializedAttr = 0;
}
-// TODO: Add cases for other languages that Clang supports.
-
def CIR_SourceLanguageAttr : CIR_EnumAttr<CIR_SourceLanguage, "lang"> {
let summary = "Module source language";
More information about the cfe-commits
mailing list