diff options
Diffstat (limited to 'tools/libclang/Indexing.cpp')
-rw-r--r-- | tools/libclang/Indexing.cpp | 253 |
1 files changed, 133 insertions, 120 deletions
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp index 99fcdb692add..58af61811bf5 100644 --- a/tools/libclang/Indexing.cpp +++ b/tools/libclang/Indexing.cpp @@ -219,7 +219,7 @@ private: assert(RegionLoc.isFileID()); FileID RegionFID; unsigned RegionOffset; - llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc); + std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc); if (RegionFID != FID) { if (isParsedOnceInclude(FE)) { @@ -253,8 +253,8 @@ public: IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx) : PP(PP), IndexCtx(indexCtx), IsMainFileEntered(false) { } - virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType, FileID PrevFID) { + void FileChanged(SourceLocation Loc, FileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, FileID PrevFID) override { if (IsMainFileEntered) return; @@ -267,15 +267,11 @@ public: } } - virtual void InclusionDirective(SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - const FileEntry *File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported) { + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported) override { bool isImport = (IncludeTok.is(tok::identifier) && IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import); IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled, @@ -283,25 +279,21 @@ public: } /// MacroDefined - This hook is called whenever a macro definition is seen. - virtual void MacroDefined(const Token &Id, const MacroDirective *MD) { - } + void MacroDefined(const Token &Id, const MacroDirective *MD) override {} /// MacroUndefined - This hook is called whenever a macro #undef is seen. /// MI is released immediately following this callback. - virtual void MacroUndefined(const Token &MacroNameTok, - const MacroDirective *MD) { - } + void MacroUndefined(const Token &MacroNameTok, + const MacroDirective *MD) override {} /// MacroExpands - This is called by when a macro invocation is found. - virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range, const MacroArgs *Args) { - } + void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range, const MacroArgs *Args) override {} /// SourceRangeSkipped - This hook is called when a source range is skipped. /// \param Range The SourceRange that was skipped. The range begins at the /// #if/#else directive and ends after the #endif/#else directive. - virtual void SourceRangeSkipped(SourceRange Range) { - } + void SourceRangeSkipped(SourceRange Range) override {} }; //===----------------------------------------------------------------------===// @@ -318,24 +310,24 @@ public: // ASTConsumer Implementation - virtual void Initialize(ASTContext &Context) { + void Initialize(ASTContext &Context) override { IndexCtx.setASTContext(Context); IndexCtx.startedTranslationUnit(); } - virtual void HandleTranslationUnit(ASTContext &Ctx) { + void HandleTranslationUnit(ASTContext &Ctx) override { if (SKCtrl) SKCtrl->finished(); } - virtual bool HandleTopLevelDecl(DeclGroupRef DG) { + bool HandleTopLevelDecl(DeclGroupRef DG) override { IndexCtx.indexDeclGroupRef(DG); return !IndexCtx.shouldAbort(); } /// \brief Handle the specified top-level declaration that occurred inside /// and ObjC container. - virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { + void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override { // They will be handled after the interface is seen first. IndexCtx.addTUDeclInObjCContainer(D); } @@ -343,9 +335,9 @@ public: /// \brief This is called by the AST reader when deserializing things. /// The default implementation forwards to HandleTopLevelDecl but we don't /// care about them when indexing, so have an empty definition. - virtual void HandleInterestingDecl(DeclGroupRef D) {} + void HandleInterestingDecl(DeclGroupRef D) override {} - virtual void HandleTagDeclDefinition(TagDecl *D) { + void HandleTagDeclDefinition(TagDecl *D) override { if (!IndexCtx.shouldIndexImplicitTemplateInsts()) return; @@ -353,14 +345,14 @@ public: IndexCtx.indexDecl(D); } - virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) { + void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override { if (!IndexCtx.shouldIndexImplicitTemplateInsts()) return; IndexCtx.indexDecl(D); } - virtual bool shouldSkipFunctionBody(Decl *D) { + bool shouldSkipFunctionBody(Decl *D) override { if (!SKCtrl) { // Always skip bodies. return true; @@ -375,7 +367,7 @@ public: FileID FID; unsigned Offset; - llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc); + std::tie(FID, Offset) = SM.getDecomposedLoc(Loc); // Don't skip bodies from main files; this may be revisited. if (SM.getMainFileID() == FID) return false; @@ -395,8 +387,8 @@ class CaptureDiagnosticConsumer : public DiagnosticConsumer { SmallVector<StoredDiagnostic, 4> Errors; public: - virtual void HandleDiagnostic(DiagnosticsEngine::Level level, - const Diagnostic &Info) { + void HandleDiagnostic(DiagnosticsEngine::Level level, + const Diagnostic &Info) override { if (level >= DiagnosticsEngine::Error) Errors.push_back(StoredDiagnostic(level, Info)); } @@ -411,7 +403,7 @@ class IndexingFrontendAction : public ASTFrontendAction { CXTranslationUnit CXTU; SessionSkipBodyData *SKData; - OwningPtr<TUSkipBodyControl> SKCtrl; + std::unique_ptr<TUSkipBodyControl> SKCtrl; public: IndexingFrontendAction(CXClientData clientData, @@ -422,8 +414,8 @@ public: : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU), CXTU(cxTU), SKData(skData) { } - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); if (!PPOpts.ImplicitPCHInclude.empty()) { @@ -446,17 +438,17 @@ public: return new IndexingConsumer(IndexCtx, SKCtrl.get()); } - virtual void EndSourceFileAction() { + void EndSourceFileAction() override { indexDiagnostics(CXTU, IndexCtx); } - virtual TranslationUnitKind getTranslationUnitKind() { + TranslationUnitKind getTranslationUnitKind() override { if (IndexCtx.shouldIndexImplicitTemplateInsts()) return TU_Complete; else return TU_Prefix; } - virtual bool hasCodeCompletionSupport() const { return false; } + bool hasCodeCompletionSupport() const override { return false; } }; //===----------------------------------------------------------------------===// @@ -465,7 +457,7 @@ public: struct IndexSessionData { CXIndex CIdx; - OwningPtr<SessionSkipBodyData> SkipBodyData; + std::unique_ptr<SessionSkipBodyData> SkipBodyData; explicit IndexSessionData(CXIndex cIdx) : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {} @@ -480,28 +472,17 @@ struct IndexSourceFileInfo { const char *source_filename; const char *const *command_line_args; int num_command_line_args; - struct CXUnsavedFile *unsaved_files; - unsigned num_unsaved_files; + ArrayRef<CXUnsavedFile> unsaved_files; CXTranslationUnit *out_TU; unsigned TU_options; - int result; -}; - -struct MemBufferOwner { - SmallVector<const llvm::MemoryBuffer *, 8> Buffers; - - ~MemBufferOwner() { - for (SmallVectorImpl<const llvm::MemoryBuffer *>::iterator - I = Buffers.begin(), E = Buffers.end(); I != E; ++I) - delete *I; - } + CXErrorCode &result; }; } // anonymous namespace static void clang_indexSourceFile_Impl(void *UserData) { - IndexSourceFileInfo *ITUI = - static_cast<IndexSourceFileInfo*>(UserData); + const IndexSourceFileInfo *ITUI = + static_cast<IndexSourceFileInfo *>(UserData); CXIndexAction cxIdxAction = ITUI->idxAction; CXClientData client_data = ITUI->client_data; IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks; @@ -510,20 +491,21 @@ static void clang_indexSourceFile_Impl(void *UserData) { const char *source_filename = ITUI->source_filename; const char * const *command_line_args = ITUI->command_line_args; int num_command_line_args = ITUI->num_command_line_args; - struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files; - unsigned num_unsaved_files = ITUI->num_unsaved_files; CXTranslationUnit *out_TU = ITUI->out_TU; unsigned TU_options = ITUI->TU_options; - ITUI->result = 1; // init as error. - + if (out_TU) - *out_TU = 0; - bool requestedToGetTU = (out_TU != 0); + *out_TU = nullptr; + bool requestedToGetTU = (out_TU != nullptr); - if (!cxIdxAction) + if (!cxIdxAction) { + ITUI->result = CXError_InvalidArguments; return; - if (!client_index_callbacks || index_callbacks_size == 0) + } + if (!client_index_callbacks || index_callbacks_size == 0) { + ITUI->result = CXError_InvalidArguments; return; + } IndexerCallbacks CB; memset(&CB, 0, sizeof(CB)); @@ -539,7 +521,7 @@ static void clang_indexSourceFile_Impl(void *UserData) { bool CaptureDiagnostics = !Logger::isLoggingEnabled(); - CaptureDiagnosticConsumer *CaptureDiag = 0; + CaptureDiagnosticConsumer *CaptureDiag = nullptr; if (CaptureDiagnostics) CaptureDiag = new CaptureDiagnosticConsumer(); @@ -552,10 +534,10 @@ static void clang_indexSourceFile_Impl(void *UserData) { // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > - DiagCleanup(Diags.getPtr()); - - OwningPtr<std::vector<const char *> > - Args(new std::vector<const char*>()); + DiagCleanup(Diags.get()); + + std::unique_ptr<std::vector<const char *>> Args( + new std::vector<const char *>()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> > @@ -581,23 +563,23 @@ static void clang_indexSourceFile_Impl(void *UserData) { // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation, llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> > - CInvokCleanup(CInvok.getPtr()); + CInvokCleanup(CInvok.get()); if (CInvok->getFrontendOpts().Inputs.empty()) return; - OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner()); + typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner; + std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner); // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> - BufOwnerCleanup(BufOwner.get()); - - for (unsigned I = 0; I != num_unsaved_files; ++I) { - StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); - const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename, Buffer); - BufOwner->Buffers.push_back(Buffer); + llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup( + BufOwner.get()); + + for (auto &UF : ITUI->unsaved_files) { + llvm::MemoryBuffer *MB = + llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename); + BufOwner->push_back(std::unique_ptr<llvm::MemoryBuffer>(MB)); + CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB); } // Since libclang is primarily used by batch tools dealing with @@ -609,10 +591,16 @@ static void clang_indexSourceFile_Impl(void *UserData) { if (index_options & CXIndexOpt_SuppressWarnings) CInvok->getDiagnosticOpts().IgnoreWarnings = true; - ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags, + ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags, CaptureDiagnostics, /*UserFilesAreVolatile=*/true); - OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit))); + if (!Unit) { + ITUI->result = CXError_InvalidArguments; + return; + } + + std::unique_ptr<CXTUOwner> CXTU( + new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit))); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner> @@ -625,10 +613,10 @@ static void clang_indexSourceFile_Impl(void *UserData) { if (SkipBodies) CInvok->getFrontendOpts().SkipFunctionBodies = true; - OwningPtr<IndexingFrontendAction> IndexAction; + std::unique_ptr<IndexingFrontendAction> IndexAction; IndexAction.reset(new IndexingFrontendAction(client_data, CB, index_options, CXTU->getTU(), - SkipBodies ? IdxSession->SkipBodyData.get() : 0)); + SkipBodies ? IdxSession->SkipBodyData.get() : nullptr)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction> @@ -657,7 +645,7 @@ static void clang_indexSourceFile_Impl(void *UserData) { PPOpts.DetailedRecord = false; DiagnosticErrorTrap DiagTrap(*Diags); - bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags, + bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), Diags, IndexAction.get(), Unit, Persistent, @@ -671,13 +659,18 @@ static void clang_indexSourceFile_Impl(void *UserData) { if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics()) printDiagsToStderr(Unit); + if (isASTReadError(Unit)) { + ITUI->result = CXError_ASTReadError; + return; + } + if (!Success) return; if (out_TU) *out_TU = CXTU->takeTU(); - ITUI->result = 0; // success. + ITUI->result = CXError_Success; } //===----------------------------------------------------------------------===// @@ -706,7 +699,7 @@ static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) { // FIXME: Only deserialize inclusion directives. PreprocessingRecord::iterator I, E; - llvm::tie(I, E) = Unit.getLocalPreprocessingEntities(); + std::tie(I, E) = Unit.getLocalPreprocessingEntities(); bool isModuleFile = Unit.isModuleFile(); for (; I != E; ++I) { @@ -754,12 +747,20 @@ static void clang_indexTranslationUnit_Impl(void *UserData) { IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks; unsigned index_callbacks_size = ITUI->index_callbacks_size; unsigned index_options = ITUI->index_options; - ITUI->result = 1; // init as error. - if (!TU) + // Set up the initial return value. + ITUI->result = CXError_Failure; + + // Check arguments. + if (isNotUsableTU(TU)) { + LOG_BAD_TU(TU); + ITUI->result = CXError_InvalidArguments; return; - if (!client_index_callbacks || index_callbacks_size == 0) + } + if (!client_index_callbacks || index_callbacks_size == 0) { + ITUI->result = CXError_InvalidArguments; return; + } CIndexer *CXXIdx = TU->CIdx; if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) @@ -771,15 +772,15 @@ static void clang_indexTranslationUnit_Impl(void *UserData) { ? index_callbacks_size : sizeof(CB); memcpy(&CB, client_index_callbacks, ClientCBSize); - OwningPtr<IndexingContext> IndexCtx; + std::unique_ptr<IndexingContext> IndexCtx; IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext> IndexCtxCleanup(IndexCtx.get()); - OwningPtr<IndexingConsumer> IndexConsumer; - IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0)); + std::unique_ptr<IndexingConsumer> IndexConsumer; + IndexConsumer.reset(new IndexingConsumer(*IndexCtx, nullptr)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer> @@ -797,7 +798,7 @@ static void clang_indexTranslationUnit_Impl(void *UserData) { FileManager &FileMgr = Unit->getFileManager(); if (Unit->getOriginalSourceFileName().empty()) - IndexCtx->enteredMainFile(0); + IndexCtx->enteredMainFile(nullptr); else IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName())); @@ -807,7 +808,7 @@ static void clang_indexTranslationUnit_Impl(void *UserData) { indexTranslationUnit(*Unit, *IndexCtx); indexDiagnostics(TU, *IndexCtx); - ITUI->result = 0; + ITUI->result = CXError_Success; } //===----------------------------------------------------------------------===// @@ -823,46 +824,46 @@ int clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) { const CXIdxObjCContainerDeclInfo * clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) { if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); if (const ObjCContainerDeclInfo * ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI)) return &ContInfo->ObjCContDeclInfo; - return 0; + return nullptr; } const CXIdxObjCInterfaceDeclInfo * clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) { if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); if (const ObjCInterfaceDeclInfo * InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI)) return &InterInfo->ObjCInterDeclInfo; - return 0; + return nullptr; } const CXIdxObjCCategoryDeclInfo * clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){ if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); if (const ObjCCategoryDeclInfo * CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI)) return &CatInfo->ObjCCatDeclInfo; - return 0; + return nullptr; } const CXIdxObjCProtocolRefListInfo * clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) { if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); @@ -877,50 +878,50 @@ clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) { if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI)) return CatInfo->ObjCCatDeclInfo.protocols; - return 0; + return nullptr; } const CXIdxObjCPropertyDeclInfo * clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) { if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI)) return &PropInfo->ObjCPropDeclInfo; - return 0; + return nullptr; } const CXIdxIBOutletCollectionAttrInfo * clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) { if (!AInfo) - return 0; + return nullptr; const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo); if (const IBOutletCollectionInfo * IBInfo = dyn_cast<IBOutletCollectionInfo>(DI)) return &IBInfo->IBCollInfo; - return 0; + return nullptr; } const CXIdxCXXClassDeclInfo * clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) { if (!DInfo) - return 0; + return nullptr; const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo); if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI)) return &ClassInfo->CXXClassInfo; - return 0; + return nullptr; } CXIdxClientContainer clang_index_getClientContainer(const CXIdxContainerInfo *info) { if (!info) - return 0; + return nullptr; const ContainerInfo *Container = static_cast<const ContainerInfo *>(info); return Container->IndexCtx->getClientContainerForDC(Container->DC); } @@ -935,7 +936,7 @@ void clang_index_setClientContainer(const CXIdxContainerInfo *info, CXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) { if (!info) - return 0; + return nullptr; const EntityInfo *Entity = static_cast<const EntityInfo *>(info); return Entity->IndexCtx->getClientEntity(Entity->Dcl); } @@ -975,15 +976,27 @@ int clang_indexSourceFile(CXIndexAction idxAction, *Log << command_line_args[i] << " "; } - IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks, - index_callbacks_size, index_options, - source_filename, command_line_args, - num_command_line_args, unsaved_files, - num_unsaved_files, out_TU, TU_options, 0 }; + if (num_unsaved_files && !unsaved_files) + return CXError_InvalidArguments; + + CXErrorCode result = CXError_Failure; + IndexSourceFileInfo ITUI = { + idxAction, + client_data, + index_callbacks, + index_callbacks_size, + index_options, + source_filename, + command_line_args, + num_command_line_args, + llvm::makeArrayRef(unsaved_files, num_unsaved_files), + out_TU, + TU_options, + result}; if (getenv("LIBCLANG_NOTHREADS")) { clang_indexSourceFile_Impl(&ITUI); - return ITUI.result; + return result; } llvm::CrashRecoveryContext CRC; @@ -1014,8 +1027,8 @@ int clang_indexSourceFile(CXIndexAction idxAction, if (out_TU) PrintLibclangResourceUsage(*out_TU); } - - return ITUI.result; + + return result; } int clang_indexTranslationUnit(CXIndexAction idxAction, @@ -1054,8 +1067,8 @@ void clang_indexLoc_getFileLocation(CXIdxLoc location, unsigned *line, unsigned *column, unsigned *offset) { - if (indexFile) *indexFile = 0; - if (file) *file = 0; + if (indexFile) *indexFile = nullptr; + if (file) *file = nullptr; if (line) *line = 0; if (column) *column = 0; if (offset) *offset = 0; |