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"
@@ -996,16 +997,16 @@ namespace {
996997// / A struct which can be used to peephole certain kinds of finalization
997998// / that normally happen during l-value emission.
998999struct ConstantLValue {
999- using SymbolTy = mlir::SymbolRefAttr;
1000- llvm::PointerUnion<mlir::Value, SymbolTy> Value;
1000+ llvm::PointerUnion<mlir::Value, mlir::Attribute> Value;
10011001 bool HasOffsetApplied;
10021002
10031003 /* implicit*/ ConstantLValue(mlir::Value value, bool hasOffsetApplied = false )
10041004 : Value(value), HasOffsetApplied(hasOffsetApplied) {}
10051005
1006- /* implicit*/ ConstantLValue(SymbolTy address) : Value(address) {}
1006+ /* implicit*/ ConstantLValue(mlir::SymbolRefAttr address) : Value(address) {}
10071007
10081008 ConstantLValue (std::nullptr_t ) : ConstantLValue({}, false ) {}
1009+ ConstantLValue (mlir::Attribute value) : Value(value) {}
10091010};
10101011
10111012// / A helper class for emitting constant l-values.
@@ -1050,10 +1051,13 @@ class ConstantLValueEmitter
10501051 // / Return the value offset.
10511052 mlir::Attribute getOffset () { llvm_unreachable (" NYI" ); }
10521053
1054+ // TODO(cir): create a proper interface to absctract CIR constant values.
1055+
10531056 // / Apply the value offset to the given constant.
1054- mlir::Attribute applyOffset (mlir::Attribute C) {
1057+ ConstantLValue applyOffset (ConstantLValue & C) {
10551058 if (!hasNonZeroOffset ())
10561059 return C;
1060+
10571061 // TODO(cir): use ptr_stride, or something...
10581062 llvm_unreachable (" NYI" );
10591063 }
@@ -1089,15 +1093,15 @@ mlir::Attribute ConstantLValueEmitter::tryEmit() {
10891093 return {};
10901094
10911095 // Apply the offset if necessary and not already done.
1092- if (!result.HasOffsetApplied && !value.is <ConstantLValue::SymbolTy >()) {
1093- assert ( 0 && " NYI " ) ;
1096+ if (!result.HasOffsetApplied && !value.is <mlir::Attribute >()) {
1097+ value = applyOffset (result). Value ;
10941098 }
10951099
10961100 // Convert to the appropriate type; this could be an lvalue for
10971101 // an integer. FIXME: performAddrSpaceCast
10981102 if (destTy.isa <mlir::cir::PointerType>()) {
1099- if (value.is <ConstantLValue::SymbolTy >())
1100- return value.get <ConstantLValue::SymbolTy >();
1103+ if (value.is <mlir::Attribute >())
1104+ return value.get <mlir::Attribute >();
11011105 llvm_unreachable (" NYI" );
11021106 }
11031107
@@ -1121,7 +1125,30 @@ ConstantLValue
11211125ConstantLValueEmitter::tryEmitBase (const APValue::LValueBase &base) {
11221126 // Handle values.
11231127 if (const ValueDecl *D = base.dyn_cast <const ValueDecl *>()) {
1124- assert (0 && " NYI" );
1128+ // The constant always points to the canonical declaration. We want to look
1129+ // at properties of the most recent declaration at the point of emission.
1130+ D = cast<ValueDecl>(D->getMostRecentDecl ());
1131+
1132+ if (D->hasAttr <WeakRefAttr>())
1133+ llvm_unreachable (" emit pointer base for weakref is NYI" );
1134+
1135+ if (auto *FD = dyn_cast<FunctionDecl>(D))
1136+ llvm_unreachable (" emit pointer base for fun decl is NYI" );
1137+
1138+ if (auto *VD = dyn_cast<VarDecl>(D)) {
1139+ // We can never refer to a variable with local storage.
1140+ if (!VD->hasLocalStorage ()) {
1141+ if (VD->isFileVarDecl () || VD->hasExternalStorage ())
1142+ return CGM.getAddrOfGlobalVarAttr (VD);
1143+
1144+ if (VD->isLocalVarDecl ()) {
1145+ auto linkage =
1146+ CGM.getCIRLinkageVarDefinition (VD, /* IsConstant=*/ false );
1147+ return CGM.getBuilder ().getGlobalViewAttr (
1148+ CGM.getOrCreateStaticVarDecl (*VD, linkage));
1149+ }
1150+ }
1151+ }
11251152 }
11261153
11271154 // Handle typeid(T).
0 commit comments