]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/lib/Index/ASTLocation.cpp
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / lib / Index / ASTLocation.cpp
1 //===--- ASTLocation.cpp - A <Decl, Stmt> pair ------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  ASTLocation is Decl or a Stmt and its immediate Decl parent.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/Index/ASTLocation.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/Stmt.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprObjC.h"
20 using namespace clang;
21 using namespace idx;
22
23 static Decl *getDeclFromExpr(Stmt *E) {
24   if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
25     return RefExpr->getDecl();
26   if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
27     return ME->getMemberDecl();
28   if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
29     return RE->getDecl();
30
31   if (CallExpr *CE = dyn_cast<CallExpr>(E))
32     return getDeclFromExpr(CE->getCallee());
33   if (CastExpr *CE = dyn_cast<CastExpr>(E))
34     return getDeclFromExpr(CE->getSubExpr());
35
36   return 0;
37 }
38
39 Decl *ASTLocation::getReferencedDecl() {
40   if (isInvalid())
41     return 0;
42
43   switch (getKind()) {
44   default: llvm_unreachable("Invalid Kind");
45   case N_Type:
46     return 0;
47   case N_Decl:
48     return D;
49   case N_NamedRef:
50     return NDRef.ND;
51   case N_Stmt:
52     return getDeclFromExpr(Stm);
53   }
54   
55   return 0;
56 }
57
58 SourceRange ASTLocation::getSourceRange() const {
59   if (isInvalid())
60     return SourceRange();
61
62   switch (getKind()) {
63   default: llvm_unreachable("Invalid Kind");
64   case N_Decl:
65     return D->getSourceRange();
66   case N_Stmt:
67     return Stm->getSourceRange();
68   case N_NamedRef:
69     return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
70   case N_Type:
71     return AsTypeLoc().getLocalSourceRange();
72   }
73   
74   return SourceRange();
75 }
76
77 void ASTLocation::print(raw_ostream &OS) const {
78   if (isInvalid()) {
79     OS << "<< Invalid ASTLocation >>\n";
80     return;
81   }
82   
83   ASTContext &Ctx = getParentDecl()->getASTContext();
84
85   switch (getKind()) {
86   case N_Decl:
87     OS << "[Decl: " << AsDecl()->getDeclKindName() << " ";
88     if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl()))
89       OS << *ND;
90     break;
91
92   case N_Stmt:
93     OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
94     AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
95     break;
96     
97   case N_NamedRef:
98     OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " ";
99     OS << *AsNamedRef().ND;
100     break;
101     
102   case N_Type: {
103     QualType T = AsTypeLoc().getType();
104     OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
105   }
106   }
107
108   OS << "] <";
109
110   SourceRange Range = getSourceRange();
111   SourceManager &SourceMgr = Ctx.getSourceManager();
112   Range.getBegin().print(OS, SourceMgr);
113   OS << ", ";
114   Range.getEnd().print(OS, SourceMgr);
115   OS << ">\n";
116 }