clang API Documentation
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 }