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

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.