66 #include "llvm/ADT/ArrayRef.h"
67 #include "llvm/ADT/DenseMap.h"
68 #include "llvm/ADT/IntrusiveRefCntPtr.h"
69 #include "llvm/ADT/None.h"
70 #include "llvm/ADT/Optional.h"
71 #include "llvm/ADT/STLExtras.h"
72 #include "llvm/ADT/ScopeExit.h"
73 #include "llvm/ADT/SmallString.h"
74 #include "llvm/ADT/SmallVector.h"
75 #include "llvm/ADT/StringMap.h"
76 #include "llvm/ADT/StringRef.h"
77 #include "llvm/ADT/StringSet.h"
78 #include "llvm/ADT/Twine.h"
79 #include "llvm/ADT/iterator_range.h"
80 #include "llvm/Bitstream/BitstreamWriter.h"
81 #include "llvm/Support/Allocator.h"
82 #include "llvm/Support/Casting.h"
83 #include "llvm/Support/CrashRecoveryContext.h"
84 #include "llvm/Support/DJB.h"
85 #include "llvm/Support/ErrorHandling.h"
86 #include "llvm/Support/ErrorOr.h"
87 #include "llvm/Support/FileSystem.h"
88 #include "llvm/Support/FileUtilities.h"
89 #include "llvm/Support/MemoryBuffer.h"
90 #include "llvm/Support/Timer.h"
91 #include "llvm/Support/VirtualFileSystem.h"
92 #include "llvm/Support/raw_ostream.h"
106 using namespace clang;
108 using llvm::TimeRecord;
118 explicit SimpleTimer(
bool WantTiming) : WantTiming(WantTiming) {
120 Start = TimeRecord::getCurrentTime();
125 TimeRecord Elapsed = TimeRecord::getCurrentTime();
127 llvm::errs() << Output <<
':';
128 Elapsed.print(Elapsed, llvm::errs());
129 llvm::errs() <<
'\n';
133 void setOutput(
const Twine &Output) {
135 this->Output = Output.str();
142 static std::unique_ptr<T>
valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
145 return std::move(*Val);
152 Output = std::move(*Val);
158 static std::unique_ptr<llvm::MemoryBuffer>
160 llvm::vfs::FileSystem *VFS,
161 StringRef FilePath,
bool isVolatile) {
167 llvm::MemoryBuffer *Buffer =
nullptr;
168 std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
169 auto FileStatus = VFS->status(FilePath);
171 llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
174 for (
const auto &RF : PreprocessorOpts.RemappedFiles) {
176 auto MPathStatus = VFS->status(MPath);
178 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
179 if (MainFileID == MID) {
181 BufferOwner =
valueOrNull(VFS->getBufferForFile(RF.second, -1,
true, isVolatile));
190 for (
const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
192 auto MPathStatus = VFS->status(MPath);
194 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
195 if (MainFileID == MID) {
198 Buffer =
const_cast<llvm::MemoryBuffer *
>(RB.second);
205 if (!Buffer && !BufferOwner) {
206 BufferOwner =
valueOrNull(VFS->getBufferForFile(FilePath, -1,
true, isVolatile));
215 return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
227 void ASTUnit::clearFileLevelDecls() {
242 ASTUnit::ASTUnit(
bool _MainFileIsAST)
243 : MainFileIsAST(_MainFileIsAST), WantTiming(getenv(
"LIBCLANG_TIMING")),
244 ShouldCacheCodeCompletionResults(
false),
245 IncludeBriefCommentsInCodeCompletion(
false), UserFilesAreVolatile(
false),
246 UnsafeToFree(
false) {
247 if (getenv(
"LIBCLANG_OBJTRACKING"))
251 ASTUnit::~ASTUnit() {
257 clearFileLevelDecls();
263 if (Invocation && OwnsRemappedFileBuffers) {
269 ClearCachedCompletionResults();
271 if (getenv(
"LIBCLANG_OBJTRACKING"))
276 this->PP = std::move(PP);
281 "Bad context for source file");
289 bool &IsNestedNameSpecifier) {
290 IsNestedNameSpecifier =
false;
292 if (isa<UsingShadowDecl>(ND))
298 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
299 isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) ||
300 isa<TypeAliasTemplateDecl>(ND)) {
302 if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
311 if (LangOpts.CPlusPlus)
316 if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
320 if (
const auto *
ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
322 if (
ID->getDefinition())
328 if (isa<EnumDecl>(ND)) {
332 if (LangOpts.CPlusPlus11)
333 IsNestedNameSpecifier =
true;
334 }
else if (
const auto *Record = dyn_cast<RecordDecl>(ND)) {
335 if (Record->isUnion())
340 if (LangOpts.CPlusPlus)
341 IsNestedNameSpecifier =
true;
342 }
else if (isa<ClassTemplateDecl>(ND))
343 IsNestedNameSpecifier =
true;
344 }
else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
350 }
else if (isa<ObjCProtocolDecl>(ND)) {
352 }
else if (isa<ObjCCategoryDecl>(ND)) {
354 }
else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
358 IsNestedNameSpecifier =
true;
364 void ASTUnit::CacheCodeCompletionResults() {
368 SimpleTimer Timer(WantTiming);
369 Timer.setOutput(
"Cache global code completions for " +
getMainFileName());
372 ClearCachedCompletionResults();
377 CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
379 TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
383 llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
386 for (
auto &R : Results) {
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;
405 CachedResult.Type = 0;
414 unsigned &TypeValue = CompletionTypes[CanUsageType];
415 if (TypeValue == 0) {
416 TypeValue = CompletionTypes.size();
421 CachedResult.Type = TypeValue;
424 CachedCompletionResults.push_back(CachedResult);
427 if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
428 !R.StartsNestedNameSpecifier) {
444 if (isa<NamespaceDecl>(R.Declaration) ||
445 isa<NamespaceAliasDecl>(R.Declaration))
449 = NNSContexts & ~CachedResult.ShowInContexts) {
453 R.StartsNestedNameSpecifier =
true;
454 CachedResult.Completion = R.CreateCodeCompletionString(
455 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
456 IncludeBriefCommentsInCodeCompletion);
457 CachedResult.ShowInContexts = RemainingContexts;
460 CachedResult.Type = 0;
461 CachedCompletionResults.push_back(CachedResult);
467 case Result::RK_Keyword:
468 case Result::RK_Pattern:
473 case Result::RK_Macro: {
474 CachedCodeCompletionResult CachedResult;
475 CachedResult.Completion = R.CreateCodeCompletionString(
476 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
477 IncludeBriefCommentsInCodeCompletion);
478 CachedResult.ShowInContexts
492 CachedResult.Priority = R.Priority;
493 CachedResult.Kind = R.CursorKind;
494 CachedResult.Availability = R.Availability;
496 CachedResult.Type = 0;
497 CachedCompletionResults.push_back(CachedResult);
504 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
507 void ASTUnit::ClearCachedCompletionResults() {
508 CachedCompletionResults.clear();
509 CachedCompletionTypes.clear();
510 CachedCompletionAllocator =
nullptr;
523 std::shared_ptr<TargetOptions> &TargetOpts;
526 bool InitializedLanguage =
false;
532 std::shared_ptr<TargetOptions> &TargetOpts,
534 : PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
535 LangOpt(LangOpt), TargetOpts(TargetOpts),
Target(
Target),
538 bool ReadLanguageOptions(
const LangOptions &LangOpts,
bool Complain,
539 bool AllowCompatibleDifferences)
override {
540 if (InitializedLanguage)
544 InitializedLanguage =
true;
551 StringRef SpecificModuleCachePath,
552 bool Complain)
override {
553 this->HSOpts = HSOpts;
559 this->PPOpts = PPOpts;
563 bool ReadTargetOptions(
const TargetOptions &TargetOpts,
bool Complain,
564 bool AllowCompatibleDifferences)
override {
569 this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
578 unsigned Value)
override {
584 if (!Target || !InitializedLanguage)
616 bool CaptureNonErrorsFromIncludes =
true;
621 FilterAndStoreDiagnosticConsumer(
624 bool CaptureNonErrorsFromIncludes)
625 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
626 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
627 assert((StoredDiags || StandaloneDiags) &&
628 "No output collections were passed to StoredDiagnosticConsumer.");
633 this->LangOpts = &LangOpts;
644 class CaptureDroppedDiagnostics {
646 FilterAndStoreDiagnosticConsumer Client;
648 std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
651 CaptureDroppedDiagnostics(
656 Client(StoredDiags, StandaloneDiags,
657 CaptureDiagnostics !=
667 ~CaptureDroppedDiagnostics() {
669 Diags.
setClient(PreviousClient, !!OwningPreviousClient.release());
687 void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
703 StoredDiags->emplace_back(
Level, Info);
704 ResultDiag = &StoredDiags->back();
707 if (StandaloneDiags) {
710 StoredDiag.emplace(
Level, Info);
711 ResultDiag = StoredDiag.getPointer();
713 StandaloneDiags->push_back(
725 return &WriterData->Writer;
731 return &WriterData->Writer;
735 std::unique_ptr<llvm::MemoryBuffer>
738 auto Buffer = FileMgr->getBufferForFile(
Filename, UserFilesAreVolatile);
740 return std::move(*Buffer);
742 *ErrorStr = Buffer.getError().message();
750 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
752 Diags->setClient(
new FilterAndStoreDiagnosticConsumer(
753 &AST.StoredDiagnostics,
nullptr,
762 bool AllowASTWithCompilerErrors,
bool UserFilesAreVolatile,
764 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
true));
767 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
768 ASTUnitCleanup(AST.get());
770 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
771 DiagCleanup(Diags.get());
773 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
775 AST->LangOpts = std::make_shared<LangOptions>();
776 AST->OnlyLocalDecls = OnlyLocalDecls;
777 AST->CaptureDiagnostics = CaptureDiagnostics;
778 AST->Diagnostics = Diags;
779 AST->FileMgr =
new FileManager(FileSystemOpts, VFS);
780 AST->UserFilesAreVolatile = UserFilesAreVolatile;
782 AST->getFileManager(),
783 UserFilesAreVolatile);
785 AST->HSOpts = std::make_shared<HeaderSearchOptions>();
788 AST->getSourceManager(),
789 AST->getDiagnostics(),
792 AST->PPOpts = std::make_shared<PreprocessorOptions>();
799 AST->PP = std::make_shared<Preprocessor>(
800 AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
801 AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
807 AST->Ctx =
new ASTContext(*AST->LangOpts, AST->getSourceManager(),
810 AST->getTranslationUnitKind());
814 if (::getenv(
"LIBCLANG_DISABLE_PCH_VALIDATION"))
817 PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
819 disableValid, AllowASTWithCompilerErrors);
821 AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
822 *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
823 AST->TargetOpts, AST->Target, Counter));
831 AST->Ctx->setExternalSource(AST->Reader);
844 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
848 AST->OriginalSourceFile =
std::string(AST->Reader->getOriginalSourceFile());
858 AST->TheSema.reset(
new Sema(PP, *AST->Ctx, *AST->Consumer));
859 AST->TheSema->Initialize();
860 AST->Reader->InitializeSema(*AST->TheSema);
864 AST->getDiagnostics().getClient()->BeginSourceFile(PP.
getLangOpts(), &PP);
878 class MacroDefinitionTrackerPPCallbacks :
public PPCallbacks {
882 explicit MacroDefinitionTrackerPPCallbacks(
unsigned &Hash) : Hash(Hash) {}
884 void MacroDefined(
const Token &MacroNameTok,
904 if (
const auto *ND = dyn_cast<NamedDecl>(D)) {
905 if (
const auto *EnumD = dyn_cast<EnumDecl>(D)) {
908 if (!EnumD->isScoped()) {
909 for (
const auto *EI : EnumD->enumerators()) {
910 if (EI->getIdentifier())
911 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
916 if (ND->getIdentifier())
917 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
920 Hash = llvm::djbHash(NameStr, Hash);
925 if (
const auto *ImportD = dyn_cast<ImportDecl>(D)) {
926 if (
const Module *Mod = ImportD->getImportedModule()) {
928 Hash = llvm::djbHash(ModName, Hash);
936 class TopLevelDeclTrackerConsumer :
public ASTConsumer {
941 TopLevelDeclTrackerConsumer(
ASTUnit &_Unit,
unsigned &Hash)
942 : Unit(_Unit), Hash(Hash) {
946 void handleTopLevelDecl(
Decl *D) {
954 if (isa<ObjCMethodDecl>(D))
960 handleFileLevelDecl(D);
963 void handleFileLevelDecl(
Decl *D) {
965 if (
auto *NSD = dyn_cast<NamespaceDecl>(D)) {
966 for (
auto *I : NSD->decls())
967 handleFileLevelDecl(I);
972 for (
auto *TopLevelDecl : D)
973 handleTopLevelDecl(TopLevelDecl);
980 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
981 for (
auto *TopLevelDecl : D)
982 handleTopLevelDecl(TopLevelDecl);
999 StringRef InFile)
override {
1001 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1003 return std::make_unique<TopLevelDeclTrackerConsumer>(
1008 TopLevelDeclTrackerAction(
ASTUnit &_Unit) : Unit(_Unit) {}
1010 bool hasCodeCompletionSupport()
const override {
return false; }
1019 unsigned getHash()
const {
return Hash; }
1021 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
1023 std::vector<serialization::DeclID> takeTopLevelDeclIDs() {
1024 return std::move(TopLevelDeclIDs);
1027 void AfterPCHEmitted(
ASTWriter &Writer)
override {
1028 TopLevelDeclIDs.reserve(TopLevelDecls.size());
1029 for (
const auto *D : TopLevelDecls) {
1031 if (D->isInvalidDecl())
1033 TopLevelDeclIDs.push_back(Writer.
getDeclID(D));
1038 for (
auto *D : DG) {
1043 if (isa<ObjCMethodDecl>(D))
1046 TopLevelDecls.push_back(D);
1050 std::unique_ptr<PPCallbacks> createPPCallbacks()
override {
1051 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
1056 std::vector<Decl *> TopLevelDecls;
1057 std::vector<serialization::DeclID> TopLevelDeclIDs;
1082 for (
auto &SD : StoredDiagnostics) {
1083 if (SD.getLocation().isValid()) {
1085 SD.setLocation(Loc);
1095 bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1096 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1102 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1103 "VFS passed to Parse and VFS in FileMgr are different");
1105 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
1106 if (OverrideMainBuffer) {
1108 "No preamble was built, but OverrideMainBuffer is not null");
1109 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
1114 std::unique_ptr<CompilerInstance> Clang(
1118 auto CleanOnError = llvm::make_scope_exit([&]() {
1120 SavedMainFileBuffer =
nullptr;
1124 transferASTDataFromCompilerInstance(*Clang);
1125 FailedParseDiagnostics.swap(StoredDiagnostics);
1126 StoredDiagnostics.clear();
1127 NumStoredDiagnosticsFromDriver = 0;
1133 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS)
1134 Clang->setFileManager(&*FileMgr);
1136 FileMgr = Clang->createFileManager(std::move(VFS));
1139 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1140 CICleanup(Clang.get());
1142 Clang->setInvocation(CCInvocation);
1143 OriginalSourceFile =
1144 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1151 if (!Clang->createTarget())
1154 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1155 "Invocation must have exactly one source file!");
1156 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1158 "FIXME: AST inputs not yet supported here!");
1159 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1161 "IR inputs not support here!");
1164 LangOpts = Clang->getInvocation().LangOpts;
1165 FileSystemOpts = Clang->getFileSystemOpts();
1170 UserFilesAreVolatile);
1171 if (!OverrideMainBuffer) {
1173 TopLevelDeclsInPreamble.clear();
1181 if (OverrideMainBuffer) {
1190 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1193 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1194 new TopLevelDeclTrackerAction(*
this));
1197 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1198 ActCleanup(Act.get());
1200 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
1203 if (SavedMainFileBuffer)
1205 PreambleDiagnostics, StoredDiagnostics);
1207 PreambleSrcLocCache.clear();
1209 if (llvm::Error Err = Act->Execute()) {
1210 consumeError(std::move(Err));
1214 transferASTDataFromCompilerInstance(*Clang);
1216 Act->EndSourceFile();
1218 FailedParseDiagnostics.clear();
1220 CleanOnError.release();
1225 static std::pair<unsigned, unsigned>
1230 unsigned EndOffset =
SM.getFileOffset(FileRange.
getEnd());
1231 return std::make_pair(
Offset, EndOffset);
1262 for (
const auto &Range : InDiag.
getRanges())
1290 std::unique_ptr<llvm::MemoryBuffer>
1291 ASTUnit::getMainBufferWithPrecompiledPreamble(
1292 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1295 unsigned MaxLines) {
1298 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1300 MainFilePath, UserFilesAreVolatile);
1301 if (!MainFileBuffer)
1305 *PreambleInvocationIn.
getLangOpts(), *MainFileBuffer, MaxLines);
1310 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1321 PreambleRebuildCountdown = 1;
1322 return MainFileBuffer;
1325 PreambleDiagnostics.clear();
1326 TopLevelDeclsInPreamble.clear();
1327 PreambleSrcLocCache.clear();
1328 PreambleRebuildCountdown = 1;
1335 if (PreambleRebuildCountdown > 1) {
1336 --PreambleRebuildCountdown;
1340 assert(!Preamble &&
"No Preamble should be stored at that point");
1350 ASTUnitPreambleCallbacks Callbacks;
1354 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
1355 &NewPreambleDiagsStandalone);
1358 SimpleTimer PreambleTimer(WantTiming);
1359 PreambleTimer.setOutput(
"Precompiling preamble");
1361 const bool PreviousSkipFunctionBodies =
1367 PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
1368 PCHContainerOps,
false, Callbacks);
1371 PreviousSkipFunctionBodies;
1374 Preamble = std::move(*NewPreamble);
1375 PreambleRebuildCountdown = 1;
1380 PreambleRebuildCountdown = 1;
1390 llvm_unreachable(
"unexpected BuildPreambleError");
1394 assert(Preamble &&
"Preamble wasn't built");
1396 TopLevelDecls.clear();
1397 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1398 PreambleTopLevelHashValue = Callbacks.getHash();
1403 StoredDiagnostics = std::move(NewPreambleDiags);
1404 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1409 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1410 CompletionCacheTopLevelHashValue = 0;
1411 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1414 return MainFileBuffer;
1417 void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1418 assert(Preamble &&
"Should only be called when preamble was built");
1420 std::vector<Decl *> Resolved;
1421 Resolved.reserve(TopLevelDeclsInPreamble.size());
1423 for (
const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1427 Resolved.push_back(D);
1429 TopLevelDeclsInPreamble.clear();
1430 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1453 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1458 return Input.
getBuffer().getBufferIdentifier();
1464 return FE->getName();
1475 Mod = Reader->getModuleManager().getPrimaryModule();
1479 std::unique_ptr<ASTUnit>
1483 bool UserFilesAreVolatile) {
1484 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1485 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1488 AST->Diagnostics = Diags;
1489 AST->FileSystemOpts = CI->getFileSystemOpts();
1490 AST->Invocation = std::move(CI);
1491 AST->FileMgr =
new FileManager(AST->FileSystemOpts, VFS);
1492 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1493 AST->SourceMgr =
new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
1494 UserFilesAreVolatile);
1501 std::shared_ptr<CompilerInvocation> CI,
1502 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1504 ASTUnit *Unit,
bool Persistent, StringRef ResourceFilesPath,
1506 unsigned PrecompilePreambleAfterNParses,
bool CacheCodeCompletionResults,
1507 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1508 assert(CI &&
"A CompilerInvocation is required");
1510 std::unique_ptr<ASTUnit> OwnAST;
1514 OwnAST =
create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1520 if (!ResourceFilesPath.empty()) {
1524 AST->OnlyLocalDecls = OnlyLocalDecls;
1525 AST->CaptureDiagnostics = CaptureDiagnostics;
1526 if (PrecompilePreambleAfterNParses > 0)
1527 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1529 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1530 AST->IncludeBriefCommentsInCodeCompletion =
false;
1533 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1534 ASTUnitCleanup(OwnAST.get());
1536 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1537 DiagCleanup(Diags.get());
1540 CI->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1541 CI->getFrontendOpts().DisableFree =
false;
1545 std::unique_ptr<CompilerInstance> Clang(
1549 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1550 CICleanup(Clang.get());
1552 Clang->setInvocation(std::move(CI));
1553 AST->OriginalSourceFile =
1554 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1561 if (!Clang->createTarget())
1564 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1565 "Invocation must have exactly one source file!");
1566 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1568 "FIXME: AST inputs not yet supported here!");
1569 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1571 "IR inputs not support here!");
1574 AST->TheSema.reset();
1577 AST->Reader =
nullptr;
1587 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1589 TrackerAct.reset(
new TopLevelDeclTrackerAction(*AST));
1590 Act = TrackerAct.get();
1594 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1595 ActCleanup(TrackerAct.get());
1597 if (!Act->
BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
1598 AST->transferASTDataFromCompilerInstance(*Clang);
1599 if (OwnAST && ErrAST)
1600 ErrAST->swap(OwnAST);
1605 if (Persistent && !TrackerAct) {
1606 Clang->getPreprocessor().addPPCallbacks(
1607 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1609 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1610 if (Clang->hasASTConsumer())
1611 Consumers.push_back(Clang->takeASTConsumer());
1612 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1614 Clang->setASTConsumer(
1615 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1617 if (llvm::Error Err = Act->
Execute()) {
1618 consumeError(std::move(Err));
1619 AST->transferASTDataFromCompilerInstance(*Clang);
1620 if (OwnAST && ErrAST)
1621 ErrAST->swap(OwnAST);
1627 AST->transferASTDataFromCompilerInstance(*Clang);
1632 return OwnAST.release();
1637 bool ASTUnit::LoadFromCompilerInvocation(
1638 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1639 unsigned PrecompilePreambleAfterNParses,
1644 assert(VFS &&
"VFS is null");
1647 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1648 Invocation->getFrontendOpts().DisableFree =
false;
1652 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1653 if (PrecompilePreambleAfterNParses > 0) {
1654 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1655 OverrideMainBuffer =
1656 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1661 SimpleTimer ParsingTimer(WantTiming);
1665 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1666 MemBufferCleanup(OverrideMainBuffer.get());
1668 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1671 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1672 std::shared_ptr<CompilerInvocation> CI,
1673 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1677 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1678 bool UserFilesAreVolatile) {
1680 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1681 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1682 AST->Diagnostics = Diags;
1683 AST->OnlyLocalDecls = OnlyLocalDecls;
1684 AST->CaptureDiagnostics = CaptureDiagnostics;
1685 AST->TUKind = TUKind;
1686 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1687 AST->IncludeBriefCommentsInCodeCompletion
1688 = IncludeBriefCommentsInCodeCompletion;
1689 AST->Invocation = std::move(CI);
1691 AST->FileMgr = FileMgr;
1692 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1695 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1696 ASTUnitCleanup(AST.get());
1698 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1699 DiagCleanup(Diags.get());
1701 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1702 PrecompilePreambleAfterNParses,
1703 &AST->FileMgr->getVirtualFileSystem()))
1709 const char **ArgBegin,
const char **ArgEnd,
1710 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1715 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1717 bool SingleFileParse,
bool UserFilesAreVolatile,
bool ForSerialization,
1718 bool RetainExcludedConditionalBlocks,
1721 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
1725 std::shared_ptr<CompilerInvocation> CI;
1728 CaptureDroppedDiagnostics
Capture(CaptureDiagnostics, *Diags,
1729 &StoredDiagnostics,
nullptr);
1733 CIOpts.
Diags = Diags;
1743 CI->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1753 CI->getHeaderSearchOpts().ResourceDir =
std::string(ResourceFilesPath);
1755 CI->getFrontendOpts().SkipFunctionBodies =
1759 CI->getHeaderSearchOpts().ModuleFormat =
std::string(*ModuleFormat);
1762 std::unique_ptr<ASTUnit> AST;
1763 AST.reset(
new ASTUnit(
false));
1764 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1765 AST->StoredDiagnostics.swap(StoredDiagnostics);
1766 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1767 AST->Diagnostics = Diags;
1768 AST->FileSystemOpts = CI->getFileSystemOpts();
1770 VFS = llvm::vfs::getRealFileSystem();
1772 AST->FileMgr =
new FileManager(AST->FileSystemOpts, VFS);
1774 AST->OnlyLocalDecls = OnlyLocalDecls;
1775 AST->CaptureDiagnostics = CaptureDiagnostics;
1776 AST->TUKind = TUKind;
1777 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1778 AST->IncludeBriefCommentsInCodeCompletion
1779 = IncludeBriefCommentsInCodeCompletion;
1780 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1781 AST->Invocation = CI;
1782 AST->SkipFunctionBodies = SkipFunctionBodies;
1783 if (ForSerialization)
1784 AST->WriterData.reset(
new ASTWriterData(*AST->ModuleCache));
1790 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1791 ASTUnitCleanup(AST.get());
1793 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1794 PrecompilePreambleAfterNParses,
1799 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1805 return AST.release();
1815 assert(FileMgr &&
"FileMgr is null on Reparse call");
1816 VFS = &FileMgr->getVirtualFileSystem();
1819 clearFileLevelDecls();
1821 SimpleTimer ParsingTimer(WantTiming);
1829 Invocation->getPreprocessorOpts().clearRemappedFiles();
1831 Invocation->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1837 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1838 if (Preamble || PreambleRebuildCountdown > 0)
1839 OverrideMainBuffer =
1840 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1846 if (OverrideMainBuffer)
1851 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1855 if (!Result && ShouldCacheCodeCompletionResults &&
1856 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1857 CacheCodeCompletionResults();
1867 SavedMainFileBuffer.reset();
1875 TopLevelDecls.clear();
1876 clearFileLevelDecls();
1922 unsigned NumResults)
override;
1924 void ProcessOverloadCandidates(
Sema &S,
unsigned CurrentArg,
1926 unsigned NumCandidates,
1928 bool Braced)
override {
1929 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1930 OpenParLoc, Braced);
1934 return Next.getAllocator();
1938 return Next.getCodeCompletionTUInfo();
1948 unsigned NumResults,
1950 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
1951 bool OnlyTagNames =
false;
1952 switch (Context.getKind()) {
1976 OnlyTagNames =
true;
2001 for (
unsigned I = 0; I != NumResults; ++I) {
2002 if (Results[I].
Kind != Result::RK_Declaration)
2006 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
2008 bool Hiding =
false;
2017 Hiding = (IDNS & HiddenIDNS);
2027 HiddenNames.insert(Name.getAsString());
2031 void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(
Sema &S,
2034 unsigned NumResults) {
2036 bool AddedResult =
false;
2039 ? NormalContexts : (1LL << Context.getKind());
2041 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2050 if ((
C->ShowInContexts & InContexts) == 0)
2057 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2064 HiddenNames.count(
C->Completion->getTypedText()))
2070 if (!Context.getPreferredType().isNull()) {
2074 Context.getPreferredType()->isAnyPointerType());
2075 }
else if (
C->Type) {
2078 Context.getPreferredType().getUnqualifiedType());
2080 if (ExpectedSTC ==
C->TypeClass) {
2082 llvm::StringMap<unsigned> &CachedCompletionTypes
2084 llvm::StringMap<unsigned>::iterator Pos
2086 if (Pos != CachedCompletionTypes.end() && Pos->second ==
C->Type)
2101 Builder.AddTypedTextChunk(
C->Completion->getTypedText());
2103 Completion = Builder.TakeString();
2106 AllResults.push_back(Result(Completion,
Priority,
C->Kind,
2113 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2117 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2122 StringRef File,
unsigned Line,
unsigned Column,
2124 bool IncludeCodePatterns,
bool IncludeBriefComments,
2126 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2133 SimpleTimer CompletionTimer(WantTiming);
2134 CompletionTimer.setOutput(
"Code completion @ " +
File +
":" +
2135 Twine(
Line) +
":" + Twine(Column));
2137 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2144 CachedCompletionResults.empty();
2146 CodeCompleteOpts.
IncludeGlobals = CachedCompletionResults.empty();
2151 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2158 LangOpts = *CCInvocation->getLangOpts();
2161 LangOpts.SpellChecking =
false;
2162 CCInvocation->getDiagnosticOpts().IgnoreWarnings =
true;
2164 std::unique_ptr<CompilerInstance> Clang(
2168 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2169 CICleanup(Clang.get());
2171 auto &Inv = *CCInvocation;
2172 Clang->setInvocation(std::move(CCInvocation));
2173 OriginalSourceFile =
2174 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2177 Clang->setDiagnostics(&
Diag);
2179 Clang->getDiagnostics(),
2180 &StoredDiagnostics,
nullptr);
2184 if (!Clang->createTarget()) {
2185 Clang->setInvocation(
nullptr);
2189 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2190 "Invocation must have exactly one source file!");
2191 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2193 "FIXME: AST inputs not yet supported here!");
2194 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2196 "IR inputs not support here!");
2199 Clang->setFileManager(&FileMgr);
2200 Clang->setSourceManager(&SourceMgr);
2212 AugmentedCodeCompleteConsumer *AugmentedConsumer
2213 =
new AugmentedCodeCompleteConsumer(*
this, Consumer, CodeCompleteOpts);
2214 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2219 return Status->getUniqueID();
2223 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2226 if (
auto LHSID = getUniqueID(LHS))
2227 if (
auto RHSID = getUniqueID(RHS))
2228 return *LHSID == *RHSID;
2236 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2237 if (Preamble &&
Line > 1 && hasSameUniqueID(
File, OriginalSourceFile)) {
2238 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2244 if (OverrideMainBuffer) {
2246 "No preamble was built, but OverrideMainBuffer is not null");
2250 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2251 OverrideMainBuffer.get());
2256 OwnedBuffers.push_back(OverrideMainBuffer.release());
2263 if (!Clang->getLangOpts().Modules)
2266 std::unique_ptr<SyntaxOnlyAction> Act;
2268 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
2269 if (llvm::Error Err = Act->Execute()) {
2270 consumeError(std::move(Err));
2272 Act->EndSourceFile();
2277 if (HadModuleLoaderFatalFailure)
2284 TempPath +=
"-%%%%%%%%";
2288 if (llvm::Error Err = llvm::writeFileAtomically(
2289 TempPath,
File, [
this](llvm::raw_ostream &Out) {
2290 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2291 "ASTUnit serialization failed",
2292 llvm::inconvertibleErrorCode())
2293 : llvm::Error::success();
2295 consumeError(std::move(Err));
2309 if (!Buffer.empty())
2310 OS.write(Buffer.data(), Buffer.size());
2320 return serializeUnit(WriterData->Writer, WriterData->Buffer,
2324 llvm::BitstreamWriter Stream(Buffer);
2326 ASTWriter Writer(Stream, Buffer, ModuleCache, {});
2332 void ASTUnit::TranslateStoredDiagnostics(
2342 Result.reserve(Diags.size());
2344 for (
const auto &SD : Diags) {
2346 if (SD.Filename.empty())
2348 auto FE = FileMgr.
getFile(SD.Filename);
2352 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2353 if (ItFileID == PreambleSrcLocCache.end()) {
2356 PreambleSrcLocCache[SD.Filename] = FileLoc;
2358 FileLoc = ItFileID->getValue();
2367 Ranges.reserve(SD.Ranges.size());
2368 for (
const auto &Range : SD.Ranges) {
2375 FixIts.reserve(SD.FixIts.size());
2376 for (
const auto &
FixIt : SD.FixIts) {
2386 SD.Message, Loc, Ranges, FixIts));
2400 if (Loc.
isInvalid() || !
SM.isLocalSourceLocation(Loc))
2408 assert(
SM.isLocalSourceLocation(FileLoc));
2411 std::tie(FID,
Offset) =
SM.getDecomposedLoc(FileLoc);
2415 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2417 Decls = std::make_unique<LocDeclsTy>();
2419 std::pair<unsigned, Decl *> LocDecl(
Offset, D);
2421 if (Decls->empty() || Decls->back().first <=
Offset) {
2422 Decls->push_back(LocDecl);
2426 LocDeclsTy::iterator I =
2427 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2429 Decls->insert(I, LocDecl);
2434 if (
File.isInvalid())
2438 assert(Ctx->getExternalSource() &&
"No external source!");
2439 return Ctx->getExternalSource()->FindFileRegionDecls(
File,
Offset, Length,
2443 FileDeclsTy::iterator I = FileDecls.find(
File);
2444 if (I == FileDecls.end())
2448 if (LocDecls.empty())
2451 LocDeclsTy::iterator BeginIt =
2452 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2453 return LD.first <
Offset;
2455 if (BeginIt != LocDecls.begin())
2461 while (BeginIt != LocDecls.begin() &&
2462 BeginIt->second->isTopLevelDeclInObjCContainer())
2465 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2466 LocDecls, std::make_pair(
Offset + Length, (
Decl *)
nullptr),
2467 llvm::less_first());
2468 if (EndIt != LocDecls.end())
2471 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2472 Decls.push_back(DIt->second);
2476 unsigned Line,
unsigned Col)
const {
2479 return SM.getMacroArgExpandedLocation(Loc);
2501 if (SourceMgr->
isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2523 Offs < Preamble->getBounds().Size) {
2575 llvm::iterator_range<PreprocessingRecord::iterator>
2579 Mod = Reader->getModuleManager().getPrimaryModule();
2580 return Reader->getModulePreprocessedEntities(Mod);
2584 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2593 Mod = Reader->getModuleManager().getPrimaryModule();
2594 for (
const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2595 if (!Fn(context, D))
2604 TL != TLEnd; ++TL) {
2605 if (!Fn(context, *TL))
2619 case serialization::MK_ImplicitModule:
2620 case serialization::MK_ExplicitModule:
2621 case serialization::MK_PrebuiltModule:
2623 case serialization::MK_PCH:
2626 case serialization::MK_Preamble:
2628 case serialization::MK_MainFile:
2648 if (LangOpts.OpenCL)
2650 else if (LangOpts.CUDA)
2652 else if (LangOpts.RenderScript)
2654 else if (LangOpts.CPlusPlus)
2670 ASTUnit::ConcurrencyState::ConcurrencyState() {
2671 Mutex =
new std::recursive_mutex;
2674 ASTUnit::ConcurrencyState::~ConcurrencyState() {
2675 delete static_cast<std::recursive_mutex *
>(Mutex);
2678 void ASTUnit::ConcurrencyState::start() {
2679 bool acquired =
static_cast<std::recursive_mutex *
>(Mutex)->try_lock();
2680 assert(acquired &&
"Concurrent access to ASTUnit!");
2683 void ASTUnit::ConcurrencyState::finish() {
2684 static_cast<std::recursive_mutex *
>(Mutex)->unlock();
2689 ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex =
nullptr; }
2690 ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2691 void ASTUnit::ConcurrencyState::start() {}
2692 void ASTUnit::ConcurrencyState::finish() {}