clang: lib/Sema/SemaAccess.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

24

25using namespace clang;

26using namespace sema;

27

28

34

38 if (!PrevMemberDecl) {

39

41 return false;

42 }

43

44

45

46 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {

48 diag::err_class_redeclared_with_different_access)

49 << MemberDecl << LexicalAS;

50 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)

51 << PrevMemberDecl << PrevMemberDecl->getAccess();

52

54 return true;

55 }

56

58 return false;

59}

60

63

64

65

68

72 return DeclaringClass;

73}

74

75namespace {

76struct EffectiveContext {

78

79 explicit EffectiveContext(DeclContext *DC)

80 : Inner(DC),

81 Dependent(DC->isDependentContext()) {

82

83

84

85

86 if (auto *DGD = dyn_cast(DC)) {

87 if (DGD->isImplicit()) {

88 DC = DGD->getCorrespondingConstructor();

89 if (!DC) {

90

91

92 DC = cast(DGD->getDeducedTemplate()->getTemplatedDecl());

93 }

94 }

95 }

96

97

98

99

100

101

102

103

104

105

106

107

108

109 while (true) {

110

111

112

113

114

115

119 DC = Record->getDeclContext();

122 Functions.push_back(Function->getCanonicalDecl());

123 if (Function->getFriendObjectKind())

124 DC = Function->getLexicalDeclContext();

125 else

126 DC = Function->getDeclContext();

128 break;

129 } else {

131 }

132 }

133 }

134

135 bool isDependent() const { return Dependent; }

136

137 bool includesClass(const CXXRecordDecl *R) const {

139 return llvm::is_contained(Records, R);

140 }

141

142

143

144 DeclContext *getInnerContext() const {

145 return Inner;

146 }

147

148 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;

149

150 DeclContext *Inner;

151 SmallVector<FunctionDecl*, 4> Functions;

152 SmallVector<CXXRecordDecl*, 4> Records;

154};

155

156

157

159 AccessTarget(const AccessedEntity &Entity)

160 : AccessedEntity(Entity) {

162 }

163

164 AccessTarget(ASTContext &Context,

165 MemberNonce _,

166 CXXRecordDecl *NamingClass,

167 DeclAccessPair FoundDecl,

168 QualType BaseObjectType)

169 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,

170 FoundDecl, BaseObjectType) {

172 }

173

174 AccessTarget(ASTContext &Context,

175 BaseNonce _,

176 CXXRecordDecl *BaseClass,

177 CXXRecordDecl *DerivedClass,

179 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,

180 Access) {

182 }

183

184 bool isInstanceMember() const {

185 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());

186 }

187

188 bool hasInstanceContext() const {

189 return HasInstanceContext;

190 }

191

192 class SavedInstanceContext {

193 public:

194 SavedInstanceContext(SavedInstanceContext &&S)

196 S.Target = nullptr;

197 }

198

199

200

201 SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;

202

203

204

205 SavedInstanceContext(const SavedInstanceContext &) = delete;

206 SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;

207

208 ~SavedInstanceContext() {

210 Target->HasInstanceContext = Has;

211 }

212

213 private:

214 friend struct AccessTarget;

215 explicit SavedInstanceContext(AccessTarget &Target)

217 AccessTarget *Target;

218 bool Has;

219 };

220

221 SavedInstanceContext saveInstanceContext() {

222 return SavedInstanceContext(*this);

223 }

224

225 void suppressInstanceContext() {

226 HasInstanceContext = false;

227 }

228

229 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {

230 assert(HasInstanceContext);

231 if (CalculatedInstanceContext)

232 return InstanceContext;

233

234 CalculatedInstanceContext = true;

237 : nullptr);

238 return InstanceContext;

239 }

240

241 const CXXRecordDecl *getDeclaringClass() const {

242 return DeclaringClass;

243 }

244

245

246

247 const CXXRecordDecl *getEffectiveNamingClass() const {

248 const CXXRecordDecl *namingClass = getNamingClass();

252 }

253

254private:

256 HasInstanceContext = (isMemberAccess() &&

257 !getBaseObjectType().isNull() &&

258 getTargetDecl()->isCXXInstanceMember());

259 CalculatedInstanceContext = false;

260 InstanceContext = nullptr;

261

262 if (isMemberAccess())

264 else

265 DeclaringClass = getBaseClass();

266 DeclaringClass = DeclaringClass->getCanonicalDecl();

267 }

268

269 bool HasInstanceContext : 1;

270 mutable bool CalculatedInstanceContext : 1;

271 mutable const CXXRecordDecl *InstanceContext;

272 const CXXRecordDecl *DeclaringClass;

273};

274

275}

276

277

280

282 return false;

283

286 if (FromDC == ToDC) return true;

288

289

290 return true;

291}

292

293

294

295

296

297

301 assert(Target->getCanonicalDecl() == Target);

302

304

308

311

312 while (true) {

316

317 for (const auto &I : Derived->bases()) {

319

322 RD = Rec;

323 } else {

324 assert(T->isDependentType() && "non-dependent base wasn't a record?");

326 continue;

327 }

328

333

334 Queue.push_back(RD);

335 }

336

337 if (Queue.empty()) break;

338

339 Derived = Queue.pop_back_val();

340 }

341

342 return OnFailure;

343}

344

345

348 if (Friend == Context)

349 return true;

350

351 assert(Friend->isDependentContext() &&

352 "can't handle friends with dependent contexts here");

353

354 if (!Context->isDependentContext())

355 return false;

356

357 if (Friend->isFileContext())

358 return false;

359

360

361 return true;

362}

363

364

365

367 if (Friend == Context)

368 return true;

369

370 if (Friend->isDependentType() && !Context->isDependentType())

371 return false;

372

373

374 return true;

375}

376

380 if (Context->getDeclName() != Friend->getDeclName())

381 return false;

382

384 Context->getDeclContext(),

385 Friend->getDeclContext()))

386 return false;

387

394

395

396

397 if (FriendTy.getQualifiers() != ContextTy.getQualifiers())

398 return false;

399

400 if (FriendTy->getNumParams() != ContextTy->getNumParams())

401 return false;

402

404 FriendTy->getReturnType()))

405 return false;

406

407 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)

409 FriendTy->getParamType(I)))

410 return false;

411

412 return true;

413}

414

419 Context->getTemplatedDecl(),

420 Friend->getTemplatedDecl());

421}

422

424 const EffectiveContext &EC,

426 if (EC.includesClass(Friend))

428

429 if (EC.isDependent()) {

430 for (const CXXRecordDecl *Context : EC.Records) {

433 }

434 }

435

437}

438

440 const EffectiveContext &EC,

442 if (const auto *RD = Friend->getAsCXXRecordDecl())

444

445

446 if (Friend->isDependentType())

448

450}

451

452

453

455 const EffectiveContext &EC,

458

459

460

462 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {

464

465

467

468

471 ->getSpecializedTemplate();

472

473

474 } else {

475 CTD = Record->getDescribedClassTemplate();

476 if (!CTD) continue;

477 }

478

479

482

483

484 if (!EC.isDependent())

485 continue;

486

487

488

490 continue;

491

492

493

495 Friend->getDeclContext()))

496 continue;

497

498

500 }

501

502 return OnFailure;

503}

504

505

506

508 const EffectiveContext &EC,

511

513 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {

516

519 }

520

521 return OnFailure;

522}

523

524

525

527 const EffectiveContext &EC,

530

532

534 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {

535

537 if (!FTD)

538 FTD = (*I)->getDescribedFunctionTemplate();

539 if (!FTD)

540 continue;

541

543

546

549 }

550

551 return OnFailure;

552}

553

554

555

557 const EffectiveContext &EC,

559

560

563

565 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());

566

569

570

571

574

577

580

583}

584

586 const EffectiveContext &EC,

589

590

591 for (auto *Friend : Class->friends()) {

595

597 continue;

598

601 break;

602 }

603 }

604

605

606 return OnFailure;

607}

608

609namespace {

610

611

612

613struct ProtectedFriendContext {

614 Sema &S;

615 const EffectiveContext &EC;

616 const CXXRecordDecl *NamingClass;

617 bool CheckDependent;

618 bool EverDependent;

619

620

621 SmallVector<const CXXRecordDecl*, 20> CurPath;

622

623 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,

624 const CXXRecordDecl *InstanceContext,

625 const CXXRecordDecl *NamingClass)

626 : S(S), EC(EC), NamingClass(NamingClass),

627 CheckDependent(InstanceContext->isDependentContext() ||

628 NamingClass->isDependentContext()),

629 EverDependent(false) {}

630

631

632

633 bool checkFriendshipAlongPath(unsigned I) {

634 assert(I < CurPath.size());

635 for (unsigned E = CurPath.size(); I != E; ++I) {

639 case AR_dependent: EverDependent = true; continue;

640 }

641 }

642 return false;

643 }

644

645

646

647

648

649

650 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {

651

652

653

654 if (Cur == NamingClass)

655 return checkFriendshipAlongPath(PrivateDepth);

656

658 EverDependent = true;

659

660

661 for (const auto &I : Cur->bases()) {

662

663

664 unsigned BasePrivateDepth = PrivateDepth;

665 if (I.getAccessSpecifier() == AS_private)

666 BasePrivateDepth = CurPath.size() - 1;

667

668 const CXXRecordDecl *RD;

669

670 QualType T = I.getType();

672 RD = Rec;

673 } else {

674 assert(T->isDependentType() && "non-dependent base wasn't a record?");

675 EverDependent = true;

676 continue;

677 }

678

679

680 CurPath.push_back(RD);

681 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))

682 return true;

683 CurPath.pop_back();

684 }

685

686 return false;

687 }

688

689 bool findFriendship(const CXXRecordDecl *Cur) {

690 assert(CurPath.empty());

691 CurPath.push_back(Cur);

692 return findFriendship(Cur, 0);

693 }

694};

695}

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714

715

716

717

718

719

720

721

722

726 assert(InstanceContext == nullptr ||

729

730

731

732

733 if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);

734

735 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);

736 if (PRC.findFriendship(InstanceContext)) return AR_accessible;

739}

740

742 const EffectiveContext &EC,

745 const AccessTarget &Target) {

747 "declaration should be canonicalized before being passed here");

748

751

753

754 for (EffectiveContext::record_iterator

755 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {

756

757

759

760

762 if (ECRecord == NamingClass)

764

767

768

769 } else {

775 }

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794 if (Target.hasInstanceContext()) {

795

797

798

799

800

801

802

803

804

805 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())

806 if (CXXMethodDecl* MD = dyn_cast(EC.Functions.front()))

808

809

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825 if (NamingClass == ECRecord) return AR_accessible;

826

827

828 continue;

829 }

830

831 assert(Target.isInstanceMember());

832

834 if (!InstanceContext) {

836 continue;

837 }

838

843 }

844 }

845 }

846

847

848

849

850

851

852

853

854

855

856

858

860 if (Target.hasInstanceContext()) {

861 InstanceContext = Target.resolveInstanceContext(S);

863 }

864

869 }

870 llvm_unreachable("impossible friendship kind");

871 }

872

877 }

878

879

880 llvm_unreachable("impossible friendship kind");

881}

882

883

884

885

886

887

888

889

890

891

892

893

894

895

896

897

898

899

900

901

902

903

904

905

906

907

908

909

910

911

912

913

914

915

916

917

918

919

920

921

922

923

924

925

926

927

928

929

930

931

932

933

934

935

936

937

938

940 const EffectiveContext &EC,

941 AccessTarget &Target,

944

947

948

950 Paths);

951 assert(isDerived && "derived class not actually derived from base");

952 (void) isDerived;

953

955

956 assert(FinalAccess != AS_none && "forbidden access after declaring class");

957

958 bool AnyDependent = false;

959

960

962 PI != PE; ++PI) {

963 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();

964

965

967 CXXBasePath::iterator I = PI->end(), E = PI->begin();

968 while (I != E) {

969 --I;

970

971 assert(PathAccess != AS_none);

972

973

974

975

978 break;

979 }

980

982

983 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();

984 PathAccess = std::max(PathAccess, BaseAccess);

985

990

991

992

993 Target.suppressInstanceContext();

994 break;

996 AnyDependent = true;

998 }

999 }

1000

1001

1002

1003 if (BestPath == nullptr || PathAccess < BestPath->Access) {

1004 BestPath = &*PI;

1005 BestPath->Access = PathAccess;

1006

1007

1009 return BestPath;

1010 }

1011

1013 }

1014

1016 "fell out of loop with public path");

1017

1018

1019

1020 if (AnyDependent)

1021 return nullptr;

1022

1023 return BestPath;

1024}

1025

1026

1027

1028

1029

1030

1032 AccessTarget &Target) {

1033

1034 if (Target.isInstanceMember())

1035 return false;

1036

1037 assert(Target.isMemberAccess());

1038

1040

1041 for (EffectiveContext::record_iterator

1042 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {

1048 }

1049

1050

1051

1052

1053

1054

1055

1056

1057

1059

1060

1061

1062 if (Target.hasInstanceContext()) {

1063

1064 if (NamingClass == ECRecord) continue;

1065

1066

1067

1068 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)

1070 return true;

1071 }

1072

1073 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);

1074 assert(InstanceContext && "diagnosing dependent access");

1075

1080 break;

1081 }

1082

1083

1084

1085

1091 diag::note_access_protected_restricted_ctordtor)

1093 }

1094

1095

1097 diag::note_access_protected_restricted_object)

1099 }

1100

1101 return false;

1102}

1103

1104

1105

1107 const EffectiveContext &EC,

1108 AccessTarget &entity) {

1109 assert(entity.isMemberAccess());

1110 NamedDecl *D = entity.getTargetDecl();

1111

1114 return;

1115

1116

1119 if (VarDecl *VD = dyn_cast(D))

1121 else if (FunctionDecl *FD = dyn_cast(D))

1123 else if (TypedefNameDecl *TND = dyn_cast(D))

1125 else if (TagDecl *TD = dyn_cast(D)) {

1126 if (const auto *RD = dyn_cast(TD);

1128 break;

1130 }

1131 if (!PrevDecl) break;

1132 D = PrevDecl;

1133 }

1134

1136 Decl *ImmediateChild;

1138 ImmediateChild = D;

1139 else {

1141 while (DC->getParent() != DeclaringClass)

1144 }

1145

1146

1147

1148 bool isImplicit = true;

1149 for (const auto *I : DeclaringClass->decls()) {

1150 if (I == ImmediateChild) break;

1152 isImplicit = false;

1153 break;

1154 }

1155 }

1156

1159 << isImplicit;

1160}

1161

1162

1163

1165 const EffectiveContext &EC,

1166 AccessTarget &entity) {

1167

1168 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();

1169

1170

1171

1172

1173

1175

1176

1177 if (entity.isMemberAccess()) {

1178 NamedDecl *D = entity.getTargetDecl();

1180 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();

1181

1182 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {

1183

1184

1187 entity.suppressInstanceContext();

1188 break;

1189

1192 declaringClass == entity.getEffectiveNamingClass())

1194 break;

1195

1197 llvm_unreachable("cannot diagnose dependent access");

1198 }

1199 }

1200

1204

1205 CXXBasePath::iterator i = path.end(), e = path.begin();

1206 CXXBasePath::iterator constrainingBase = i;

1207 while (i != e) {

1208 --i;

1209

1211

1212

1213

1216

1217

1218

1220 if (baseAccess > accessSoFar) {

1221 constrainingBase = i;

1222 accessSoFar = baseAccess;

1223 }

1224

1225 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {

1229 entity.suppressInstanceContext();

1230 constrainingBase = nullptr;

1231 break;

1233 llvm_unreachable("cannot diagnose dependent access");

1234 }

1235

1236

1237

1240 assert(constrainingBase == i);

1241 break;

1242 }

1243 }

1244

1245

1246

1247 if (constrainingBase == path.end())

1249

1250

1251

1252

1253 unsigned diagnostic;

1254 if (entity.isMemberAccess() ||

1255 constrainingBase + 1 != path.end()) {

1256 diagnostic = diag::note_access_constrained_by_path;

1257 } else {

1258 diagnostic = diag::note_access_natural;

1259 }

1260

1262

1267

1268 if (entity.isMemberAccess())

1269 S.Diag(entity.getTargetDecl()->getLocation(),

1270 diag::note_member_declared_at);

1271}

1272

1274 const EffectiveContext &EC,

1275 AccessTarget &Entity) {

1276 const CXXRecordDecl *NamingClass = Entity.getNamingClass();

1277 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();

1278 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);

1279

1280 S.Diag(Loc, Entity.getDiag())

1286}

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1305

1306

1307

1310 AccessTarget &Entity) {

1312 dyn_cast(Entity.getTargetDecl()))

1313 if (UsingDecl *UD = dyn_cast(Shadow->getIntroducer())) {

1314 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();

1315 if (Entity.getTargetDecl()->getAccess() == AS_private &&

1318 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)

1319 << UD->getQualifiedNameAsString()

1321 return true;

1322 }

1323 }

1324 return false;

1325}

1326

1327

1328

1330 const EffectiveContext &EC,

1331 AccessTarget &Entity) {

1332

1333 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();

1334

1335 AccessSpecifier UnprivilegedAccess = Entity.getAccess();

1336 assert(UnprivilegedAccess != AS_public && "public access not weeded out");

1337

1338

1339

1340

1341

1342 if (UnprivilegedAccess != AS_none) {

1343 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {

1345

1346

1347

1348

1349

1350

1351

1353

1356 }

1357 }

1358

1359 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();

1360

1361

1362

1364

1365 if (Entity.isMemberAccess()) {

1366

1367

1369 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();

1370

1371 FinalAccess = Target->getAccess();

1372 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {

1374

1375

1376

1377

1378

1380 Entity.suppressInstanceContext();

1381 break;

1384 }

1385

1386 if (DeclaringClass == NamingClass)

1388 } else {

1390 }

1391

1392 assert(Entity.getDeclaringClass() != NamingClass);

1393

1394

1397 if (!Path)

1399

1400 assert(Path->Access <= UnprivilegedAccess &&

1401 "access along best path worse than direct?");

1405}

1406

1408 const EffectiveContext &EC,

1410 const AccessTarget &Entity) {

1411 assert(EC.isDependent() && "delaying non-dependent access");

1413 assert(DC->isDependentContext() && "delaying non-dependent access");

1415 Loc,

1416 Entity.isMemberAccess(),

1417 Entity.getAccess(),

1418 Entity.getTargetDecl(),

1419 Entity.getNamingClass(),

1420 Entity.getBaseObjectType(),

1421 Entity.getDiag());

1422}

1423

1424

1426 const EffectiveContext &EC,

1428 AccessTarget &Entity) {

1429 assert(Entity.getAccess() != AS_public && "called for public access!");

1430

1435

1440 if (!Entity.isQuiet())

1443

1446 }

1447

1448

1449 llvm_unreachable("invalid access result");

1450}

1451

1453 AccessTarget &Entity) {

1454

1455 if (Entity.getAccess() == AS_public)

1457

1458

1459

1460

1461

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1474

1476

1477

1478

1479

1480

1481

1483 bool IsFriendDeclaration = false;

1484 while (TS && !IsFriendDeclaration) {

1487 }

1488 if (!IsFriendDeclaration) {

1491 }

1492 }

1493

1499 }

1500 llvm_unreachable("invalid access result");

1501}

1502

1504

1505

1506

1507

1508

1512 } else if (FunctionDecl *FN = dyn_cast(D)) {

1513 DC = FN;

1514 } else if (TemplateDecl *TD = dyn_cast(D)) {

1515 if (auto *D = dyn_cast_if_present(TD->getTemplatedDecl()))

1516 DC = D;

1517 } else if (auto *RD = dyn_cast(D)) {

1518 DC = RD;

1519 }

1520

1521 EffectiveContext EC(DC);

1522

1524

1527}

1528

1533

1535 TemplateArgs);

1536 if (!NamingD) return;

1538 TemplateArgs);

1539 if (!TargetD) return;

1540

1545 if (!BaseObjectType.isNull()) {

1546 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,

1548 if (BaseObjectType.isNull()) return;

1549 }

1550

1551 AccessTarget Entity(Context,

1552 AccessTarget::Member,

1553 NamingClass,

1555 BaseObjectType);

1558 } else {

1559 AccessTarget Entity(Context,

1560 AccessTarget::Base,

1563 Access);

1566 }

1567}

1568

1575

1578 Entity.setDiag(diag::err_access) << E->getSourceRange();

1579

1581}

1582

1588

1592

1594 Found, BaseType);

1595 Entity.setDiag(diag::err_access) << E->getSourceRange();

1596

1598}

1599

1605

1607 return true;

1608

1609 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,

1610 ObjectType);

1611

1612

1613 Entity.setDiag(Diag);

1614

1615 switch (CheckAccess(*this, Loc, Entity)) {

1618 case AR_dependent: llvm_unreachable("dependent for =delete computation");

1619 case AR_delayed: llvm_unreachable("cannot delay =delete computation");

1620 }

1621 llvm_unreachable("bad access result");

1622}

1623

1630

1631

1635

1637 if (ObjectTy.isNull())

1638 ObjectTy = Context.getCanonicalTagType(NamingClass);

1639

1640 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,

1642 ObjectTy);

1643 Entity.setDiag(PDiag);

1644

1646}

1647

1652 bool IsCopyBindingRefToTemp) {

1655

1657 switch (Entity.getKind()) {

1658 default:

1659 PD = PDiag(IsCopyBindingRefToTemp

1660 ? diag::ext_rvalue_to_reference_access_ctor

1661 : diag::err_access_ctor);

1662

1663 break;

1664

1666 PD = PDiag(diag::err_access_base_ctor);

1669 break;

1670

1674 PD = PDiag(diag::err_access_field_ctor);

1676 break;

1677 }

1678

1681 PD = PDiag(diag::err_access_lambda_capture);

1683 break;

1684 }

1685

1686 }

1687

1689}

1690

1699

1701

1702

1703

1704

1705

1706

1707

1708

1714 } else if (auto *Shadow =

1715 dyn_cast(Found.getDecl())) {

1716

1717

1718 ObjectClass = Shadow->getParent();

1719 } else {

1720 ObjectClass = NamingClass;

1721 }

1722

1723 AccessTarget AccessEntity(

1724 Context, AccessTarget::Member, NamingClass,

1726 Context.getCanonicalTagType(ObjectClass));

1727 AccessEntity.setDiag(PD);

1728

1729 return CheckAccess(*this, UseLoc, AccessEntity);

1730}

1731

1738 !NamingClass ||

1741

1742 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,

1745 Entity.setDiag(diag::err_access)

1746 << PlacementRange;

1747

1748 return CheckAccess(*this, OpLoc, Entity);

1749}

1750

1755 !NamingClass ||

1758

1759 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,

1761

1762 return CheckAccess(*this, UseLoc, Entity);

1763}

1764

1772

1773 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,

1774 Context.getCanonicalTagType(DecomposedClass));

1775 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);

1776

1777 return CheckAccess(*this, UseLoc, Entity);

1778}

1779

1781 Expr *ObjectExpr,

1786

1788 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,

1790 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;

1791

1792 return CheckAccess(*this, OpLoc, Entity);

1793}

1794

1796 Expr *ObjectExpr,

1797 Expr *ArgExpr,

1802}

1803

1805 Expr *ObjectExpr,

1809 if (!ArgExprs.empty()) {

1810 R = SourceRange(ArgExprs.front()->getBeginLoc(),

1811 ArgExprs.back()->getEndLoc());

1812 }

1813

1815}

1816

1819

1820

1821

1823

1826

1828

1829 AccessTarget entity(Context, AccessTarget::Member,

1832 QualType());

1833 entity.setDiag(diag::err_access_friend_function)

1836

1837

1838

1844 }

1845 llvm_unreachable("invalid access result");

1846}

1847

1854

1857

1858 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,

1859 QualType());

1860 Entity.setDiag(diag::err_access)

1862

1864}

1865

1868 const CXXBasePath &Path, unsigned DiagID,

1869 llvm::function_ref<void(PartialDiagnostic &)> SetupPDiag, bool ForceCheck,

1870 bool ForceUnprivileged) {

1871 if (!ForceCheck && getLangOpts().AccessControl)

1873

1876

1877 AccessTarget Entity(Context, AccessTarget::Base, Base, Derived, Path.Access);

1878 if (DiagID)

1879 SetupPDiag(Entity.setDiag(DiagID));

1880

1881 if (ForceUnprivileged) {

1882 switch (

1884 case ::AR_accessible:

1886 case ::AR_inaccessible:

1888 case ::AR_dependent:

1890 }

1891 llvm_unreachable("unexpected result from CheckEffectiveAccess");

1892 }

1893 return CheckAccess(*this, AccessLoc, Entity);

1894}

1895

1899 unsigned DiagID, bool ForceCheck,

1900 bool ForceUnprivileged) {

1903 Path, DiagID, [&](PartialDiagnostic &PD) { PD << Derived << Base; },

1904 ForceCheck, ForceUnprivileged);

1905}

1906

1909 && "performing access check without access control");

1910 assert(R.getNamingClass() && "performing access check without naming class");

1911

1913 if (I.getAccess() != AS_public) {

1917 Entity.setDiag(diag::err_access);

1919 }

1920 }

1921}

1922

1925

1926 if (Target->isCXXClassMember() && NamingClass) {

1928 return false;

1929

1930

1931

1932

1937 }

1938

1940

1943 return true;

1944

1945

1946

1949 ClassOfMethodDecl = MD->getClassInterface();

1952 = dyn_cast(FD->getLexicalDeclContext())) {

1954 = dyn_cast(Impl))

1955 ClassOfMethodDecl = IMPD->getClassInterface();

1957 = dyn_cast(Impl))

1958 ClassOfMethodDecl = CatImplClass->getClassInterface();

1959 }

1960 }

1961

1962

1963 if (!ClassOfMethodDecl)

1964 return false;

1965

1966

1967 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))

1968 return true;

1969

1970

1972 return false;

1973

1974 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);

1975 }

1976

1977 return true;

1978}

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.

Defines the clang::Expr interface and subclasses for C++ expressions.

FormatToken * Next

The next token in the unwrapped line.

llvm::MachO::Target Target

llvm::MachO::Records Records

llvm::MachO::Record Record

static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)

Definition SemaAccess.cpp:1273

AccessResult

A copy of Sema's enum without AR_delayed.

Definition SemaAccess.cpp:29

@ AR_accessible

Definition SemaAccess.cpp:30

@ AR_dependent

Definition SemaAccess.cpp:32

@ AR_inaccessible

Definition SemaAccess.cpp:31

static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, AccessTarget &Target)

Given that an entity has protected natural access, check whether access might be denied because of th...

Definition SemaAccess.cpp:1031

static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)

Checks whether one class is derived from another, inclusively.

Definition SemaAccess.cpp:298

static void diagnoseBadDirectAccess(Sema &S, const EffectiveContext &EC, AccessTarget &entity)

We are unable to access a given declaration due to its direct access control; diagnose that.

Definition SemaAccess.cpp:1106

static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)

Definition SemaAccess.cpp:1452

static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)

Definition SemaAccess.cpp:585

static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)

Definition SemaAccess.cpp:423

static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass)

Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...

Definition SemaAccess.cpp:723

static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)

MSVC has a bug where if during an using declaration name lookup, the declaration found is unaccessibl...

Definition SemaAccess.cpp:1308

static CXXBasePath * FindBestPath(Sema &S, const EffectiveContext &EC, AccessTarget &Target, AccessSpecifier FinalAccess, CXXBasePaths &Paths)

Finds the best path from the naming class to the declaring class, taking friend declarations into acc...

Definition SemaAccess.cpp:939

static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)

Determines whether the accessed entity is accessible.

Definition SemaAccess.cpp:1329

static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target)

Definition SemaAccess.cpp:741

static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)

Checks whether one class might instantiate to the other.

Definition SemaAccess.cpp:278

static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)

Diagnose the path which caused the given declaration or base class to become inaccessible.

Definition SemaAccess.cpp:1164

static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)

Definition SemaAccess.cpp:61

static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity)

Checks access to an entity from the given effective context.

Definition SemaAccess.cpp:1425

static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)

Definition SemaAccess.cpp:1407

Defines various enumerations that describe declaration and type specifiers.

static QualType getPointeeType(const MemRegion *R)

static CanQualType getCanonicalType(QualType T)

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

CanQualType getCanonicalTagType(const TagDecl *TD) const

Represents a path from a specific derived class (which is not represented as part of the path) to a p...

AccessSpecifier Access

The access along this inheritance path.

BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...

std::list< CXXBasePath >::iterator paths_iterator

Represents a base class of a C++ class.

AccessSpecifier getAccessSpecifierAsWritten() const

Retrieves the access specifier as written in the source code (which may mean that no access specifier...

QualType getType() const

Retrieves the type of the base class.

SourceRange getSourceRange() const LLVM_READONLY

Retrieves the source range that contains the entire base specifier.

AccessSpecifier getAccessSpecifier() const

Returns the access specifier for this base specifier.

Represents a C++ constructor within a class.

Represents a C++ destructor within a class.

Represents a static or instance method of a struct/union/class.

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

Represents a C++ struct/union/class.

bool isLambda() const

Determine whether this class describes a lambda function object.

bool hasDefinition() const

bool isInjectedClassName() const

Determines whether this declaration represents the injected class name.

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isDerivedFrom(const CXXRecordDecl *Base) const

Determine whether this class is derived from the class Base.

Represents a canonical, potentially-qualified type.

Qualifiers getQualifiers() const

Retrieve all qualifiers.

CanProxy< U > getAs() const

Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.

Declaration of a class template.

ClassTemplateDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

A POD class for pairing a NamedDecl* with an access specifier.

static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool isFileContext() const

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

DeclContext * getPrimaryContext()

getPrimaryContext - There may be many different declarations of the same entity (including forward de...

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.

Decl * getPreviousDecl()

Retrieve the previous declaration that declares the same entity as this declaration,...

virtual bool isOutOfLine() const

Determine whether this declaration is declared out of line (outside its semantic context).

FunctionDecl * getAsFunction() LLVM_READONLY

Returns the function itself, or the templated function if this is a function template.

bool isInvalidDecl() const

bool isLocalExternDecl() const

Determine whether this is a block-scope declaration with linkage.

void setAccess(AccessSpecifier AS)

SourceLocation getLocation() const

DeclContext * getDeclContext()

AccessSpecifier getAccess() const

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

The name of a declaration.

NestedNameSpecifierLoc getQualifierLoc() const

Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...

NestedNameSpecifier getQualifier() const

Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...

A dependently-generated diagnostic.

NamedDecl * getAccessNamingClass() const

QualType getAccessBaseObjectType() const

bool isAccessToMember() const

NamedDecl * getAccessTarget() const

SourceLocation getAccessLoc() const

const PartialDiagnostic & getDiagnostic() const

static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)

AccessSpecifier getAccess() const

This represents one expression.

Represents a member of a struct/union/class.

FriendDecl - Represents the declaration of a friend entity, which can be a function,...

bool isUnsupportedFriend() const

Determines if this friend kind is unsupported.

NamedDecl * getFriendDecl() const

If this friend declaration doesn't name a type, return the inner declaration.

TypeSourceInfo * getFriendType() const

If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...

Represents a function declaration or definition.

DeclarationNameInfo getNameInfo() const

Represents a prototype with parameter type info, e.g.

Declaration of a template function.

FunctionTemplateDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

Describes an entity that is being initialized.

EntityKind getKind() const

Determine the kind of initialization.

QualType getType() const

Retrieve type being initialized.

ValueDecl * getDecl() const

Retrieve the variable, parameter, or field being initialized.

const InitializedEntity * getParent() const

Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...

bool isInheritedVirtualBase() const

Return whether the base is an inherited virtual base.

@ EK_Member

The entity being initialized is a non-static data member subobject.

@ EK_Base

The entity being initialized is a base member subobject.

@ EK_ParenAggInitMember

The entity being initialized is a non-static data member subobject of an object initialized via paren...

@ EK_Delegating

The initialization is being done by a delegating constructor.

@ EK_LambdaCapture

The entity being initialized is the field that captures a variable in a lambda.

StringRef getCapturedVarName() const

For a lambda capture, return the capture's name.

const CXXBaseSpecifier * getBaseSpecifier() const

Retrieve the base specifier.

Represents the results of name lookup.

SourceLocation getNameLoc() const

Gets the location of the identifier.

CXXRecordDecl * getNamingClass() const

Returns the 'naming class' for this lookup, i.e.

QualType getBaseObjectType() const

Returns the base object type associated with this lookup; important for [class.protected].

UnresolvedSetImpl::iterator iterator

Data structure that captures multiple levels of template argument lists for use in template instantia...

This represents a decl that may have a name.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

std::string getQualifiedNameAsString() const

SourceRange getSourceRange() const LLVM_READONLY

Retrieve the source range covering the entirety of this nested-name-specifier.

ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

Represents an ObjC class declaration.

bool isSuperClassOf(const ObjCInterfaceDecl *I) const

isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCMethodDecl - Represents an instance or class method declaration.

A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.

static FindResult find(Expr *E)

Finds the overloaded expression in the given expression E of OverloadTy.

SourceLocation getNameLoc() const

Gets the location of the name.

CXXRecordDecl * getNamingClass()

Gets the naming class of this lookup, if any.

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

bool isAnonymousStructOrUnion() const

Whether this is an anonymous struct or union.

Scope - A scope is a transient data structure that is used while parsing the program.

bool isFriendScope() const

Determine whether this scope is a friend scope.

const Scope * getParent() const

getParent - Return the scope that this is nested in.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

bool shouldDelayDiagnostics()

Determines whether diagnostics should be delayed.

void add(const sema::DelayedDiagnostic &diag)

Adds a delayed diagnostic.

Sema - This implements semantic analysis and AST building for C.

Scope * getCurScope() const

Retrieve the parser's current scope.

CXXSpecialMemberKind getSpecialMember(const CXXMethodDecl *MD)

bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)

SetMemberAccessSpecifier - Set the access specifier of a member.

Definition SemaAccess.cpp:35

NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)

Find the instantiation of the given declaration within the current instantiation.

AccessResult CheckFriendAccess(NamedDecl *D)

Checks access to the target of a friend declaration.

Definition SemaAccess.cpp:1817

class clang::Sema::DelayedDiagnostics DelayedDiagnostics

bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)

Is the given member accessible for the purposes of deciding whether to define a special member functi...

Definition SemaAccess.cpp:1600

FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const

Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...

AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())

Definition SemaAccess.cpp:1624

TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)

Perform substitution on the type T with a given set of template arguments.

AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)

Checks access to an overloaded operator new or delete.

Definition SemaAccess.cpp:1732

AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)

Definition SemaAccess.cpp:1780

ObjCMethodDecl * getCurMethodDecl()

getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...

void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaAccess.cpp:1529

const LangOptions & getLangOpts() const

AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)

Checks implicit access to a member in a structured binding.

Definition SemaAccess.cpp:1766

AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)

Checks access for a hierarchy conversion.

Definition SemaAccess.cpp:1896

AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)

Perform access-control checking on a previously-unresolved member access which has now been resolved ...

Definition SemaAccess.cpp:1583

bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)

Checks access to Target from the given class.

Definition SemaAccess.cpp:1923

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)

Checks access to a constructor.

Definition SemaAccess.cpp:1648

AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)

Definition SemaAccess.cpp:1848

DeclContext * computeDeclContext(QualType T)

Compute the DeclContext that is associated with the given type.

void CheckLookupAccess(const LookupResult &R)

Checks access to all the declarations in the given result set.

Definition SemaAccess.cpp:1907

AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)

Definition SemaAccess.cpp:1569

AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)

Checks access to a member.

Definition SemaAccess.cpp:1751

void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)

Definition SemaAccess.cpp:1503

@ Diagnose

Diagnose issues that are non-constant or that are extensions.

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

Represents the declaration of a struct/union/class/enum.

The base class of all kinds of template declarations (e.g., class, function, etc.).

A container of type source information.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

CXXRecordDecl * castAsCXXRecordDecl() const

const T * castAs() const

Member-template castAs.

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

Base class for declarations which introduce a typedef-name.

A reference to a name which we were able to look up during parsing but could not resolve to a specifi...

CXXRecordDecl * getNamingClass()

Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.

Represents a C++ member access expression for which lookup produced a set of overloaded functions.

QualType getBaseType() const

bool isArrow() const

Determine whether this member expression used the '->' operator; otherwise, it used the '.

CXXRecordDecl * getNamingClass()

Retrieve the naming class of this lookup.

SourceLocation getMemberLoc() const

Retrieve the location of the name of the member that this expression refers to.

Represents a C++ using-declaration.

Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...

Represents a variable declaration or definition.

A declaration being accessed, together with information about how it was accessed.

A diagnostic message which has been conditionally emitted pending the complete parsing of the current...

AccessedEntity & getAccessData()

static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)

The JSON file list parser is used to communicate input to InstallAPI.

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

bool isa(CodeGen::Address addr)

void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

@ Dependent

Parse the block as a dependent block, which may be used in some template instantiations but not other...

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

U cast(CodeGen::Address addr)

SourceRange getSourceRange() const LLVM_READONLY

getSourceRange - The range of the declaration name.

OverloadExpr * Expression