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
368
369 if (const auto *fd = dyn_cast(global)) {
370
371
372 if (fd->hasAttr())
373 errorNYI(fd->getSourceRange(), "deferredAnnotations");
374 if (!fd->doesThisDeclarationHaveABody()) {
375 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
376 return;
377
378 errorNYI(fd->getSourceRange(),
379 "function declaration that forces code gen");
380 return;
381 }
382 } else {
384 assert(vd->isFileVarDecl() && "Cannot emit local var decl as global.");
386 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
388
389
390 if (astContext.getInlineVariableDefinitionKind(vd) ==
393
394
395 return;
396 }
397 }
398
399
400
401
402
404
406 return;
407 }
408
409
410
412
415
418
421 } else {
422
423
425 }
426}
427
429 mlir::Operation *op) {
433 cir::FuncOp funcOp = dyn_cast_if_presentcir::FuncOp(op);
434 if (!funcOp || funcOp.getFunctionType() != funcType) {
437 }
438
439
440 if (!funcOp.isDeclaration())
441 return;
442
448
450 curCGF = &cgf;
451 {
452 mlir::OpBuilder::InsertionGuard guard(builder);
454 }
455 curCGF = nullptr;
456
457 setNonAliasAttributes(gd, funcOp);
459
460 auto getPriority = [this](const auto *attr) -> int {
461 Expr *e = attr->getPriority();
462 if (e)
464 return attr->DefaultPriority;
465 };
466
467 if (const ConstructorAttr *ca = funcDecl->getAttr())
469 if (const DestructorAttr *da = funcDecl->getAttr())
471
472 if (funcDecl->getAttr())
473 errorNYI(funcDecl->getSourceRange(), "deferredAnnotations");
474}
475
476
478 std::optional priority) {
481
482
483
484
485
486
487 ctor.setGlobalCtorPriority(priority);
488}
489
490
492 std::optional priority) {
493 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
495 errorNYI(dtor.getLoc(), "registerGlobalDtorsWithAtExit");
496
497
498 dtor.setGlobalDtorPriority(priority);
499}
500
504 return;
505
507
508
511
513}
514
516 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
517}
518
520 mlir::Location loc, StringRef name,
521 mlir::Type t, bool isConstant,
522 mlir::Operation *insertPoint) {
523 cir::GlobalOp g;
525
526 {
527 mlir::OpBuilder::InsertionGuard guard(builder);
528
529
530
531
532 if (insertPoint) {
533 builder.setInsertionPoint(insertPoint);
534 } else {
535
537 builder.setInsertionPointAfter(cgm.lastGlobalOp);
538 else
539 builder.setInsertionPointToStart(cgm.getModule().getBody());
540 }
541
542 g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
543 if (!insertPoint)
545
546
547
548 mlir::SymbolTable::setSymbolVisibility(
549 g, mlir::SymbolTable::Visibility::Private);
550 }
551 return g;
552}
553
556 if (isa_and_nonnull(d))
560}
561
562void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
564
569
571}
572
573std::optionalcir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
575 using CIRLang = cir::SourceLanguage;
577
578 if (opts.CPlusPlus)
579 return CIRLang::CXX;
580 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
581 opts.LangStd == ClangStd::lang_c89 ||
582 opts.LangStd == ClangStd::lang_gnu89)
583 return CIRLang::C;
584
585
587 errorNYI("CIR does not yet support the given source language");
588 return std::nullopt;
589}
590
592
594
595
596
599 gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
600}
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616cir::GlobalOp
618 LangAS langAS, const VarDecl *d,
620
621 cir::GlobalOp entry;
622 if (mlir::Operation *v = getGlobalValue(mangledName)) {
626 }
627
628 if (entry) {
631
634
635 if (entry.getSymType() == ty)
636 return entry;
637
638
639
640
641
642
643
644 if (isForDefinition && !entry.isDeclaration()) {
646 }
647
648
649
650
651
652
653 if (!isForDefinition)
654 return entry;
655 }
656
658
659
660
661 cir::GlobalOp gv =
663 entry.getOperation());
664
665
666
667
670
671
674 }
675
676
677 if (d) {
678 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
680
681 gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
682
683
685 astContext, false, false));
686
688
693 }
694
696
697
698
699 if (astContext.isMSStaticDataMemberInlineDefinition(d))
701
704
705
706 if (getTriple().getArch() == llvm::Triple::xcore)
708
709
710
711
716 "external const declaration with initializer");
717 }
718
719 return gv;
720}
721
722cir::GlobalOp
727 if (!ty)
729
732 isForDefinition);
733}
734
735
736
737
738
739
740
745 if (!ty)
747
750 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
752 g.getSymNameAttr(), tlsAccess);
753}
754
758
761 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
762 return builder.getGlobalViewAttr(ptrTy, globalOp);
763}
764
766 bool isTentative) {
769 return;
770 }
771
772
773
774
775 bool isDefinitionAvailableExternally =
777
778
779
780 if (isDefinitionAvailableExternally &&
782
783
786 return;
787
788 mlir::Attribute init;
789 bool needsGlobalCtor = false;
790 bool needsGlobalDtor =
791 !isDefinitionAvailableExternally &&
795
796 std::optional emitter;
797
799
800 if (vd->hasAttr()) {
802 return;
803 } else if (!initExpr) {
804
805
806
807
808
809
810
811
812
815 } else {
816 emitter.emplace(*this);
817 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
818 if (!initializer) {
822
826 init = builder.getZeroInitAttr(convertType(qt));
827 if (!isDefinitionAvailableExternally)
828 needsGlobalCtor = true;
829 } else {
831 }
832 } else {
833 init = initializer;
834
835
836
838 }
839 }
840
841 mlir::Type initType;
842 if (mlir::isamlir::SymbolRefAttr(init)) {
844 return;
845 } else {
846 assert(mlir::isamlir::TypedAttr(init) && "This should have a type");
847 auto typedInitAttr = mlir::castmlir::TypedAttr(init);
848 initType = typedInitAttr.getType();
849 }
850 assert(!mlir::isamlir::NoneType(initType) && "Should have a type by now");
851
852 cir::GlobalOp gv =
854
855
856 if (!gv || gv.getSymType() != initType) {
858 return;
859 }
860
862
863 if (vd->hasAttr()) {
865 }
866
867 if (langOpts.CUDA) {
869 }
870
871
873 if (emitter)
874 emitter->finalize(gv);
875
876
877 gv.setConstant((vd->hasAttr() && langOpts.CUDAIsDevice) ||
878 (!needsGlobalCtor && !needsGlobalDtor &&
880 astContext, true, true)));
882
883
884 cir::GlobalLinkageKind linkage =
886
887
888 gv.setLinkage(linkage);
889
892 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
893
894 gv.setConstant(false);
895
896
897
898
899 std::optionalmlir::Attribute initializer = gv.getInitialValue();
900 if (initializer && ().isNullValue(*initializer))
901 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
902 }
903
904 setNonAliasAttributes(vd, gv);
905
907
909
910
911 if (needsGlobalCtor || needsGlobalDtor)
913}
914
916 mlir::Operation *op) {
918 if (const auto *fd = dyn_cast(decl)) {
919
920
921
922 if (const auto *method = dyn_cast(decl)) {
923
924
926 abi->emitCXXStructor(gd);
927 else if (fd->isMultiVersion())
928 errorNYI(method->getSourceRange(), "multiversion functions");
929 else
931
932 if (method->isVirtual())
934
935 return;
936 }
937
938 if (fd->isMultiVersion())
939 errorNYI(fd->getSourceRange(), "multiversion functions");
941 return;
942 }
943
944 if (const auto *vd = dyn_cast(decl))
946
947 llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
948}
949
950mlir::Attribute
953
954
955
958
959
961 astContext.getAsConstantArrayType(e->getType());
962 uint64_t finalSize = cat->getZExtSize();
963 str.resize(finalSize);
964
965 mlir::Type eltTy = convertType(cat->getElementType());
966 return builder.getString(str, eltTy, finalSize);
967 }
968
969 auto arrayTy = mlir::castcir::ArrayType(convertType(e->getType()));
970
971 auto arrayEltTy = mlir::castcir::IntType(arrayTy.getElementType());
972
973 uint64_t arraySize = arrayTy.getSize();
974 unsigned literalSize = e->getLength();
975 assert(arraySize == literalSize + 1 &&
976 "wide string literal array size must be literal length plus null "
977 "terminator");
978
979
980
981 bool isAllZero = true;
982 for (unsigned i = 0; i < literalSize; ++i) {
984 isAllZero = false;
985 break;
986 }
987 }
988
989 if (isAllZero)
990 return cir::ZeroAttr::get(arrayTy);
991
992
994 elements.reserve(arraySize);
995 for (unsigned i = 0; i < literalSize; ++i)
996 elements.push_back(cir::IntAttr::get(arrayEltTy, e->getCodeUnit(i)));
997
998 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
999
1000 auto elementsAttr = mlir::ArrayAttr::get(&getMLIRContext(), elements);
1001 return builder.getConstArray(elementsAttr, arrayTy);
1002}
1003
1005 return getTriple().supportsCOMDAT();
1006}
1007
1010 return false;
1011
1012 if (d.hasAttr())
1013 return true;
1014
1016 if (auto *vd = dyn_cast(&d))
1018 else
1019 linkage =
1021
1022 switch (linkage) {
1026 return false;
1029 return true;
1030 }
1031 llvm_unreachable("No such linkage");
1032}
1033
1036 return;
1037 if (auto globalOp = dyn_cast_or_nullcir::GlobalOp(op)) {
1038 globalOp.setComdat(true);
1039 } else {
1041 funcOp.setComdat(true);
1042 }
1043}
1044
1046
1047 genTypes.updateCompletedType(td);
1048}
1049
1051 replacements[name] = op;
1052}
1053
1054void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
1055 std::optionalmlir::SymbolTable::UseRange optionalUseRange =
1056 oldF.getSymbolUses(theModule);
1057 if (!optionalUseRange)
1058 return;
1059
1060 for (const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1061
1062 auto call = mlir::dyn_castcir::CallOp(u.getUser());
1063 if (!call)
1064 continue;
1065
1066 for (const auto [argOp, fnArgType] :
1067 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1068 if (argOp.getType() == fnArgType)
1069 continue;
1070
1071
1072
1073
1074 errorNYI(call.getLoc(), "replace call with mismatched types");
1075 }
1076 }
1077}
1078
1079void CIRGenModule::applyReplacements() {
1080 for (auto &i : replacements) {
1081 StringRef mangledName = i.first();
1082 mlir::Operation *replacement = i.second;
1083 mlir::Operation *entry = getGlobalValue(mangledName);
1084 if (!entry)
1085 continue;
1088 auto newF = dyn_castcir::FuncOp(replacement);
1089 if (!newF) {
1090
1091 errorNYI(replacement->getLoc(), "replacement is not a function");
1092 continue;
1093 }
1094
1095
1096
1097 replacePointerTypeArgs(oldF, newF);
1098
1099
1100 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1101 llvm_unreachable("internal error, cannot RAUW symbol");
1102 if (newF) {
1103 newF->moveBefore(oldF);
1104 oldF->erase();
1105 }
1106 }
1107}
1108
1110 mlir::Location loc, StringRef name, mlir::Type ty,
1111 cir::GlobalLinkageKind linkage, clang::CharUnits alignment) {
1112 auto gv = mlir::dyn_cast_or_nullcir::GlobalOp(
1113 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1114
1115 if (gv) {
1116
1117 if (gv.getSymType() == ty)
1118 return gv;
1119
1120
1121
1122
1123 assert(gv.isDeclaration() && "Declaration has wrong type!");
1124
1125 errorNYI(loc, "createOrReplaceCXXRuntimeVariable: declaration exists with "
1126 "wrong type");
1127 return gv;
1128 }
1129
1130
1132
1133
1134 gv.setLinkageAttr(
1135 cir::GlobalLinkageKindAttr::get(&getMLIRContext(), linkage));
1136 mlir::SymbolTable::setSymbolVisibility(gv,
1138
1140 !gv.hasAvailableExternallyLinkage()) {
1141 gv.setComdat(true);
1142 }
1143
1144 gv.setAlignmentAttr(getSize(alignment));
1145 setDSOLocal(static_cast<mlir::Operation *>(gv));
1146 return gv;
1147}
1148
1149
1152 bool noCommon) {
1153
1154
1155 if ((noCommon || vd->hasAttr()) && !vd->hasAttr())
1156 return true;
1157
1158
1159
1160
1161
1163 return true;
1164
1165
1166 if (vd->hasAttr())
1167 return true;
1168
1169
1170
1171
1172 if (vd->hasAttr() ||
1173 vd->hasAttr() ||
1174 vd->hasAttr() ||
1175 vd->hasAttr())
1176 return true;
1177
1178
1180 return true;
1181
1182
1183 if (vd->hasAttr())
1184 return true;
1185
1186
1188 return true;
1189
1190
1191
1193 if (vd->hasAttr())
1194 return true;
1197 return true;
1198
1200 for (const FieldDecl *fd : rd->fields()) {
1201 if (fd->isBitField())
1202 continue;
1203 if (fd->hasAttr())
1204 return true;
1206 return true;
1207 }
1208 }
1209 }
1210
1211
1212
1213
1214
1215
1216
1220 return true;
1221
1222 return false;
1223}
1224
1228 return cir::GlobalLinkageKind::InternalLinkage;
1229
1230 if (dd->hasAttr()) {
1231 if (isConstantVariable)
1232 return cir::GlobalLinkageKind::WeakODRLinkage;
1233 return cir::GlobalLinkageKind::WeakAnyLinkage;
1234 }
1235
1238 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1239
1240
1241
1243 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1257 return !astContext.getLangOpts().AppleKext
1258 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1259 : cir::GlobalLinkageKind::InternalLinkage;
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1273 return cir::GlobalLinkageKind::ExternalLinkage;
1275 ().GPURelocatableDeviceCode)
1276 return dd->hasAttr()
1277 ? cir::GlobalLinkageKind::ExternalLinkage
1278 : cir::GlobalLinkageKind::InternalLinkage;
1279 return cir::GlobalLinkageKind::WeakODRLinkage;
1280 }
1281
1282
1283
1287 return cir::GlobalLinkageKind::CommonLinkage;
1288
1289
1290
1291
1292
1293 if (dd->hasAttr())
1294 return cir::GlobalLinkageKind::WeakODRLinkage;
1295
1296
1298 return cir::GlobalLinkageKind::ExternalLinkage;
1299}
1300
1301
1302
1303
1304
1305
1306
1307
1308
1310 mlir::Operation *old, cir::FuncOp newFn) {
1311
1312 auto oldFn = mlir::dyn_castcir::FuncOp(old);
1313 if (!oldFn)
1314 return;
1315
1316
1320 if (oldFn->getAttrs().size() <= 1)
1322 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1323
1324
1325 newFn.setNoProto(oldFn.getNoProto());
1326
1327
1328 std::optionalmlir::SymbolTable::UseRange symUses =
1329 oldFn.getSymbolUses(oldFn->getParentOp());
1330 for (const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1331 mlir::OpBuilder::InsertionGuard guard(builder);
1332
1333 if (auto noProtoCallOp = mlir::dyn_castcir::CallOp(use.getUser())) {
1334 builder.setInsertionPoint(noProtoCallOp);
1335
1336
1337 cir::CallOp realCallOp = builder.createCallOp(
1338 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1339
1340
1341 noProtoCallOp.replaceAllUsesWith(realCallOp);
1342 noProtoCallOp.erase();
1343 } else if (auto getGlobalOp =
1344 mlir::dyn_castcir::GetGlobalOp(use.getUser())) {
1345
1346 getGlobalOp.getAddr().setType(
1347 cir::PointerType::get(newFn.getFunctionType()));
1348 } else {
1349 errorNYI(use.getUser()->getLoc(),
1350 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1351 }
1352 }
1353}
1354
1355cir::GlobalLinkageKind
1357 assert(!isConstant && "constant variables NYI");
1358 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1360}
1361
1364
1365 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1366
1367 if (const auto *dtor = dyn_cast(d))
1369
1371}
1372
1373static cir::GlobalOp
1375 cir::GlobalLinkageKind lt, CIRGenModule &cgm,
1376 StringRef globalName, CharUnits alignment) {
1378
1379
1380
1382 cgm, loc, globalName, c.getType(), !cgm.getLangOpts().WritableStrings);
1383
1384
1385 gv.setAlignmentAttr(cgm.getSize(alignment));
1386 gv.setLinkageAttr(
1387 cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
1391 if (gv.isWeakForLinker()) {
1392 assert(cgm.supportsCOMDAT() && "Only COFF uses weak string literals");
1393 gv.setComdat(true);
1394 }
1395 cgm.setDSOLocal(static_cast<mlir::Operation *>(gv));
1396 return gv;
1397}
1398
1399
1400
1401
1402
1403
1404
1405
1406
1408
1409
1413 return baseName;
1414 }
1415
1416 std::string result =
1417 baseName + "." + std::to_string(cgGlobalNames[baseName]++);
1418
1419 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1420 return result;
1421}
1422
1423
1425 StringRef name) {
1427 astContext.getAlignOfGlobalVarInChars(s->getType(), nullptr);
1428
1430
1431 cir::GlobalOp gv;
1434
1435 if (!gv.getAlignment() ||
1436 uint64_t(alignment.getQuantity()) > *gv.getAlignment())
1437 gv.setAlignmentAttr(getSize(alignment));
1438 } else {
1439
1440
1441
1442 if (getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
1445 "getGlobalForStringLiteral: mangle string literals");
1446 }
1447
1448
1449
1451
1452
1453 mlir::Location loc = s->getBeginLoc().isValid()
1454 ? getLoc(s->getSourceRange())
1455 : builder.getUnknownLoc();
1456 auto typedC = llvm::castmlir::TypedAttr(c);
1458 cir::GlobalLinkageKind::PrivateLinkage, *this,
1459 uniqueName, alignment);
1460 setDSOLocal(static_cast<mlir::Operation *>(gv));
1462
1464 }
1465 return gv;
1466}
1467
1468
1469cir::GlobalViewAttr
1471 StringRef name) {
1473 auto arrayTy = mlir::dyn_castcir::ArrayType(gv.getSymType());
1474 assert(arrayTy && "String literal must be array");
1477
1478 return builder.getGlobalViewAttr(ptrTy, gv);
1479}
1480
1481
1485
1486
1487
1488
1491
1494 errorNYI("SYCL or OpenMP temp address space");
1496}
1497
1502
1504 "emitExplicitCastExprType");
1505}
1506
1509
1511
1513
1514
1517 return {};
1518 }
1519
1520
1521 auto ty = mlir::castcir::DataMemberType(convertType(e->getType()));
1523 return cir::ConstantOp::create(
1524 builder, loc, builder.getDataMemberAttr(ty, fieldDecl->getFieldIndex()));
1525}
1526
1529
1530
1531
1532
1533
1534 if (auto *oid = dyn_cast(decl))
1535 errorNYI(oid->getSourceRange(), "emitDeclConext: ObjCImplDecl");
1536
1538 }
1539}
1540
1541
1543
1544
1545 if (decl->isTemplated())
1546 return;
1547
1548 switch (decl->getKind()) {
1549 default:
1550 errorNYI(decl->getBeginLoc(), "declaration of kind",
1551 decl->getDeclKindName());
1552 break;
1553
1554 case Decl::CXXConversion:
1555 case Decl::CXXMethod:
1556 case Decl::Function: {
1558
1559 if (!fd->isConsteval())
1561 break;
1562 }
1563
1564 case Decl::Var:
1565 case Decl::Decomposition:
1566 case Decl::VarTemplateSpecialization: {
1569 errorNYI(decl->getSourceRange(), "global variable decompositions");
1570 break;
1571 }
1573 break;
1574 }
1575 case Decl::OpenACCRoutine:
1577 break;
1578 case Decl::OpenACCDeclare:
1580 break;
1581 case Decl::Enum:
1582 case Decl::Using:
1583 case Decl::UsingDirective:
1584 case Decl::UsingEnum:
1585 case Decl::NamespaceAlias:
1586 case Decl::Typedef:
1587 case Decl::TypeAlias:
1588 case Decl::Record:
1590 break;
1591
1592
1593 case Decl::ClassTemplate:
1594 case Decl::Concept:
1595 case Decl::CXXDeductionGuide:
1596 case Decl::Empty:
1597 case Decl::FunctionTemplate:
1598 case Decl::StaticAssert:
1599 case Decl::TypeAliasTemplate:
1600 case Decl::UsingShadow:
1601 case Decl::VarTemplate:
1602 case Decl::VarTemplatePartialSpecialization:
1603 break;
1604
1605 case Decl::CXXConstructor:
1607 break;
1608 case Decl::CXXDestructor:
1610 break;
1611
1612
1613 case Decl::LinkageSpec:
1614 case Decl::Namespace:
1616 break;
1617
1618 case Decl::ClassTemplateSpecialization:
1619 case Decl::CXXRecord: {
1622 for (auto *childDecl : crd->decls())
1625 break;
1626 }
1627
1628 case Decl::FileScopeAsm:
1629
1630 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1631 break;
1632
1633 if (langOpts.OpenMPIsTargetDevice)
1634 break;
1635
1636 if (langOpts.SYCLIsDevice)
1637 break;
1639 std::string line = file_asm->getAsmString();
1640 globalScopeAsm.push_back(builder.getStringAttr(line));
1641 break;
1642 }
1643}
1644
1646
1647 op.setInitialValueAttr(value);
1649}
1650
1655
1657
1658
1661 md->getParent()->getNumVBases() == 0)
1662 errorNYI(md->getSourceRange(),
1663 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1664 }
1665
1666 if (!fnType) {
1667 if (!fnInfo)
1670 }
1671
1673 false, dontDefer,
1674 false, isForDefinition);
1675
1676 return {fnType, fn};
1677}
1678
1680 mlir::Type funcType, bool forVTable,
1681 bool dontDefer,
1684 "consteval function should never be emitted");
1685
1686 if (!funcType) {
1689 }
1690
1691
1692
1693
1694 if (const auto *dd = dyn_cast(gd.getDecl())) {
1697 dd->getParent()->getNumVBases() == 0)
1698 errorNYI(dd->getSourceRange(),
1699 "getAddrOfFunction: MS ABI complete destructor");
1700 }
1701
1703 cir::FuncOp func =
1705 false, isForDefinition);
1706 return func;
1707}
1708
1712
1713 llvm::raw_svector_ostream out(buffer);
1715
1717
1720 } else {
1722 assert(ii && "Attempt to mangle unnamed decl.");
1723
1724 const auto *fd = dyn_cast(nd);
1725 if (fd &&
1728 } else if (fd && fd->hasAttr() &&
1731 }
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1743
1744 if (const auto *fd = dyn_cast(nd)) {
1745 if (fd->isMultiVersion()) {
1747 "getMangledName: multi-version functions");
1748 }
1749 }
1750 if (cgm.getLangOpts().GPURelocatableDeviceCode) {
1752 "getMangledName: GPU relocatable device code");
1753 }
1754
1755 return std::string(out.str());
1756}
1757
1758static FunctionDecl *
1761
1762
1768
1771
1772
1773 if (auto *methodDecl = dyn_cast(protoFunc);
1774 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
1776 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
1777
1778 funcTy = ctx.getFunctionType(fpt->getReturnType(), paramTypes,
1779 fpt->getExtProtoInfo());
1781 }
1782
1783 auto *tempFunc =
1788
1790 params.reserve(fpt->getNumParams());
1791
1792
1793 for (unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
1797 nullptr, fpt->getParamType(i), nullptr,
1800 params.push_back(parm);
1801 }
1802
1803 tempFunc->setParams(params);
1804
1805 return tempFunc;
1806}
1807
1808std::string
1813
1815
1816
1817
1818
1820 return ret;
1821}
1822
1825
1826
1827
1828 if (const auto *cd = dyn_cast(canonicalGd.getDecl())) {
1830 errorNYI(cd->getSourceRange(),
1831 "getMangledName: C++ constructor without variants");
1833 }
1834 }
1835
1836
1839
1840 auto result = manglings.insert(std::make_pair(mangledName, gd));
1841 return mangledDeclNames[canonicalGd] = result.first->first();
1842}
1843
1845 assert(!d->getInit() && "Cannot emit definite definitions here!");
1846
1849
1850
1851
1852
1853 if (gv && !mlir::castcir::GlobalOp(gv).isDeclaration())
1854 return;
1855
1856
1857
1860 return;
1861 }
1862
1863
1865}
1866
1868
1869 if (langOpts.EmitAllDecls)
1870 return true;
1871
1872 const auto *vd = dyn_cast(global);
1873 if (vd &&
1874 ((codeGenOpts.KeepPersistentStorageVariables &&
1875 (vd->getStorageDuration() == SD_Static ||
1876 vd->getStorageDuration() == SD_Thread)) ||
1877 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() == SD_Static &&
1878 vd->getType().isConstQualified())))
1879 return true;
1880
1882}
1883
1885
1886
1887
1888
1889
1890
1891 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1892 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1893 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1894 if (!activeAttr || (*activeAttr)->getLevel() != (unsigned)-1)
1895 return false;
1896 }
1897
1898 const auto *fd = dyn_cast(global);
1899 if (fd) {
1900
1901
1903 return false;
1904
1905 if (fd->hasAttr() && !fd->isMultiVersion())
1906 return false;
1907 if (langOpts.SYCLIsDevice) {
1908 errorNYI(fd->getSourceRange(), "mayBeEmittedEagerly: SYCL");
1909 return false;
1910 }
1911 }
1912 const auto *vd = dyn_cast(global);
1913 if (vd)
1914 if (astContext.getInlineVariableDefinitionKind(vd) ==
1916
1917
1918 return false;
1919
1920
1921
1922 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1923 astContext.getTargetInfo().isTLSSupported() && isa(global) &&
1925 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1926 return false;
1927
1928 assert((fd || vd) &&
1929 "Only FunctionDecl and VarDecl should hit this path so far.");
1930 return true;
1931}
1932
1934 cir::CIRGlobalValueInterface gv) {
1935 if (gv.hasLocalLinkage())
1936 return true;
1937
1938 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1939 return true;
1940
1941
1942
1943
1945
1946 const llvm::Triple &tt = cgm.getTriple();
1948 if (tt.isOSCygMing()) {
1949
1950
1951
1952
1953
1954
1955
1956
1957 cgm.errorNYI("shouldAssumeDSOLocal: MinGW");
1958 }
1959
1960
1961
1962
1963 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1964 return false;
1965
1966
1967
1968
1969
1970
1971 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1972 return true;
1973
1974
1975 if (!tt.isOSBinFormatELF())
1976 return false;
1977
1980 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
1981
1982
1983
1984
1985
1986 if (!(isacir::FuncOp(gv) && gv.canBenefitFromLocalAlias()))
1987 return false;
1988 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
1989 }
1990
1991
1992 if (!gv.isDeclarationForLinker())
1993 return true;
1994
1995
1996
1997
1998 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
1999 return false;
2000
2001
2002 if (tt.isPPC64())
2003 return false;
2004
2005 if (cgOpts.DirectAccessExternalData) {
2006
2007
2008
2009
2010
2011 if (auto globalOp = dyn_castcir::GlobalOp(gv.getOperation())) {
2012
2014 return true;
2015 }
2016
2017
2018
2019
2020
2021
2022
2023 if (isacir::FuncOp(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
2024 return true;
2025 }
2026
2027
2028
2029
2030
2031 return false;
2032}
2033
2038
2042
2044 if (auto globalValue = dyn_castcir::CIRGlobalValueInterface(op))
2046}
2047
2053
2060
2064 return cir::TLS_Model::GeneralDynamic;
2066 return cir::TLS_Model::LocalDynamic;
2068 return cir::TLS_Model::InitialExec;
2070 return cir::TLS_Model::LocalExec;
2071 }
2072 llvm_unreachable("Invalid TLS model!");
2073}
2074
2076 assert(d.getTLSKind() && "setting TLS mode on non-TLS var!");
2077
2079
2080
2081 if (d.getAttr())
2083
2085 global.setTlsModel(tlm);
2086}
2087
2089 cir::FuncOp func,
2090 bool isIncompleteFunction,
2091 bool isThunk) {
2092
2093
2094
2095
2098
2099
2100
2101
2102
2106 }
2107
2108
2110 if (fd->isInlineBuiltinDeclaration()) {
2112 bool hasBody = fd->hasBody(fdBody);
2113 (void)hasBody;
2114 assert(hasBody && "Inline builtin declarations should always have an "
2115 "available body!");
2117 }
2118}
2119
2124
2125 std::optionalcir::InlineKind existingInlineKind = f.getInlineKind();
2126 bool isNoInline =
2127 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2128 bool isAlwaysInline = existingInlineKind &&
2129 *existingInlineKind == cir::InlineKind::AlwaysInline;
2130 if () {
2132
2133 if (!isAlwaysInline &&
2135
2136
2137
2138 f.setInlineKind(cir::InlineKind::NoInline);
2139 }
2140
2141 return;
2142 }
2143
2151
2152
2153 if (decl->hasAttr() && !isAlwaysInline) {
2154
2155 f.setInlineKind(cir::InlineKind::NoInline);
2156 } else if (decl->hasAttr() && !isNoInline) {
2157
2158
2159 f.setInlineKind(cir::InlineKind::AlwaysInline);
2161
2162
2163 if (!isAlwaysInline) {
2164 f.setInlineKind(cir::InlineKind::NoInline);
2165 }
2166 } else {
2167
2168
2169
2170 if (auto *fd = dyn_cast(decl)) {
2171
2172
2173
2175 auto checkRedeclForInline = [](const FunctionDecl *redecl) {
2176 return redecl->isInlineSpecified();
2177 };
2178 if (any_of(decl->redecls(), checkRedeclForInline))
2179 return true;
2180 const FunctionDecl *pattern = decl->getTemplateInstantiationPattern();
2181 if (!pattern)
2182 return false;
2183 return any_of(pattern->redecls(), checkRedeclForInline);
2184 };
2185 if (checkForInline(fd)) {
2186 f.setInlineKind(cir::InlineKind::InlineHint);
2187 } else if (codeGenOpts.getInlining() ==
2189 !fd->isInlined() && !isAlwaysInline) {
2190 f.setInlineKind(cir::InlineKind::NoInline);
2191 }
2192 }
2193 }
2194
2196}
2197
2199 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
2200 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
2201 mlir::ArrayAttr extraAttrs) {
2203
2204 if (isThunk)
2206
2207
2208
2209
2210 if (const auto *fd = cast_or_null(d)) {
2211
2212 if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2213 !isForDefinition)
2214 errorNYI(fd->getSourceRange(),
2215 "getOrCreateCIRFunction: OpenMP target function");
2216
2217
2218
2219 if (fd->isMultiVersion())
2220 errorNYI(fd->getSourceRange(), "getOrCreateCIRFunction: multi-version");
2221 }
2222
2223
2224 mlir::Operation *entry = getGlobalValue(mangledName);
2225 if (entry) {
2226 assert(mlir::isacir::FuncOp(entry));
2227
2229
2230
2231 if (d && !d->hasAttr() && !d->hasAttr()) {
2234 }
2235
2236
2237
2239 if (isForDefinition && fn && !fn.isDeclaration()) {
2241 }
2242 if (fn && fn.getFunctionType() == funcType) {
2243 return fn;
2244 }
2245
2246 if (!isForDefinition) {
2247 return fn;
2248 }
2249
2250
2251
2252 }
2253
2254 auto *funcDecl = llvm::cast_or_null(gd.getDecl());
2255 bool invalidLoc = !funcDecl ||
2256 funcDecl->getSourceRange().getBegin().isInvalid() ||
2257 funcDecl->getSourceRange().getEnd().isInvalid();
2259 invalidLoc ? theModule->getLoc() : getLoc(funcDecl->getSourceRange()),
2260 mangledName, mlir::castcir::FuncType(funcType), funcDecl);
2261
2262
2263
2264
2265
2266
2267
2268 if (entry) {
2269
2270
2271 auto symbolOp = mlir::castmlir::SymbolOpInterface(entry);
2272
2273
2274
2275
2276
2277
2278
2279 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2281
2282
2283 entry->erase();
2284 }
2285
2286 if (d)
2288
2289
2290 if (dontDefer) {
2291
2292
2293 assert(funcOp.getFunctionType() == funcType);
2294 return funcOp;
2295 }
2296
2297
2298
2299
2300 if (isa_and_nonnull(d) &&
2304
2305
2306
2307
2310
2311
2312
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2328
2329 for (const auto *fd = cast(d)->getMostRecentDecl(); fd;
2330 fd = fd->getPreviousDecl()) {
2332 if (fd->doesThisDeclarationHaveABody()) {
2334 break;
2335 }
2336 }
2337 }
2338 }
2339
2340 return funcOp;
2341}
2342
2343cir::FuncOp
2345 cir::FuncType funcType,
2347 cir::FuncOp func;
2348 {
2349 mlir::OpBuilder::InsertionGuard guard(builder);
2350
2351
2352
2353
2354
2356 if (cgf)
2357 builder.setInsertionPoint(cgf->curFn);
2358
2359 func = cir::FuncOp::create(builder, loc, name, funcType);
2360
2362
2364 func.setNoProto(true);
2365
2366 assert(func.isDeclaration() && "expected empty body");
2367
2368
2369
2370 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2371 &getMLIRContext(), cir::GlobalLinkageKind::ExternalLinkage));
2372 mlir::SymbolTable::setSymbolVisibility(
2373 func, mlir::SymbolTable::Visibility::Private);
2374
2376
2377
2379
2380 if (!cgf)
2381 theModule.push_back(func);
2382
2384
2385
2386 for (const auto *attr :
2389 attr->Clauses);
2390 }
2391 }
2392 return func;
2393}
2394
2395cir::FuncOp
2397 cir::FuncType ty,
2400 fnOp.setBuiltin(true);
2401 return fnOp;
2402}
2403
2406 return cir::CtorKind::Default;
2408 return cir::CtorKind::Copy;
2410 return cir::CtorKind::Move;
2411 return cir::CtorKind::Custom;
2412}
2413
2416 return cir::AssignKind::Copy;
2418 return cir::AssignKind::Move;
2419 llvm_unreachable("not a copy or move assignment operator");
2420}
2421
2424 if (!funcDecl)
2425 return;
2426
2427 if (const auto *dtor = dyn_cast(funcDecl)) {
2428 auto cxxDtor = cir::CXXDtorAttr::get(
2430 dtor->isTrivial());
2431 funcOp.setCxxSpecialMemberAttr(cxxDtor);
2432 return;
2433 }
2434
2435 if (const auto *ctor = dyn_cast(funcDecl)) {
2437 auto cxxCtor = cir::CXXCtorAttr::get(
2439 kind, ctor->isTrivial());
2440 funcOp.setCxxSpecialMemberAttr(cxxCtor);
2441 return;
2442 }
2443
2444 const auto *method = dyn_cast(funcDecl);
2445 if (method && (method->isCopyAssignmentOperator() ||
2446 method->isMoveAssignmentOperator())) {
2448 auto cxxAssign = cir::CXXAssignAttr::get(
2450 assignKind, method->isTrivial());
2451 funcOp.setCxxSpecialMemberAttr(cxxAssign);
2452 return;
2453 }
2454}
2455
2457 cir::FuncOp funcOp, StringRef name) {
2458
2459
2460
2461
2462
2463 if (!isLocal && cgm.getTarget().getTriple().isWindowsItaniumEnvironment() &&
2468 }
2469}
2470
2472 StringRef name, mlir::ArrayAttr,
2473 bool isLocal,
2474 bool assumeConvergent) {
2475 if (assumeConvergent)
2476 errorNYI("createRuntimeFunction: assumeConvergent");
2477
2479 false);
2480
2481 if (entry) {
2482
2486 entry.setDSOLocal(true);
2487 }
2488
2489 return entry;
2490}
2491
2492mlir::SymbolTable::Visibility
2494
2495
2496 if (op.isDeclaration())
2497 return mlir::SymbolTable::Visibility::Private;
2499}
2500
2501mlir::SymbolTable::Visibility
2503 switch (glk) {
2504 case cir::GlobalLinkageKind::InternalLinkage:
2505 case cir::GlobalLinkageKind::PrivateLinkage:
2506 return mlir::SymbolTable::Visibility::Private;
2507 case cir::GlobalLinkageKind::ExternalLinkage:
2508 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2509 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2510 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2511 case cir::GlobalLinkageKind::CommonLinkage:
2512 case cir::GlobalLinkageKind::WeakAnyLinkage:
2513 case cir::GlobalLinkageKind::WeakODRLinkage:
2514 return mlir::SymbolTable::Visibility::Public;
2515 default: {
2516 llvm::errs() << "visibility not implemented for '"
2517 << stringifyGlobalLinkageKind(glk) << "'\n";
2518 assert(0 && "not implemented");
2519 }
2520 }
2521 llvm_unreachable("linkage should be handled above!");
2522}
2523
2525 clang::VisibilityAttr::VisibilityType visibility) {
2526 switch (visibility) {
2527 case clang::VisibilityAttr::VisibilityType::Default:
2528 return cir::VisibilityKind::Default;
2529 case clang::VisibilityAttr::VisibilityType::Hidden:
2530 return cir::VisibilityKind::Hidden;
2531 case clang::VisibilityAttr::VisibilityType::Protected:
2532 return cir::VisibilityKind::Protected;
2533 }
2534 llvm_unreachable("unexpected visibility value");
2535}
2536
2537cir::VisibilityAttr
2539 const clang::VisibilityAttr *va = decl->getAttrclang::VisibilityAttr();
2540 cir::VisibilityAttr cirVisibility =
2542 if (va) {
2543 cirVisibility = cir::VisibilityAttr::get(
2546 }
2547 return cirVisibility;
2548}
2549
2552 applyReplacements();
2553
2554 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2555 builder.getArrayAttr(globalScopeAsm));
2556
2557
2559}
2560
2562 mlir::Operation *op, GlobalDecl aliasGD,
2563 cir::FuncOp aliasee,
2564 cir::GlobalLinkageKind linkage) {
2565
2566 auto *aliasFD = dyn_cast(aliasGD.getDecl());
2567 assert(aliasFD && "expected FunctionDecl");
2568
2569
2570
2571
2575
2576 cir::FuncOp alias =
2578 mangledName, fnType, aliasFD);
2579 alias.setAliasee(aliasee.getName());
2580 alias.setLinkage(linkage);
2581
2582
2583
2584 mlir::SymbolTable::setSymbolVisibility(
2585 alias, mlir::SymbolTable::Visibility::Private);
2586
2587
2589
2590
2591 if (op) {
2592 errorNYI(aliasFD->getSourceRange(), "emitAliasForGlobal: previous uses");
2593 } else {
2594
2595 }
2596
2597
2599}
2600
2602 return genTypes.convertType(type);
2603}
2604
2606
2607
2608
2609 return mlir::verify(theModule).succeeded();
2610}
2611
2614
2615
2616
2618 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2619
2621 langOpts.ObjCRuntime.isGNUFamily()) {
2622 errorNYI(loc, "getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
2623 return {};
2624 }
2625
2627}
2628
2629
2632 llvm::iterator_rangeCastExpr::path\_const\_iterator path) {
2634
2637
2639 assert(!base->isVirtual() && "Should not see virtual bases here!");
2640
2641
2642 const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd);
2643
2644 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2645
2646
2648
2649 rd = baseDecl;
2650 }
2651
2652 return offset;
2653}
2654
2656 llvm::StringRef feature) {
2657 unsigned diagID = diags.getCustomDiagID(
2659 return diags.Report(loc, diagID) << feature;
2660}
2661
2663 llvm::StringRef feature) {
2665}
2666
2668 cir::LabelOp label) {
2669 [[maybe_unused]] auto result =
2671 assert(result.second &&
2672 "attempting to map a blockaddress info that is already mapped");
2673}
2674
2677 assert(result.second &&
2678 "attempting to map a blockaddress operation that is already mapped");
2679}
2680
2682 cir::LabelOp label) {
2683 [[maybe_unused]] auto result = blockAddressToLabel.try_emplace(op, label);
2684 assert(result.second &&
2685 "attempting to map a blockaddress operation that is already mapped");
2686}
2687
2689 cir::LabelOp newLabel) {
2692 "trying to update a blockaddress not previously mapped");
2693 assert(!it->second && "blockaddress already has a resolved label");
2694
2695 it->second = newLabel;
2696}
2697
2698cir::LabelOp
Defines the clang::ASTContext interface.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
Definition CIRGenModule.cpp:1933
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
Definition CIRGenModule.cpp:2414
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
Definition CIRGenModule.cpp:1759
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
Definition CIRGenModule.cpp:1008
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
Definition CIRGenModule.cpp:2456
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
Definition CIRGenModule.cpp:1709
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
Definition CIRGenModule.cpp:1374
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:1150
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
Definition CIRGenModule.cpp:591
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
Definition CIRGenModule.cpp:2404
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:2688
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:1309
llvm::StringRef getMangledName(clang::GlobalDecl gd)
Definition CIRGenModule.cpp:1823
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
Definition CIRGenModule.cpp:2630
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
Definition CIRGenModule.cpp:2034
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
Definition CIRGenModule.cpp:2655
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:2471
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:1542
void addReplacement(llvm::StringRef name, mlir::Operation *op)
Definition CIRGenModule.cpp:1050
mlir::Type convertType(clang::QualType type)
Definition CIRGenModule.cpp:2601
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:1424
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
Definition CIRGenModule.cpp:2675
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:1867
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
Definition CIRGenModule.cpp:2043
std::string getUniqueGlobalName(const std::string &baseName)
Definition CIRGenModule.cpp:1407
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:1651
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
Definition CIRGenModule.cpp:2048
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:2396
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:501
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
Definition CIRGenModule.cpp:915
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
Definition CIRGenModule.cpp:2681
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:2612
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:2088
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
Definition CIRGenModule.cpp:2502
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:1844
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:1109
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:2198
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
Definition CIRGenModule.cpp:765
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
Definition CIRGenModule.cpp:2075
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:1679
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
Definition CIRGenModule.cpp:2561
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
Definition CIRGenModule.cpp:1507
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
Definition CIRGenModule.cpp:2605
void release()
Definition CIRGenModule.cpp:2550
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
Definition CIRGenModule.cpp:1498
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:741
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
Definition CIRGenModule.cpp:1645
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
Definition CIRGenModule.cpp:755
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
Definition CIRGenModule.cpp:477
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
Definition CIRGenModule.cpp:1362
void updateCompletedType(const clang::TagDecl *td)
Definition CIRGenModule.cpp:1045
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:2061
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:491
void addDeferredDeclToEmit(clang::GlobalDecl GD)
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
Definition CIRGenModule.cpp:2344
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:2054
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
Definition CIRGenModule.cpp:1482
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:2524
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:2422
mlir::Operation * getGlobalValue(llvm::StringRef ref)
Definition CIRGenModule.cpp:515
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
Definition CIRGenModule.cpp:1004
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
Definition CIRGenModule.cpp:1225
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:519
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
Definition CIRGenModule.cpp:1034
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:1470
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
void emitDeclContext(const DeclContext *dc)
Definition CIRGenModule.cpp:1527
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:2699
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:1884
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
Definition CIRGenModule.cpp:1356
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
Definition CIRGenModule.cpp:2667
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
Definition CIRGenModule.cpp:2120
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
Definition CIRGenModule.cpp:1809
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
Definition CIRGenModule.cpp:428
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
Definition CIRGenModule.cpp:951
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
Definition CIRGenModule.cpp:2538
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:554
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.