Skip to content

Commit 761125f

Browse files
authored
[CIR][Dialect] Add SourceLangAttr (#152511)
This patch upstreams `SourceLangAttr` and its CodeGen logic in the CGM, which encodes the source language in CIR.
1 parent 436f391 commit 761125f

File tree

8 files changed

+92
-0
lines changed

8 files changed

+92
-0
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,45 @@ class CIR_UnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
5050
let isOptional = 1;
5151
}
5252

53+
//===----------------------------------------------------------------------===//
54+
// SourceLanguageAttr
55+
//===----------------------------------------------------------------------===//
56+
57+
// TODO: Add cases for other languages that Clang supports.
58+
59+
def CIR_SourceLanguage : CIR_I32EnumAttr<"SourceLanguage", "source language", [
60+
I32EnumAttrCase<"C", 1, "c">,
61+
I32EnumAttrCase<"CXX", 2, "cxx">
62+
]> {
63+
// The enum attr class is defined in `CIR_SourceLanguageAttr` below,
64+
// so that it can define extra class methods.
65+
let genSpecializedAttr = 0;
66+
}
67+
68+
def CIR_SourceLanguageAttr : CIR_EnumAttr<CIR_SourceLanguage, "lang"> {
69+
70+
let summary = "Module source language";
71+
let description = [{
72+
Represents the source language used to generate the module.
73+
74+
Example:
75+
```
76+
// Module compiled from C.
77+
module attributes {cir.lang = cir.lang<c>} {}
78+
// Module compiled from C++.
79+
module attributes {cir.lang = cir.lang<cxx>} {}
80+
```
81+
82+
Module source language attribute name is `cir.lang` is defined by
83+
`getSourceLanguageAttrName` method in CIRDialect class.
84+
}];
85+
86+
let extraClassDeclaration = [{
87+
bool isC() const { return getValue() == SourceLanguage::C; }
88+
bool isCXX() const { return getValue() == SourceLanguage::CXX; }
89+
}];
90+
}
91+
5392
//===----------------------------------------------------------------------===//
5493
// OptInfoAttr
5594
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRDialect.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def CIR_Dialect : Dialect {
3535
let hasConstantMaterializer = 1;
3636

3737
let extraClassDeclaration = [{
38+
static llvm::StringRef getSourceLanguageAttrName() { return "cir.lang"; }
3839
static llvm::StringRef getTripleAttrName() { return "cir.triple"; }
3940
static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
4041
static llvm::StringRef getCalleeAttrName() { return "callee"; }

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ struct MissingFeatures {
264264
static bool setNonGC() { return false; }
265265
static bool setObjCGCLValueClass() { return false; }
266266
static bool setTargetAttributes() { return false; }
267+
static bool sourceLanguageCases() { return false; }
267268
static bool stackBase() { return false; }
268269
static bool stackSaveOp() { return false; }
269270
static bool targetCIRGenInfoArch() { return false; }

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
103103
PtrDiffTy =
104104
cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true);
105105

106+
theModule->setAttr(
107+
cir::CIRDialect::getSourceLanguageAttrName(),
108+
cir::SourceLanguageAttr::get(&mlirContext, getCIRSourceLanguage()));
106109
theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
107110
builder.getStringAttr(getTriple().str()));
108111

@@ -510,6 +513,23 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
510513
assert(!cir::MissingFeatures::setTargetAttributes());
511514
}
512515

516+
cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
517+
using ClangStd = clang::LangStandard;
518+
using CIRLang = cir::SourceLanguage;
519+
auto opts = getLangOpts();
520+
521+
if (opts.CPlusPlus)
522+
return CIRLang::CXX;
523+
if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
524+
opts.LangStd == ClangStd::lang_c89 ||
525+
opts.LangStd == ClangStd::lang_gnu89)
526+
return CIRLang::C;
527+
528+
// TODO(cir): support remaining source languages.
529+
assert(!cir::MissingFeatures::sourceLanguageCases());
530+
errorNYI("CIR does not yet support the given source language");
531+
}
532+
513533
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
514534
// Set linkage and visibility in case we never see a definition.
515535
LinkageInfo lv = nd->getLinkageAndVisibility();

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ class CIRGenModule : public CIRGenTypeCache {
461461
void replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF);
462462

463463
void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
464+
465+
/// Map source language used to a CIR attribute.
466+
cir::SourceLanguage getCIRSourceLanguage() const;
464467
};
465468
} // namespace CIRGen
466469

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cpp.cir
2+
// RUN: FileCheck --check-prefix=CIR-CPP --input-file=%t.cpp.cir %s
3+
// RUN: %clang_cc1 -x c -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.c.cir
4+
// RUN: FileCheck --check-prefix=CIR-C --input-file=%t.c.cir %s
5+
6+
// CIR-CPP: module attributes {{{.*}}cir.lang = #cir.lang<cxx>{{.*}}}
7+
// CIR-C: module attributes {{{.*}}cir.lang = #cir.lang<c>{{.*}}}
8+
9+
int main() {
10+
return 0;
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: cir-opt %s -verify-diagnostics
2+
3+
// expected-error@below {{expected ::cir::SourceLanguage to be one of}}
4+
// expected-error@below {{failed to parse CIR_SourceLanguageAttr parameter 'value'}}
5+
module attributes {cir.lang = #cir.lang<dummy>} { }

clang/test/CIR/IR/module.cir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: cir-opt %s -split-input-file -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
// Should parse and print C source language attribute.
5+
module attributes {cir.lang = #cir.lang<c>} { }
6+
// CHECK: module attributes {cir.lang = #cir.lang<c>}
7+
8+
// -----
9+
10+
// Should parse and print C++ source language attribute.
11+
module attributes {cir.lang = #cir.lang<cxx>} { }
12+
// CHECK: module attributes {cir.lang = #cir.lang<cxx>}

0 commit comments

Comments
 (0)