diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-03 02:20:32 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-03 02:20:32 +0000 |
commit | dfb332d0081c6641d1dbae6a2aeff757c99cc740 (patch) | |
tree | 6c7b45c894999ae07bb0f5892a281882f42892e3 /lib/Serialization/ASTReader.cpp | |
parent | dcaca015a2f08e03a6d86222fec2e83e04f6b848 (diff) |
[libclang] Add infrastructure to be able to only deserialize decls in a file region and
use it for clang_getCursor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143605 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 153b0e0dfe..cbf6cd0c5c 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4020,6 +4020,25 @@ bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, return &M == I->second; } +SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { + if (ID < NUM_PREDEF_DECL_IDS) + return SourceLocation(); + + unsigned Index = ID - NUM_PREDEF_DECL_IDS; + + if (Index > DeclsLoaded.size()) { + Error("declaration ID out-of-range for AST file"); + return SourceLocation(); + } + + if (Decl *D = DeclsLoaded[Index]) + return D->getLocation(); + + unsigned RawLocation = 0; + RecordLocation Rec = DeclCursorForID(ID, RawLocation); + return ReadSourceLocation(*Rec.F, RawLocation); +} + Decl *ASTReader::GetDecl(DeclID ID) { if (ID < NUM_PREDEF_DECL_IDS) { switch ((PredefinedDeclIDs)ID) { @@ -4163,6 +4182,74 @@ ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC, } namespace { + +class DeclIDComp { + ASTReader &Reader; + Module &Mod; + +public: + DeclIDComp(ASTReader &Reader, Module &M) : Reader(Reader), Mod(M) {} + + bool operator()(LocalDeclID L, LocalDeclID R) const { + SourceLocation LHS = getLocation(L); + SourceLocation RHS = getLocation(R); + return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); + } + + bool operator()(SourceLocation LHS, LocalDeclID R) const { + SourceLocation RHS = getLocation(R); + return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); + } + + bool operator()(LocalDeclID L, SourceLocation RHS) const { + SourceLocation LHS = getLocation(L); + return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); + } + + SourceLocation getLocation(LocalDeclID ID) const { + return Reader.getSourceManager().getFileLoc( + Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID))); + } +}; + +} + +void ASTReader::FindFileRegionDecls(FileID File, + unsigned Offset, unsigned Length, + SmallVectorImpl<Decl *> &Decls) { + SourceManager &SM = getSourceManager(); + + llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File); + if (I == FileDeclIDs.end()) + return; + + FileDeclsInfo &DInfo = I->second; + if (DInfo.Decls.empty()) + return; + + SourceLocation + BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset); + SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); + + DeclIDComp DIDComp(*this, *DInfo.Mod); + ArrayRef<serialization::LocalDeclID>::iterator + BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(), + BeginLoc, DIDComp); + if (BeginIt != DInfo.Decls.begin()) + --BeginIt; + + ArrayRef<serialization::LocalDeclID>::iterator + EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(), + EndLoc, DIDComp); + if (EndIt != DInfo.Decls.end()) + ++EndIt; + + for (ArrayRef<serialization::LocalDeclID>::iterator + DIt = BeginIt; DIt != EndIt; ++DIt) + Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); +} + +namespace { /// \brief Module visitor used to perform name lookup into a /// declaration context. class DeclContextNameLookupVisitor { |