Skip to content

Commit 2acefcd

Browse files
authored
[CIR] Add support for SourceLocExpr (#171492)
Add support for the SourceLocExpr
1 parent cef490d commit 2acefcd

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "CIRGenConstantEmitter.h"
1314
#include "CIRGenFunction.h"
1415
#include "CIRGenValue.h"
1516

@@ -810,8 +811,14 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
810811
return {};
811812
}
812813
mlir::Value VisitSourceLocExpr(SourceLocExpr *e) {
813-
cgf.cgm.errorNYI(e->getSourceRange(), "ScalarExprEmitter: source loc");
814-
return {};
814+
ASTContext &ctx = cgf.getContext();
815+
APValue evaluated =
816+
e->EvaluateInContext(ctx, cgf.curSourceLocExprScope.getDefaultExpr());
817+
mlir::Attribute attribute = ConstantEmitter(cgf).emitAbstract(
818+
e->getLocation(), evaluated, e->getType());
819+
mlir::TypedAttr typedAttr = mlir::cast<mlir::TypedAttr>(attribute);
820+
return cir::ConstantOp::create(builder, cgf.getLoc(e->getExprLoc()),
821+
typedAttr);
815822
}
816823
mlir::Value VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
817824
CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,11 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
14141414
// Unlike LLVM IR, CIR doesn't automatically unique names for globals, so
14151415
// we need to do that explicitly.
14161416
std::string uniqueName = getUniqueGlobalName(name.str());
1417-
mlir::Location loc = getLoc(s->getSourceRange());
1417+
// Synthetic string literals (e.g., from SourceLocExpr) may not have valid
1418+
// source locations. Use unknown location in those cases.
1419+
mlir::Location loc = s->getBeginLoc().isValid()
1420+
? getLoc(s->getSourceRange())
1421+
: builder.getUnknownLoc();
14181422
auto typedC = llvm::cast<mlir::TypedAttr>(c);
14191423
gv = generateStringLiteral(loc, typedC,
14201424
cir::GlobalLinkageKind::PrivateLinkage, *this,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
void line_column() {
9+
unsigned int a = __builtin_LINE();
10+
unsigned int b = __builtin_COLUMN();
11+
}
12+
13+
// CIR: %[[A_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
14+
// CIR: %[[B_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["b", init]
15+
// CIR: %[[CONST_9:.*]] = cir.const #cir.int<9> : !u32i
16+
// CIR: cir.store {{.*}} %[[CONST_9]], %[[A_ADDR]] : !u32i, !cir.ptr<!u32i>
17+
// CIR: %[[CONST_20:.*]] = cir.const #cir.int<20> : !u32i
18+
// CIR: cir.store {{.*}} %[[CONST_20]], %[[B_ADDR]] : !u32i, !cir.ptr<!u32i>
19+
20+
// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
21+
// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
22+
// LLVM: store i32 9, ptr %[[A_ADDR]], align 4
23+
// LLVM: store i32 20, ptr %[[B_ADDR]], align 4
24+
25+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
26+
// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
27+
// OGCG: store i32 9, ptr %[[A_ADDR]], align 4
28+
// OGCG: store i32 20, ptr %[[B_ADDR]], align 4
29+
30+
void function_file() {
31+
const char *a = __builtin_FUNCTION();
32+
const char *b = __builtin_FILE();
33+
const char *c = __builtin_FILE_NAME();
34+
}
35+
36+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>, ["a", init]
37+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>, ["b", init]
38+
// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>, ["c", init]
39+
// CIR: %[[FUNC__GV:.*]] = cir.const #cir.global_view<@".str"> : !cir.ptr<!s8i>
40+
// CIR: cir.store {{.*}} %[[FUNC__GV]], %[[A_ADDR]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
41+
// CIR: %[[FILE_PATH_GV:.*]] = cir.const #cir.global_view<@".str.1"> : !cir.ptr<!s8i>
42+
// CIR: cir.store {{.*}} %[[FILE_PATH_GV]], %[[B_ADDR]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
43+
// CIR: %[[FILE_GV:.*]] = cir.const #cir.global_view<@".str.2"> : !cir.ptr<!s8i>
44+
// CIR: cir.store {{.*}} %[[FILE_GV]], %[[C_ADDR]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
45+
46+
// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8
47+
// LLVM: %[[B_ADDR:.*]] = alloca ptr, i64 1, align 8
48+
// LLVM: %[[C_ADDR:.*]] = alloca ptr, i64 1, align 8
49+
// LLVM: store ptr @.str, ptr %[[A_ADDR]], align 8
50+
// LLVM: store ptr @.str.1, ptr %[[B_ADDR]], align 8
51+
// LLVM: store ptr @.str.2, ptr %[[C_ADDR]], align 8
52+
53+
// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
54+
// OGCG: %[[B_ADDR:.*]] = alloca ptr, align 8
55+
// OGCG: %[[C_ADDR:.*]] = alloca ptr, align 8
56+
// OGCG: store ptr @.str, ptr %[[A_ADDR]], align 8
57+
// OGCG: store ptr @.str.1, ptr %[[B_ADDR]], align 8
58+
// OGCG: store ptr @.str.2, ptr %[[C_ADDR]], align 8

0 commit comments

Comments
 (0)