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 && getBuilder().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 getLangOpts().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 (decl) {

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.