clang API Documentation

ASTLocation.cpp
Go to the documentation of this file.
00001 //===--- ASTLocation.cpp - A <Decl, Stmt> pair ------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  ASTLocation is Decl or a Stmt and its immediate Decl parent.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Index/ASTLocation.h"
00015 #include "clang/AST/Decl.h"
00016 #include "clang/AST/DeclObjC.h"
00017 #include "clang/AST/Stmt.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/AST/ExprObjC.h"
00020 using namespace clang;
00021 using namespace idx;
00022 
00023 static Decl *getDeclFromExpr(Stmt *E) {
00024   if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
00025     return RefExpr->getDecl();
00026   if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
00027     return ME->getMemberDecl();
00028   if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
00029     return RE->getDecl();
00030 
00031   if (CallExpr *CE = dyn_cast<CallExpr>(E))
00032     return getDeclFromExpr(CE->getCallee());
00033   if (CastExpr *CE = dyn_cast<CastExpr>(E))
00034     return getDeclFromExpr(CE->getSubExpr());
00035 
00036   return 0;
00037 }
00038 
00039 Decl *ASTLocation::getReferencedDecl() {
00040   if (isInvalid())
00041     return 0;
00042 
00043   switch (getKind()) {
00044   case N_Type:
00045     return 0;
00046   case N_Decl:
00047     return D;
00048   case N_NamedRef:
00049     return NDRef.ND;
00050   case N_Stmt:
00051     return getDeclFromExpr(Stm);
00052   }
00053 
00054   llvm_unreachable("Invalid ASTLocation Kind!");
00055 }
00056 
00057 SourceRange ASTLocation::getSourceRange() const {
00058   if (isInvalid())
00059     return SourceRange();
00060 
00061   switch (getKind()) {
00062   case N_Decl:
00063     return D->getSourceRange();
00064   case N_Stmt:
00065     return Stm->getSourceRange();
00066   case N_NamedRef:
00067     return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
00068   case N_Type:
00069     return AsTypeLoc().getLocalSourceRange();
00070   }
00071 
00072   llvm_unreachable("Invalid ASTLocation Kind!");
00073 }
00074 
00075 void ASTLocation::print(raw_ostream &OS) const {
00076   if (isInvalid()) {
00077     OS << "<< Invalid ASTLocation >>\n";
00078     return;
00079   }
00080   
00081   ASTContext &Ctx = getParentDecl()->getASTContext();
00082 
00083   switch (getKind()) {
00084   case N_Decl:
00085     OS << "[Decl: " << AsDecl()->getDeclKindName() << " ";
00086     if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl()))
00087       OS << *ND;
00088     break;
00089 
00090   case N_Stmt:
00091     OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
00092     AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOpts()));
00093     break;
00094     
00095   case N_NamedRef:
00096     OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " ";
00097     OS << *AsNamedRef().ND;
00098     break;
00099     
00100   case N_Type: {
00101     QualType T = AsTypeLoc().getType();
00102     OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
00103   }
00104   }
00105 
00106   OS << "] <";
00107 
00108   SourceRange Range = getSourceRange();
00109   SourceManager &SourceMgr = Ctx.getSourceManager();
00110   Range.getBegin().print(OS, SourceMgr);
00111   OS << ", ";
00112   Range.getEnd().print(OS, SourceMgr);
00113   OS << ">\n";
00114 }