blob: a1494e4e1e390d25fbdcbbc800828f4ac5431357 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- ASTStreamers.cpp - ASTStreamer Drivers ---------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Bill Wendling and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// ASTStreamer drivers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ASTStreamers.h"
15#include "clang/AST/AST.h"
Ted Kremenek97f75312007-08-21 21:42:03 +000016#include "clang/AST/CFG.h"
Ted Kremenekaa04c512007-09-06 00:17:54 +000017#include "clang/Analysis/LiveVariables.h"
Chris Lattner4b009652007-07-25 00:24:17 +000018#include "clang/Lex/Preprocessor.h"
19#include "clang/Sema/ASTStreamer.h"
Chris Lattner95578782007-08-08 22:51:59 +000020using namespace clang;
Chris Lattner4b009652007-07-25 00:24:17 +000021
22void clang::BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
23 // collect global stats on Decls/Stmts (until we have a module streamer)
24 if (Stats) {
25 Decl::CollectingStats(true);
26 Stmt::CollectingStats(true);
27 }
28
29 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
30 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
31
32 while (ASTStreamer_ReadTopLevelDecl(Streamer))
33 /* keep reading */;
34
35 if (Stats) {
36 fprintf(stderr, "\nSTATISTICS:\n");
37 ASTStreamer_PrintStats(Streamer);
38 Context.PrintStats();
39 Decl::PrintStats();
40 Stmt::PrintStats();
41 }
42
43 ASTStreamer_Terminate(Streamer);
44}
45
Chris Lattner95578782007-08-08 22:51:59 +000046
47
48static void PrintFunctionDeclStart(FunctionDecl *FD) {
Chris Lattner4b009652007-07-25 00:24:17 +000049 bool HasBody = FD->getBody();
50
Chris Lattner987058a2007-08-26 04:02:13 +000051 fprintf(stderr, "\n");
52
53 switch (FD->getStorageClass()) {
54 default: assert(0 && "Unknown storage class");
55 case FunctionDecl::None: break;
56 case FunctionDecl::Extern: fprintf(stderr, "extern "); break;
57 case FunctionDecl::Static: fprintf(stderr, "static "); break;
58 }
59
60 if (FD->isInline())
61 fprintf(stderr, "inline ");
62
Chris Lattner4b009652007-07-25 00:24:17 +000063 std::string Proto = FD->getName();
64 FunctionType *AFT = cast<FunctionType>(FD->getType());
65
66 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
67 Proto += "(";
68 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
69 if (i) Proto += ", ";
70 std::string ParamStr;
71 if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
72
73 FT->getArgType(i).getAsStringInternal(ParamStr);
74 Proto += ParamStr;
75 }
76
77 if (FT->isVariadic()) {
78 if (FD->getNumParams()) Proto += ", ";
79 Proto += "...";
80 }
81 Proto += ")";
82 } else {
83 assert(isa<FunctionTypeNoProto>(AFT));
84 Proto += "()";
85 }
86
87 AFT->getResultType().getAsStringInternal(Proto);
Chris Lattner987058a2007-08-26 04:02:13 +000088 fprintf(stderr, "%s", Proto.c_str());
Chris Lattner4b009652007-07-25 00:24:17 +000089
Chris Lattner95578782007-08-08 22:51:59 +000090 if (!FD->getBody())
Chris Lattner4b009652007-07-25 00:24:17 +000091 fprintf(stderr, ";\n");
Chris Lattner95578782007-08-08 22:51:59 +000092 // Doesn't print the body.
Chris Lattner4b009652007-07-25 00:24:17 +000093}
94
Chris Lattner95578782007-08-08 22:51:59 +000095static void PrintTypeDefDecl(TypedefDecl *TD) {
Chris Lattner4b009652007-07-25 00:24:17 +000096 std::string S = TD->getName();
97 TD->getUnderlyingType().getAsStringInternal(S);
98 fprintf(stderr, "typedef %s;\n", S.c_str());
99}
100
101void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
102 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
103 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
104
105 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
106 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Chris Lattner95578782007-08-08 22:51:59 +0000107 PrintFunctionDeclStart(FD);
108
109 if (FD->getBody()) {
110 fprintf(stderr, " ");
111 FD->getBody()->dumpPretty();
112 fprintf(stderr, "\n");
113 }
Chris Lattner4b009652007-07-25 00:24:17 +0000114 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
115 PrintTypeDefDecl(TD);
116 } else {
117 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
118 }
119 }
120
121 if (Stats) {
122 fprintf(stderr, "\nSTATISTICS:\n");
123 ASTStreamer_PrintStats(Streamer);
124 Context.PrintStats();
125 }
126
127 ASTStreamer_Terminate(Streamer);
128}
Chris Lattner95578782007-08-08 22:51:59 +0000129
130void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
131 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
132 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
133
134 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
135 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
136 PrintFunctionDeclStart(FD);
137
138 if (FD->getBody()) {
139 fprintf(stderr, "\n");
Chris Lattnerbbc51ad2007-08-30 00:40:08 +0000140 FD->getBody()->dumpAll(PP.getSourceManager());
Chris Lattner95578782007-08-08 22:51:59 +0000141 fprintf(stderr, "\n");
142 }
143 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
144 PrintTypeDefDecl(TD);
145 } else {
146 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
147 }
148 }
149
150 if (Stats) {
151 fprintf(stderr, "\nSTATISTICS:\n");
152 ASTStreamer_PrintStats(Streamer);
153 Context.PrintStats();
154 }
155
156 ASTStreamer_Terminate(Streamer);
157}
158
Ted Kremenekb3bb91b2007-08-29 21:56:09 +0000159void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
160 bool Stats, bool use_graphviz)
161{
Ted Kremenek97f75312007-08-21 21:42:03 +0000162 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
163 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
164
165 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
166 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
167 if (FD->getBody()) {
168 PrintFunctionDeclStart(FD);
169 fprintf(stderr,"\n");
Ted Kremenekb3bb91b2007-08-29 21:56:09 +0000170 if (CFG* C = CFG::buildCFG(FD->getBody())) {
171 if (use_graphviz) C->viewCFG(); else C->dump();
172 }
Ted Kremenek97f75312007-08-21 21:42:03 +0000173 else
174 fprintf(stderr," Error processing CFG.\n");
175 }
176 }
177 }
178
179 if (Stats) {
180 fprintf(stderr, "\nSTATISTICS:\n");
181 ASTStreamer_PrintStats(Streamer);
182 Context.PrintStats();
183 }
184
185 ASTStreamer_Terminate(Streamer);
186}
187
Ted Kremenekaa04c512007-09-06 00:17:54 +0000188void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID)
189{
190 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
191 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
192
193 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
194 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
195 if (FD->getBody()) {
196 PrintFunctionDeclStart(FD);
197 fprintf(stderr,"\n");
198 if (CFG* C = CFG::buildCFG(FD->getBody())) {
199 LiveVariables L;
200 L.runOnCFG(*C);
201 L.DumpBlockLiveness();
202 }
203 else
204 fprintf(stderr," Error processing CFG.\n");
205 }
206 }
207 }
208
209 ASTStreamer_Terminate(Streamer);
210}
211
Chris Lattner95578782007-08-08 22:51:59 +0000212