diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-06 21:35:02 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-06 21:35:02 +0000 |
commit | 818e15b89facfe0b62c8c22c18fde383a17455eb (patch) | |
tree | 6957e11614b5c66ed86cbfd99df8115133fa95ae /lib/Frontend/ResolveLocation.cpp | |
parent | ccbcb70ee96cb67ed6c8b4142d050f3a6764edd7 (diff) |
Move the 'ResolveLocationInAST' function from the Frontend library to the Index library.
Also, cut down its comments; more comments will be added to ASTLocation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74860 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/ResolveLocation.cpp')
-rw-r--r-- | lib/Frontend/ResolveLocation.cpp | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/lib/Frontend/ResolveLocation.cpp b/lib/Frontend/ResolveLocation.cpp deleted file mode 100644 index 9fbae30a48..0000000000 --- a/lib/Frontend/ResolveLocation.cpp +++ /dev/null @@ -1,332 +0,0 @@ -//===--- ResolveLocation.cpp - Source location resolver ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This defines the ResolveLocationInAST function, which resolves a -// source location into a <Decl *, Stmt *> pair. -// -//===----------------------------------------------------------------------===// - -#include "clang/Frontend/Utils.h" -#include "clang/Index/ASTLocation.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/Lex/Lexer.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/Support/Compiler.h" -using namespace clang; -using namespace idx; - -namespace { - -/// \brief Base for the LocResolver classes. Mostly does source range checking. -class VISIBILITY_HIDDEN LocResolverBase { -protected: - ASTContext &Ctx; - SourceLocation Loc; - - Decl *Dcl; - Stmt *Stm; - bool PassedLoc; - - /// \brief Checks whether Loc is in the source range of 'D'. - /// - /// If it is, updates Dcl. If Loc is passed the source range, it sets - /// PassedLoc, otherwise it does nothing. - void CheckRange(Decl *D); - - /// \brief Checks whether Loc is in the source range of 'Node'. - /// - /// If it is, updates Stm. If Loc is passed the source range, it sets - /// PassedLoc, otherwise it does nothing. - void CheckRange(Stmt *Node); - - /// \brief Updates the end source range to cover the full length of the token - /// positioned at the end of the source range. - /// - /// e.g., - /// @code - /// int foo - /// ^ ^ - /// @endcode - /// will be updated to - /// @code - /// int foo - /// ^ ^ - /// @endcode - void FixRange(SourceRange &Range); - -public: - LocResolverBase(ASTContext &ctx, SourceLocation loc) - : Ctx(ctx), Loc(loc), Dcl(0), Stm(0), PassedLoc(0) {} - - /// \brief We found a AST node that corresponds to the source location. - bool FoundIt() const { return Dcl != 0 || Stm != 0; } - - /// \brief We either found a AST node or we passed the source location while - /// searching. - bool Finished() const { return FoundIt() || PassedLoc; } - - Decl *getDecl() const { return Dcl; } - Stmt *getStmt() const { return Stm; } - - std::pair<Decl *, Stmt *> getResult() const { - return std::make_pair(getDecl(), getStmt()); - } - - /// \brief Debugging output. - void print(Decl *D); - /// \brief Debugging output. - void print(Stmt *Node); -}; - -/// \brief Searches a statement for the AST node that corresponds to a source -/// location. -class VISIBILITY_HIDDEN StmtLocResolver : public LocResolverBase, - public StmtVisitor<StmtLocResolver> { -public: - StmtLocResolver(ASTContext &ctx, SourceLocation loc) - : LocResolverBase(ctx, loc) {} - - void VisitDeclStmt(DeclStmt *Node); - void VisitStmt(Stmt *Node); -}; - -/// \brief Searches a declaration for the AST node that corresponds to a source -/// location. -class VISIBILITY_HIDDEN DeclLocResolver : public LocResolverBase, - public DeclVisitor<DeclLocResolver> { -public: - DeclLocResolver(ASTContext &ctx, SourceLocation loc) - : LocResolverBase(ctx, loc) {} - - void VisitDeclContext(DeclContext *DC); - void VisitTranslationUnitDecl(TranslationUnitDecl *TU); - void VisitVarDecl(VarDecl *D); - void VisitFunctionDecl(FunctionDecl *D); - void VisitDecl(Decl *D); -}; - -} // anonymous namespace - -void StmtLocResolver::VisitDeclStmt(DeclStmt *Node) { - CheckRange(Node); - if (!FoundIt()) - return; - assert(Stm == Node && "Result not updated ?"); - - // Search all declarations of this DeclStmt. If we found the one corresponding - // to the source location, update this StmtLocResolver's result. - DeclLocResolver DLR(Ctx, Loc); - for (DeclStmt::decl_iterator - I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) { - DLR.Visit(*I); - if (DLR.Finished()) { - if (DLR.FoundIt()) - llvm::tie(Dcl, Stm) = DLR.getResult(); - return; - } - } -} - -void StmtLocResolver::VisitStmt(Stmt *Node) { - CheckRange(Node); - if (!FoundIt()) - return; - assert(Stm == Node && "Result not updated ?"); - - // Search the child statements. - StmtLocResolver SLR(Ctx, Loc); - for (Stmt::child_iterator - I = Node->child_begin(), E = Node->child_end(); I != E; ++I) { - SLR.Visit(*I); - if (!SLR.Finished()) - continue; - - // We either found it or we passed the source location. - - if (SLR.FoundIt()) { - // Only update Dcl if we found another more immediate 'parent' Decl for - // the statement. - if (SLR.getDecl()) - Dcl = SLR.getDecl(); - Stm = SLR.getStmt(); - } - - return; - } -} - -void DeclLocResolver::VisitDeclContext(DeclContext *DC) { - DeclLocResolver DLR(Ctx, Loc); - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { - DLR.Visit(*I); - if (DLR.Finished()) { - if (DLR.FoundIt()) - llvm::tie(Dcl, Stm) = DLR.getResult(); - return; - } - } -} - -void DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { - VisitDeclContext(TU); -} - -void DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) { - CheckRange(D); - if (!FoundIt()) - return; - assert(Dcl == D && "Result not updated ?"); - - // First, search through the parameters of the function. - DeclLocResolver ParmRes(Ctx, Loc); - for (FunctionDecl::param_iterator - I = D->param_begin(), E = D->param_end(); I != E; ++I) { - ParmRes.Visit(*I); - if (ParmRes.Finished()) { - if (ParmRes.FoundIt()) - llvm::tie(Dcl, Stm) = ParmRes.getResult(); - return; - } - } - - // We didn't found the location in the parameters and we didn't get passed it. - - if (!D->isThisDeclarationADefinition()) - return; - - // Second, search through the declarations that are part of the function. - // If we find he location there, we won't have to search through its body. - - DeclLocResolver DLR(Ctx, Loc); - for (DeclContext::decl_iterator - I = D->decls_begin(), E = D->decls_end(); I != E; ++I) { - if (isa<ParmVarDecl>(*I)) - continue; // We already searched through the parameters. - - DLR.Visit(*I); - if (DLR.FoundIt()) { - llvm::tie(Dcl, Stm) = DLR.getResult(); - return; - } - } - - // We didn't find a declaration that corresponds to the source location. - - // Finally, search through the body of the function. - assert(D->getBody() && "Expected definition"); - StmtLocResolver SLR(Ctx, Loc); - SLR.Visit(D->getBody()); - if (SLR.FoundIt()) { - llvm::tie(Dcl, Stm) = SLR.getResult(); - // If we didn't find a more immediate 'parent' declaration for the - // statement, set the function as the parent. - if (Dcl == 0) - Dcl = D; - } -} - -void DeclLocResolver::VisitVarDecl(VarDecl *D) { - CheckRange(D); - if (!FoundIt()) - return; - assert(Dcl == D && "Result not updated ?"); - - // Check whether the location points to the init expression. - if (D->getInit()) { - StmtLocResolver SLR(Ctx, Loc); - SLR.Visit(D->getInit()); - Stm = SLR.getStmt(); - } -} - -void DeclLocResolver::VisitDecl(Decl *D) { - CheckRange(D); -} - -void LocResolverBase::CheckRange(Decl *D) { - SourceRange Range = D->getSourceRange(); - if (!Range.isValid()) - return; - - FixRange(Range); - - SourceManager &SourceMgr = Ctx.getSourceManager(); - if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc)) - return; - - if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin())) - PassedLoc = true; - else - Dcl = D; -} - -void LocResolverBase::CheckRange(Stmt *Node) { - SourceRange Range = Node->getSourceRange(); - if (!Range.isValid()) - return; - - FixRange(Range); - - SourceManager &SourceMgr = Ctx.getSourceManager(); - if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc)) - return; - - if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin())) - PassedLoc = true; - else - Stm = Node; -} - -void LocResolverBase::FixRange(SourceRange &Range) { - if (!Range.isValid()) - return; - - unsigned TokSize = Lexer::MeasureTokenLength(Range.getEnd(), - Ctx.getSourceManager(), - Ctx.getLangOptions()); - Range.setEnd(Range.getEnd().getFileLocWithOffset(TokSize-1)); -} - -void LocResolverBase::print(Decl *D) { - llvm::raw_ostream &OS = llvm::outs(); - OS << "#### DECL ####\n"; - D->print(OS); - OS << " <"; - D->getLocStart().print(OS, Ctx.getSourceManager()); - OS << " > - <"; - D->getLocEnd().print(OS, Ctx.getSourceManager()); - OS << ">\n\n"; - OS.flush(); -} - -void LocResolverBase::print(Stmt *Node) { - llvm::raw_ostream &OS = llvm::outs(); - OS << "#### STMT ####\n"; - Node->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions())); - OS << " <"; - Node->getLocStart().print(OS, Ctx.getSourceManager()); - OS << " > - <"; - Node->getLocEnd().print(OS, Ctx.getSourceManager()); - OS << ">\n\n"; - OS.flush(); -} - - -/// \brief Returns the AST node that a source location points to. -/// -ASTLocation clang::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc) { - if (Loc.isInvalid()) - return ASTLocation(); - - DeclLocResolver DLR(Ctx, Loc); - DLR.Visit(Ctx.getTranslationUnitDecl()); - return ASTLocation(DLR.getDecl(), DLR.getStmt()); -} |