Skip to content

[CIR][NFC] Add Symbol Table to CIRGenFunction #153625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ struct MissingFeatures {
// Address space related
static bool addressSpace() { return false; }

// CIRGenFunction implementation details
static bool cgfSymbolTable() { return false; }

// Unhandled global/linkage information.
static bool opGlobalThreadLocal() { return false; }
static bool opGlobalConstant() { return false; }
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,12 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
? emitLoadOfReferenceLValue(addr, getLoc(e->getSourceRange()),
vd->getType(), AlignmentSource::Decl)
: makeAddrLValue(addr, ty, AlignmentSource::Decl);

// Statics are defined as globals, so they are not include in the function's
// symbol table.
assert((vd->isStaticLocal() || symbolTable.count(vd)) &&
"non-static locals should be already mapped");

return lv;
}

Expand Down
9 changes: 8 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty,
mlir::Location loc, CharUnits alignment,
bool isParam) {
assert(isa<NamedDecl>(var) && "Needs a named decl");
assert(!cir::MissingFeatures::cgfSymbolTable());
assert(!symbolTable.count(var) && "not supposed to be available just yet");

auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>();
assert(allocaOp && "expected cir::AllocaOp");
Expand All @@ -224,6 +224,8 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty,
allocaOp.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
if (ty->isReferenceType() || ty.isConstQualified())
allocaOp.setConstantAttr(mlir::UnitAttr::get(&getMLIRContext()));

symbolTable.insert(var, allocaOp);
}

void CIRGenFunction::LexicalScope::cleanup() {
Expand Down Expand Up @@ -485,6 +487,9 @@ void CIRGenFunction::finishFunction(SourceLocation endLoc) {
}

mlir::LogicalResult CIRGenFunction::emitFunctionBody(const clang::Stmt *body) {
// We start with function level scope for variables.
SymTableScopeTy varScope(symbolTable);

auto result = mlir::LogicalResult::success();
if (const CompoundStmt *block = dyn_cast<CompoundStmt>(body))
emitCompoundStmtWithoutScope(*block);
Expand Down Expand Up @@ -531,6 +536,8 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
FunctionArgList args;
QualType retTy = buildFunctionArgList(gd, args);

// Create a scope in the symbol table to hold variable declarations.
SymTableScopeTy varScope(symbolTable);
{
LexicalScope lexScope(*this, fusedLoc, entryBB);

Expand Down
18 changes: 17 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/MissingFeatures.h"
#include "clang/CIR/TypeEvaluationKind.h"
#include "llvm/ADT/ScopedHashTable.h"

namespace {
class ScalarExprEmitter;
Expand Down Expand Up @@ -103,6 +104,14 @@ class CIRGenFunction : public CIRGenTypeCache {
/// Sanitizers enabled for this function.
clang::SanitizerSet sanOpts;

/// The symbol table maps a variable name to a value in the current scope.
/// Entering a function creates a new scope, and the function arguments are
/// added to the mapping. When the processing of a function is terminated,
/// the scope is destroyed and the mappings created in this scope are
/// dropped.
using SymTableTy = llvm::ScopedHashTable<const clang::Decl *, mlir::Value>;
SymTableTy symbolTable;

/// Whether or not a Microsoft-style asm block has been processed within
/// this fuction. These can potentially set the return value.
bool sawAsmBlock = false;
Expand Down Expand Up @@ -325,6 +334,9 @@ class CIRGenFunction : public CIRGenTypeCache {
~SourceLocRAIIObject() { restore(); }
};

using SymTableScopeTy =
llvm::ScopedHashTableScope<const clang::Decl *, mlir::Value>;

/// Hold counters for incrementally naming temporaries
unsigned counterRefTmp = 0;
unsigned counterAggTmp = 0;
Expand Down Expand Up @@ -499,7 +511,11 @@ class CIRGenFunction : public CIRGenTypeCache {
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr) {
assert(!localDeclMap.count(vd) && "Decl already exists in LocalDeclMap!");
localDeclMap.insert({vd, addr});
// TODO: Add symbol table support

// Add to the symbol table if not there already.
if (symbolTable.count(vd))
return;
symbolTable.insert(vd, addr.getPointer());
}

bool shouldNullCheckClassCastValue(const CastExpr *ce);
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void CIRGenFunction::emitCompoundStmtWithoutScope(const CompoundStmt &s) {
}

void CIRGenFunction::emitCompoundStmt(const CompoundStmt &s) {
// Add local scope to track new declared variables.
SymTableScopeTy varScope(symbolTable);
mlir::Location scopeLoc = getLoc(s.getSourceRange());
mlir::OpBuilder::InsertPoint scopeInsPt;
builder.create<cir::ScopeOp>(
Expand Down