[clang] [CIR][Dialect] Add SourceLangAttr (PR #152511)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 7 07:15:17 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: 7mile (seven-mile)
<details>
<summary>Changes</summary>
This patch upstreams `SourceLangAttr` and its CodeGen logic in the CGM, which encodes the source language in CIR.
---
Full diff: https://github.com/llvm/llvm-project/pull/152511.diff
8 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+37)
- (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.td (+1)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+24)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+3)
- (added) clang/test/CIR/CodeGen/lang-c.c (+8)
- (added) clang/test/CIR/CodeGen/lang-cpp.cpp (+8)
- (added) clang/test/CIR/IR/invalid-lang-attr.cir (+5)
- (added) clang/test/CIR/IR/module.cir (+12)
``````````diff
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>}
``````````
</details>
https://github.com/llvm/llvm-project/pull/152511
More information about the cfe-commits
mailing list