blob: 0acaf7803cfa375016c276e0fba9ebeb28056bb9 [file] [log] [blame]
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +00001//===--- index-test.cpp - Indexing test bed -------------------------------===//
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// This utility may be invoked in the following manner:
11// index-test --help - Output help info.
12// index-test [options] - Read from stdin.
13// index-test [options] file - Read from "file".
14// index-test [options] file1 file2 - Read these files.
15//
16// Files must be AST files.
17//
18//===----------------------------------------------------------------------===//
19//
20// -Wfatal-errors
21// -ftabstop=width
22//
23//===----------------------------------------------------------------------===//
24
25#include "clang/Frontend/ASTUnit.h"
26#include "clang/Frontend/Utils.h"
27#include "clang/Frontend/CommandLineSourceLoc.h"
28#include "clang/AST/Decl.h"
29#include "clang/AST/Stmt.h"
30#include "clang/Basic/FileManager.h"
31#include "clang/Basic/SourceManager.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/Support/CommandLine.h"
34#include "llvm/Support/ManagedStatic.h"
35#include "llvm/Support/PrettyStackTrace.h"
36#include "llvm/Support/raw_ostream.h"
37#include "llvm/System/Signals.h"
38using namespace clang;
39
40
41static llvm::cl::list<ParsedSourceLocation>
42PointAtLocation("point-at", llvm::cl::Optional,
43 llvm::cl::value_desc("source-location"),
44 llvm::cl::desc("Point at the given source location of the first AST file"));
45
46static llvm::cl::opt<bool>
47DisableFree("disable-free",
48 llvm::cl::desc("Disable freeing of memory on exit"),
49 llvm::cl::init(false));
50
51static llvm::cl::list<std::string>
52InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
53
54int main(int argc, char **argv) {
55 llvm::sys::PrintStackTraceOnErrorSignal();
56 llvm::PrettyStackTraceProgram X(argc, argv);
57 llvm::cl::ParseCommandLineOptions(argc, argv,
58 "LLVM 'Clang' Indexing Test Bed: http://clang.llvm.org\n");
59
60 FileManager FileMgr;
61
62 // If no input was specified, read from stdin.
63 if (InputFilenames.empty())
64 InputFilenames.push_back("-");
65
66 // FIXME: Only the first AST file is used for now.
67
68 const std::string &InFile = InputFilenames[0];
69
70 std::string ErrMsg;
71 llvm::OwningPtr<ASTUnit> AST;
72
73 AST.reset(ASTUnit::LoadFromPCHFile(InFile, FileMgr, &ErrMsg));
74 if (!AST) {
75 llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
76 return 1;
77 }
78
79 struct ASTPoint {
80 Decl *D;
81 Stmt *Node;
82 ASTPoint() : D(0), Node(0) {}
83 };
84
85 ASTPoint Point;
86
87 if (!PointAtLocation.empty()) {
88 const std::string &Filename = PointAtLocation[0].FileName;
89 const FileEntry *File = FileMgr.getFile(Filename);
90 if (File == 0) {
91 llvm::errs() << "File '" << Filename << "' does not exist\n";
92 return 1;
93 }
94 unsigned Line = PointAtLocation[0].Line;
95 unsigned Col = PointAtLocation[0].Column;
96
97 SourceLocation Loc = AST->getSourceManager().getLocation(File, Line, Col);
98 if (Loc.isInvalid()) {
99 llvm::errs() << "[" << InFile << "] Error: " <<
100 "Couldn't resolve source location (invalid location)\n";
101 return 1;
102 }
103
104 llvm::tie(Point.D, Point.Node) =
105 ResolveLocationInAST(AST->getASTContext(), Loc);
106 if (Point.D == 0) {
107 llvm::errs() << "[" << InFile << "] Error: " <<
108 "Couldn't resolve source location (no declaration found)\n";
109 return 1;
110 }
111 }
112
113 if (Point.D) {
114 if (PointAtLocation.empty()) {
115 llvm::errs() << "'-print-point-info' should be used together "
116 "with '-point-at'\n";
117 return 1;
118 }
119
120 llvm::raw_ostream &OS = llvm::outs();
121 assert(Point.D && "If no node was found we should have exited with error");
122 OS << "Declaration node at point: " << Point.D->getDeclKindName() << " ";
123 if (NamedDecl *ND = dyn_cast<NamedDecl>(Point.D))
124 OS << ND->getNameAsString();
125 OS << "\n";
126
127 if (Point.Node) {
128 OS << "Statement node at point: " << Point.Node->getStmtClassName()
129 << " ";
130 Point.Node->printPretty(OS, AST->getASTContext());
131 OS << "\n";
132 }
133 }
134
135 if (DisableFree)
136 AST.take();
137
138 // Managed static deconstruction. Useful for making things like
139 // -time-passes usable.
140 llvm::llvm_shutdown();
141
142 return 0;
143}