blob: 95d39fa35287f2b06be8066e90c76a59a5c4fd28 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +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 Kremenekfddd5182007-08-21 21:42:03 +000016#include "clang/AST/CFG.h"
Ted Kremeneke4e63342007-09-06 00:17:54 +000017#include "clang/Analysis/LiveVariables.h"
Ted Kremenek055c2752007-09-06 23:00:42 +000018#include "clang/Analysis/LocalCheckers.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000019#include "clang/Lex/Preprocessor.h"
20#include "clang/Sema/ASTStreamer.h"
Chris Lattner6000dac2007-08-08 22:51:59 +000021using namespace clang;
Reid Spencer5f016e22007-07-11 17:01:13 +000022
23void clang::BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
24 // collect global stats on Decls/Stmts (until we have a module streamer)
25 if (Stats) {
26 Decl::CollectingStats(true);
27 Stmt::CollectingStats(true);
28 }
29
30 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
31 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
32
33 while (ASTStreamer_ReadTopLevelDecl(Streamer))
34 /* keep reading */;
35
36 if (Stats) {
37 fprintf(stderr, "\nSTATISTICS:\n");
38 ASTStreamer_PrintStats(Streamer);
39 Context.PrintStats();
40 Decl::PrintStats();
41 Stmt::PrintStats();
42 }
43
44 ASTStreamer_Terminate(Streamer);
45}
46
Chris Lattner6000dac2007-08-08 22:51:59 +000047
48
49static void PrintFunctionDeclStart(FunctionDecl *FD) {
Reid Spencer5f016e22007-07-11 17:01:13 +000050 bool HasBody = FD->getBody();
51
Chris Lattner70c8b2e2007-08-26 04:02:13 +000052 fprintf(stderr, "\n");
53
54 switch (FD->getStorageClass()) {
55 default: assert(0 && "Unknown storage class");
56 case FunctionDecl::None: break;
57 case FunctionDecl::Extern: fprintf(stderr, "extern "); break;
58 case FunctionDecl::Static: fprintf(stderr, "static "); break;
59 }
60
61 if (FD->isInline())
62 fprintf(stderr, "inline ");
63
Reid Spencer5f016e22007-07-11 17:01:13 +000064 std::string Proto = FD->getName();
65 FunctionType *AFT = cast<FunctionType>(FD->getType());
66
67 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
68 Proto += "(";
69 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
70 if (i) Proto += ", ";
71 std::string ParamStr;
72 if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
73
74 FT->getArgType(i).getAsStringInternal(ParamStr);
75 Proto += ParamStr;
76 }
77
78 if (FT->isVariadic()) {
79 if (FD->getNumParams()) Proto += ", ";
80 Proto += "...";
81 }
82 Proto += ")";
83 } else {
84 assert(isa<FunctionTypeNoProto>(AFT));
85 Proto += "()";
86 }
87
88 AFT->getResultType().getAsStringInternal(Proto);
Chris Lattner70c8b2e2007-08-26 04:02:13 +000089 fprintf(stderr, "%s", Proto.c_str());
Reid Spencer5f016e22007-07-11 17:01:13 +000090
Chris Lattner6000dac2007-08-08 22:51:59 +000091 if (!FD->getBody())
Reid Spencer5f016e22007-07-11 17:01:13 +000092 fprintf(stderr, ";\n");
Chris Lattner6000dac2007-08-08 22:51:59 +000093 // Doesn't print the body.
Reid Spencer5f016e22007-07-11 17:01:13 +000094}
95
Chris Lattner6000dac2007-08-08 22:51:59 +000096static void PrintTypeDefDecl(TypedefDecl *TD) {
Reid Spencer5f016e22007-07-11 17:01:13 +000097 std::string S = TD->getName();
98 TD->getUnderlyingType().getAsStringInternal(S);
99 fprintf(stderr, "typedef %s;\n", S.c_str());
100}
101
102void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
103 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
104 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
105
106 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
107 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Chris Lattner6000dac2007-08-08 22:51:59 +0000108 PrintFunctionDeclStart(FD);
109
110 if (FD->getBody()) {
111 fprintf(stderr, " ");
112 FD->getBody()->dumpPretty();
113 fprintf(stderr, "\n");
114 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000115 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
116 PrintTypeDefDecl(TD);
117 } else {
118 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
119 }
120 }
121
122 if (Stats) {
123 fprintf(stderr, "\nSTATISTICS:\n");
124 ASTStreamer_PrintStats(Streamer);
125 Context.PrintStats();
126 }
127
128 ASTStreamer_Terminate(Streamer);
129}
Chris Lattner6000dac2007-08-08 22:51:59 +0000130
131void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
132 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
133 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
134
135 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
136 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
137 PrintFunctionDeclStart(FD);
138
139 if (FD->getBody()) {
140 fprintf(stderr, "\n");
Chris Lattner0c727a32007-08-30 00:40:08 +0000141 FD->getBody()->dumpAll(PP.getSourceManager());
Chris Lattner6000dac2007-08-08 22:51:59 +0000142 fprintf(stderr, "\n");
143 }
144 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
145 PrintTypeDefDecl(TD);
146 } else {
147 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
148 }
149 }
150
151 if (Stats) {
152 fprintf(stderr, "\nSTATISTICS:\n");
153 ASTStreamer_PrintStats(Streamer);
154 Context.PrintStats();
155 }
156
157 ASTStreamer_Terminate(Streamer);
158}
159
Ted Kremenek7dba8602007-08-29 21:56:09 +0000160void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
161 bool Stats, bool use_graphviz)
162{
Ted Kremenekfddd5182007-08-21 21:42:03 +0000163 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
164 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
165
166 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
167 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
168 if (FD->getBody()) {
169 PrintFunctionDeclStart(FD);
170 fprintf(stderr,"\n");
Ted Kremenek7dba8602007-08-29 21:56:09 +0000171 if (CFG* C = CFG::buildCFG(FD->getBody())) {
172 if (use_graphviz) C->viewCFG(); else C->dump();
173 }
Ted Kremenekfddd5182007-08-21 21:42:03 +0000174 else
175 fprintf(stderr," Error processing CFG.\n");
176 }
177 }
178 }
179
180 if (Stats) {
181 fprintf(stderr, "\nSTATISTICS:\n");
182 ASTStreamer_PrintStats(Streamer);
183 Context.PrintStats();
184 }
185
186 ASTStreamer_Terminate(Streamer);
187}
188
Ted Kremeneke4e63342007-09-06 00:17:54 +0000189void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID)
190{
191 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
192 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
193
194 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
195 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
196 if (FD->getBody()) {
197 PrintFunctionDeclStart(FD);
198 fprintf(stderr,"\n");
199 if (CFG* C = CFG::buildCFG(FD->getBody())) {
200 LiveVariables L;
201 L.runOnCFG(*C);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000202 L.dumpBlockLiveness(PP.getSourceManager());
Ted Kremeneke4e63342007-09-06 00:17:54 +0000203 }
204 else
205 fprintf(stderr," Error processing CFG.\n");
206 }
207 }
208 }
209
210 ASTStreamer_Terminate(Streamer);
211}
212
Ted Kremenek055c2752007-09-06 23:00:42 +0000213void clang::RunDeadStoresCheck(Preprocessor &PP, unsigned MainFileID,bool Stats)
214{
215 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
216 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
217
218 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
219 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
220 if (FD->getBody()) {
221 if (CFG* C = CFG::buildCFG(FD->getBody())) {
222 clang::CheckDeadStores(*C,PP);
223 }
224 else
225 fprintf(stderr," Error processing CFG.\n");
226 }
227 }
228 }
229
230 if (Stats) {
231 fprintf(stderr, "\nSTATISTICS:\n");
232 ASTStreamer_PrintStats(Streamer);
233 Context.PrintStats();
234 }
235
236 ASTStreamer_Terminate(Streamer);
237}
238
Chris Lattner6000dac2007-08-08 22:51:59 +0000239