static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) { // FIXME: Only deserialize stuff from the last chained PCH, not the PCH/Module // that it depends on. bool OnlyLocal = !Unit.isMainFileAST() && Unit.getOnlyLocalDecls(); if (OnlyLocal) { for (ASTUnit::top_level_iterator TL = Unit.top_level_begin(), TLEnd = Unit.top_level_end(); TL != TLEnd; ++TL) { IdxCtx.indexTopLevelDecl(*TL); if (IdxCtx.shouldAbort()) return; } } else { TranslationUnitDecl *TUDecl = Unit.getASTContext().getTranslationUnitDecl(); for (TranslationUnitDecl::decl_iterator I = TUDecl->decls_begin(), E = TUDecl->decls_end(); I != E; ++I) { IdxCtx.indexTopLevelDecl(*I); if (IdxCtx.shouldAbort()) return; } } }
bool SerializationTest::Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint, ASTContext &Ctx) { { // Pretty-print the decls to a temp file. std::string Err; llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); assert (Err.empty() && "Could not open file for printing out decls."); llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl(); for (DeclContext::decl_iterator I = TUD->decls_begin(Ctx), E = TUD->decls_end(Ctx); I != E; ++I) FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); } // Serialize the translation unit. // Reserve 256K for bitstream buffer. std::vector<unsigned char> Buffer; Buffer.reserve(256*1024); Ctx.EmitASTBitcodeBuffer(Buffer); // Write the bits to disk. if (FILE* fp = fopen(Filename.c_str(),"wb")) { fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); fclose(fp); return true; } return false; }
bool FlattenCFGTransformer::execute() { this->renamer = new VarRenamer(this->resMgr); this->preTranser = new StmtPretransformer(this->resMgr); OwningPtr<RefVarToPtrMap> refMap(new RefVarToPtrMap(0)); assert(refMap.get() && "reference variable map alloc failed"); this->dclMover = new LocalDeclMover(this->resMgr, refMap.get()); this->flat = new CFGFlattener(this->resMgr); TranslationUnitDecl *decls = this->resMgr.getCompilerInstance().getASTContext().getTranslationUnitDecl(); for(TranslationUnitDecl::decl_iterator I = decls->decls_begin(), E = decls->decls_end(); I != E; ++I) { Decl *D = *I; DPRINT("TUDecl %s %x | Ctx %x -> p %x", D->getDeclKindName(), (unsigned int)D, (unsigned int)D->getDeclContext(), (unsigned int)decls); SourceLocation Loc = D->getLocation(); if(Loc.isInvalid() || this->compInst.getSourceManager().isInSystemHeader(Loc)){ continue; } if(HandleAnyFunctionDecl(D)) { continue; } else if(HandleAnyClassDecl(D)) { continue; } } delete this->renamer; delete this->preTranser; delete this->dclMover; delete this->flat; refMap.reset(); return true; }
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); if (MigrateProperty) for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); D != DEnd; ++D) { if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D)) migrateObjCInterfaceDecl(Ctx, CDecl); else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D)) ObjCProtocolDecls.insert(PDecl); else if (const ObjCImplementationDecl *ImpDecl = dyn_cast<ObjCImplementationDecl>(*D)) migrateProtocolConformance(Ctx, ImpDecl); else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) { DeclContext::decl_iterator N = D; ++N; if (N != DEnd) if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N)) migrateNSEnumDecl(Ctx, ED, TD); } // migrate methods which can have instancetype as their result type. if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) migrateInstanceType(Ctx, CDecl); } Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); RewritesReceiver Rec(rewriter); Editor->applyRewrites(Rec); for (Rewriter::buffer_iterator I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { FileID FID = I->first; RewriteBuffer &buf = I->second; const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID); assert(file); SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); vecOS.flush(); llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy( StringRef(newText.data(), newText.size()), file->getName()); SmallString<64> filePath(file->getName()); FileMgr.FixupRelativePath(filePath); Remapper.remap(filePath.str(), memBuf); } if (IsOutputFile) { Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics()); } else { Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics()); } }
void ClangInternalState::printAST(llvm::raw_ostream& Out, ASTContext& C) { TranslationUnitDecl* TU = C.getTranslationUnitDecl(); unsigned Indentation = 0; bool PrintInstantiation = false; std::string ErrMsg; clang::PrintingPolicy policy = C.getPrintingPolicy(); TU->print(Out, policy, Indentation, PrintInstantiation); // TODO: For future when we relpace the bump allocation with slab. // //Out << "Allocated memory: " << C.getAllocatedMemory(); //Out << "Side table allocated memory: " << C.getSideTableAllocatedMemory(); Out.flush(); }
void ASTMergeAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); CI.getDiagnostics().getClient()->BeginSourceFile( CI.getASTContext().getLangOpts()); CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &CI.getASTContext()); IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(), new ForwardingDiagnosticConsumer( *CI.getDiagnostics().getClient()), /*ShouldOwnClient=*/true)); std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerOperations(), Diags, CI.getFileSystemOpts(), false); if (!Unit) continue; ASTImporter Importer(CI.getASTContext(), CI.getFileManager(), Unit->getASTContext(), Unit->getFileManager(), /*MinimalImport=*/false); TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); CI.getASTConsumer().Initialize(CI.getASTContext()); for (auto *D : TU->decls()) { // Don't re-import __va_list_tag, __builtin_va_list. if (const auto *ND = dyn_cast<NamedDecl>(D)) if (IdentifierInfo *II = ND->getIdentifier()) if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) continue; Decl *ToD = Importer.Import(D); if (ToD) { DeclGroupRef DGR(ToD); CI.getASTConsumer().HandleTopLevelDecl(DGR); } } } AdaptedAction->ExecuteAction(); CI.getDiagnostics().getClient()->EndSourceFile(); }
void ASTMergeAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); CI.getDiagnostics().getClient()->BeginSourceFile( CI.getASTContext().getLangOpts()); CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &CI.getASTContext()); IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(), new ForwardingDiagnosticConsumer( *CI.getDiagnostics().getClient()), /*ShouldOwnClient=*/true)); ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, CI.getFileSystemOpts(), false); if (!Unit) continue; ASTImporter Importer(CI.getASTContext(), CI.getFileManager(), Unit->getASTContext(), Unit->getFileManager(), /*MinimalImport=*/false); TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); D != DEnd; ++D) { // Don't re-import __va_list_tag, __builtin_va_list. if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) if (IdentifierInfo *II = ND->getIdentifier()) if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) continue; Importer.Import(*D); } delete Unit; } AdaptedAction->ExecuteAction(); CI.getDiagnostics().getClient()->EndSourceFile(); }
bool SerializationTest::Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint) { // Deserialize the translation unit. ASTContext *NewCtx; { // Create the memory buffer that contains the contents of the file. llvm::OwningPtr<llvm::MemoryBuffer> MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str())); if (!MBuffer) return false; NewCtx = ASTContext::ReadASTBitcodeBuffer(*MBuffer, FMgr); } if (!NewCtx) return false; { // Pretty-print the deserialized decls to a temp file. std::string Err; llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); assert (Err.empty() && "Could not open file for printing out decls."); llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl(); for (DeclContext::decl_iterator I = TUD->decls_begin(*NewCtx), E = TUD->decls_end(*NewCtx); I != E; ++I) FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); } delete NewCtx; return true; }
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); D != DEnd; ++D) { if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D)) migrateObjCInterfaceDecl(Ctx, CDecl); } Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); RewritesReceiver Rec(rewriter); Editor->applyRewrites(Rec); for (Rewriter::buffer_iterator I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { FileID FID = I->first; RewriteBuffer &buf = I->second; const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID); assert(file); SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); vecOS.flush(); llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy( StringRef(newText.data(), newText.size()), file->getName()); SmallString<64> filePath(file->getName()); FileMgr.FixupRelativePath(filePath); Remapper.remap(filePath.str(), memBuf); } if (IsOutputFile) { Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics()); } else { Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics()); } }
ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) { // If we've already handled this import, just return the cached result. // This one-element cache is important to eliminate redundant diagnostics // when both the preprocessor and parser see the same import declaration. if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. if (LastModuleImportResult) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility); return LastModuleImportResult; } // Determine what file we're searching from. StringRef ModuleName = Path[0].first->getName(); SourceLocation ModuleNameLoc = Path[0].second; clang::Module *Module = 0; // If we don't already have information on this module, load the module now. llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known = KnownModules.find(Path[0].first); if (Known != KnownModules.end()) { // Retrieve the cached top-level module. Module = Known->second; } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); std::string ModuleFileName; if (Module) ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); else ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); if (ModuleFileName.empty()) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return LastModuleImportResult; } const FileEntry *ModuleFile = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false, /*CacheFailure=*/false); bool BuildingModule = false; if (!ModuleFile && Module) { // The module is not cached, but we have a module map from which we can // build the module. // Check whether there is a cycle in the module graph. ModuleBuildStack Path = getSourceManager().getModuleBuildStack(); ModuleBuildStack::iterator Pos = Path.begin(), PosEnd = Path.end(); for (; Pos != PosEnd; ++Pos) { if (Pos->first == ModuleName) break; } if (Pos != PosEnd) { SmallString<256> CyclePath; for (; Pos != PosEnd; ++Pos) { CyclePath += Pos->first; CyclePath += " -> "; } CyclePath += ModuleName; getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) << ModuleName << CyclePath; return ModuleLoadResult(); } // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } BuildingModule = true; compileModule(*this, ModuleNameLoc, Module, ModuleFileName); ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile && getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); } if (!ModuleFile) { getDiagnostics().Report(ModuleNameLoc, BuildingModule? diag::err_module_not_built : diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } // If we don't already have an ASTReader, create one now. if (!ModuleManager) { if (!hasASTContext()) createASTContext(); std::string Sysroot = getHeaderSearchOpts().Sysroot; const PreprocessorOptions &PPOpts = getPreprocessorOpts(); ModuleManager = new ASTReader(getPreprocessor(), *Context, Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); getASTContext().setASTMutationListener( getASTConsumer().GetASTMutationListener()); getPreprocessor().setPPMutationListener( getASTConsumer().GetPPMutationListener()); } OwningPtr<ExternalASTSource> Source; Source.reset(ModuleManager); getASTContext().setExternalSource(Source); if (hasSema()) ModuleManager->InitializeSema(getSema()); if (hasASTConsumer()) ModuleManager->StartTranslationUnit(&getASTConsumer()); } // Try to load the module we found. unsigned ARRFlags = ASTReader::ARR_None; if (Module) ARRFlags |= ASTReader::ARR_OutOfDate; switch (ModuleManager->ReadAST(ModuleFile->getName(), serialization::MK_Module, ImportLoc, ARRFlags)) { case ASTReader::Success: break; case ASTReader::OutOfDate: { // The module file is out-of-date. Rebuild it. getFileManager().invalidateCache(ModuleFile); bool Existed; llvm::sys::fs::remove(ModuleFileName, Existed); // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } compileModule(*this, ModuleNameLoc, Module, ModuleFileName); // Try loading the module again. ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile || ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, ImportLoc, ASTReader::ARR_None) != ASTReader::Success) { if (getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } // Okay, we've rebuilt and now loaded the module. break; } case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: // FIXME: The ASTReader will already have complained, but can we showhorn // that diagnostic information into a more useful form? KnownModules[Path[0].first] = 0; return ModuleLoadResult(); case ASTReader::Failure: // Already complained, but note now that we failed. KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } if (!Module) { // If we loaded the module directly, without finding a module map first, // we'll have loaded the module's information from the module itself. Module = PP->getHeaderSearchInfo().getModuleMap() .findModule((Path[0].first->getName())); } if (Module) Module->setASTFile(ModuleFile); // Cache the result of this top-level module lookup for later. Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } // If we never found the module, fail. if (!Module) return ModuleLoadResult(); // Verify that the rest of the module path actually corresponds to // a submodule. if (Path.size() > 1) { for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(Name); if (!Sub) { // Attempt to perform typo correction to find a module name that works. llvm::SmallVector<StringRef, 2> Best; unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); for (clang::Module::submodule_iterator J = Module->submodule_begin(), JEnd = Module->submodule_end(); J != JEnd; ++J) { unsigned ED = Name.edit_distance((*J)->Name, /*AllowReplacements=*/true, BestEditDistance); if (ED <= BestEditDistance) { if (ED < BestEditDistance) { Best.clear(); BestEditDistance = ED; } Best.push_back((*J)->Name); } } // If there was a clear winner, user it. if (Best.size() == 1) { getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest) << Path[I].first << Module->getFullModuleName() << Best[0] << SourceRange(Path[0].second, Path[I-1].second) << FixItHint::CreateReplacement(SourceRange(Path[I].second), Best[0]); Sub = Module->findSubmodule(Best[0]); } } if (!Sub) { // No submodule by this name. Complain, and don't look for further // submodules. getDiagnostics().Report(Path[I].second, diag::err_no_submodule) << Path[I].first << Module->getFullModuleName() << SourceRange(Path[0].second, Path[I-1].second); break; } Module = Sub; } } // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) { if (!Module->IsFromModuleFile) { // We have an umbrella header or directory that doesn't actually include // all of the headers within the directory it covers. Complain about // this missing submodule and recover by forgetting that we ever saw // this submodule. // FIXME: Should we detect this at module load time? It seems fairly // expensive (and rare). getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) << Module->getFullModuleName() << SourceRange(Path.front().second, Path.back().second); return ModuleLoadResult(0, true); } // Check whether this module is available. StringRef Feature; if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) << Module->getFullModuleName() << Feature << SourceRange(Path.front().second, Path.back().second); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return ModuleLoadResult(); } ModuleManager->makeModuleVisible(Module, Visibility); } // If this module import was due to an inclusion directive, create an // implicit import declaration to capture it in the AST. if (IsInclusionDirective && hasASTContext()) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, ImportLoc, Module, Path.back().second); TU->addDecl(ImportD); if (Consumer) Consumer->HandleImplicitImportDecl(ImportD); } LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(Module, false); return LastModuleImportResult; }