clang: lib/Frontend/ASTUnit.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

67#include "llvm/ADT/ArrayRef.h"

68#include "llvm/ADT/DenseMap.h"

69#include "llvm/ADT/IntrusiveRefCntPtr.h"

70#include "llvm/ADT/STLExtras.h"

71#include "llvm/ADT/ScopeExit.h"

72#include "llvm/ADT/SmallVector.h"

73#include "llvm/ADT/StringMap.h"

74#include "llvm/ADT/StringRef.h"

75#include "llvm/ADT/StringSet.h"

76#include "llvm/ADT/Twine.h"

77#include "llvm/ADT/iterator_range.h"

78#include "llvm/Bitstream/BitstreamWriter.h"

79#include "llvm/Support/Allocator.h"

80#include "llvm/Support/Casting.h"

81#include "llvm/Support/CrashRecoveryContext.h"

82#include "llvm/Support/DJB.h"

83#include "llvm/Support/ErrorHandling.h"

84#include "llvm/Support/ErrorOr.h"

85#include "llvm/Support/FileSystem.h"

86#include "llvm/Support/MemoryBuffer.h"

87#include "llvm/Support/SaveAndRestore.h"

88#include "llvm/Support/Timer.h"

89#include "llvm/Support/VirtualFileSystem.h"

90#include "llvm/Support/raw_ostream.h"

91#include

92#include

93#include

94#include

95#include

96#include

97#include

98#include

99#include

100#include

101#include

102#include

103#include

104

105using namespace clang;

106

107using llvm::TimeRecord;

108

109namespace {

110

111 class SimpleTimer {

112 bool WantTiming;

113 TimeRecord Start;

114 std::string Output;

115

116 public:

117 explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {

118 if (WantTiming)

119 Start = TimeRecord::getCurrentTime();

120 }

121

122 ~SimpleTimer() {

123 if (WantTiming) {

124 TimeRecord Elapsed = TimeRecord::getCurrentTime();

125 Elapsed -= Start;

126 llvm::errs() << Output << ':';

127 Elapsed.print(Elapsed, llvm::errs());

128 llvm::errs() << '\n';

129 }

130 }

131

132 void setOutput(const Twine &Output) {

133 if (WantTiming)

134 this->Output = Output.str();

135 }

136 };

137

138}

139

140template

141static std::unique_ptr valueOrNull(llvm::ErrorOr<std::unique_ptr> Val) {

142 if (!Val)

143 return nullptr;

144 return std::move(*Val);

145}

146

147template

149 if (!Val)

150 return false;

151 Output = std::move(*Val);

152 return true;

153}

154

155

156

157static std::unique_ptrllvm::MemoryBuffer

159 llvm::vfs::FileSystem *VFS,

160 StringRef FilePath, bool isVolatile) {

162

163

164

165

166 llvm::MemoryBuffer *Buffer = nullptr;

167 std::unique_ptrllvm::MemoryBuffer BufferOwner;

168 auto FileStatus = VFS->status(FilePath);

169 if (FileStatus) {

170 llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();

171

172

173 for (const auto &RF : PreprocessorOpts.RemappedFiles) {

174 std::string MPath(RF.first);

175 auto MPathStatus = VFS->status(MPath);

176 if (MPathStatus) {

177 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();

178 if (MainFileID == MID) {

179

180 BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));

181 if (!BufferOwner)

182 return nullptr;

183 }

184 }

185 }

186

187

188

189 for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {

190 std::string MPath(RB.first);

191 auto MPathStatus = VFS->status(MPath);

192 if (MPathStatus) {

193 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();

194 if (MainFileID == MID) {

195

196 BufferOwner.reset();

197 Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);

198 }

199 }

200 }

201 }

202

203

204 if (!Buffer && !BufferOwner) {

205 BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));

206 if (!BufferOwner)

207 return nullptr;

208 }

209

210 if (BufferOwner)

211 return BufferOwner;

212 if (!Buffer)

213 return nullptr;

214 return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);

215}

216

221

224};

225

226void ASTUnit::clearFileLevelDecls() {

227 FileDecls.clear();

228}

229

230

231

232

233

235

236

237

238

240

241ASTUnit::ASTUnit(bool _MainFileIsAST)

242 : MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),

243 ShouldCacheCodeCompletionResults(false),

244 IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),

245 UnsafeToFree(false) {

246 if (getenv("LIBCLANG_OBJTRACKING"))

248}

249

251

254 }

255

256 clearFileLevelDecls();

257

258

259

260

261

262 if (Invocation && OwnsRemappedFileBuffers) {

265 delete RB.second;

266 }

267

268 ClearCachedCompletionResults();

269

270 if (getenv("LIBCLANG_OBJTRACKING"))

272}

273

275 this->PP = std::move(PP);

276}

277

280 "Bad context for source file");

282}

283

284

285

288 bool &IsNestedNameSpecifier) {

289 IsNestedNameSpecifier = false;

290

291 if (isa(ND))

293 if (!ND)

294 return 0;

295

296 uint64_t Contexts = 0;

297 if (isa(ND) || isa(ND) ||

298 isa(ND) || isa(ND) ||

299 isa(ND)) {

300

301 if (LangOpts.CPlusPlus || !isa(ND))

308

309

310 if (LangOpts.CPlusPlus)

312

313

314

315 if (LangOpts.CPlusPlus || isa(ND))

317

318

319 if (const auto *ID = dyn_cast(ND)) {

320

321 if (ID->getDefinition())

325 }

326

327

328 if (isa(ND)) {

330

331

332 if (LangOpts.CPlusPlus11)

333 IsNestedNameSpecifier = true;

334 } else if (const auto *Record = dyn_cast(ND)) {

335 if (Record->isUnion())

337 else

339

340 if (LangOpts.CPlusPlus)

341 IsNestedNameSpecifier = true;

342 } else if (isa(ND))

343 IsNestedNameSpecifier = true;

344 } else if (isa(ND) || isa(ND)) {

345

350 } else if (isa(ND)) {

352 } else if (isa(ND)) {

354 } else if (isa(ND) || isa(ND)) {

356

357

358 IsNestedNameSpecifier = true;

359 }

360

361 return Contexts;

362}

363

364void ASTUnit::CacheCodeCompletionResults() {

365 if (!TheSema)

366 return;

367

368 SimpleTimer Timer(WantTiming);

369 Timer.setOutput("Cache global code completions for " + getMainFileName());

370

371

372 ClearCachedCompletionResults();

373

374

377 CachedCompletionAllocator = std::make_shared();

379 TheSema->CodeCompletion().GatherGlobalCodeCompletions(

380 *CachedCompletionAllocator, CCTUInfo, Results);

381

382

383 llvm::DenseMap<CanQualType, unsigned> CompletionTypes;

385

386 for (auto &R : Results) {

387 switch (R.Kind) {

388 case Result::RK_Declaration: {

389 bool IsNestedNameSpecifier = false;

390 CachedCodeCompletionResult CachedResult;

391 CachedResult.Completion = R.CreateCodeCompletionString(

392 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,

393 IncludeBriefCommentsInCodeCompletion);

395 R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier);

396 CachedResult.Priority = R.Priority;

397 CachedResult.Kind = R.CursorKind;

398 CachedResult.Availability = R.Availability;

399

400

401

403 if (UsageType.isNull()) {

404 CachedResult.TypeClass = STC_Void;

405 CachedResult.Type = 0;

406 } else {

410

411

412

413

414 unsigned &TypeValue = CompletionTypes[CanUsageType];

415 if (TypeValue == 0) {

416 TypeValue = CompletionTypes.size();

418 = TypeValue;

419 }

420

421 CachedResult.Type = TypeValue;

422 }

423

424 CachedCompletionResults.push_back(CachedResult);

425

426

427 if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&

428 !R.StartsNestedNameSpecifier) {

429

443

444 if (isa(R.Declaration) ||

445 isa(R.Declaration))

447

448 if (uint64_t RemainingContexts

449 = NNSContexts & ~CachedResult.ShowInContexts) {

450

451

452

453 R.StartsNestedNameSpecifier = true;

454 CachedResult.Completion = R.CreateCodeCompletionString(

455 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,

456 IncludeBriefCommentsInCodeCompletion);

457 CachedResult.ShowInContexts = RemainingContexts;

459 CachedResult.TypeClass = STC_Void;

460 CachedResult.Type = 0;

461 CachedCompletionResults.push_back(CachedResult);

462 }

463 }

464 break;

465 }

466

467 case Result::RK_Keyword:

468 case Result::RK_Pattern:

469

470

471 break;

472

473 case Result::RK_Macro: {

474 CachedCodeCompletionResult CachedResult;

475 CachedResult.Completion = R.CreateCodeCompletionString(

476 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,

477 IncludeBriefCommentsInCodeCompletion);

478 CachedResult.ShowInContexts

491

492 CachedResult.Priority = R.Priority;

493 CachedResult.Kind = R.CursorKind;

494 CachedResult.Availability = R.Availability;

495 CachedResult.TypeClass = STC_Void;

496 CachedResult.Type = 0;

497 CachedCompletionResults.push_back(CachedResult);

498 break;

499 }

500 }

501 }

502

503

504 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;

505}

506

507void ASTUnit::ClearCachedCompletionResults() {

508 CachedCompletionResults.clear();

509 CachedCompletionTypes.clear();

510 CachedCompletionAllocator = nullptr;

511}

512

513namespace {

514

515

516

523 std::shared_ptr &TargetOpts;

525 unsigned &Counter;

526 bool InitializedLanguage = false;

527 bool InitializedHeaderSearchPaths = false;

528

529public:

533 std::shared_ptr &TargetOpts,

535 : PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),

536 LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target),

537 Counter(Counter) {}

538

539 bool ReadLanguageOptions(const LangOptions &LangOpts,

540 StringRef ModuleFilename, bool Complain,

541 bool AllowCompatibleDifferences) override {

542 if (InitializedLanguage)

543 return false;

544

545

546

547

548 auto PICLevel = LangOpt.PICLevel;

549 auto PIE = LangOpt.PIE;

550

551 LangOpt = LangOpts;

552

553 LangOpt.PICLevel = PICLevel;

554 LangOpt.PIE = PIE;

555

556 InitializedLanguage = true;

557

558 updated();

559 return false;

560 }

561

563 StringRef ModuleFilename,

564 StringRef SpecificModuleCachePath,

565 bool Complain) override {

566

567 auto ForceCheckCXX20ModulesInputFiles =

572

573 this->HSOpts = HSOpts;

575 ForceCheckCXX20ModulesInputFiles;

576

577 return false;

578 }

579

581 bool Complain) override {

582 if (InitializedHeaderSearchPaths)

583 return false;

584

588

589

590

591

595

596 InitializedHeaderSearchPaths = true;

597

598 return false;

599 }

600

602 StringRef ModuleFilename, bool ReadMacros,

603 bool Complain,

604 std::string &SuggestedPredefines) override {

605 this->PPOpts = PPOpts;

606 return false;

607 }

608

609 bool ReadTargetOptions(const TargetOptions &TargetOpts,

610 StringRef ModuleFilename, bool Complain,

611 bool AllowCompatibleDifferences) override {

612

614 return false;

615

616 this->TargetOpts = std::make_shared(TargetOpts);

619

620 updated();

621 return false;

622 }

623

625 unsigned Value) override {

627 }

628

629private:

630 void updated() {

631 if (Target || !InitializedLanguage)

632 return;

633

634

635

636

637

639

640

642

643 if (!Context)

644 return;

645

646

648

649

651

652

653

656 }

657};

658

659

663 bool CaptureNonErrorsFromIncludes = true;

666

667public:

668 FilterAndStoreDiagnosticConsumer(

671 bool CaptureNonErrorsFromIncludes)

672 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),

673 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {

674 assert((StoredDiags || StandaloneDiags) &&

675 "No output collections were passed to StoredDiagnosticConsumer.");

676 }

677

678 void BeginSourceFile(const LangOptions &LangOpts,

680 this->LangOpts = &LangOpts;

681 if (PP)

683 }

684

687};

688

689

690

691class CaptureDroppedDiagnostics {

693 FilterAndStoreDiagnosticConsumer Client;

695 std::unique_ptr OwningPreviousClient;

696

697public:

698 CaptureDroppedDiagnostics(

702 : Diags(Diags),

703 Client(StoredDiags, StandaloneDiags,

704 CaptureDiagnostics !=

706 if (CaptureDiagnostics != CaptureDiagsKind::None ||

708 OwningPreviousClient = Diags.takeClient();

709 PreviousClient = Diags.getClient();

711 }

712 }

713

714 ~CaptureDroppedDiagnostics() {

715 if (Diags.getClient() == &Client)

716 Diags.setClient(PreviousClient, !!OwningPreviousClient.release());

717 }

718};

719

720}

721

725

728 return false;

729

730 auto &M = D.getSourceManager();

731 return M.isWrittenInMainFile(M.getExpansionLoc(D.getLocation()));

732}

733

734void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(

736

738

739

740

741

745 return;

746 }

747

749 if (StoredDiags) {

750 StoredDiags->emplace_back(Level, Info);

751 ResultDiag = &StoredDiags->back();

752 }

753

754 if (StandaloneDiags) {

755 std::optional StoredDiag;

756 if (!ResultDiag) {

757 StoredDiag.emplace(Level, Info);

758 ResultDiag = &*StoredDiag;

759 }

760 StandaloneDiags->push_back(

762 }

763 }

764}

765

767 return Reader;

768}

769

771 if (WriterData)

772 return &WriterData->Writer;

773 return nullptr;

774}

775

777 if (WriterData)

778 return &WriterData->Writer;

779 return nullptr;

780}

781

782std::unique_ptrllvm::MemoryBuffer

784 assert(FileMgr);

785 auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);

786 if (Buffer)

787 return std::move(*Buffer);

788 if (ErrorStr)

789 *ErrorStr = Buffer.getError().message();

790 return nullptr;

791}

792

793

797 assert(Diags.get() && "no DiagnosticsEngine was provided");

799 Diags->setClient(new FilterAndStoreDiagnosticConsumer(

800 &AST.StoredDiagnostics, nullptr,

802}

803

808 std::shared_ptr HSOpts,

809 std::shared_ptr LangOpts, bool OnlyLocalDecls,

810 CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,

812 std::unique_ptr AST(new ASTUnit(true));

813

814

815 llvm::CrashRecoveryContextCleanupRegistrar

816 ASTUnitCleanup(AST.get());

818 llvm::CrashRecoveryContextReleaseRefCleanup>

819 DiagCleanup(Diags.get());

820

821 ConfigureDiags(Diags, *AST, CaptureDiagnostics);

822

823 AST->LangOpts = LangOpts ? LangOpts : std::make_shared();

824 AST->OnlyLocalDecls = OnlyLocalDecls;

825 AST->CaptureDiagnostics = CaptureDiagnostics;

826 AST->Diagnostics = Diags;

827 AST->FileMgr = new FileManager(FileSystemOpts, VFS);

828 AST->UserFilesAreVolatile = UserFilesAreVolatile;

829 AST->SourceMgr = new SourceManager(AST->getDiagnostics(),

830 AST->getFileManager(),

831 UserFilesAreVolatile);

833 AST->HSOpts = HSOpts ? HSOpts : std::make_shared();

834 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());

835 AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,

836 AST->getSourceManager(),

837 AST->getDiagnostics(),

838 AST->getLangOpts(),

839 nullptr));

840 AST->PPOpts = std::make_shared();

841

842

843

845

846 AST->PP = std::make_shared(

847 AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,

848 AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,

849 nullptr,

850 false);

852

854 AST->Ctx = new ASTContext(*AST->LangOpts, AST->getSourceManager(),

857 AST->getTranslationUnitKind());

858

861 if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))

864 PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},

865 "",

866 disableValid, AllowASTWithCompilerErrors);

867

868 unsigned Counter = 0;

869 AST->Reader->setListener(std::make_unique(

870 *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,

871 AST->TargetOpts, AST->Target, Counter));

872

873

874

875

876

877

878 if (AST->Ctx)

879 AST->Ctx->setExternalSource(AST->Reader);

880

884 break;

885

892 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);

893 return nullptr;

894 }

895

896 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());

897

899

900 Module *M = HeaderInfo.lookupModule(AST->getLangOpts().CurrentModule);

901 if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule())

902 AST->Ctx->setCurrentNamedModule(M);

903

904

907

908

910 AST->TheSema.reset(new Sema(PP, *AST->Ctx, *AST->Consumer));

911 AST->TheSema->Initialize();

912 AST->Reader->InitializeSema(*AST->TheSema);

913 }

914

915

916 AST->getDiagnostics().getClient()->BeginSourceFile(PP.getLangOpts(), &PP);

917

918 return AST;

919}

920

921

924}

925

926namespace {

927

928

929

930class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {

931 unsigned &Hash;

932

933public:

934 explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}

935

936 void MacroDefined(const Token &MacroNameTok,

939 }

940};

941

942}

943

944

946 if (D)

947 return;

948

950 if (!DC)

951 return;

952

954 return;

955

956 if (const auto *ND = dyn_cast(D)) {

957 if (const auto *EnumD = dyn_cast(D)) {

958

959

960 if (!EnumD->isScoped()) {

961 for (const auto *EI : EnumD->enumerators()) {

962 if (EI->getIdentifier())

963 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);

964 }

965 }

966 }

967

968 if (ND->getIdentifier())

969 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);

971 std::string NameStr = Name.getAsString();

972 Hash = llvm::djbHash(NameStr, Hash);

973 }

974 return;

975 }

976

977 if (const auto *ImportD = dyn_cast(D)) {

978 if (const Module *Mod = ImportD->getImportedModule()) {

979 std::string ModName = Mod->getFullModuleName();

980 Hash = llvm::djbHash(ModName, Hash);

981 }

982 return;

983 }

984}

985

986namespace {

987

988class TopLevelDeclTrackerConsumer : public ASTConsumer {

990 unsigned &Hash;

991

992public:

993 TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)

994 : Unit(_Unit), Hash(Hash) {

995 Hash = 0;

996 }

997

998 void handleTopLevelDecl(Decl *D) {

999 if (D)

1000 return;

1001

1002

1003

1004

1005

1006 if (isa(D))

1007 return;

1008

1011

1012 handleFileLevelDecl(D);

1013 }

1014

1015 void handleFileLevelDecl(Decl *D) {

1017 if (auto *NSD = dyn_cast(D)) {

1018 for (auto *I : NSD->decls())

1019 handleFileLevelDecl(I);

1020 }

1021 }

1022

1023 bool HandleTopLevelDecl(DeclGroupRef D) override {

1024 for (auto *TopLevelDecl : D)

1025 handleTopLevelDecl(TopLevelDecl);

1026 return true;

1027 }

1028

1029

1030 void HandleInterestingDecl(DeclGroupRef) override {}

1031

1032 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {

1033 for (auto *TopLevelDecl : D)

1034 handleTopLevelDecl(TopLevelDecl);

1035 }

1036

1039 }

1040

1043 }

1044};

1045

1047public:

1049

1050 std::unique_ptr CreateASTConsumer(CompilerInstance &CI,

1051 StringRef InFile) override {

1053 std::make_unique(

1055 return std::make_unique(

1057 }

1058

1059public:

1060 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}

1061

1062 bool hasCodeCompletionSupport() const override { return false; }

1063

1066 }

1067};

1068

1070public:

1071 unsigned getHash() const { return Hash; }

1072

1073 std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }

1074

1075 std::vector takeTopLevelDeclIDs() {

1076 return std::move(TopLevelDeclIDs);

1077 }

1078

1079 void AfterPCHEmitted(ASTWriter &Writer) override {

1080 TopLevelDeclIDs.reserve(TopLevelDecls.size());

1081 for (const auto *D : TopLevelDecls) {

1082

1084 continue;

1085 TopLevelDeclIDs.push_back(Writer.getDeclID(D));

1086 }

1087 }

1088

1089 void HandleTopLevelDecl(DeclGroupRef DG) override {

1090 for (auto *D : DG) {

1091

1092

1093

1094

1095 if (isa(D))

1096 continue;

1098 TopLevelDecls.push_back(D);

1099 }

1100 }

1101

1102 std::unique_ptr createPPCallbacks() override {

1103 return std::make_unique(Hash);

1104 }

1105

1106private:

1107 unsigned Hash = 0;

1108 std::vector<Decl *> TopLevelDecls;

1109 std::vector TopLevelDeclIDs;

1111};

1112

1113}

1114

1117}

1118

1119static void

1121

1122

1124}

1125

1127 StoredDiagnostics,

1129

1130

1131

1132

1133

1134 for (auto &SD : StoredDiagnostics) {

1135 if (SD.getLocation().isValid()) {

1137 SD.setLocation(Loc);

1138 }

1139 }

1140}

1141

1142

1143

1144

1145

1146

1147bool ASTUnit::Parse(std::shared_ptr PCHContainerOps,

1148 std::unique_ptrllvm::MemoryBuffer OverrideMainBuffer,

1150 if (!Invocation)

1151 return true;

1152

1153 if (VFS && FileMgr)

1154 assert(VFS == &FileMgr->getVirtualFileSystem() &&

1155 "VFS passed to Parse and VFS in FileMgr are different");

1156

1157 auto CCInvocation = std::make_shared(*Invocation);

1158 if (OverrideMainBuffer) {

1159 assert(Preamble &&

1160 "No preamble was built, but OverrideMainBuffer is not null");

1161 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());

1162

1163 }

1164

1165

1166 std::unique_ptr Clang(

1168 Clang->setInvocation(CCInvocation);

1169

1170

1171 auto CleanOnError = llvm::make_scope_exit([&]() {

1172

1173 SavedMainFileBuffer = nullptr;

1174

1175

1176

1177 transferASTDataFromCompilerInstance(*Clang);

1178 FailedParseDiagnostics.swap(StoredDiagnostics);

1179 StoredDiagnostics.clear();

1180 NumStoredDiagnosticsFromDriver = 0;

1181 });

1182

1183

1184

1185

1186 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS)

1187 Clang->setFileManager(&*FileMgr);

1188 else

1189 FileMgr = Clang->createFileManager(std::move(VFS));

1190

1191

1192 llvm::CrashRecoveryContextCleanupRegistrar

1193 CICleanup(Clang.get());

1194

1195 OriginalSourceFile =

1196 std::string(Clang->getFrontendOpts().Inputs[0].getFile());

1197

1198

1199

1201

1202

1203 if (!Clang->createTarget())

1204 return true;

1205

1206 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&

1207 "Invocation must have exactly one source file!");

1208 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==

1210 "FIXME: AST inputs not yet supported here!");

1211 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=

1213 "IR inputs not support here!");

1214

1215

1216 LangOpts = Clang->getInvocation().LangOpts;

1217 FileSystemOpts = Clang->getFileSystemOpts();

1218

1220

1222 UserFilesAreVolatile);

1223 if (!OverrideMainBuffer) {

1225 TopLevelDeclsInPreamble.clear();

1226 }

1227

1228

1230

1231

1232

1233 if (OverrideMainBuffer) {

1234

1235

1236

1237

1238

1240

1241

1242 SavedMainFileBuffer = std::move(OverrideMainBuffer);

1243 }

1244

1245 std::unique_ptr Act(

1246 new TopLevelDeclTrackerAction(*this));

1247

1248

1249 llvm::CrashRecoveryContextCleanupRegistrar

1250 ActCleanup(Act.get());

1251

1252 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))

1253 return true;

1254

1255 if (SavedMainFileBuffer)

1257 PreambleDiagnostics, StoredDiagnostics);

1258 else

1259 PreambleSrcLocCache.clear();

1260

1261 if (llvm::Error Err = Act->Execute()) {

1262 consumeError(std::move(Err));

1263 return true;

1264 }

1265

1266 transferASTDataFromCompilerInstance(*Clang);

1267

1268 Act->EndSourceFile();

1269

1270 FailedParseDiagnostics.clear();

1271

1272 CleanOnError.release();

1273

1274 return false;

1275}

1276

1277static std::pair<unsigned, unsigned>

1281 unsigned Offset = SM.getFileOffset(FileRange.getBegin());

1282 unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());

1283 return std::make_pair(Offset, EndOffset);

1284}

1285

1292 LangOpts);

1295 return OutFix;

1296}

1297

1302 OutDiag.ID = InDiag.getID();

1307 return OutDiag;

1310 OutDiag.Filename = std::string(SM.getFilename(FileLoc));

1311 if (OutDiag.Filename.empty())

1312 return OutDiag;

1313 OutDiag.LocOffset = SM.getFileOffset(FileLoc);

1316 for (const auto &FixIt : InDiag.getFixIts())

1318

1319 return OutDiag;

1320}

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332

1333

1334

1335

1336

1337

1338

1339

1340

1341

1342std::unique_ptrllvm::MemoryBuffer

1343ASTUnit::getMainBufferWithPrecompiledPreamble(

1344 std::shared_ptr PCHContainerOps,

1347 unsigned MaxLines) {

1348 auto MainFilePath =

1350 std::unique_ptrllvm::MemoryBuffer MainFileBuffer =

1352 MainFilePath, UserFilesAreVolatile);

1353 if (!MainFileBuffer)

1354 return nullptr;

1355

1357 PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);

1358 if (!Bounds.Size)

1359 return nullptr;

1360

1361 if (Preamble) {

1362 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,

1363 *VFS)) {

1364

1365

1366

1367

1372

1373 PreambleRebuildCountdown = 1;

1374 return MainFileBuffer;

1375 } else {

1376 Preamble.reset();

1377 PreambleDiagnostics.clear();

1378 TopLevelDeclsInPreamble.clear();

1379 PreambleSrcLocCache.clear();

1380 PreambleRebuildCountdown = 1;

1381 }

1382 }

1383

1384

1385

1386

1387 if (PreambleRebuildCountdown > 1) {

1388 --PreambleRebuildCountdown;

1389 return nullptr;

1390 }

1391

1392 assert(!Preamble && "No Preamble should be stored at that point");

1393

1394

1395 if (!AllowRebuild)

1396 return nullptr;

1397

1398 ++PreambleCounter;

1399

1402 ASTUnitPreambleCallbacks Callbacks;

1403 {

1404 std::optional Capture;

1406 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,

1407 &NewPreambleDiagsStandalone);

1408

1409

1410 SimpleTimer PreambleTimer(WantTiming);

1411 PreambleTimer.setOutput("Precompiling preamble");

1412

1413 const bool PreviousSkipFunctionBodies =

1417

1419 PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,

1420 PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,

1421 Callbacks);

1422

1424 PreviousSkipFunctionBodies;

1425

1426 if (NewPreamble) {

1427 Preamble = std::move(*NewPreamble);

1428 PreambleRebuildCountdown = 1;

1429 } else {

1430 switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {

1432

1433 PreambleRebuildCountdown = 1;

1434 return nullptr;

1439

1441 return nullptr;

1442 }

1443 llvm_unreachable("unexpected BuildPreambleError");

1444 }

1445 }

1446

1447 assert(Preamble && "Preamble wasn't built");

1448

1449 TopLevelDecls.clear();

1450 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();

1451 PreambleTopLevelHashValue = Callbacks.getHash();

1452

1454

1456 StoredDiagnostics = std::move(NewPreambleDiags);

1457 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);

1458

1459

1460

1461

1462 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {

1463 CompletionCacheTopLevelHashValue = 0;

1464 PreambleTopLevelHashValue = CurrentTopLevelHashValue;

1465 }

1466

1467 return MainFileBuffer;

1468}

1469

1470void ASTUnit::RealizeTopLevelDeclsFromPreamble() {

1471 assert(Preamble && "Should only be called when preamble was built");

1472

1473 std::vector<Decl *> Resolved;

1474 Resolved.reserve(TopLevelDeclsInPreamble.size());

1475

1477 for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {

1478

1479

1480 if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))

1481 Resolved.push_back(D);

1482 }

1483 TopLevelDeclsInPreamble.clear();

1484 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());

1485}

1486

1487void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {

1488

1489

1490 assert(CI.hasInvocation() && "missing invocation");

1504}

1505

1507 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {

1508 const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];

1511 else

1512 return Input.getBuffer().getBufferIdentifier();

1513 }

1514

1515 if (SourceMgr) {

1518 return FE->getName();

1519 }

1520

1521 return {};

1522}

1523

1526 return {};

1527

1529 Mod = Reader->getModuleManager().getPrimaryModule();

1531}

1532

1533std::unique_ptr

1537 bool UserFilesAreVolatile) {

1538 std::unique_ptr AST(new ASTUnit(false));

1539 ConfigureDiags(Diags, *AST, CaptureDiagnostics);

1542 AST->Diagnostics = Diags;

1543 AST->FileSystemOpts = CI->getFileSystemOpts();

1544 AST->Invocation = std::move(CI);

1545 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);

1546 AST->UserFilesAreVolatile = UserFilesAreVolatile;

1547 AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,

1548 UserFilesAreVolatile);

1550

1551 return AST;

1552}

1553

1555 std::shared_ptr CI,

1556 std::shared_ptr PCHContainerOps,

1558 ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,

1560 unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,

1561 bool UserFilesAreVolatile, std::unique_ptr *ErrAST) {

1562 assert(CI && "A CompilerInvocation is required");

1563

1564 std::unique_ptr OwnAST;

1566 if (!AST) {

1567

1568 OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);

1569 AST = OwnAST.get();

1570 if (!AST)

1571 return nullptr;

1572 }

1573

1574 if (!ResourceFilesPath.empty()) {

1575

1577 }

1578 AST->OnlyLocalDecls = OnlyLocalDecls;

1579 AST->CaptureDiagnostics = CaptureDiagnostics;

1580 if (PrecompilePreambleAfterNParses > 0)

1581 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;

1583 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;

1584 AST->IncludeBriefCommentsInCodeCompletion = false;

1585

1586

1587 llvm::CrashRecoveryContextCleanupRegistrar

1588 ASTUnitCleanup(OwnAST.get());

1590 llvm::CrashRecoveryContextReleaseRefCleanup>

1591 DiagCleanup(Diags.get());

1592

1593

1594 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;

1595 CI->getFrontendOpts().DisableFree = false;

1598

1599

1600 std::unique_ptr Clang(

1602

1603

1604 llvm::CrashRecoveryContextCleanupRegistrar

1605 CICleanup(Clang.get());

1606

1607 Clang->setInvocation(std::move(CI));

1608 AST->OriginalSourceFile =

1609 std::string(Clang->getFrontendOpts().Inputs[0].getFile());

1610

1611

1612

1614

1615

1616 if (!Clang->createTarget())

1617 return nullptr;

1618

1619 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&

1620 "Invocation must have exactly one source file!");

1621 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==

1623 "FIXME: AST inputs not yet supported here!");

1624 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=

1626 "IR inputs not support here!");

1627

1628

1629 AST->TheSema.reset();

1630 AST->Ctx = nullptr;

1631 AST->PP = nullptr;

1632 AST->Reader = nullptr;

1633

1634

1636

1637

1639

1641

1642 std::unique_ptr TrackerAct;

1643 if (!Act) {

1644 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));

1645 Act = TrackerAct.get();

1646 }

1647

1648

1649 llvm::CrashRecoveryContextCleanupRegistrar

1650 ActCleanup(TrackerAct.get());

1651

1652 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {

1653 AST->transferASTDataFromCompilerInstance(*Clang);

1654 if (OwnAST && ErrAST)

1655 ErrAST->swap(OwnAST);

1656

1657 return nullptr;

1658 }

1659

1660 if (Persistent && !TrackerAct) {

1661 Clang->getPreprocessor().addPPCallbacks(

1662 std::make_unique(

1664 std::vector<std::unique_ptr> Consumers;

1665 if (Clang->hasASTConsumer())

1666 Consumers.push_back(Clang->takeASTConsumer());

1667 Consumers.push_back(std::make_unique(

1669 Clang->setASTConsumer(

1670 std::make_unique(std::move(Consumers)));

1671 }

1672 if (llvm::Error Err = Act->Execute()) {

1673 consumeError(std::move(Err));

1674 AST->transferASTDataFromCompilerInstance(*Clang);

1675 if (OwnAST && ErrAST)

1676 ErrAST->swap(OwnAST);

1677

1678 return nullptr;

1679 }

1680

1681

1682 AST->transferASTDataFromCompilerInstance(*Clang);

1683

1685

1686 if (OwnAST)

1687 return OwnAST.release();

1688 else

1689 return AST;

1690}

1691

1692bool ASTUnit::LoadFromCompilerInvocation(

1693 std::shared_ptr PCHContainerOps,

1694 unsigned PrecompilePreambleAfterNParses,

1696 if (!Invocation)

1697 return true;

1698

1699 assert(VFS && "VFS is null");

1700

1701

1702 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;

1703 Invocation->getFrontendOpts().DisableFree = false;

1706 *VFS);

1707

1708 std::unique_ptrllvm::MemoryBuffer OverrideMainBuffer;

1709 if (PrecompilePreambleAfterNParses > 0) {

1710 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;

1711 OverrideMainBuffer =

1712 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);

1715 *VFS);

1716 }

1717

1718 SimpleTimer ParsingTimer(WantTiming);

1720

1721

1722 llvm::CrashRecoveryContextCleanupRegistrarllvm::MemoryBuffer

1723 MemBufferCleanup(OverrideMainBuffer.get());

1724

1725 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);

1726}

1727

1728std::unique_ptr ASTUnit::LoadFromCompilerInvocation(

1729 std::shared_ptr CI,

1730 std::shared_ptr PCHContainerOps,

1734 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,

1735 bool UserFilesAreVolatile) {

1736

1737 std::unique_ptr AST(new ASTUnit(false));

1738 ConfigureDiags(Diags, *AST, CaptureDiagnostics);

1739 AST->Diagnostics = Diags;

1740 AST->OnlyLocalDecls = OnlyLocalDecls;

1741 AST->CaptureDiagnostics = CaptureDiagnostics;

1742 AST->TUKind = TUKind;

1743 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;

1744 AST->IncludeBriefCommentsInCodeCompletion

1745 = IncludeBriefCommentsInCodeCompletion;

1746 AST->Invocation = std::move(CI);

1748 AST->FileMgr = FileMgr;

1749 AST->UserFilesAreVolatile = UserFilesAreVolatile;

1750

1751

1752 llvm::CrashRecoveryContextCleanupRegistrar

1753 ASTUnitCleanup(AST.get());

1755 llvm::CrashRecoveryContextReleaseRefCleanup>

1756 DiagCleanup(Diags.get());

1757

1758 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),

1759 PrecompilePreambleAfterNParses,

1760 &AST->FileMgr->getVirtualFileSystem()))

1761 return nullptr;

1762 return AST;

1763}

1764

1766 const char **ArgBegin, const char **ArgEnd,

1767 std::shared_ptr PCHContainerOps,

1769 bool StorePreamblesInMemory, StringRef PreambleStoragePath,

1773 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,

1775 bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,

1776 bool RetainExcludedConditionalBlocks, std::optional ModuleFormat,

1777 std::unique_ptr *ErrAST,

1779 assert(Diags.get() && "no DiagnosticsEngine was provided");

1780

1781

1782

1783

1784 if (!VFS)

1785 VFS = llvm::vfs::createPhysicalFileSystem();

1786

1788

1789 std::shared_ptr CI;

1790

1791 {

1792 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,

1793 &StoredDiagnostics, nullptr);

1794

1796 CIOpts.VFS = VFS;

1797 CIOpts.Diags = Diags;

1798 CIOpts.ProbePrecompiled = true;

1800 if (!CI)

1801 return nullptr;

1802 }

1803

1804

1805 for (const auto &RemappedFile : RemappedFiles) {

1806 CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,

1808 }

1814

1815

1816 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);

1817

1818 CI->getFrontendOpts().SkipFunctionBodies =

1820

1821 if (ModuleFormat)

1822 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);

1823

1824

1825 std::unique_ptr AST;

1826 AST.reset(new ASTUnit(false));

1827 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();

1828 AST->StoredDiagnostics.swap(StoredDiagnostics);

1829 ConfigureDiags(Diags, *AST, CaptureDiagnostics);

1830 AST->Diagnostics = Diags;

1831 AST->FileSystemOpts = CI->getFileSystemOpts();

1833 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);

1834 AST->StorePreamblesInMemory = StorePreamblesInMemory;

1835 AST->PreambleStoragePath = PreambleStoragePath;

1837 AST->OnlyLocalDecls = OnlyLocalDecls;

1838 AST->CaptureDiagnostics = CaptureDiagnostics;

1839 AST->TUKind = TUKind;

1840 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;

1841 AST->IncludeBriefCommentsInCodeCompletion

1842 = IncludeBriefCommentsInCodeCompletion;

1843 AST->UserFilesAreVolatile = UserFilesAreVolatile;

1844 AST->Invocation = CI;

1845 AST->SkipFunctionBodies = SkipFunctionBodies;

1846 if (ForSerialization)

1847 AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));

1848

1849 CI = nullptr;

1850 Diags = nullptr;

1851

1852

1853 llvm::CrashRecoveryContextCleanupRegistrar

1854 ASTUnitCleanup(AST.get());

1855

1856 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),

1857 PrecompilePreambleAfterNParses,

1858 VFS)) {

1859

1860

1861 if (ErrAST) {

1862 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);

1863 ErrAST->swap(AST);

1864 }

1865 return nullptr;

1866 }

1867

1868 return AST;

1869}

1870

1871bool ASTUnit::Reparse(std::shared_ptr PCHContainerOps,

1874 if (!Invocation)

1875 return true;

1876

1877 if (!VFS) {

1878 assert(FileMgr && "FileMgr is null on Reparse call");

1879 VFS = &FileMgr->getVirtualFileSystem();

1880 }

1881

1882 clearFileLevelDecls();

1883

1884 SimpleTimer ParsingTimer(WantTiming);

1885 ParsingTimer.setOutput("Reparsing " + getMainFileName());

1886

1887

1890 delete RB.second;

1891

1892 Invocation->getPreprocessorOpts().clearRemappedFiles();

1893 for (const auto &RemappedFile : RemappedFiles) {

1894 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,

1896 }

1897

1898

1899

1900 std::unique_ptrllvm::MemoryBuffer OverrideMainBuffer;

1901 if (Preamble || PreambleRebuildCountdown > 0)

1902 OverrideMainBuffer =

1903 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);

1904

1905

1906 FileMgr.reset();

1909 *VFS);

1910 if (OverrideMainBuffer)

1912

1913

1915 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);

1916

1917

1918

1919 if (Result && ShouldCacheCodeCompletionResults &&

1920 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)

1921 CacheCodeCompletionResults();

1922

1923

1924

1925 CCTUInfo.reset();

1926

1928}

1929

1931 SavedMainFileBuffer.reset();

1932

1933 SourceMgr.reset();

1934 TheSema.reset();

1935 Ctx.reset();

1936 PP.reset();

1937 Reader.reset();

1938

1939 TopLevelDecls.clear();

1940 clearFileLevelDecls();

1941}

1942

1943

1944

1945

1946

1947namespace {

1948

1949

1950

1951

1953 uint64_t NormalContexts;

1956

1957 public:

1961

1962

1963 NormalContexts

1977

1982 }

1983

1986 unsigned NumResults) override;

1987

1988 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,

1990 unsigned NumCandidates,

1992 bool Braced) override {

1993 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,

1994 OpenParLoc, Braced);

1995 }

1996

1998 return Next.getAllocator();

1999 }

2000

2002 return Next.getCodeCompletionTUInfo();

2003 }

2004 };

2005

2006}

2007

2008

2009

2012 unsigned NumResults,

2014 llvm::StringSetllvm::BumpPtrAllocator &HiddenNames){

2015 bool OnlyTagNames = false;

2016 switch (Context.getKind()) {

2036 break;

2037

2041 OnlyTagNames = true;

2042 break;

2043

2061

2062

2063 return;

2064 }

2065

2067 for (unsigned I = 0; I != NumResults; ++I) {

2068 if (Results[I].Kind != Result::RK_Declaration)

2069 continue;

2070

2071 unsigned IDNS

2072 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();

2073

2074 bool Hiding = false;

2075 if (OnlyTagNames)

2077 else {

2083 Hiding = (IDNS & HiddenIDNS);

2084 }

2085

2086 if (!Hiding)

2087 continue;

2088

2089 DeclarationName Name = Results[I].Declaration->getDeclName();

2091 HiddenNames.insert(Identifier->getName());

2092 else

2093 HiddenNames.insert(Name.getAsString());

2094 }

2095}

2096

2097void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,

2100 unsigned NumResults) {

2101

2102 bool AddedResult = false;

2105 ? NormalContexts : (1LL << Context.getKind());

2106

2107 llvm::StringSetllvm::BumpPtrAllocator HiddenNames;

2113 C != CEnd; ++C) {

2114

2115

2116 if ((C->ShowInContexts & InContexts) == 0)

2117 continue;

2118

2119

2120 if (!AddedResult) {

2122 HiddenNames);

2123 AllResults.insert(AllResults.end(), Results, Results + NumResults);

2124 AddedResult = true;

2125 }

2126

2127

2128

2130 HiddenNames.count(C->Completion->getTypedText()))

2131 continue;

2132

2133

2134 unsigned Priority = C->Priority;

2136 if (!Context.getPreferredType().isNull()) {

2140 Context.getPreferredType()->isAnyPointerType());

2141 } else if (C->Type) {

2144 Context.getPreferredType().getUnqualifiedType());

2146 if (ExpectedSTC == C->TypeClass) {

2147

2148 llvm::StringMap &CachedCompletionTypes

2150 llvm::StringMap::iterator Pos

2152 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)

2154 else

2156 }

2157 }

2158 }

2159

2160

2163

2164

2167 Builder.AddTypedTextChunk(C->Completion->getTypedText());

2169 Completion = Builder.TakeString();

2170 }

2171

2172 AllResults.push_back(Result(Completion, Priority, C->Kind,

2173 C->Availability));

2174 }

2175

2176

2177

2178 if (!AddedResult) {

2179 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);

2180 return;

2181 }

2182

2183 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),

2184 AllResults.size());

2185}

2186

2190 bool IncludeCodePatterns, bool IncludeBriefComments,

2192 std::shared_ptr PCHContainerOps,

2196 std::unique_ptr Act) {

2197 if (!Invocation)

2198 return;

2199

2200 SimpleTimer CompletionTimer(WantTiming);

2201 CompletionTimer.setOutput("Code completion @ " + File + ":" +

2203

2204 auto CCInvocation = std::make_shared(*Invocation);

2205

2206 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();

2208 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();

2209

2210 CodeCompleteOpts.IncludeMacros = IncludeMacros &&

2211 CachedCompletionResults.empty();

2213 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();

2217

2218 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);

2219

2223

2224

2225 LangOpts = CCInvocation->getLangOpts();

2226

2227

2228 LangOpts.SpellChecking = false;

2229 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;

2230

2231 std::unique_ptr Clang(

2233

2234

2235 llvm::CrashRecoveryContextCleanupRegistrar

2236 CICleanup(Clang.get());

2237

2238 auto &Inv = *CCInvocation;

2239 Clang->setInvocation(std::move(CCInvocation));

2240 OriginalSourceFile =

2241 std::string(Clang->getFrontendOpts().Inputs[0].getFile());

2242

2243

2244 Clang->setDiagnostics(&Diag);

2246 Clang->getDiagnostics(),

2247 &StoredDiagnostics, nullptr);

2250

2251

2252 if (!Clang->createTarget()) {

2253 Clang->setInvocation(nullptr);

2254 return;

2255 }

2256

2257 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&

2258 "Invocation must have exactly one source file!");

2259 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==

2261 "FIXME: AST inputs not yet supported here!");

2262 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=

2264 "IR inputs not support here!");

2265

2266

2267 Clang->setFileManager(&FileMgr);

2268 Clang->setSourceManager(&SourceMgr);

2269

2270

2273 for (const auto &RemappedFile : RemappedFiles) {

2275 OwnedBuffers.push_back(RemappedFile.second);

2276 }

2277

2278

2279

2280 AugmentedCodeCompleteConsumer *AugmentedConsumer

2281 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);

2282 Clang->setCodeCompletionConsumer(AugmentedConsumer);

2283

2284 auto getUniqueID =

2285 [&FileMgr](StringRef Filename) -> std::optionalllvm::sys::fs::UniqueID {

2287 return Status->getUniqueID();

2288 return std::nullopt;

2289 };

2290

2291 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {

2292 if (LHS == RHS)

2293 return true;

2294 if (auto LHSID = getUniqueID(LHS))

2295 if (auto RHSID = getUniqueID(RHS))

2296 return *LHSID == *RHSID;

2297 return false;

2298 };

2299

2300

2301

2302

2303

2304 std::unique_ptrllvm::MemoryBuffer OverrideMainBuffer;

2305 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {

2306 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(

2308 }

2309

2310

2311

2312 if (OverrideMainBuffer) {

2313 assert(Preamble &&

2314 "No preamble was built, but OverrideMainBuffer is not null");

2315

2318 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,

2319 OverrideMainBuffer.get());

2320

2321

2322

2323

2324 OwnedBuffers.push_back(OverrideMainBuffer.release());

2325 } else {

2328 }

2329

2330

2331 if (!Clang->getLangOpts().Modules)

2333

2334 if (!Act)

2336

2337 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {

2338 if (llvm::Error Err = Act->Execute()) {

2339 consumeError(std::move(Err));

2340 }

2341 Act->EndSourceFile();

2342 }

2343}

2344

2346 if (HadModuleLoaderFatalFailure)

2347 return true;

2348

2349

2350

2351

2352 if (llvm::Error Err = llvm::writeToOutput(

2353 File, [this](llvm::raw_ostream &Out) {

2354 return serialize(Out) ? llvm::make_errorllvm::StringError(

2355 "ASTUnit serialization failed",

2356 llvm::inconvertibleErrorCode())

2357 : llvm::Error::success();

2358 })) {

2359 consumeError(std::move(Err));

2360 return true;

2361 }

2362 return false;

2363}

2364

2366 Sema &S, raw_ostream &OS) {

2367 Writer.WriteAST(&S, std::string(), nullptr, "");

2368

2369

2370 if (!Buffer.empty())

2371 OS.write(Buffer.data(), Buffer.size());

2372

2373 return false;

2374}

2375

2377 if (WriterData)

2378 return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);

2379

2381 llvm::BitstreamWriter Stream(Buffer);

2383 ASTWriter Writer(Stream, Buffer, ModuleCache, {});

2385}

2386

2387void ASTUnit::TranslateStoredDiagnostics(

2392

2393

2394

2395

2397 Result.reserve(Diags.size());

2398

2399 for (const auto &SD : Diags) {

2400

2401 if (SD.Filename.empty())

2402 continue;

2404 if (!FE)

2405 continue;

2407 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);

2408 if (ItFileID == PreambleSrcLocCache.end()) {

2411 PreambleSrcLocCache[SD.Filename] = FileLoc;

2412 } else {

2413 FileLoc = ItFileID->getValue();

2414 }

2415

2417 continue;

2420

2422 Ranges.reserve(SD.Ranges.size());

2423 for (const auto &Range : SD.Ranges) {

2427 }

2428

2430 FixIts.reserve(SD.FixIts.size());

2431 for (const auto &FixIt : SD.FixIts) {

2438 }

2439

2441 SD.Message, Loc, Ranges, FixIts));

2442 }

2444}

2445

2447 assert(D);

2448

2449

2451 return;

2452

2456 return;

2457

2458

2460 return;

2461

2463 assert(SM.isLocalSourceLocation(FileLoc));

2465 unsigned Offset;

2466 std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);

2468 return;

2469

2470 std::unique_ptr &Decls = FileDecls[FID];

2471 if (!Decls)

2472 Decls = std::make_unique();

2473

2474 std::pair<unsigned, Decl *> LocDecl(Offset, D);

2475

2476 if (Decls->empty() || Decls->back().first <= Offset) {

2477 Decls->push_back(LocDecl);

2478 return;

2479 }

2480

2481 LocDeclsTy::iterator I =

2482 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());

2483

2484 Decls->insert(I, LocDecl);

2485}

2486

2489 if (File.isInvalid())

2490 return;

2491

2493 assert(Ctx->getExternalSource() && "No external source!");

2494 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,

2495 Decls);

2496 }

2497

2498 FileDeclsTy::iterator I = FileDecls.find(File);

2499 if (I == FileDecls.end())

2500 return;

2501

2503 if (LocDecls.empty())

2504 return;

2505

2506 LocDeclsTy::iterator BeginIt =

2507 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {

2508 return LD.first < Offset;

2509 });

2510 if (BeginIt != LocDecls.begin())

2511 --BeginIt;

2512

2513

2514

2515

2516 while (BeginIt != LocDecls.begin() &&

2517 BeginIt->second->isTopLevelDeclInObjCContainer())

2518 --BeginIt;

2519

2520 LocDeclsTy::iterator EndIt = llvm::upper_bound(

2521 LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),

2522 llvm::less_first());

2523 if (EndIt != LocDecls.end())

2524 ++EndIt;

2525

2526 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)

2527 Decls.push_back(DIt->second);

2528}

2529

2531 unsigned Line, unsigned Col) const {

2534 return SM.getMacroArgExpandedLocation(Loc);

2535}

2536

2538 unsigned Offset) const {

2541 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));

2542}

2543

2544

2545

2546

2549 if (SourceMgr)

2551

2553 return Loc;

2554

2555 unsigned Offs;

2556 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {

2560 }

2561

2562 return Loc;

2563}

2564

2565

2566

2567

2570 if (SourceMgr)

2572

2574 return Loc;

2575

2576 unsigned Offs;

2578 Offs < Preamble->getBounds().Size) {

2581 }

2582

2583 return Loc;

2584}

2585

2588 if (SourceMgr)

2590

2592 return false;

2593

2595}

2596

2599 if (SourceMgr)

2601

2603 return false;

2604

2606}

2607

2610 if (SourceMgr)

2612

2614 return {};

2615

2617}

2618

2621 if (SourceMgr)

2623

2625 return {};

2626

2628}

2629

2630llvm::iterator_rangePreprocessingRecord::iterator

2634 Mod = Reader->getModuleManager().getPrimaryModule();

2635 return Reader->getModulePreprocessedEntities(Mod);

2636 }

2637

2639 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());

2640

2643}

2644

2648 Mod = Reader->getModuleManager().getPrimaryModule();

2649 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {

2650 if (!Fn(context, D))

2651 return false;

2652 }

2653

2654 return true;

2655 }

2656

2659 TL != TLEnd; ++TL) {

2660 if (!Fn(context, *TL))

2661 return false;

2662 }

2663

2664 return true;

2665}

2666

2668 if (!Reader)

2669 return std::nullopt;

2670

2673 switch (M.Kind) {

2674 case serialization::MK_ImplicitModule:

2675 case serialization::MK_ExplicitModule:

2676 case serialization::MK_PrebuiltModule:

2677 return true;

2678 case serialization::MK_PCH:

2679 Mod = &M;

2680 return true;

2681 case serialization::MK_Preamble:

2682 return false;

2683 case serialization::MK_MainFile:

2684 return false;

2685 }

2686

2687 return true;

2688 });

2689 if (Mod)

2690 return Mod->File;

2691

2692 return std::nullopt;

2693}

2694

2697}

2698

2701

2703 if (LangOpts.OpenCL)

2705 else if (LangOpts.CUDA)

2707 else if (LangOpts.CPlusPlus)

2709 else

2711

2715

2716

2717 bool PP = false;

2718

2719 return InputKind(Lang, Fmt, PP);

2720}

2721

2722#ifndef NDEBUG

2723ASTUnit::ConcurrencyState::ConcurrencyState() {

2724 Mutex = new std::recursive_mutex;

2725}

2726

2727ASTUnit::ConcurrencyState::~ConcurrencyState() {

2728 delete static_cast<std::recursive_mutex *>(Mutex);

2729}

2730

2731void ASTUnit::ConcurrencyState::start() {

2732 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();

2733 assert(acquired && "Concurrent access to ASTUnit!");

2734}

2735

2736void ASTUnit::ConcurrencyState::finish() {

2737 static_cast<std::recursive_mutex *>(Mutex)->unlock();

2738}

2739

2740#else

2741

2742ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }

2743ASTUnit::ConcurrencyState::~ConcurrencyState() {}

2744void ASTUnit::ConcurrencyState::start() {}

2745void ASTUnit::ConcurrencyState::finish() {}

2746

2747#endif

Defines the clang::ASTContext interface.

static void checkAndSanitizeDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SourceManager &SM)

static void CalculateHiddenNames(const CodeCompletionContext &Context, CodeCompletionResult *Results, unsigned NumResults, ASTContext &Ctx, llvm::StringSet< llvm::BumpPtrAllocator > &HiddenNames)

Helper function that computes which global names are hidden by the local code-completion results.

static uint64_t getDeclShowContexts(const NamedDecl *ND, const LangOptions &LangOpts, bool &IsNestedNameSpecifier)

Determine the set of code-completion contexts in which this declaration should be shown.

static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash)

Add the given declaration to the hash of all top-level entities.

static bool moveOnNoError(llvm::ErrorOr< T > Val, T &Output)

static std::unique_ptr< T > valueOrNull(llvm::ErrorOr< std::unique_ptr< T > > Val)

static std::pair< unsigned, unsigned > makeStandaloneRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)

static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl< char > &Buffer, Sema &S, raw_ostream &OS)

static std::unique_ptr< llvm::MemoryBuffer > getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation, llvm::vfs::FileSystem *VFS, StringRef FilePath, bool isVolatile)

Get a source buffer for MainFilePath, handling all file-to-file and file-to-buffer remappings inside ...

const unsigned DefaultPreambleRebuildInterval

After failing to build a precompiled preamble (due to errors in the source that occurs in the preambl...

static void checkAndRemoveNonDriverDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiags)

static bool isInMainFile(const clang::Diagnostic &D)

static ASTUnit::StandaloneDiagnostic makeStandaloneDiagnostic(const LangOptions &LangOpts, const StoredDiagnostic &InDiag)

static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag)

static std::atomic< unsigned > ActiveASTUnitObjects

Tracks the number of ASTUnit objects that are currently active.

static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM, const LangOptions &LangOpts, const FixItHint &InFix)

static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash)

Add the given macro to the hash of all top-level entities.

Defines the Diagnostic-related interfaces.

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

Defines the C++ template declaration subclasses.

Defines the clang::FileManager interface and associated types.

Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::Target Target

llvm::MachO::Record Record

Defines the clang::Module class, which describes a module in the source code.

Defines the PPCallbacks interface.

Defines the clang::Preprocessor interface.

This file declares facilities that support code completion.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines the clang::TargetOptions class.

Allows QualTypes to be sorted and hence used in maps and sets.

C Language Family Type Representation.

ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

void InitBuiltinTypes(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)

Initialize built-in types.

CanQualType getCanonicalType(QualType T) const

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

comments::CommandTraits & getCommentCommandTraits() const

const LangOptions & getLangOpts() const

void setPrintingPolicy(const clang::PrintingPolicy &Policy)

Abstract base class to use for AST consumer-based frontend actions.

An abstract interface that should be implemented by listeners that want to be notified when an AST en...

Abstract interface for callback invocations by the ASTReader.

Reads an AST files chain containing the contents of a translation unit.

@ ARR_None

The client can't handle any AST loading failures.

@ Success

The control block was read successfully.

@ ConfigurationMismatch

The AST file was written with a different language/target configuration.

@ OutOfDate

The AST file is out-of-date relative to its input files, and needs to be regenerated.

@ Failure

The AST file itself appears corrupted.

@ VersionMismatch

The AST file was written by a different version of Clang.

@ HadErrors

The AST file has errors.

@ Missing

The AST file was missing.

Utility class for loading a ASTContext from an AST file.

unsigned & getCurrentTopLevelHashValue()

Retrieve a reference to the current top-level name hash value.

void enableSourceFileDiagnostics()

Enable source-range based diagnostic messages.

void addFileLevelDecl(Decl *D)

Add a new local file-level declaration.

const FileManager & getFileManager() const

void CodeComplete(StringRef File, unsigned Line, unsigned Column, ArrayRef< RemappedFile > RemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, bool IncludeBriefComments, CodeCompleteConsumer &Consumer, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr, FileManager &FileMgr, SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SmallVectorImpl< const llvm::MemoryBuffer * > &OwnedBuffers, std::unique_ptr< SyntaxOnlyAction > Act)

Perform code completion at the given file, line, and column within this translation unit.

cached_completion_iterator cached_completion_end()

bool serialize(raw_ostream &OS)

Serialize this translation unit with the given output stream.

ASTDeserializationListener * getDeserializationListener()

bool Reparse(std::shared_ptr< PCHContainerOperations > PCHContainerOps, ArrayRef< RemappedFile > RemappedFiles={}, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)

Reparse the source files using the same command-line options that were originally used to produce thi...

std::unique_ptr< llvm::MemoryBuffer > getBufferForFile(StringRef Filename, std::string *ErrorStr=nullptr)

llvm::StringMap< unsigned > & getCachedCompletionTypes()

Retrieve the mapping from formatted type names to unique type identifiers.

const DiagnosticsEngine & getDiagnostics() const

SourceLocation getLocation(const FileEntry *File, unsigned Line, unsigned Col) const

Get the source location for the given file:line:col triplet.

void ResetForParse()

Free data that will be re-generated on the next parse.

InputKind getInputKind() const

Determine the input kind this AST unit represents.

OptionalFileEntryRef getPCHFile()

Get the PCH file if one was included.

StringRef getMainFileName() const

SourceLocation mapLocationToPreamble(SourceLocation Loc) const

If Loc is a local location of the main file but inside the preamble chunk, returns the corresponding ...

cached_completion_iterator cached_completion_begin()

const LangOptions & getLangOpts() const

static std::unique_ptr< ASTUnit > LoadFromCommandLine(const char **ArgBegin, const char **ArgEnd, std::shared_ptr< PCHContainerOperations > PCHContainerOps, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, StringRef ResourceFilesPath, bool StorePreamblesInMemory=false, StringRef PreambleStoragePath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, ArrayRef< RemappedFile > RemappedFiles={}, bool RemappedFilesKeepOriginalName=true, unsigned PrecompilePreambleAfterNParses=0, TranslationUnitKind TUKind=TU_Complete, bool CacheCodeCompletionResults=false, bool IncludeBriefCommentsInCodeCompletion=false, bool AllowPCHWithCompilerErrors=false, SkipFunctionBodiesScope SkipFunctionBodies=SkipFunctionBodiesScope::None, bool SingleFileParse=false, bool UserFilesAreVolatile=false, bool ForSerialization=false, bool RetainExcludedConditionalBlocks=false, std::optional< StringRef > ModuleFormat=std::nullopt, std::unique_ptr< ASTUnit > *ErrAST=nullptr, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)

LoadFromCommandLine - Create an ASTUnit from a vector of command line arguments, which must specify e...

bool isMainFileAST() const

std::vector< Decl * >::iterator top_level_iterator

const SourceManager & getSourceManager() const

SourceLocation getEndOfPreambleFileID() const

@ LoadASTOnly

Load the AST, but do not restore Sema state.

@ LoadEverything

Load everything, including Sema.

top_level_iterator top_level_end()

SourceLocation getStartOfMainFileID() const

IntrusiveRefCntPtr< ASTReader > getASTReader() const

bool(*)(void *context, const Decl *D) DeclVisitorFn

Type for a function iterating over a number of declarations.

bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)

Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...

llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const

Returns an iterator range for the local preprocessing entities of the local Preprocessor,...

top_level_iterator top_level_begin()

std::vector< CachedCodeCompletionResult >::iterator cached_completion_iterator

ASTMutationListener * getASTMutationListener()

static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, std::shared_ptr< HeaderSearchOptions > HSOpts, std::shared_ptr< LangOptions > LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=llvm::vfs::getRealFileSystem())

Create a ASTUnit from an AST file.

TranslationUnitKind getTranslationUnitKind() const

Determine what kind of translation unit this AST represents.

void setPreprocessor(std::shared_ptr< Preprocessor > pp)

StringRef getASTFileName() const

If this ASTUnit came from an AST file, returns the filename for it.

bool Save(StringRef File)

Save this translation unit to a file with the given name.

static std::unique_ptr< ASTUnit > create(std::shared_ptr< CompilerInvocation > CI, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile)

Create a ASTUnit. Gets ownership of the passed CompilerInvocation.

const HeaderSearchOptions & getHeaderSearchOpts() const

void addTopLevelDecl(Decl *D)

Add a new top-level declaration.

static ASTUnit * LoadFromCompilerInvocationAction(std::shared_ptr< CompilerInvocation > CI, std::shared_ptr< PCHContainerOperations > PCHContainerOps, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, FrontendAction *Action=nullptr, ASTUnit *Unit=nullptr, bool Persistent=true, StringRef ResourceFilesPath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, unsigned PrecompilePreambleAfterNParses=0, bool CacheCodeCompletionResults=false, bool UserFilesAreVolatile=false, std::unique_ptr< ASTUnit > *ErrAST=nullptr)

Create an ASTUnit from a source file, via a CompilerInvocation object, by invoking the optionally pro...

bool isInMainFileID(SourceLocation Loc) const

bool isModuleFile() const

Returns true if the ASTUnit was constructed from a serialized module file.

void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, SmallVectorImpl< Decl * > &Decls)

Get the decls that are contained in a file in the Offset/Length range.

const ASTContext & getASTContext() const

bool isInPreambleFileID(SourceLocation Loc) const

SourceLocation mapLocationFromPreamble(SourceLocation Loc) const

If Loc is a loaded location from the preamble, returns the corresponding local location of the main f...

std::pair< std::string, llvm::MemoryBuffer * > RemappedFile

A mapping from a file name to the memory buffer that stores the remapped contents of that file.

Writes an AST file containing the contents of a translation unit.

LocalDeclID getDeclID(const Decl *D)

Determine the local declaration ID of an already-emitted declaration.

ASTFileSignature WriteAST(llvm::PointerUnion< Sema *, Preprocessor * > Subject, StringRef OutputFile, Module *WritingModule, StringRef isysroot, bool ShouldCacheASTInMemory=false)

Write a precompiled header or a module with the AST produced by the Sema object, or a dependency scan...

Represents a character-granular source range.

static CharSourceRange getCharRange(SourceRange R)

SourceLocation getEnd() const

SourceLocation getBegin() const

Abstract interface for a consumer of code-completion information.

bool includeFixIts() const

Whether to include completion items with small fix-its, e.g.

bool loadExternal() const

Hint whether to load data from the external AST in order to provide full results.

Options controlling the behavior of code completion.

unsigned IncludeCodePatterns

Show code patterns in code completion results.

unsigned IncludeFixIts

Include results after corrections (small fix-its), e.g.

unsigned LoadExternal

Hint whether to load data from the external AST to provide full results.

unsigned IncludeMacros

Show macros in code completion results.

unsigned IncludeBriefComments

Show brief documentation comments in code completion results.

unsigned IncludeGlobals

Show top-level decls in code completion results.

An allocator used specifically for the purpose of code completion.

A builder class used to construct new code-completion strings.

The context in which code completion occurred, so that the code-completion consumer can process the r...

@ CCC_TypeQualifiers

Code completion within a type-qualifier list.

@ CCC_ObjCMessageReceiver

Code completion occurred where an Objective-C message receiver is expected.

@ CCC_PreprocessorExpression

Code completion occurred within a preprocessor expression.

@ CCC_ObjCCategoryName

Code completion where an Objective-C category name is expected.

@ CCC_ObjCIvarList

Code completion occurred within the instance variable list of an Objective-C interface,...

@ CCC_Statement

Code completion occurred where a statement (or declaration) is expected in a function,...

@ CCC_Type

Code completion occurred where a type name is expected.

@ CCC_ArrowMemberAccess

Code completion occurred on the right-hand side of a member access expression using the arrow operato...

@ CCC_ClassStructUnion

Code completion occurred within a class, struct, or union.

@ CCC_ObjCInterface

Code completion occurred within an Objective-C interface, protocol, or category interface.

@ CCC_ObjCPropertyAccess

Code completion occurred on the right-hand side of an Objective-C property access expression.

@ CCC_Expression

Code completion occurred where an expression is expected.

@ CCC_SelectorName

Code completion for a selector, as in an @selector expression.

@ CCC_TopLevelOrExpression

Code completion at a top level, i.e.

@ CCC_EnumTag

Code completion occurred after the "enum" keyword, to indicate an enumeration name.

@ CCC_UnionTag

Code completion occurred after the "union" keyword, to indicate a union name.

@ CCC_ParenthesizedExpression

Code completion in a parenthesized expression, which means that we may also have types here in C and ...

@ CCC_TopLevel

Code completion occurred within a "top-level" completion context, e.g., at namespace or global scope.

@ CCC_ClassOrStructTag

Code completion occurred after the "struct" or "class" keyword, to indicate a struct or class name.

@ CCC_ObjCClassMessage

Code completion where an Objective-C class message is expected.

@ CCC_ObjCImplementation

Code completion occurred within an Objective-C implementation or category implementation.

@ CCC_IncludedFile

Code completion inside the filename part of a #include directive.

@ CCC_ObjCInstanceMessage

Code completion where an Objective-C instance message is expected.

@ CCC_SymbolOrNewName

Code completion occurred where both a new name and an existing symbol is permissible.

@ CCC_Recovery

An unknown context, in which we are recovering from a parsing error and don't know which completions ...

@ CCC_ObjCProtocolName

Code completion occurred where a protocol name is expected.

@ CCC_OtherWithMacros

An unspecified code-completion context where we should also add macro completions.

@ CCC_NewName

Code completion occurred where a new name is expected.

@ CCC_MacroNameUse

Code completion occurred where a macro name is expected (without any arguments, in the case of a func...

@ CCC_Symbol

Code completion occurred where an existing name(such as type, function or variable) is expected.

@ CCC_Attribute

Code completion of an attribute name.

@ CCC_Other

An unspecified code-completion context.

@ CCC_DotMemberAccess

Code completion occurred on the right-hand side of a member access expression using the dot operator.

@ CCC_MacroName

Code completion occurred where an macro is being defined.

@ CCC_Namespace

Code completion occurred where a namespace or namespace alias is expected.

@ CCC_PreprocessorDirective

Code completion occurred where a preprocessor directive is expected.

@ CCC_NaturalLanguage

Code completion occurred in a context where natural language is expected, e.g., a comment or string l...

@ CCC_ObjCInterfaceName

Code completion where the name of an Objective-C class is expected.

@ CCC_ObjCClassForwardDecl

Captures a result of code completion.

A "string" used to describe how code completion can be performed for an entity.

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

void setFileManager(FileManager *Value)

Replace the current file manager and virtual file system.

void setSourceManager(SourceManager *Value)

setSourceManager - Replace the current source manager.

std::shared_ptr< Preprocessor > getPreprocessorPtr()

std::unique_ptr< Sema > takeSema()

IntrusiveRefCntPtr< ASTReader > getASTReader() const

bool hasASTContext() const

Preprocessor & getPreprocessor() const

Return the current preprocessor.

ASTContext & getASTContext() const

bool hasInvocation() const

bool hadModuleLoaderFatalFailure() const

CompilerInvocation & getInvocation()

std::unique_ptr< ASTConsumer > takeASTConsumer()

takeASTConsumer - Remove the current AST consumer and give ownership to the caller.

TargetInfo & getTarget() const

bool hasPreprocessor() const

Helper class for holding the data necessary to invoke the compiler.

PreprocessorOptions & getPreprocessorOpts()

LangOptions & getLangOpts()

Mutable getters.

FrontendOptions & getFrontendOpts()

std::shared_ptr< LangOptions > LangOpts

Base class internals.

DiagnosticOptions & getDiagnosticOpts()

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

bool isFileContext() const

bool isTranslationUnit() const

DeclContext * getLookupParent()

Find the parent context of this context that will be used for unqualified name lookup.

Decl - This represents one declaration (or definition), e.g.

bool isFromASTFile() const

Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...

bool isInvalidDecl() const

SourceLocation getLocation() const

@ IDNS_NonMemberOperator

This declaration is a C++ operator declared in a non-class context.

@ IDNS_Ordinary

Ordinary names.

@ IDNS_Type

Types, declared with 'struct foo', typedefs, etc.

@ IDNS_Member

Members, declared with object declarations within tag definitions.

@ IDNS_Namespace

Namespaces, declared with 'namespace foo {}'.

@ IDNS_Tag

Tags, declared with 'struct foo;' and referenced with 'struct foo'.

DeclContext * getDeclContext()

DeclContext * getLexicalDeclContext()

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

The name of a declaration.

Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...

virtual void EndSourceFile()

Callback to inform the diagnostic client that processing of a source file has ended.

virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info)

Handle this diagnostic, reporting it to the user or capturing it to a log as needed.

virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)

Callback to inform the diagnostic client that processing of a source file is beginning.

A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...

SourceManager & getSourceManager() const

bool hasSourceManager() const

Concrete class used by the front-end to report problems and issues.

void setNumWarnings(unsigned NumWarnings)

void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)

Set the diagnostic client associated with this diagnostic object.

std::unique_ptr< DiagnosticConsumer > takeClient()

Return the current diagnostic client along with ownership of that client.

Level

The level of the diagnostic, after it has been through mapping.

DiagnosticConsumer * getClient()

unsigned getNumWarnings() const

void Reset(bool soft=false)

Reset the state of the diagnostic object to its initial configuration.

Cached information about one file (either on disk or in the virtual file system).

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

Implements support for file system lookup, file system caching, and directory search management.

llvm::vfs::FileSystem & getVirtualFileSystem() const

OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)

Get a FileEntryRef if it exists, without doing anything on error.

FileSystemOptions & getFileSystemOpts()

Returns the current file system options.

llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const

void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)

Keeps track of options that affect how file operations are performed.

Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...

bool BeforePreviousInsertions

CharSourceRange RemoveRange

Code that should be replaced to correct the error.

CharSourceRange InsertFromRange

Code in the specific range that should be inserted in the insertion location.

std::string CodeToInsert

The actual code to insert at the insertion location, as a string.

Abstract base class for actions which can be performed by the frontend.

virtual void EndSourceFile()

Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...

llvm::Error Execute()

Set the source manager's main input file, and run the action.

virtual TranslationUnitKind getTranslationUnitKind()

For AST-based actions, the kind of translation unit we're handling.

bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)

Prepare the action for processing the input file Input.

An input file for the front end.

llvm::MemoryBufferRef getBuffer() const

StringRef getFile() const

FrontendOptions - Options for controlling the behavior of the frontend.

unsigned SkipFunctionBodies

Skip over function bodies to speed up parsing in cases you do not need them (e.g.

CodeCompleteOptions CodeCompleteOpts

ParsedSourceLocation CodeCompletionAt

If given, enable code completion at the provided location.

SmallVector< FrontendInputFile, 0 > Inputs

The input files and their types.

A SourceLocation and its associated SourceManager.

const SourceManager & getManager() const

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

In-memory cache for modules.

The kind of a file that we've been handed as an input.

Format

The input file format.

@ CMK_ModuleMap

Compiling a module from a module map.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

CommentOptions CommentOpts

Options for parsing comments.

bool isCompilingModule() const

Are we compiling a module?

static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)

Accepts a range and returns a character range with file locations.

Encapsulates changes to the "macros namespace" (the location where the macro name became active,...

Describes a module or submodule.

bool isNamedModule() const

Does this Module is a named module of a standard named module?

This represents a decl that may have a name.

NamedDecl * getUnderlyingDecl()

Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.

This abstract interface provides operations for unwrapping containers for serialized ASTs (precompile...

virtual llvm::ArrayRef< llvm::StringRef > getFormats() const =0

Equivalent to the format passed to -fmodule-format=.

This interface provides a way to observe the actions of the preprocessor as it does its thing.

A set of callbacks to gather useful information while building a preamble.

static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, bool StoreInMemory, StringRef StoragePath, PreambleCallbacks &Callbacks)

Try to build PrecompiledPreamble for Invocation.

Iteration over the preprocessed entities.

A record of the steps taken while preprocessing a source file, including the various preprocessing di...

PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...

std::pair< unsigned, bool > PrecompiledPreambleBytes

If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...

bool RemappedFilesKeepOriginalName

True if the SourceManager should report the original file name for contents of files that were remapp...

bool RetainRemappedFileBuffers

Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...

bool SingleFileParseMode

When enabled, preprocessor is in a mode for parsing a single file only.

bool DetailedRecord

Whether we should maintain a detailed record of all macro definitions and expansions.

bool RetainExcludedConditionalBlocks

When enabled, excluded conditional blocks retain in the main file.

void clearRemappedFiles()

void addRemappedFile(StringRef From, StringRef To)

bool AllowPCHWithCompilerErrors

When true, a PCH with compiler errors will not be rejected.

std::vector< std::pair< std::string, llvm::MemoryBuffer * > > RemappedFileBuffers

The set of file-to-buffer remappings, which take existing files on the system (the first part of each...

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

void addPPCallbacks(std::unique_ptr< PPCallbacks > C)

SourceManager & getSourceManager() const

FileManager & getFileManager() const

void Initialize(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)

Initialize the preprocessor using information about the target.

IdentifierTable & getIdentifierTable()

Builtin::Context & getBuiltinInfo()

const LangOptions & getLangOpts() const

void setCounterValue(unsigned V)

PreprocessingRecord * getPreprocessingRecord() const

Retrieve the preprocessing record, or NULL if there is no preprocessing record.

DiagnosticsEngine & getDiagnostics() const

SelectorTable & getSelectorTable()

A (possibly-)qualified type.

bool isNull() const

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

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

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

const LangOptions & getLangOpts() const

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

FileID translateFile(const FileEntry *SourceFile) const

Get the FileID for the given file.

SourceLocation getLocForEndOfFile(FileID FID) const

Return the source location corresponding to the last byte of the specified file.

FileID getMainFileID() const

Returns the FileID of the main source file.

bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const

Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...

FileID getPreambleFileID() const

Get the file ID for the precompiled preamble if there is one.

bool isLoadedFileID(FileID FID) const

Returns true if FID came from a PCH/Module.

SourceLocation getLocForStartOfFile(FileID FID) const

Return the source location corresponding to the first byte of the specified file.

Represents a diagnostic in a form that can be retained until its corresponding source manager is dest...

ArrayRef< FixItHint > getFixIts() const

ArrayRef< CharSourceRange > getRanges() const

DiagnosticsEngine::Level getLevel() const

const FullSourceLoc & getLocation() const

StringRef getMessage() const

static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)

Construct a target for the given options.

Options for controlling the target.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

Information about a module that has been loaded by the ASTReader.

FileEntryRef File

The file entry for the module file.

std::string FileName

The file name of the module file.

ModuleKind Kind

The type of this module.

@ CXCursor_MacroDefinition

Defines the clang::TargetInfo interface.

@ FixIt

Parse and apply any fixits to the source.

@ MK_MainFile

File is a PCH file treated as the actual main file.

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

IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)

QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND)

Determine the type that this declaration will have if it is used as a type or in an expression.

SkipFunctionBodiesScope

Enumerates the available scopes for skipping function bodies.

std::unique_ptr< CompilerInvocation > createInvocation(ArrayRef< const char * > Args, CreateInvocationOptions Opts={})

Interpret clang arguments in preparation to parse a file.

Language

The language for the input, used to select and validate the language standard and possible actions.

@ C

Languages that the frontend can parse and compile.

@ Result

The result type of a method or function.

SimplifiedTypeClass

A simplified classification of types used when determining "similar" types for code completion.

CaptureDiagsKind

Enumerates the available kinds for capturing diagnostics.

@ AllWithoutNonErrorsFromIncludes

IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)

@ CCF_ExactTypeMatch

Divide by this factor when a code-completion result's type exactly matches the type we expect.

@ CCF_SimilarTypeMatch

Divide by this factor when a code-completion result's type is similar to the type we expect (e....

void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, llvm::vfs::FileSystem &VFS, bool ReportDiags=true)

ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...

TranslationUnitKind

Describes the kind of translation unit being processed.

@ TU_Complete

The translation unit is a complete translation unit.

SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T)

Determine the simplified type class of the given canonical type.

@ CCP_NestedNameSpecifier

Priority for a nested-name-specifier.

@ CCP_CodePattern

Priority for a code pattern.

const FunctionProtoType * T

unsigned getMacroUsagePriority(StringRef MacroName, const LangOptions &LangOpts, bool PreferredTypeIsPointer=false)

Determine the priority to be given to a macro code completion result with the given name.

DisableValidationForModuleKind

Whether to disable the normal validation performed on precompiled headers and module files when they ...

@ None

Perform validation, don't disable it.

@ All

Disable validation for all kinds.

PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, const llvm::MemoryBufferRef &Buffer, unsigned MaxLines)

Runs lexer to compute suggested preamble bounds.

@ CouldntCreateTargetInfo

llvm::StringRef getAsString(SyncScope S)

llvm::BitstreamWriter Stream

SmallString< 128 > Buffer

ASTWriterData(InMemoryModuleCache &ModuleCache)

DiagnosticsEngine::Level Level

std::vector< std::pair< unsigned, unsigned > > Ranges

std::vector< StandaloneFixIt > FixIts

std::pair< unsigned, unsigned > InsertFromRange

std::pair< unsigned, unsigned > RemoveRange

bool BeforePreviousInsertions

Optional inputs to createInvocation.

IntrusiveRefCntPtr< DiagnosticsEngine > Diags

Receives diagnostics encountered while parsing command-line flags.

bool ProbePrecompiled

Allow the driver to probe the filesystem for PCH files.

IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS

Used e.g.

OverloadCandidate - A single candidate in an overload set (C++ 13.3).

Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...

unsigned Size

Size of the preamble in bytes.

Describes how types, statements, expressions, and declarations should be printed.