blob: 0fa0d5a466f6ed0f779c21ce6ba5fd5774451e31 [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//
Argyrios Kyrtzidis6e4a86d2009-06-25 21:54:50 +000020// -point-at [file:column:line]
21// Point at a declaration/statement/expression. If no other operation is
22// specified, prints some info about it.
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +000023//
24//===----------------------------------------------------------------------===//
25
26#include "clang/Frontend/ASTUnit.h"
27#include "clang/Frontend/Utils.h"
28#include "clang/Frontend/CommandLineSourceLoc.h"
29#include "clang/AST/Decl.h"
30#include "clang/AST/Stmt.h"
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +000031#include "clang/AST/ASTNode.h"
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +000032#include "clang/Basic/FileManager.h"
33#include "clang/Basic/SourceManager.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/ManagedStatic.h"
37#include "llvm/Support/PrettyStackTrace.h"
38#include "llvm/Support/raw_ostream.h"
39#include "llvm/System/Signals.h"
40using namespace clang;
41
42
43static llvm::cl::list<ParsedSourceLocation>
44PointAtLocation("point-at", llvm::cl::Optional,
45 llvm::cl::value_desc("source-location"),
46 llvm::cl::desc("Point at the given source location of the first AST file"));
47
48static llvm::cl::opt<bool>
49DisableFree("disable-free",
50 llvm::cl::desc("Disable freeing of memory on exit"),
51 llvm::cl::init(false));
52
53static llvm::cl::list<std::string>
54InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
55
56int main(int argc, char **argv) {
57 llvm::sys::PrintStackTraceOnErrorSignal();
58 llvm::PrettyStackTraceProgram X(argc, argv);
59 llvm::cl::ParseCommandLineOptions(argc, argv,
60 "LLVM 'Clang' Indexing Test Bed: http://clang.llvm.org\n");
61
62 FileManager FileMgr;
63
64 // If no input was specified, read from stdin.
65 if (InputFilenames.empty())
66 InputFilenames.push_back("-");
67
68 // FIXME: Only the first AST file is used for now.
69
70 const std::string &InFile = InputFilenames[0];
71
72 std::string ErrMsg;
73 llvm::OwningPtr<ASTUnit> AST;
74
75 AST.reset(ASTUnit::LoadFromPCHFile(InFile, FileMgr, &ErrMsg));
76 if (!AST) {
77 llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
78 return 1;
79 }
80
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +000081 ASTNode Node;
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +000082
83 if (!PointAtLocation.empty()) {
84 const std::string &Filename = PointAtLocation[0].FileName;
85 const FileEntry *File = FileMgr.getFile(Filename);
Argyrios Kyrtzidis119b7fe2009-06-25 22:15:12 +000086
87 // Safety check. Using an out-of-date AST file will only lead to crashes
88 // or incorrect results.
89 // FIXME: Check all the source files that make up the AST file.
90 const FileEntry *ASTFile = FileMgr.getFile(InFile);
91 if (File->getModificationTime() > ASTFile->getModificationTime()) {
92 llvm::errs() << "[" << InFile << "] Error: " <<
93 "Pointing at a source file which was modified after creating "
94 "the AST file\n";
95 return 1;
96 }
97
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +000098 if (File == 0) {
99 llvm::errs() << "File '" << Filename << "' does not exist\n";
100 return 1;
101 }
102 unsigned Line = PointAtLocation[0].Line;
103 unsigned Col = PointAtLocation[0].Column;
104
105 SourceLocation Loc = AST->getSourceManager().getLocation(File, Line, Col);
106 if (Loc.isInvalid()) {
107 llvm::errs() << "[" << InFile << "] Error: " <<
108 "Couldn't resolve source location (invalid location)\n";
109 return 1;
110 }
111
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000112 Node = ResolveLocationInAST(AST->getASTContext(), Loc);
113 if (Node.isInvalid()) {
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +0000114 llvm::errs() << "[" << InFile << "] Error: " <<
115 "Couldn't resolve source location (no declaration found)\n";
116 return 1;
117 }
118 }
119
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000120 if (Node.isValid()) {
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +0000121 llvm::raw_ostream &OS = llvm::outs();
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000122 OS << "Declaration node at point: " << Node.getDecl()->getDeclKindName()
123 << " ";
124 if (NamedDecl *ND = dyn_cast<NamedDecl>(Node.getDecl()))
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +0000125 OS << ND->getNameAsString();
126 OS << "\n";
127
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000128 if (const char *Comment =
129 AST->getASTContext().getCommentForDecl(Node.getDecl()))
Douglas Gregor2e222532009-07-02 17:08:52 +0000130 OS << "Comment associated with this declaration:\n" << Comment << "\n";
131
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000132 if (Node.getStmt()) {
133 OS << "Statement node at point: " << Node.getStmt()->getStmtClassName()
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +0000134 << " ";
Argyrios Kyrtzidis49dd5852009-07-05 22:21:40 +0000135 Node.getStmt()->printPretty(OS, AST->getASTContext(), 0,
136 PrintingPolicy(AST->getASTContext().getLangOptions()));
Argyrios Kyrtzidis30b983b2009-06-25 18:22:52 +0000137 OS << "\n";
138 }
139 }
140
141 if (DisableFree)
142 AST.take();
143
144 // Managed static deconstruction. Useful for making things like
145 // -time-passes usable.
146 llvm::llvm_shutdown();
147
148 return 0;
149}