@@ -18,6 +18,8 @@ include "clang/CIR/Dialect/IR/CIRDialect.td"
1818include "clang/CIR/Dialect/IR/CIRTypes.td"
1919include "clang/CIR/Dialect/IR/CIRAttrs.td"
2020
21+ include "clang/CIR/Interfaces/CIROpInterfaces.td"
22+
2123include "mlir/IR/BuiltinAttributeInterfaces.td"
2224include "mlir/IR/EnumAttr.td"
2325include "mlir/IR/SymbolInterfaces.td"
@@ -430,6 +432,59 @@ def ScopeOp : CIR_Op<"scope", [
430432// GlobalOp
431433//===----------------------------------------------------------------------===//
432434
435+ // Linkage types. This is currently a replay of llvm/IR/GlobalValue.h, this is
436+ // currently handy as part of forwarding appropriate linkage types for LLVM
437+ // lowering, specially useful for C++ support.
438+
439+ // Externally visible function
440+ def Global_ExternalLinkage :
441+ I32EnumAttrCase<"ExternalLinkage", 0, "external">;
442+ // Available for inspection, not emission.
443+ def Global_AvailableExternallyLinkage :
444+ I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">;
445+ // Keep one copy of function when linking (inline)
446+ def Global_LinkOnceAnyLinkage :
447+ I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">;
448+ // Same, but only replaced by something equivalent.
449+ def Global_LinkOnceODRLinkage :
450+ I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">;
451+ // Keep one copy of named function when linking (weak)
452+ def Global_WeakAnyLinkage :
453+ I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">;
454+ // Same, but only replaced by something equivalent.
455+ def Global_WeakODRLinkage :
456+ I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">;
457+ // TODO: should we add something like appending linkage too?
458+ // Special purpose, only applies to global arrays
459+ // def Global_AppendingLinkage :
460+ // I32EnumAttrCase<"AppendingLinkage", 6, "appending">;
461+ // Rename collisions when linking (static functions).
462+ def Global_InternalLinkage :
463+ I32EnumAttrCase<"InternalLinkage", 7, "internal">;
464+ // Like Internal, but omit from symbol table, prefix it with
465+ // "cir_" to prevent clash with MLIR's symbol "private".
466+ def Global_PrivateLinkage :
467+ I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">;
468+ // ExternalWeak linkage description.
469+ def Global_ExternalWeakLinkage :
470+ I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">;
471+ // Tentative definitions.
472+ def Global_CommonLinkage :
473+ I32EnumAttrCase<"CommonLinkage", 10, "common">;
474+
475+ /// An enumeration for the kinds of linkage for global values.
476+ def GlobalLinkageKind : I32EnumAttr<
477+ "GlobalLinkageKind",
478+ "Linkage type/kind",
479+ [Global_ExternalLinkage, Global_AvailableExternallyLinkage,
480+ Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage,
481+ Global_WeakAnyLinkage, Global_WeakODRLinkage,
482+ Global_InternalLinkage, Global_PrivateLinkage,
483+ Global_ExternalWeakLinkage, Global_CommonLinkage
484+ ]> {
485+ let cppNamespace = "::cir";
486+ }
487+
433488// TODO(CIR): For starters, cir.global has only name and type. The other
434489// properties of a global variable will be added over time as more of ClangIR
435490// is upstreamed.
@@ -441,12 +496,19 @@ def GlobalOp : CIR_Op<"global"> {
441496
442497 The backing memory for the variable is allocated statically and is
443498 described by the type of the variable.
499+
500+ The `linkage` tracks C/C++ linkage types, currently very similar to LLVM's.
444501 }];
445502
446- let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type,
447- OptionalAttr<AnyAttr>:$initial_value);
503+ let arguments = (ins SymbolNameAttr:$sym_name,
504+ TypeAttr:$sym_type,
505+ Arg<GlobalLinkageKind, "linkage type">:$linkage,
506+ OptionalAttr<AnyAttr>:$initial_value,
507+ UnitAttr:$dsolocal);
448508
449509 let assemblyFormat = [{
510+ $linkage
511+ (`dsolocal` $dsolocal^)?
450512 $sym_name
451513 custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value)
452514 attr-dict
@@ -459,8 +521,12 @@ def GlobalOp : CIR_Op<"global"> {
459521
460522 let skipDefaultBuilders = 1;
461523
462- let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name,
463- "mlir::Type":$sym_type)>];
524+ let builders = [OpBuilder<(ins
525+ "llvm::StringRef":$sym_name,
526+ "mlir::Type":$sym_type,
527+ // CIR defaults to external linkage.
528+ CArg<"cir::GlobalLinkageKind",
529+ "cir::GlobalLinkageKind::ExternalLinkage">:$linkage)>];
464530
465531 let hasVerifier = 1;
466532}
0 commit comments