clang: lib/CIR/CodeGen/CIRGenModule.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
17
29
31#include "mlir/IR/BuiltinOps.h"
32#include "mlir/IR/Location.h"
33#include "mlir/IR/MLIRContext.h"
34#include "mlir/IR/Verifier.h"
35
36#include
37
38using namespace clang;
40
43 case TargetCXXABI::GenericItanium:
44 case TargetCXXABI::GenericAArch64:
45 case TargetCXXABI::AppleARM64:
47
48 case TargetCXXABI::Fuchsia:
49 case TargetCXXABI::GenericARM:
50 case TargetCXXABI::iOS:
51 case TargetCXXABI::WatchOS:
52 case TargetCXXABI::GenericMIPS:
53 case TargetCXXABI::WebAssembly:
54 case TargetCXXABI::XL:
55 case TargetCXXABI::Microsoft:
56 cgm.errorNYI("C++ ABI kind not yet implemented");
57 return nullptr;
58 }
59
60 llvm_unreachable("invalid C++ ABI kind");
61}
62
63CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
67 : builder(mlirContext, *this), astContext(astContext),
68 langOpts(astContext.getLangOpts()), codeGenOpts(cgo),
69 theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))},
70 diags(diags), target(astContext.getTargetInfo()),
71 abi(createCXXABI(*this)), genTypes(*this), vtables(*this) {
72
73
94
96
98 astContext
99 .toCharUnitsFromBits(
100 astContext.getTargetInfo().getPointerAlign(LangAS::Default))
101 .getQuantity();
102
103 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
105
106
107 const unsigned sizeTypeSize =
108 astContext.getTypeSize(astContext.getSignedSizeType());
109 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
110
112 cir::IntType::get(&getMLIRContext(), sizeTypeSize, false);
114 cir::IntType::get(&getMLIRContext(), sizeTypeSize, true);
115
116 std::optionalcir::SourceLanguage sourceLanguage = getCIRSourceLanguage();
117 if (sourceLanguage)
118 theModule->setAttr(
119 cir::CIRDialect::getSourceLanguageAttrName(),
120 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
121 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
122 builder.getStringAttr(getTriple().str()));
123
124 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
125 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
126 cir::OptInfoAttr::get(&mlirContext,
127 cgo.OptimizationLevel,
128 cgo.OptimizeSize));
129
130
131
132 FileID mainFileId = astContext.getSourceManager().getMainFileID();
134 *astContext.getSourceManager().getFileEntryForID(mainFileId);
136 if (!path.empty()) {
137 theModule.setSymName(path);
138 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
139 0,
140 0));
141 }
142}
143
145
146
147
148
149
152 return CharUnits::One();
153
154 auto &layout = astContext.getASTRecordLayout(rd);
155
156
157
159 return layout.getAlignment();
160
161
162 return layout.getNonVirtualAlignment();
163}
164
168
169
170
171
172
173
174
176 if (unsigned align = tt->getDecl()->getMaxAlignment()) {
177 if (baseInfo)
179 return astContext.toCharUnitsFromBits(align);
180 }
181 }
182
183
184
185 t = astContext.getBaseElementType(t);
186
188
189
190
191
192
193
194 if (baseInfo)
197 }
198
199 if (baseInfo)
201
205 } else {
207 alignment = astContext.getTypeAlignInChars(t);
208 }
209
210
211
212 if (unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
213 if (alignment.getQuantity() > maxAlign &&
214 !astContext.isAlignmentRequired(t))
216 }
217 return alignment;
218}
219
221 if (theTargetCIRGenInfo)
222 return *theTargetCIRGenInfo;
223
225 switch (triple.getArch()) {
226 default:
228
229
230 [[fallthrough]];
231
232 case llvm::Triple::x86_64: {
233 switch (triple.getOS()) {
234 default:
236
237
238 [[fallthrough]];
239
240 case llvm::Triple::Linux:
242 return *theTargetCIRGenInfo;
243 }
244 }
245 }
246}
247
249 assert(cLoc.isValid() && "expected valid source location");
250 const SourceManager &sm = astContext.getSourceManager();
253 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
255}
256
258 assert(cRange.isValid() && "expected a valid source range");
260 mlir::Location end = getLoc(cRange.getEnd());
261 mlir::Attribute metadata;
262 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
263}
264
265mlir::Operation *
268
271 false, isForDefinition);
272
277 return getAddrOfFunction(gd, ty, false, false,
278 isForDefinition);
279 }
280
284 return getAddrOfFunction(gd, ty, false, false,
285 isForDefinition);
286 }
287
289 .getDefiningOp();
290}
291
293
294
295
296
298
299
300
301
302 if (!op)
304
305 assert(op && "expected a valid global op");
306
307
308
309
310
311
312
313 mlir::Operation *globalValueOp = op;
314 if (auto gv = dyn_castcir::GetGlobalOp(op))
315 globalValueOp =
316 mlir::SymbolTable::lookupSymbolIn(getModule(), gv.getNameAttr());
317
318 if (auto cirGlobalValue =
319 dyn_castcir::CIRGlobalValueInterface(globalValueOp))
320 if (!cirGlobalValue.isDeclaration())
321 return;
322
323
325
326
328}
329
331
332
333
334
338
339
341 return;
342
343
344
345 std::vector curDeclsToEmit;
347
348 for (const GlobalDecl &d : curDeclsToEmit) {
350
351
352
353
357 }
358 }
359}
360
362 if (const auto *cd = dyn_castclang::OpenACCConstructDecl(gd.getDecl())) {
364 return;
365 }
366
367
368
369
370
371
372
374
375 if (const auto *fd = dyn_cast(global)) {
376
377
378 if (fd->hasAttr())
379 errorNYI(fd->getSourceRange(), "deferredAnnotations");
380 if (!fd->doesThisDeclarationHaveABody()) {
381 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
382 return;
383
384 errorNYI(fd->getSourceRange(),
385 "function declaration that forces code gen");
386 return;
387 }
388 } else {
390 assert(vd->isFileVarDecl() && "Cannot emit local var decl as global.");
392 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
394
395
396 if (astContext.getInlineVariableDefinitionKind(vd) ==
399
400
401 return;
402 }
403 }
404
405
406
407
408
410
412 return;
413 }
414
415
416
418
421
424
427 } else {
428
429
431 }
432}
433
435 mlir::Operation *op) {
439 cir::FuncOp funcOp = dyn_cast_if_presentcir::FuncOp(op);
440 if (!funcOp || funcOp.getFunctionType() != funcType) {
443 }
444
445
446 if (!funcOp.isDeclaration())
447 return;
448
454
456 curCGF = &cgf;
457 {
458 mlir::OpBuilder::InsertionGuard guard(builder);
460 }
461 curCGF = nullptr;
462
463 setNonAliasAttributes(gd, funcOp);
465
466 auto getPriority = [this](const auto *attr) -> int {
467 Expr *e = attr->getPriority();
468 if (e)
470 return attr->DefaultPriority;
471 };
472
473 if (const ConstructorAttr *ca = funcDecl->getAttr())
475 if (const DestructorAttr *da = funcDecl->getAttr())
477
478 if (funcDecl->getAttr())
479 errorNYI(funcDecl->getSourceRange(), "deferredAnnotations");
480}
481
482
484 std::optional priority) {
487
488
489
490
491
492
493 ctor.setGlobalCtorPriority(priority);
494}
495
496
498 std::optional priority) {
499 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
501 errorNYI(dtor.getLoc(), "registerGlobalDtorsWithAtExit");
502
503
504 dtor.setGlobalDtorPriority(priority);
505}
506
510 return;
511
513
514
517
519}
520
522 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
523}
524
526 mlir::Location loc, StringRef name,
527 mlir::Type t, bool isConstant,
528 mlir::Operation *insertPoint) {
529 cir::GlobalOp g;
531
532 {
533 mlir::OpBuilder::InsertionGuard guard(builder);
534
535
536
537
538 if (insertPoint) {
539 builder.setInsertionPoint(insertPoint);
540 } else {
541
543 builder.setInsertionPointAfter(cgm.lastGlobalOp);
544 else
545 builder.setInsertionPointToStart(cgm.getModule().getBody());
546 }
547
548 g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
549 if (!insertPoint)
551
552
553
554 mlir::SymbolTable::setSymbolVisibility(
555 g, mlir::SymbolTable::Visibility::Private);
556 }
557 return g;
558}
559
562 if (isa_and_nonnull(d))
566}
567
568void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
570
575
577}
578
579std::optionalcir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
581 using CIRLang = cir::SourceLanguage;
583
584 if (opts.CPlusPlus)
585 return CIRLang::CXX;
586 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
587 opts.LangStd == ClangStd::lang_c89 ||
588 opts.LangStd == ClangStd::lang_gnu89)
589 return CIRLang::C;
590
591
593 errorNYI("CIR does not yet support the given source language");
594 return std::nullopt;
595}
596
598
600
601
602
605 gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
606}
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622cir::GlobalOp
624 LangAS langAS, const VarDecl *d,
626
627 cir::GlobalOp entry;
628 if (mlir::Operation *v = getGlobalValue(mangledName)) {
632 }
633
634 if (entry) {
637
640
641 if (entry.getSymType() == ty)
642 return entry;
643
644
645
646
647
648
649
650 if (isForDefinition && !entry.isDeclaration()) {
652 }
653
654
655
656
657
658
659 if (!isForDefinition)
660 return entry;
661 }
662
664
665
666
667 cir::GlobalOp gv =
669 entry.getOperation());
670
671
672
673
676
677
680 }
681
682
683 if (d) {
684 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
686
687 gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
688
689
691 astContext, false, false));
692
694
699 }
700
702
703
704
705 if (astContext.isMSStaticDataMemberInlineDefinition(d))
707
710
711
712 if (getTriple().getArch() == llvm::Triple::xcore)
714
715
716
717
722 "external const declaration with initializer");
723 }
724
725 return gv;
726}
727
728cir::GlobalOp
733 if (!ty)
735
738 isForDefinition);
739}
740
741
742
743
744
745
746
751 if (!ty)
753
756 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
758 g.getSymNameAttr(), tlsAccess);
759}
760
764
767 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
768 return builder.getGlobalViewAttr(ptrTy, globalOp);
769}
770
772 bool isTentative) {
775 return;
776 }
777
778
779
780
781 bool isDefinitionAvailableExternally =
783
784
785
786 if (isDefinitionAvailableExternally &&
788
789
792 return;
793
794 mlir::Attribute init;
795 bool needsGlobalCtor = false;
796 bool needsGlobalDtor =
797 !isDefinitionAvailableExternally &&
801
802 std::optional emitter;
803
805
806 if (vd->hasAttr()) {
808 return;
809 } else if (!initExpr) {
810
811
812
813
814
815
816
817
818
821 } else {
822 emitter.emplace(*this);
823 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
824 if (!initializer) {
828
832 init = builder.getZeroInitAttr(convertType(qt));
833 if (!isDefinitionAvailableExternally)
834 needsGlobalCtor = true;
835 } else {
837 }
838 } else {
839 init = initializer;
840
841
842
844 }
845 }
846
847 mlir::Type initType;
848 if (mlir::isamlir::SymbolRefAttr(init)) {
850 return;
851 } else {
852 assert(mlir::isamlir::TypedAttr(init) && "This should have a type");
853 auto typedInitAttr = mlir::castmlir::TypedAttr(init);
854 initType = typedInitAttr.getType();
855 }
856 assert(!mlir::isamlir::NoneType(initType) && "Should have a type by now");
857
858 cir::GlobalOp gv =
860
861
862 if (!gv || gv.getSymType() != initType) {
864 return;
865 }
866
868
869 if (vd->hasAttr()) {
871 }
872
873 if (langOpts.CUDA) {
875 }
876
877
879 if (emitter)
880 emitter->finalize(gv);
881
882
883 gv.setConstant((vd->hasAttr() && langOpts.CUDAIsDevice) ||
884 (!needsGlobalCtor && !needsGlobalDtor &&
886 astContext, true, true)));
888
889
890 cir::GlobalLinkageKind linkage =
892
893
894 gv.setLinkage(linkage);
895
898 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
899
900 gv.setConstant(false);
901
902
903
904
905 std::optionalmlir::Attribute initializer = gv.getInitialValue();
906 if (initializer && ().isNullValue(*initializer))
907 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
908 }
909
910 setNonAliasAttributes(vd, gv);
911
913
915
916
917 if (needsGlobalCtor || needsGlobalDtor)
919}
920
922 mlir::Operation *op) {
924 if (const auto *fd = dyn_cast(decl)) {
925
926
927
928 if (const auto *method = dyn_cast(decl)) {
929
930
932 abi->emitCXXStructor(gd);
933 else if (fd->isMultiVersion())
934 errorNYI(method->getSourceRange(), "multiversion functions");
935 else
937
938 if (method->isVirtual())
940
941 return;
942 }
943
944 if (fd->isMultiVersion())
945 errorNYI(fd->getSourceRange(), "multiversion functions");
947 return;
948 }
949
950 if (const auto *vd = dyn_cast(decl))
952
953 llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
954}
955
956mlir::Attribute
959
960
961
964
965
967 astContext.getAsConstantArrayType(e->getType());
968 uint64_t finalSize = cat->getZExtSize();
969 str.resize(finalSize);
970
971 mlir::Type eltTy = convertType(cat->getElementType());
972 return builder.getString(str, eltTy, finalSize);
973 }
974
975 auto arrayTy = mlir::castcir::ArrayType(convertType(e->getType()));
976
977 auto arrayEltTy = mlir::castcir::IntType(arrayTy.getElementType());
978
979 uint64_t arraySize = arrayTy.getSize();
980 unsigned literalSize = e->getLength();
981 assert(arraySize == literalSize + 1 &&
982 "wide string literal array size must be literal length plus null "
983 "terminator");
984
985
986
987 bool isAllZero = true;
988 for (unsigned i = 0; i < literalSize; ++i) {
990 isAllZero = false;
991 break;
992 }
993 }
994
995 if (isAllZero)
996 return cir::ZeroAttr::get(arrayTy);
997
998
1000 elements.reserve(arraySize);
1001 for (unsigned i = 0; i < literalSize; ++i)
1002 elements.push_back(cir::IntAttr::get(arrayEltTy, e->getCodeUnit(i)));
1003
1004 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1005
1006 auto elementsAttr = mlir::ArrayAttr::get(&getMLIRContext(), elements);
1007 return builder.getConstArray(elementsAttr, arrayTy);
1008}
1009
1011 return getTriple().supportsCOMDAT();
1012}
1013
1016 return false;
1017
1018 if (d.hasAttr())
1019 return true;
1020
1022 if (auto *vd = dyn_cast(&d))
1024 else
1025 linkage =
1027
1028 switch (linkage) {
1032 return false;
1035 return true;
1036 }
1037 llvm_unreachable("No such linkage");
1038}
1039
1042 return;
1043 if (auto globalOp = dyn_cast_or_nullcir::GlobalOp(op)) {
1044 globalOp.setComdat(true);
1045 } else {
1047 funcOp.setComdat(true);
1048 }
1049}
1050
1052
1053 genTypes.updateCompletedType(td);
1054}
1055
1057 replacements[name] = op;
1058}
1059
1060void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1061 std::optionalmlir::SymbolTable::UseRange optionalUseRange =
1062 oldF.getSymbolUses(theModule);
1063 if (!optionalUseRange)
1064 return;
1065
1066 for (const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1067
1068 auto call = mlir::dyn_castcir::CallOp(u.getUser());
1069 if (!call)
1070 continue;
1071
1072 for (const auto [argOp, fnArgType] :
1073 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1074 if (argOp.getType() == fnArgType)
1075 continue;
1076
1077
1078
1079
1080 errorNYI(call.getLoc(), "replace call with mismatched types");
1081 }
1082 }
1083}
1084
1085void CIRGenModule::applyReplacements() {
1086 for (auto &i : replacements) {
1087 StringRef mangledName = i.first();
1088 mlir::Operation *replacement = i.second;
1089 mlir::Operation *entry = getGlobalValue(mangledName);
1090 if (!entry)
1091 continue;
1094 auto newF = dyn_castcir::FuncOp(replacement);
1095 if (!newF) {
1096
1097 errorNYI(replacement->getLoc(), "replacement is not a function");
1098 continue;
1099 }
1100
1101
1102
1103 replacePointerTypeArgs(oldF, newF);
1104
1105
1106 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1107 llvm_unreachable("internal error, cannot RAUW symbol");
1108 if (newF) {
1109 newF->moveBefore(oldF);
1110 oldF->erase();
1111 }
1112 }
1113}
1114
1116 mlir::Location loc, StringRef name, mlir::Type ty,
1117 cir::GlobalLinkageKind linkage, clang::CharUnits alignment) {
1118 auto gv = mlir::dyn_cast_or_nullcir::GlobalOp(
1119 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1120
1121 if (gv) {
1122
1123 if (gv.getSymType() == ty)
1124 return gv;
1125
1126
1127
1128
1129 assert(gv.isDeclaration() && "Declaration has wrong type!");
1130
1131 errorNYI(loc, "createOrReplaceCXXRuntimeVariable: declaration exists with "
1132 "wrong type");
1133 return gv;
1134 }
1135
1136
1138
1139
1140 gv.setLinkageAttr(
1141 cir::GlobalLinkageKindAttr::get(&getMLIRContext(), linkage));
1142 mlir::SymbolTable::setSymbolVisibility(gv,
1144
1146 !gv.hasAvailableExternallyLinkage()) {
1147 gv.setComdat(true);
1148 }
1149
1150 gv.setAlignmentAttr(getSize(alignment));
1151 setDSOLocal(static_cast<mlir::Operation *>(gv));
1152 return gv;
1153}
1154
1155
1158 bool noCommon) {
1159
1160
1161 if ((noCommon || vd->hasAttr()) && !vd->hasAttr())
1162 return true;
1163
1164
1165
1166
1167
1169 return true;
1170
1171
1172 if (vd->hasAttr())
1173 return true;
1174
1175
1176
1177
1178 if (vd->hasAttr() ||
1179 vd->hasAttr() ||
1180 vd->hasAttr() ||
1181 vd->hasAttr())
1182 return true;
1183
1184
1186 return true;
1187
1188
1189 if (vd->hasAttr())
1190 return true;
1191
1192
1194 return true;
1195
1196
1197
1199 if (vd->hasAttr())
1200 return true;
1203 return true;
1204
1206 for (const FieldDecl *fd : rd->fields()) {
1207 if (fd->isBitField())
1208 continue;
1209 if (fd->hasAttr())
1210 return true;
1212 return true;
1213 }
1214 }
1215 }
1216
1217
1218
1219
1220
1221
1222
1226 return true;
1227
1228 return false;
1229}
1230
1234 return cir::GlobalLinkageKind::InternalLinkage;
1235
1236 if (dd->hasAttr()) {
1237 if (isConstantVariable)
1238 return cir::GlobalLinkageKind::WeakODRLinkage;
1239 return cir::GlobalLinkageKind::WeakAnyLinkage;
1240 }
1241
1244 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1245
1246
1247
1249 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1263 return !astContext.getLangOpts().AppleKext
1264 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1265 : cir::GlobalLinkageKind::InternalLinkage;
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1279 return cir::GlobalLinkageKind::ExternalLinkage;
1281 ().GPURelocatableDeviceCode)
1282 return dd->hasAttr()
1283 ? cir::GlobalLinkageKind::ExternalLinkage
1284 : cir::GlobalLinkageKind::InternalLinkage;
1285 return cir::GlobalLinkageKind::WeakODRLinkage;
1286 }
1287
1288
1289
1293 return cir::GlobalLinkageKind::CommonLinkage;
1294
1295
1296
1297
1298
1299 if (dd->hasAttr())
1300 return cir::GlobalLinkageKind::WeakODRLinkage;
1301
1302
1304 return cir::GlobalLinkageKind::ExternalLinkage;
1305}
1306
1307
1308
1309
1310
1311
1312
1313
1314
1316 mlir::Operation *old, cir::FuncOp newFn) {
1317
1318 auto oldFn = mlir::dyn_castcir::FuncOp(old);
1319 if (!oldFn)
1320 return;
1321
1322
1326 if (oldFn->getAttrs().size() <= 1)
1328 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1329
1330
1331 newFn.setNoProto(oldFn.getNoProto());
1332
1333
1334 std::optionalmlir::SymbolTable::UseRange symUses =
1335 oldFn.getSymbolUses(oldFn->getParentOp());
1336 for (const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1337 mlir::OpBuilder::InsertionGuard guard(builder);
1338
1339 if (auto noProtoCallOp = mlir::dyn_castcir::CallOp(use.getUser())) {
1340 builder.setInsertionPoint(noProtoCallOp);
1341
1342
1343 cir::CallOp realCallOp = builder.createCallOp(
1344 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1345
1346
1347 noProtoCallOp.replaceAllUsesWith(realCallOp);
1348 noProtoCallOp.erase();
1349 } else if (auto getGlobalOp =
1350 mlir::dyn_castcir::GetGlobalOp(use.getUser())) {
1351
1352 getGlobalOp.getAddr().setType(
1353 cir::PointerType::get(newFn.getFunctionType()));
1354 } else {
1355 errorNYI(use.getUser()->getLoc(),
1356 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1357 }
1358 }
1359}
1360
1361cir::GlobalLinkageKind
1363 assert(!isConstant && "constant variables NYI");
1364 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1366}
1367
1370
1371 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1372
1373 if (const auto *dtor = dyn_cast(d))
1375
1377}
1378
1379static cir::GlobalOp
1381 cir::GlobalLinkageKind lt, CIRGenModule &cgm,
1382 StringRef globalName, CharUnits alignment) {
1384
1385
1386
1388 cgm, loc, globalName, c.getType(), !cgm.getLangOpts().WritableStrings);
1389
1390
1391 gv.setAlignmentAttr(cgm.getSize(alignment));
1392 gv.setLinkageAttr(
1393 cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
1397 if (gv.isWeakForLinker()) {
1398 assert(cgm.supportsCOMDAT() && "Only COFF uses weak string literals");
1399 gv.setComdat(true);
1400 }
1401 cgm.setDSOLocal(static_cast<mlir::Operation *>(gv));
1402 return gv;
1403}
1404
1405
1406
1407
1408
1409
1410
1411
1412
1414
1415
1419 return baseName;
1420 }
1421
1422 std::string result =
1423 baseName + "." + std::to_string(cgGlobalNames[baseName]++);
1424
1425 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1426 return result;
1427}
1428
1429
1431 StringRef name) {
1433 astContext.getAlignOfGlobalVarInChars(s->getType(), nullptr);
1434
1436
1437 cir::GlobalOp gv;
1440
1441 if (!gv.getAlignment() ||
1442 uint64_t(alignment.getQuantity()) > *gv.getAlignment())
1443 gv.setAlignmentAttr(getSize(alignment));
1444 } else {
1445
1446
1447
1448 if (getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
1451 "getGlobalForStringLiteral: mangle string literals");
1452 }
1453
1454
1455
1457
1458
1459 mlir::Location loc = s->getBeginLoc().isValid()
1460 ? getLoc(s->getSourceRange())
1461 : builder.getUnknownLoc();
1462 auto typedC = llvm::castmlir::TypedAttr(c);
1464 cir::GlobalLinkageKind::PrivateLinkage, *this,
1465 uniqueName, alignment);
1466 setDSOLocal(static_cast<mlir::Operation *>(gv));
1468
1470 }
1471 return gv;
1472}
1473
1474
1475cir::GlobalViewAttr
1477 StringRef name) {
1479 auto arrayTy = mlir::dyn_castcir::ArrayType(gv.getSymType());
1480 assert(arrayTy && "String literal must be array");
1483
1484 return builder.getGlobalViewAttr(ptrTy, gv);
1485}
1486
1487
1491
1492
1493
1494
1497
1500 errorNYI("SYCL or OpenMP temp address space");
1502}
1503
1508
1510 "emitExplicitCastExprType");
1511}
1512
1515
1517
1519
1520
1523 return {};
1524 }
1525
1526
1527 auto ty = mlir::castcir::DataMemberType(convertType(e->getType()));
1529 return cir::ConstantOp::create(
1530 builder, loc, builder.getDataMemberAttr(ty, fieldDecl->getFieldIndex()));
1531}
1532
1535
1536
1537
1538
1539
1540 if (auto *oid = dyn_cast(decl))
1541 errorNYI(oid->getSourceRange(), "emitDeclConext: ObjCImplDecl");
1542
1544 }
1545}
1546
1547
1549
1550
1551 if (decl->isTemplated())
1552 return;
1553
1554 switch (decl->getKind()) {
1555 default:
1556 errorNYI(decl->getBeginLoc(), "declaration of kind",
1557 decl->getDeclKindName());
1558 break;
1559
1560 case Decl::CXXConversion:
1561 case Decl::CXXMethod:
1562 case Decl::Function: {
1564
1565 if (!fd->isConsteval())
1567 break;
1568 }
1569
1570 case Decl::Var:
1571 case Decl::Decomposition:
1572 case Decl::VarTemplateSpecialization: {
1575 errorNYI(decl->getSourceRange(), "global variable decompositions");
1576 break;
1577 }
1579 break;
1580 }
1581 case Decl::OpenACCRoutine:
1583 break;
1584 case Decl::OpenACCDeclare:
1586 break;
1587 case Decl::OMPThreadPrivate:
1589 break;
1590 case Decl::OMPGroupPrivate:
1592 break;
1593 case Decl::OMPAllocate:
1595 break;
1596 case Decl::OMPCapturedExpr:
1598 break;
1599 case Decl::OMPDeclareReduction:
1601 break;
1602 case Decl::OMPDeclareMapper:
1604 break;
1605 case Decl::OMPRequires:
1607 break;
1608 case Decl::Enum:
1609 case Decl::Using:
1610 case Decl::UsingDirective:
1611 case Decl::UsingEnum:
1612 case Decl::NamespaceAlias:
1613 case Decl::Typedef:
1614 case Decl::TypeAlias:
1615 case Decl::Record:
1617 break;
1618
1619
1620 case Decl::ClassTemplate:
1621 case Decl::Concept:
1622 case Decl::CXXDeductionGuide:
1623 case Decl::Empty:
1624 case Decl::FunctionTemplate:
1625 case Decl::StaticAssert:
1626 case Decl::TypeAliasTemplate:
1627 case Decl::UsingShadow:
1628 case Decl::VarTemplate:
1629 case Decl::VarTemplatePartialSpecialization:
1630 break;
1631
1632 case Decl::CXXConstructor:
1634 break;
1635 case Decl::CXXDestructor:
1637 break;
1638
1639
1640 case Decl::LinkageSpec:
1641 case Decl::Namespace:
1643 break;
1644
1645 case Decl::ClassTemplateSpecialization:
1646 case Decl::CXXRecord: {
1649 for (auto *childDecl : crd->decls())
1652 break;
1653 }
1654
1655 case Decl::FileScopeAsm:
1656
1657 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1658 break;
1659
1660 if (langOpts.OpenMPIsTargetDevice)
1661 break;
1662
1663 if (langOpts.SYCLIsDevice)
1664 break;
1666 std::string line = file_asm->getAsmString();
1667 globalScopeAsm.push_back(builder.getStringAttr(line));
1668 break;
1669 }
1670}
1671
1673
1674 op.setInitialValueAttr(value);
1676}
1677
1682
1684
1685
1688 md->getParent()->getNumVBases() == 0)
1689 errorNYI(md->getSourceRange(),
1690 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1691 }
1692
1693 if (!fnType) {
1694 if (!fnInfo)
1697 }
1698
1700 false, dontDefer,
1701 false, isForDefinition);
1702
1703 return {fnType, fn};
1704}
1705
1707 mlir::Type funcType, bool forVTable,
1708 bool dontDefer,
1711 "consteval function should never be emitted");
1712
1713 if (!funcType) {
1716 }
1717
1718
1719
1720
1721 if (const auto *dd = dyn_cast(gd.getDecl())) {
1724 dd->getParent()->getNumVBases() == 0)
1725 errorNYI(dd->getSourceRange(),
1726 "getAddrOfFunction: MS ABI complete destructor");
1727 }
1728
1730 cir::FuncOp func =
1732 false, isForDefinition);
1733 return func;
1734}
1735
1739
1740 llvm::raw_svector_ostream out(buffer);
1742
1744
1747 } else {
1749 assert(ii && "Attempt to mangle unnamed decl.");
1750
1751 const auto *fd = dyn_cast(nd);
1752 if (fd &&
1755 } else if (fd && fd->hasAttr() &&
1758 }
1760 }
1761
1762
1763
1764
1765
1766
1767
1768
1770
1771 if (const auto *fd = dyn_cast(nd)) {
1772 if (fd->isMultiVersion()) {
1774 "getMangledName: multi-version functions");
1775 }
1776 }
1777 if (cgm.getLangOpts().GPURelocatableDeviceCode) {
1779 "getMangledName: GPU relocatable device code");
1780 }
1781
1782 return std::string(out.str());
1783}
1784
1785static FunctionDecl *
1788
1789
1795
1798
1799
1800 if (auto *methodDecl = dyn_cast(protoFunc);
1801 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
1803 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
1804
1805 funcTy = ctx.getFunctionType(fpt->getReturnType(), paramTypes,
1806 fpt->getExtProtoInfo());
1808 }
1809
1810 auto *tempFunc =
1815
1817 params.reserve(fpt->getNumParams());
1818
1819
1820 for (unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
1824 nullptr, fpt->getParamType(i), nullptr,
1827 params.push_back(parm);
1828 }
1829
1830 tempFunc->setParams(params);
1831
1832 return tempFunc;
1833}
1834
1835std::string
1840
1842
1843
1844
1845
1847 return ret;
1848}
1849
1852
1853
1854
1855 if (const auto *cd = dyn_cast(canonicalGd.getDecl())) {
1857 errorNYI(cd->getSourceRange(),
1858 "getMangledName: C++ constructor without variants");
1860 }
1861 }
1862
1863
1866
1867 auto result = manglings.insert(std::make_pair(mangledName, gd));
1868 return mangledDeclNames[canonicalGd] = result.first->first();
1869}
1870
1872 assert(!d->getInit() && "Cannot emit definite definitions here!");
1873
1876
1877
1878
1879
1880 if (gv && !mlir::castcir::GlobalOp(gv).isDeclaration())
1881 return;
1882
1883
1884
1887 return;
1888 }
1889
1890
1892}
1893
1895
1896 if (langOpts.EmitAllDecls)
1897 return true;
1898
1899 const auto *vd = dyn_cast(global);
1900 if (vd &&
1901 ((codeGenOpts.KeepPersistentStorageVariables &&
1902 (vd->getStorageDuration() == SD_Static ||
1903 vd->getStorageDuration() == SD_Thread)) ||
1904 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() == SD_Static &&
1905 vd->getType().isConstQualified())))
1906 return true;
1907
1909}
1910
1912
1913
1914
1915
1916
1917
1918 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1919 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1920 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1921 if (!activeAttr || (*activeAttr)->getLevel() != (unsigned)-1)
1922 return false;
1923 }
1924
1925 const auto *fd = dyn_cast(global);
1926 if (fd) {
1927
1928
1930 return false;
1931
1932 if (fd->hasAttr() && !fd->isMultiVersion())
1933 return false;
1934 if (langOpts.SYCLIsDevice) {
1935 errorNYI(fd->getSourceRange(), "mayBeEmittedEagerly: SYCL");
1936 return false;
1937 }
1938 }
1939 const auto *vd = dyn_cast(global);
1940 if (vd)
1941 if (astContext.getInlineVariableDefinitionKind(vd) ==
1943
1944
1945 return false;
1946
1947
1948
1949 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1950 astContext.getTargetInfo().isTLSSupported() && isa(global) &&
1952 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1953 return false;
1954
1955 assert((fd || vd) &&
1956 "Only FunctionDecl and VarDecl should hit this path so far.");
1957 return true;
1958}
1959
1961 cir::CIRGlobalValueInterface gv) {
1962 if (gv.hasLocalLinkage())
1963 return true;
1964
1965 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1966 return true;
1967
1968
1969
1970
1972
1973 const llvm::Triple &tt = cgm.getTriple();
1975 if (tt.isOSCygMing()) {
1976
1977
1978
1979
1980
1981
1982
1983
1984 cgm.errorNYI("shouldAssumeDSOLocal: MinGW");
1985 }
1986
1987
1988
1989
1990 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1991 return false;
1992
1993
1994
1995
1996
1997
1998 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1999 return true;
2000
2001
2002 if (!tt.isOSBinFormatELF())
2003 return false;
2004
2007 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2008
2009
2010
2011
2012
2013 if (!(isacir::FuncOp(gv) && gv.canBenefitFromLocalAlias()))
2014 return false;
2015 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2016 }
2017
2018
2019 if (!gv.isDeclarationForLinker())
2020 return true;
2021
2022
2023
2024
2025 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2026 return false;
2027
2028
2029 if (tt.isPPC64())
2030 return false;
2031
2032 if (cgOpts.DirectAccessExternalData) {
2033
2034
2035
2036
2037
2038 if (auto globalOp = dyn_castcir::GlobalOp(gv.getOperation())) {
2039
2041 return true;
2042 }
2043
2044
2045
2046
2047
2048
2049
2050 if (isacir::FuncOp(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
2051 return true;
2052 }
2053
2054
2055
2056
2057
2058 return false;
2059}
2060
2065
2069
2071 if (auto globalValue = dyn_castcir::CIRGlobalValueInterface(op))
2073}
2074
2080
2087
2091 return cir::TLS_Model::GeneralDynamic;
2093 return cir::TLS_Model::LocalDynamic;
2095 return cir::TLS_Model::InitialExec;
2097 return cir::TLS_Model::LocalExec;
2098 }
2099 llvm_unreachable("Invalid TLS model!");
2100}
2101
2103 assert(d.getTLSKind() && "setting TLS mode on non-TLS var!");
2104
2106
2107
2108 if (d.getAttr())
2110
2112 global.setTlsModel(tlm);
2113}
2114
2116 cir::FuncOp func,
2117 bool isIncompleteFunction,
2118 bool isThunk) {
2119
2120
2121
2122
2125
2126
2127
2128
2129
2133 }
2134
2135
2137 if (fd->isInlineBuiltinDeclaration()) {
2139 bool hasBody = fd->hasBody(fdBody);
2140 (void)hasBody;
2141 assert(hasBody && "Inline builtin declarations should always have an "
2142 "available body!");
2144 }
2145}
2146
2151
2152 std::optionalcir::InlineKind existingInlineKind = f.getInlineKind();
2153 bool isNoInline =
2154 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2155 bool isAlwaysInline = existingInlineKind &&
2156 *existingInlineKind == cir::InlineKind::AlwaysInline;
2157 if () {
2159
2160 if (!isAlwaysInline &&
2162
2163
2164
2165 f.setInlineKind(cir::InlineKind::NoInline);
2166 }
2167
2168 return;
2169 }
2170
2178
2179
2180 if (decl->hasAttr() && !isAlwaysInline) {
2181
2182 f.setInlineKind(cir::InlineKind::NoInline);
2183 } else if (decl->hasAttr() && !isNoInline) {
2184
2185
2186 f.setInlineKind(cir::InlineKind::AlwaysInline);
2188
2189
2190 if (!isAlwaysInline) {
2191 f.setInlineKind(cir::InlineKind::NoInline);
2192 }
2193 } else {
2194
2195
2196
2197 if (auto *fd = dyn_cast(decl)) {
2198
2199
2200
2202 auto checkRedeclForInline = [](const FunctionDecl *redecl) {
2203 return redecl->isInlineSpecified();
2204 };
2205 if (any_of(decl->redecls(), checkRedeclForInline))
2206 return true;
2207 const FunctionDecl *pattern = decl->getTemplateInstantiationPattern();
2208 if (!pattern)
2209 return false;
2210 return any_of(pattern->redecls(), checkRedeclForInline);
2211 };
2212 if (checkForInline(fd)) {
2213 f.setInlineKind(cir::InlineKind::InlineHint);
2214 } else if (codeGenOpts.getInlining() ==
2216 !fd->isInlined() && !isAlwaysInline) {
2217 f.setInlineKind(cir::InlineKind::NoInline);
2218 }
2219 }
2220 }
2221
2223}
2224
2226 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
2227 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
2228 mlir::ArrayAttr extraAttrs) {
2230
2231 if (isThunk)
2233
2234
2235
2236
2237 if (const auto *fd = cast_or_null(d)) {
2238
2239 if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2240 !isForDefinition)
2241 errorNYI(fd->getSourceRange(),
2242 "getOrCreateCIRFunction: OpenMP target function");
2243
2244
2245
2246 if (fd->isMultiVersion())
2247 errorNYI(fd->getSourceRange(), "getOrCreateCIRFunction: multi-version");
2248 }
2249
2250
2251 mlir::Operation *entry = getGlobalValue(mangledName);
2252 if (entry) {
2253 assert(mlir::isacir::FuncOp(entry));
2254
2256
2257
2258 if (d && !d->hasAttr() && !d->hasAttr()) {
2261 }
2262
2263
2264
2266 if (isForDefinition && fn && !fn.isDeclaration()) {
2268 }
2269 if (fn && fn.getFunctionType() == funcType) {
2270 return fn;
2271 }
2272
2273 if (!isForDefinition) {
2274 return fn;
2275 }
2276
2277
2278
2279 }
2280
2281 auto *funcDecl = llvm::cast_or_null(gd.getDecl());
2282 bool invalidLoc = !funcDecl ||
2283 funcDecl->getSourceRange().getBegin().isInvalid() ||
2284 funcDecl->getSourceRange().getEnd().isInvalid();
2286 invalidLoc ? theModule->getLoc() : getLoc(funcDecl->getSourceRange()),
2287 mangledName, mlir::castcir::FuncType(funcType), funcDecl);
2288
2289
2290
2291
2292
2293
2294
2295 if (entry) {
2296
2297
2298 auto symbolOp = mlir::castmlir::SymbolOpInterface(entry);
2299
2300
2301
2302
2303
2304
2305
2306 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2308
2309
2310 entry->erase();
2311 }
2312
2313 if (d)
2315
2316
2317 if (dontDefer) {
2318
2319
2320 assert(funcOp.getFunctionType() == funcType);
2321 return funcOp;
2322 }
2323
2324
2325
2326
2327 if (isa_and_nonnull(d) &&
2331
2332
2333
2334
2337
2338
2339
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2355
2356 for (const auto *fd = cast(d)->getMostRecentDecl(); fd;
2357 fd = fd->getPreviousDecl()) {
2359 if (fd->doesThisDeclarationHaveABody()) {
2361 break;
2362 }
2363 }
2364 }
2365 }
2366
2367 return funcOp;
2368}
2369
2370cir::FuncOp
2372 cir::FuncType funcType,
2374 cir::FuncOp func;
2375 {
2376 mlir::OpBuilder::InsertionGuard guard(builder);
2377
2378
2379
2380
2381
2383 if (cgf)
2384 builder.setInsertionPoint(cgf->curFn);
2385
2386 func = cir::FuncOp::create(builder, loc, name, funcType);
2387
2389
2391 func.setNoProto(true);
2392
2393 assert(func.isDeclaration() && "expected empty body");
2394
2395
2396
2397 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2398 &getMLIRContext(), cir::GlobalLinkageKind::ExternalLinkage));
2399 mlir::SymbolTable::setSymbolVisibility(
2400 func, mlir::SymbolTable::Visibility::Private);
2401
2403
2404
2406
2407 if (!cgf)
2408 theModule.push_back(func);
2409
2411
2412
2413 for (const auto *attr :
2416 attr->Clauses);
2417 }
2418 }
2419 return func;
2420}
2421
2422cir::FuncOp
2424 cir::FuncType ty,
2427 fnOp.setBuiltin(true);
2428 return fnOp;
2429}
2430
2433 return cir::CtorKind::Default;
2435 return cir::CtorKind::Copy;
2437 return cir::CtorKind::Move;
2438 return cir::CtorKind::Custom;
2439}
2440
2443 return cir::AssignKind::Copy;
2445 return cir::AssignKind::Move;
2446 llvm_unreachable("not a copy or move assignment operator");
2447}
2448
2451 if (!funcDecl)
2452 return;
2453
2454 if (const auto *dtor = dyn_cast(funcDecl)) {
2455 auto cxxDtor = cir::CXXDtorAttr::get(
2457 dtor->isTrivial());
2458 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2459 return;
2460 }
2461
2462 if (const auto *ctor = dyn_cast(funcDecl)) {
2464 auto cxxCtor = cir::CXXCtorAttr::get(
2466 kind, ctor->isTrivial());
2467 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2468 return;
2469 }
2470
2471 const auto *method = dyn_cast(funcDecl);
2472 if (method && (method->isCopyAssignmentOperator() ||
2473 method->isMoveAssignmentOperator())) {
2475 auto cxxAssign = cir::CXXAssignAttr::get(
2477 assignKind, method->isTrivial());
2478 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2479 return;
2480 }
2481}
2482
2484 cir::FuncOp funcOp, StringRef name) {
2485
2486
2487
2488
2489
2490 if (!isLocal && cgm.getTarget().getTriple().isWindowsItaniumEnvironment() &&
2495 }
2496}
2497
2499 StringRef name, mlir::ArrayAttr,
2500 bool isLocal,
2501 bool assumeConvergent) {
2502 if (assumeConvergent)
2503 errorNYI("createRuntimeFunction: assumeConvergent");
2504
2506 false);
2507
2508 if (entry) {
2509
2513 entry.setDSOLocal(true);
2514 }
2515
2516 return entry;
2517}
2518
2519mlir::SymbolTable::Visibility
2521
2522
2523 if (op.isDeclaration())
2524 return mlir::SymbolTable::Visibility::Private;
2526}
2527
2528mlir::SymbolTable::Visibility
2530 switch (glk) {
2531 case cir::GlobalLinkageKind::InternalLinkage:
2532 case cir::GlobalLinkageKind::PrivateLinkage:
2533 return mlir::SymbolTable::Visibility::Private;
2534 case cir::GlobalLinkageKind::ExternalLinkage:
2535 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2536 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2537 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2538 case cir::GlobalLinkageKind::CommonLinkage:
2539 case cir::GlobalLinkageKind::WeakAnyLinkage:
2540 case cir::GlobalLinkageKind::WeakODRLinkage:
2541 return mlir::SymbolTable::Visibility::Public;
2542 default: {
2543 llvm::errs() << "visibility not implemented for '"
2544 << stringifyGlobalLinkageKind(glk) << "'\n";
2545 assert(0 && "not implemented");
2546 }
2547 }
2548 llvm_unreachable("linkage should be handled above!");
2549}
2550
2552 clang::VisibilityAttr::VisibilityType visibility) {
2553 switch (visibility) {
2554 case clang::VisibilityAttr::VisibilityType::Default:
2555 return cir::VisibilityKind::Default;
2556 case clang::VisibilityAttr::VisibilityType::Hidden:
2557 return cir::VisibilityKind::Hidden;
2558 case clang::VisibilityAttr::VisibilityType::Protected:
2559 return cir::VisibilityKind::Protected;
2560 }
2561 llvm_unreachable("unexpected visibility value");
2562}
2563
2564cir::VisibilityAttr
2566 const clang::VisibilityAttr *va = decl->getAttrclang::VisibilityAttr();
2567 cir::VisibilityAttr cirVisibility =
2569 if (va) {
2570 cirVisibility = cir::VisibilityAttr::get(
2573 }
2574 return cirVisibility;
2575}
2576
2579 applyReplacements();
2580
2581 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2582 builder.getArrayAttr(globalScopeAsm));
2583
2584
2586}
2587
2589 mlir::Operation *op, GlobalDecl aliasGD,
2590 cir::FuncOp aliasee,
2591 cir::GlobalLinkageKind linkage) {
2592
2593 auto *aliasFD = dyn_cast(aliasGD.getDecl());
2594 assert(aliasFD && "expected FunctionDecl");
2595
2596
2597
2598
2602
2603 cir::FuncOp alias =
2605 mangledName, fnType, aliasFD);
2606 alias.setAliasee(aliasee.getName());
2607 alias.setLinkage(linkage);
2608
2609
2610
2611 mlir::SymbolTable::setSymbolVisibility(
2612 alias, mlir::SymbolTable::Visibility::Private);
2613
2614
2616
2617
2618 if (op) {
2619 errorNYI(aliasFD->getSourceRange(), "emitAliasForGlobal: previous uses");
2620 } else {
2621
2622 }
2623
2624
2626}
2627
2629 return genTypes.convertType(type);
2630}
2631
2633
2634
2635
2636 return mlir::verify(theModule).succeeded();
2637}
2638
2641
2642
2643
2645 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2646
2648 langOpts.ObjCRuntime.isGNUFamily()) {
2649 errorNYI(loc, "getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
2650 return {};
2651 }
2652
2654}
2655
2656
2659 llvm::iterator_rangeCastExpr::path\_const\_iterator path) {
2661
2664
2666 assert(!base->isVirtual() && "Should not see virtual bases here!");
2667
2668
2669 const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd);
2670
2671 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2672
2673
2675
2676 rd = baseDecl;
2677 }
2678
2679 return offset;
2680}
2681
2683 llvm::StringRef feature) {
2684 unsigned diagID = diags.getCustomDiagID(
2686 return diags.Report(loc, diagID) << feature;
2687}
2688
2690 llvm::StringRef feature) {
2692}
2693
2695 cir::LabelOp label) {
2696 [[maybe_unused]] auto result =
2698 assert(result.second &&
2699 "attempting to map a blockaddress info that is already mapped");
2700}
2701
2704 assert(result.second &&
2705 "attempting to map a blockaddress operation that is already mapped");
2706}
2707
2709 cir::LabelOp label) {
2710 [[maybe_unused]] auto result = blockAddressToLabel.try_emplace(op, label);
2711 assert(result.second &&
2712 "attempting to map a blockaddress operation that is already mapped");
2713}
2714
2716 cir::LabelOp newLabel) {
2719 "trying to update a blockaddress not previously mapped");
2720 assert(!it->second && "blockaddress already has a resolved label");
2721
2722 it->second = newLabel;
2723}
2724
2725cir::LabelOp
Defines the clang::ASTContext interface.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
Definition CIRGenModule.cpp:1960
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
Definition CIRGenModule.cpp:2441
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
Definition CIRGenModule.cpp:1786
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
Definition CIRGenModule.cpp:1014
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
Definition CIRGenModule.cpp:2483
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
Definition CIRGenModule.cpp:1736
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
Definition CIRGenModule.cpp:1380
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
Definition CIRGenModule.cpp:41
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
Definition CIRGenModule.cpp:1156
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
Definition CIRGenModule.cpp:597
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
Definition CIRGenModule.cpp:2431
This file defines OpenACC nodes for declarative directives.
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::PointerType getPointerTo(mlir::Type ty)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
Definition CIRGenModule.cpp:2715
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
Definition CIRGenModule.cpp:1315
llvm::StringRef getMangledName(clang::GlobalDecl gd)
Definition CIRGenModule.cpp:1850
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
Definition CIRGenModule.cpp:2657
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
Definition CIRGenModule.cpp:2061
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
Definition CIRGenModule.cpp:2682
void emitDeferred()
Emit any needed decls for which code generation was deferred.
Definition CIRGenModule.cpp:330
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
Definition CIRGenModule.cpp:2498
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
Definition CIRGenModule.cpp:1548
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
Definition CIRGenModule.cpp:1056
mlir::Type convertType(clang::QualType type)
Definition CIRGenModule.cpp:2628
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
Definition CIRGenModule.cpp:1430
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
Definition CIRGenModule.cpp:2702
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
Definition CIRGenModule.cpp:1894
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
Definition CIRGenModule.cpp:2070
std::string getUniqueGlobalName(const std::string &baseName)
Definition CIRGenModule.cpp:1413
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Definition CIRGenModule.cpp:1678
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
Definition CIRGenModule.cpp:2075
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType ty, const clang::FunctionDecl *fd)
Create a CIR function with builtin attribute set.
Definition CIRGenModule.cpp:2423
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
Definition CIRGenModule.cpp:150
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
Definition CIRGenModule.cpp:507
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
Definition CIRGenModule.cpp:921
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
Definition CIRGenModule.cpp:2708
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
Definition CIRGenModule.cpp:2639
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
Definition CIRGenModule.cpp:165
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
Definition CIRGenModule.cpp:2115
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
Definition CIRGenModule.cpp:2529
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
Definition CIRGenModule.cpp:1871
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
Definition CIRGenModule.cpp:1115
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
Definition CIRGenModule.cpp:292
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::ArrayAttr extraAttrs={})
Definition CIRGenModule.cpp:2225
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
Definition CIRGenModule.cpp:771
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
Definition CIRGenModule.cpp:2102
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
Definition CIRGenModule.cpp:1706
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
Definition CIRGenModule.cpp:2588
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
Definition CIRGenModule.cpp:1513
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
Definition CIRGenModule.cpp:2632
void release()
Definition CIRGenModule.cpp:2577
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
Definition CIRGenModule.cpp:1504
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
Definition CIRGenModule.cpp:747
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
Definition CIRGenModule.cpp:1672
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
Definition CIRGenModule.cpp:761
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
Definition CIRGenModule.cpp:483
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
Definition CIRGenModule.cpp:1368
void updateCompletedType(const clang::TagDecl *td)
Definition CIRGenModule.cpp:1051
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
cir::TLS_Model getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
Definition CIRGenModule.cpp:2088
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
Definition CIRGenModule.cpp:497
void addDeferredDeclToEmit(clang::GlobalDecl GD)
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
Definition CIRGenModule.cpp:2371
const TargetCIRGenInfo & getTargetCIRGenInfo()
Definition CIRGenModule.cpp:220
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
Definition CIRGenModule.cpp:2081
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
Definition CIRGenModule.cpp:1488
llvm::DenseSet< cir::BlockAddressOp > unresolvedBlockAddressToLabel
Track CIR BlockAddressOps that cannot be resolved immediately because their LabelOp has not yet been ...
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
Definition CIRGenModule.cpp:248
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
Definition CIRGenModule.cpp:2551
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
Definition CIRGenModule.cpp:2449
mlir::Operation * getGlobalValue(llvm::StringRef ref)
Definition CIRGenModule.cpp:521
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
Definition CIRGenModule.cpp:1010
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
Definition CIRGenModule.cpp:1231
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
Definition CIRGenModule.cpp:266
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
Definition CIRGenModule.cpp:525
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
Definition CIRGenModule.cpp:1040
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
Definition CIRGenModule.cpp:1476
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
void emitDeclContext(const DeclContext *dc)
Definition CIRGenModule.cpp:1533
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
Definition CIRGenModule.cpp:361
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
Definition CIRGenModule.cpp:2726
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
Definition CIRGenModule.cpp:1911
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
Definition CIRGenModule.cpp:1362
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
Definition CIRGenModule.cpp:2694
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
Definition CIRGenModule.cpp:2147
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
Definition CIRGenModule.cpp:1836
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
Definition CIRGenModule.cpp:434
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
Definition CIRGenModule.cpp:957
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
Definition CIRGenModule.cpp:2565
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
Definition CIRGenModule.cpp:560
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const
Get the address space for alloca.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Represents a member of a struct/union/class.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void setLinkage(Linkage L)
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
static bool globalCtorLexOrder()
static bool alignCXXRecordDecl()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool opGlobalSection()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
static bool opGlobalUsedOrCompilerUsed()
static bool stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setFunctionAttributes()
static bool setDLLStorageClass()
static bool opFuncUnwindTablesAttr()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncNakedAttr()
static bool opFuncSection()
static bool attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalWeakRef()
static bool setTargetAttributes()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool opFuncCallingConv()
static bool globalCtorAssociatedData()
static bool defaultVisibility()
static bool opFuncColdHotAttr()
static bool opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool deferredVtables()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
cir::TargetAddressSpaceAttr cirAllocaAddressSpace
mlir::Type uCharTy
ClangIR char.
unsigned char SizeSizeInBytes
unsigned char PointerAlignInBytes
cir::PointerType allocaInt8PtrTy
void* in alloca address space
cir::PointerType uInt8PtrTy
cir::PointerType voidPtrTy
void* in address space 0
LangStandard - Information about the properties of a particular language standard.