1717#include " CIRGenModule.h"
1818#include " mlir/IR/Attributes.h"
1919#include " mlir/IR/BuiltinAttributeInterfaces.h"
20+ #include " mlir/IR/BuiltinAttributes.h"
2021#include " clang/AST/APValue.h"
2122#include " clang/AST/ASTContext.h"
2223#include " clang/AST/Attr.h"
@@ -999,16 +1000,16 @@ namespace {
9991000// / A struct which can be used to peephole certain kinds of finalization
10001001// / that normally happen during l-value emission.
10011002struct ConstantLValue {
1002- using SymbolTy = mlir::SymbolRefAttr;
1003- llvm::PointerUnion<mlir::Value, SymbolTy> Value;
1003+ llvm::PointerUnion<mlir::Value, mlir::Attribute> Value;
10041004 bool HasOffsetApplied;
10051005
10061006 /* implicit*/ ConstantLValue(mlir::Value value, bool hasOffsetApplied = false )
10071007 : Value(value), HasOffsetApplied(hasOffsetApplied) {}
10081008
1009- /* implicit*/ ConstantLValue(SymbolTy address) : Value(address) {}
1009+ /* implicit*/ ConstantLValue(mlir::SymbolRefAttr address) : Value(address) {}
10101010
10111011 ConstantLValue (std::nullptr_t ) : ConstantLValue({}, false ) {}
1012+ ConstantLValue (mlir::Attribute value) : Value(value) {}
10121013};
10131014
10141015// / A helper class for emitting constant l-values.
@@ -1053,10 +1054,13 @@ class ConstantLValueEmitter
10531054 // / Return the value offset.
10541055 mlir::Attribute getOffset () { llvm_unreachable (" NYI" ); }
10551056
1057+ // TODO(cir): create a proper interface to absctract CIR constant values.
1058+
10561059 // / Apply the value offset to the given constant.
1057- mlir::Attribute applyOffset (mlir::Attribute C) {
1060+ ConstantLValue applyOffset (ConstantLValue & C) {
10581061 if (!hasNonZeroOffset ())
10591062 return C;
1063+
10601064 // TODO(cir): use ptr_stride, or something...
10611065 llvm_unreachable (" NYI" );
10621066 }
@@ -1092,15 +1096,15 @@ mlir::Attribute ConstantLValueEmitter::tryEmit() {
10921096 return {};
10931097
10941098 // Apply the offset if necessary and not already done.
1095- if (!result.HasOffsetApplied && !value.is <ConstantLValue::SymbolTy >()) {
1096- assert ( 0 && " NYI " ) ;
1099+ if (!result.HasOffsetApplied && !value.is <mlir::Attribute >()) {
1100+ value = applyOffset (result). Value ;
10971101 }
10981102
10991103 // Convert to the appropriate type; this could be an lvalue for
11001104 // an integer. FIXME: performAddrSpaceCast
11011105 if (destTy.isa <mlir::cir::PointerType>()) {
1102- if (value.is <ConstantLValue::SymbolTy >())
1103- return value.get <ConstantLValue::SymbolTy >();
1106+ if (value.is <mlir::Attribute >())
1107+ return value.get <mlir::Attribute >();
11041108 llvm_unreachable (" NYI" );
11051109 }
11061110
@@ -1124,7 +1128,30 @@ ConstantLValue
11241128ConstantLValueEmitter::tryEmitBase (const APValue::LValueBase &base) {
11251129 // Handle values.
11261130 if (const ValueDecl *D = base.dyn_cast <const ValueDecl *>()) {
1127- assert (0 && " NYI" );
1131+ // The constant always points to the canonical declaration. We want to look
1132+ // at properties of the most recent declaration at the point of emission.
1133+ D = cast<ValueDecl>(D->getMostRecentDecl ());
1134+
1135+ if (D->hasAttr <WeakRefAttr>())
1136+ llvm_unreachable (" emit pointer base for weakref is NYI" );
1137+
1138+ if (auto *FD = dyn_cast<FunctionDecl>(D))
1139+ llvm_unreachable (" emit pointer base for fun decl is NYI" );
1140+
1141+ if (auto *VD = dyn_cast<VarDecl>(D)) {
1142+ // We can never refer to a variable with local storage.
1143+ if (!VD->hasLocalStorage ()) {
1144+ if (VD->isFileVarDecl () || VD->hasExternalStorage ())
1145+ return CGM.getAddrOfGlobalVarAttr (VD);
1146+
1147+ if (VD->isLocalVarDecl ()) {
1148+ auto linkage =
1149+ CGM.getCIRLinkageVarDefinition (VD, /* IsConstant=*/ false );
1150+ return CGM.getBuilder ().getGlobalViewAttr (
1151+ CGM.getOrCreateStaticVarDecl (*VD, linkage));
1152+ }
1153+ }
1154+ }
11281155 }
11291156
11301157 // Handle typeid(T).
0 commit comments