blob: e347ccb832a3bef3f609b7da2ed85ac59e758dac [file] [log] [blame]
Chris Lattnereb8c9632007-10-07 06:04:32 +00001//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
Chris Lattner4b009652007-07-25 00:24:17 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnereb8c9632007-10-07 06:04:32 +00005// This file was developed by Chris Lattner and is distributed under the
Chris Lattner4b009652007-07-25 00:24:17 +00006// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnereb8c9632007-10-07 06:04:32 +000010// AST Consumer Implementations.
Chris Lattner4b009652007-07-25 00:24:17 +000011//
12//===----------------------------------------------------------------------===//
13
Chris Lattnereb8c9632007-10-07 06:04:32 +000014#include "ASTConsumers.h"
Chris Lattner4b009652007-07-25 00:24:17 +000015#include "clang/AST/AST.h"
Chris Lattnerb73abd52007-09-15 23:02:28 +000016#include "clang/AST/ASTConsumer.h"
Ted Kremenek97f75312007-08-21 21:42:03 +000017#include "clang/AST/CFG.h"
Ted Kremenekaa04c512007-09-06 00:17:54 +000018#include "clang/Analysis/LiveVariables.h"
Ted Kremeneke805c4a2007-09-06 23:00:42 +000019#include "clang/Analysis/LocalCheckers.h"
Chris Lattner95578782007-08-08 22:51:59 +000020using namespace clang;
Chris Lattner4b009652007-07-25 00:24:17 +000021
Chris Lattner95578782007-08-08 22:51:59 +000022
23static void PrintFunctionDeclStart(FunctionDecl *FD) {
Chris Lattner4b009652007-07-25 00:24:17 +000024 bool HasBody = FD->getBody();
25
Chris Lattner987058a2007-08-26 04:02:13 +000026 fprintf(stderr, "\n");
27
28 switch (FD->getStorageClass()) {
29 default: assert(0 && "Unknown storage class");
30 case FunctionDecl::None: break;
31 case FunctionDecl::Extern: fprintf(stderr, "extern "); break;
32 case FunctionDecl::Static: fprintf(stderr, "static "); break;
33 }
34
35 if (FD->isInline())
36 fprintf(stderr, "inline ");
37
Chris Lattner4b009652007-07-25 00:24:17 +000038 std::string Proto = FD->getName();
39 FunctionType *AFT = cast<FunctionType>(FD->getType());
40
41 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
42 Proto += "(";
43 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
44 if (i) Proto += ", ";
45 std::string ParamStr;
46 if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
47
48 FT->getArgType(i).getAsStringInternal(ParamStr);
49 Proto += ParamStr;
50 }
51
52 if (FT->isVariadic()) {
53 if (FD->getNumParams()) Proto += ", ";
54 Proto += "...";
55 }
56 Proto += ")";
57 } else {
58 assert(isa<FunctionTypeNoProto>(AFT));
59 Proto += "()";
60 }
61
62 AFT->getResultType().getAsStringInternal(Proto);
Chris Lattner987058a2007-08-26 04:02:13 +000063 fprintf(stderr, "%s", Proto.c_str());
Chris Lattner4b009652007-07-25 00:24:17 +000064
Chris Lattner95578782007-08-08 22:51:59 +000065 if (!FD->getBody())
Chris Lattner4b009652007-07-25 00:24:17 +000066 fprintf(stderr, ";\n");
Chris Lattner95578782007-08-08 22:51:59 +000067 // Doesn't print the body.
Chris Lattner4b009652007-07-25 00:24:17 +000068}
69
Chris Lattner95578782007-08-08 22:51:59 +000070static void PrintTypeDefDecl(TypedefDecl *TD) {
Chris Lattner4b009652007-07-25 00:24:17 +000071 std::string S = TD->getName();
72 TD->getUnderlyingType().getAsStringInternal(S);
73 fprintf(stderr, "typedef %s;\n", S.c_str());
74}
75
Fariborz Jahanian83ddf822007-11-10 20:59:13 +000076static void PrintObjcMethodDecl(ObjcMethodDecl *OMD) {
77 if (OMD->isInstance())
78 fprintf(stderr, "\n- ");
79 else
80 fprintf(stderr, "\n+ ");
81 if (!OMD->getResultType().isNull())
82 fprintf(stderr, "(%s) ", OMD->getResultType().getAsString().c_str());
83 // FIXME: just print original selector name!
84 fprintf(stderr, "%s ", OMD->getSelector().getName().c_str());
85
86 for (int i = 0; i < OMD->getNumParams(); i++) {
87 ParmVarDecl *PDecl = OMD->getParamDecl(i);
88 // FIXME: selector is missing here!
89 fprintf(stderr, " :(%s) %s", PDecl->getType().getAsString().c_str(),
90 PDecl->getName());
91 }
92}
93
94static void PrintObjcImplementationDecl(ObjcImplementationDecl *OID) {
95 std::string I = OID->getName();
96 ObjcInterfaceDecl *SID = OID->getSuperClass();
97 if (SID) {
98 std::string S = SID->getName();
99 fprintf(stderr, "@implementation %s : %s", I.c_str(), S.c_str());
100 }
101 else
102 fprintf(stderr, "@implementation %s", I.c_str());
103
104 for (int i = 0; i < OID->getNumInstanceMethods(); i++) {
105 PrintObjcMethodDecl(OID->getInstanceMethods()[i]);
106 ObjcMethodDecl *OMD = OID->getInstanceMethods()[i];
107 if (OMD->getBody()) {
108 fprintf(stderr, " ");
109 OMD->getBody()->dumpPretty();
110 fprintf(stderr, "\n");
111 }
112 }
113
114 for (int i = 0; i < OID->getNumClassMethods(); i++) {
115 PrintObjcMethodDecl(OID->getClassMethods()[i]);
116 ObjcMethodDecl *OMD = OID->getClassMethods()[i];
117 if (OMD->getBody()) {
118 fprintf(stderr, " ");
119 OMD->getBody()->dumpPretty();
120 fprintf(stderr, "\n");
121 }
122 }
123
124 fprintf(stderr,"@end\n");
125}
126
127
Steve Narofffaed3bf2007-09-10 20:51:04 +0000128static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) {
Fariborz Jahanianc04aff12007-10-08 23:06:41 +0000129 std::string I = OID->getName();
130 ObjcInterfaceDecl *SID = OID->getSuperClass();
131 if (SID) {
132 std::string S = SID->getName();
133 fprintf(stderr, "@interface %s : %s", I.c_str(), S.c_str());
134 }
135 else
136 fprintf(stderr, "@interface %s", I.c_str());
137 // Protocols?
138 int count = OID->getNumIntfRefProtocols();
139 if (count > 0) {
140 ObjcProtocolDecl **refProtocols = OID->getReferencedProtocols();
141 for (int i = 0; i < count; i++)
142 fprintf(stderr, "%c%s", (i == 0 ? '<' : ','),
143 refProtocols[i]->getName());
144 }
145 if (count > 0)
Fariborz Jahanianf468b312007-10-26 16:29:12 +0000146 fprintf(stderr, ">\n");
Fariborz Jahanianc04aff12007-10-08 23:06:41 +0000147 else
Fariborz Jahanianf468b312007-10-26 16:29:12 +0000148 fprintf(stderr, "\n");
149
Steve Naroffdd2e26c2007-11-12 13:56:41 +0000150 int NumIvars = OID->getNumInstanceVariables();
Fariborz Jahanianf468b312007-10-26 16:29:12 +0000151 if (NumIvars > 0) {
Steve Naroffdd2e26c2007-11-12 13:56:41 +0000152 ObjcIvarDecl **Ivars = OID->getInstanceVariables();
Fariborz Jahanianf468b312007-10-26 16:29:12 +0000153 fprintf(stderr,"{");
154 for (int i = 0; i < NumIvars; i++) {
155 fprintf(stderr, "\t%s %s;\n", Ivars[i]->getType().getAsString().c_str(),
156 Ivars[i]->getName());
157 }
Fariborz Jahaniand8df6d82007-11-06 22:01:00 +0000158 fprintf(stderr, "}\n");
Fariborz Jahanianf468b312007-10-26 16:29:12 +0000159 }
Fariborz Jahaniand8df6d82007-11-06 22:01:00 +0000160
161 int NumProperties = OID->getNumPropertyDecl();
162 if (NumProperties > 0) {
163 for (int i = 0; i < NumProperties; i++) {
164 ObjcPropertyDecl *PDecl = OID->getPropertyDecl()[i];
165 fprintf(stderr, "@property");
166 if (PDecl->getPropertyAttributes() != ObjcPropertyDecl::OBJC_PR_noattr) {
167 bool first = true;
168 fprintf(stderr, " (");
169 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readonly)
170 {
171 fprintf(stderr, "%creadonly", first ? ' ' : ',');
172 first = false;
173 }
174
175 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_getter)
176 {
177 fprintf(stderr, "%cgetter = %s", first ? ' ' : ','
178 , PDecl->getGetterName()->getName());
179 first = false;
180 }
181 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_setter)
182 {
183 fprintf(stderr, "%csetter = %s:", first ? ' ' : ','
184 , PDecl->getSetterName()->getName());
185 first = false;
186 }
187
188 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_assign)
189 {
190 fprintf(stderr, "%cassign", first ? ' ' : ',');
191 first = false;
192 }
193
194 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readwrite)
195 {
196 fprintf(stderr, "%creadwrite", first ? ' ' : ',');
197 first = false;
198 }
199
200 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_retain)
201 {
202 fprintf(stderr, "%cretain", first ? ' ' : ',');
203 first = false;
204 }
205
206 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_copy)
207 {
208 fprintf(stderr, "%ccopy", first ? ' ' : ',');
209 first = false;
210 }
211
212 if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_nonatomic)
213 {
214 fprintf(stderr, "%cnonatomic", first ? ' ' : ',');
215 first = false;
216 }
217 fprintf(stderr, " )");
218 }
219 ObjcIvarDecl **IDecl = PDecl->getPropertyDecls();
220 fprintf(stderr, " %s %s", IDecl[0]->getType().getAsString().c_str(),
221 IDecl[0]->getName());
222
223 for (int j = 1; j < PDecl->getNumPropertyDecls(); j++) {
224 fprintf(stderr, ", %s", IDecl[j]->getName());
225 }
226 fprintf(stderr, ";\n");
227 }
228 }
229 fprintf(stderr,"@end\n");
Steve Narofffaed3bf2007-09-10 20:51:04 +0000230 // FIXME: implement the rest...
231}
232
Fariborz Jahanianac20be22007-10-08 18:53:38 +0000233static void PrintObjcProtocolDecl(ObjcProtocolDecl *PID) {
234 std::string S = PID->getName();
235 fprintf(stderr, "@protocol %s;\n", S.c_str());
236 // FIXME: implement the rest...
237}
238
239static void PrintObjcCategoryImplDecl(ObjcCategoryImplDecl *PID) {
240 std::string S = PID->getName();
241 std::string I = PID->getClassInterface()->getName();
242 fprintf(stderr, "@implementation %s(%s);\n", I.c_str(), S.c_str());
243 // FIXME: implement the rest...
244}
245
246static void PrintObjcCategoryDecl(ObjcCategoryDecl *PID) {
247 std::string S = PID->getName();
248 std::string I = PID->getClassInterface()->getName();
249 fprintf(stderr, "@interface %s(%s);\n", I.c_str(), S.c_str());
250 // FIXME: implement the rest...
251}
252
Fariborz Jahanian05d212a2007-10-11 23:42:27 +0000253static void PrintObjcCompatibleAliasDecl(ObjcCompatibleAliasDecl *AID) {
254 std::string A = AID->getName();
255 std::string I = AID->getClassInterface()->getName();
256 fprintf(stderr, "@compatibility_alias %s %s;\n", A.c_str(), I.c_str());
257}
258
Chris Lattnerb73abd52007-09-15 23:02:28 +0000259namespace {
260 class ASTPrinter : public ASTConsumer {
261 virtual void HandleTopLevelDecl(Decl *D) {
262 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
263 PrintFunctionDeclStart(FD);
264
265 if (FD->getBody()) {
266 fprintf(stderr, " ");
267 FD->getBody()->dumpPretty();
268 fprintf(stderr, "\n");
269 }
Steve Naroff3a3a0cb2007-11-13 23:48:03 +0000270 } else if (isa<ObjcMethodDecl>(D)) {
271 // Do nothing, methods definitions are printed in
272 // PrintObjcImplementationDecl.
Chris Lattnerb73abd52007-09-15 23:02:28 +0000273 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
274 PrintTypeDefDecl(TD);
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000275 } else if (ObjcInterfaceDecl *OID = dyn_cast<ObjcInterfaceDecl>(D)) {
276 PrintObjcInterfaceDecl(OID);
Fariborz Jahanianac20be22007-10-08 18:53:38 +0000277 } else if (ObjcProtocolDecl *PID = dyn_cast<ObjcProtocolDecl>(D)) {
278 PrintObjcProtocolDecl(PID);
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000279 } else if (ObjcForwardProtocolDecl *OFPD =
280 dyn_cast<ObjcForwardProtocolDecl>(D)) {
281 fprintf(stderr, "@protocol ");
282 for (unsigned i = 0, e = OFPD->getNumForwardDecls(); i != e; ++i) {
283 const ObjcProtocolDecl *D = OFPD->getForwardProtocolDecl(i);
284 if (i) fprintf(stderr, ", ");
285 fprintf(stderr, "%s", D->getName());
286 }
Chris Lattnera845bbe2007-10-06 19:08:22 +0000287 fprintf(stderr, ";\n");
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000288 } else if (ObjcImplementationDecl *OID =
289 dyn_cast<ObjcImplementationDecl>(D)) {
Fariborz Jahanian83ddf822007-11-10 20:59:13 +0000290 PrintObjcImplementationDecl(OID);
Fariborz Jahanianac20be22007-10-08 18:53:38 +0000291 } else if (ObjcCategoryImplDecl *OID =
292 dyn_cast<ObjcCategoryImplDecl>(D)) {
293 PrintObjcCategoryImplDecl(OID);
294 } else if (ObjcCategoryDecl *OID =
295 dyn_cast<ObjcCategoryDecl>(D)) {
296 PrintObjcCategoryDecl(OID);
Fariborz Jahanian05d212a2007-10-11 23:42:27 +0000297 } else if (ObjcCompatibleAliasDecl *OID =
298 dyn_cast<ObjcCompatibleAliasDecl>(D)) {
299 PrintObjcCompatibleAliasDecl(OID);
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000300 } else if (isa<ObjcClassDecl>(D)) {
301 fprintf(stderr, "@class [printing todo]\n");
Fariborz Jahanianac20be22007-10-08 18:53:38 +0000302 } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
303 fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName());
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000304 } else {
305 assert(0 && "Unknown decl type!");
Chris Lattner95578782007-08-08 22:51:59 +0000306 }
Chris Lattner4b009652007-07-25 00:24:17 +0000307 }
Chris Lattnerb73abd52007-09-15 23:02:28 +0000308 };
Chris Lattner4b009652007-07-25 00:24:17 +0000309}
Chris Lattner95578782007-08-08 22:51:59 +0000310
Chris Lattnerb73abd52007-09-15 23:02:28 +0000311ASTConsumer *clang::CreateASTPrinter() { return new ASTPrinter(); }
312
313namespace {
314 class ASTDumper : public ASTConsumer {
315 SourceManager *SM;
316 public:
317 void Initialize(ASTContext &Context, unsigned MainFileID) {
318 SM = &Context.SourceMgr;
Chris Lattner95578782007-08-08 22:51:59 +0000319 }
Chris Lattnerb73abd52007-09-15 23:02:28 +0000320
321 virtual void HandleTopLevelDecl(Decl *D) {
322 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
323 PrintFunctionDeclStart(FD);
324
325 if (FD->getBody()) {
326 fprintf(stderr, "\n");
327 FD->getBody()->dumpAll(*SM);
328 fprintf(stderr, "\n");
329 }
330 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
331 PrintTypeDefDecl(TD);
332 } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
333 fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName());
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000334 } else if (ObjcInterfaceDecl *OID = dyn_cast<ObjcInterfaceDecl>(D)) {
335 fprintf(stderr, "Read objc interface '%s'\n", OID->getName());
Steve Naroffd5d18732007-10-14 17:03:01 +0000336 } else if (ObjcProtocolDecl *OPD = dyn_cast<ObjcProtocolDecl>(D)) {
337 fprintf(stderr, "Read objc protocol '%s'\n", OPD->getName());
338 } else if (ObjcCategoryDecl *OCD = dyn_cast<ObjcCategoryDecl>(D)) {
339 fprintf(stderr, "Read objc category '%s'\n", OCD->getName());
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000340 } else if (isa<ObjcForwardProtocolDecl>(D)) {
341 fprintf(stderr, "Read objc fwd protocol decl\n");
Steve Naroffd5d18732007-10-14 17:03:01 +0000342 } else if (isa<ObjcClassDecl>(D)) {
343 fprintf(stderr, "Read objc fwd class decl\n");
Chris Lattnerd5c9d3d2007-10-06 18:52:10 +0000344 } else {
345 assert(0 && "Unknown decl type!");
Chris Lattnerb73abd52007-09-15 23:02:28 +0000346 }
347 }
348 };
Chris Lattner95578782007-08-08 22:51:59 +0000349}
350
Chris Lattnerb73abd52007-09-15 23:02:28 +0000351ASTConsumer *clang::CreateASTDumper() { return new ASTDumper(); }
352
Ted Kremenekb6976a22007-09-19 21:29:43 +0000353namespace {
354 class ASTViewer : public ASTConsumer {
355 SourceManager *SM;
356 public:
357 void Initialize(ASTContext &Context, unsigned MainFileID) {
358 SM = &Context.SourceMgr;
359 }
360
361 virtual void HandleTopLevelDecl(Decl *D) {
362 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
363 PrintFunctionDeclStart(FD);
364
365 if (FD->getBody()) {
366 fprintf(stderr, "\n");
367 FD->getBody()->viewAST();
368 fprintf(stderr, "\n");
369 }
370 }
371 }
372 };
373}
374
375ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
376
377
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000378//===----------------------------------------------------------------------===//
379// CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
380// the CFGs for all function definitions.
381
382namespace {
383
Chris Lattner52332d02007-09-15 23:21:08 +0000384class CFGVisitor : public ASTConsumer {
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000385public:
Chris Lattner52332d02007-09-15 23:21:08 +0000386 // CFG Visitor interface to be implemented by subclass.
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000387 virtual void VisitCFG(CFG& C) = 0;
388 virtual bool printFuncDeclStart() { return true; }
Chris Lattner52332d02007-09-15 23:21:08 +0000389
390 virtual void HandleTopLevelDecl(Decl *D);
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000391};
392
393} // end anonymous namespace
394
Chris Lattner52332d02007-09-15 23:21:08 +0000395void CFGVisitor::HandleTopLevelDecl(Decl *D) {
396 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
397 if (!FD || !FD->getBody())
398 return;
399
400 if (printFuncDeclStart()) {
401 PrintFunctionDeclStart(FD);
402 fprintf(stderr,"\n");
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000403 }
Chris Lattner52332d02007-09-15 23:21:08 +0000404
Ted Kremenek3e88d752007-09-17 17:10:02 +0000405 CFG *C = CFG::buildCFG(FD->getBody());
406 VisitCFG(*C);
407 delete C;
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000408}
409
410//===----------------------------------------------------------------------===//
411// DumpCFGs - Dump CFGs to stderr or visualize with Graphviz
412
413namespace {
414 class CFGDumper : public CFGVisitor {
415 const bool UseGraphviz;
416 public:
417 CFGDumper(bool use_graphviz) : UseGraphviz(use_graphviz) {}
418
Chris Lattner52332d02007-09-15 23:21:08 +0000419 virtual void VisitCFG(CFG &C) {
420 if (UseGraphviz)
421 C.viewCFG();
422 else
423 C.dump();
424 }
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000425 };
426} // end anonymous namespace
427
Chris Lattner52332d02007-09-15 23:21:08 +0000428ASTConsumer *clang::CreateCFGDumper(bool ViewGraphs) {
429 return new CFGDumper(ViewGraphs);
Ted Kremenek97f75312007-08-21 21:42:03 +0000430}
431
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000432//===----------------------------------------------------------------------===//
433// AnalyzeLiveVariables - perform live variable analysis and dump results
434
435namespace {
436 class LivenessVisitor : public CFGVisitor {
Chris Lattner52332d02007-09-15 23:21:08 +0000437 SourceManager *SM;
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000438 public:
Chris Lattner52332d02007-09-15 23:21:08 +0000439 virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
440 SM = &Context.SourceMgr;
441 }
442
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000443 virtual void VisitCFG(CFG& C) {
Ted Kremenek8ce772b2007-10-01 20:33:52 +0000444 LiveVariables L(C);
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000445 L.runOnCFG(C);
Ted Kremenekd7a2f812007-09-25 04:31:27 +0000446 L.dumpBlockLiveness(*SM);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000447 }
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000448 };
449} // end anonymous namespace
450
Chris Lattner52332d02007-09-15 23:21:08 +0000451ASTConsumer *clang::CreateLiveVarAnalyzer() {
452 return new LivenessVisitor();
Ted Kremenekaa04c512007-09-06 00:17:54 +0000453}
454
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000455//===----------------------------------------------------------------------===//
Ted Kremenek0a03ce62007-09-17 20:49:30 +0000456// DeadStores - run checker to locate dead stores in a function
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000457
458namespace {
459 class DeadStoreVisitor : public CFGVisitor {
Chris Lattner52332d02007-09-15 23:21:08 +0000460 Diagnostic &Diags;
461 ASTContext *Ctx;
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000462 public:
Chris Lattner52332d02007-09-15 23:21:08 +0000463 DeadStoreVisitor(Diagnostic &diags) : Diags(diags) {}
464 virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
465 Ctx = &Context;
466 }
467
468 virtual void VisitCFG(CFG& C) { CheckDeadStores(C, *Ctx, Diags); }
Ted Kremenek39b8c4b2007-09-07 23:54:15 +0000469 virtual bool printFuncDeclStart() { return false; }
Ted Kremenek1e3c2022007-09-07 23:47:56 +0000470 };
471} // end anonymous namespace
472
Chris Lattner52332d02007-09-15 23:21:08 +0000473ASTConsumer *clang::CreateDeadStoreChecker(Diagnostic &Diags) {
474 return new DeadStoreVisitor(Diags);
Ted Kremeneke805c4a2007-09-06 23:00:42 +0000475}
Chris Lattner129758d2007-09-16 19:46:59 +0000476
477//===----------------------------------------------------------------------===//
Ted Kremenek0a03ce62007-09-17 20:49:30 +0000478// Unitialized Values - run checker to flag potential uses of uninitalized
479// variables.
480
481namespace {
482 class UninitValsVisitor : public CFGVisitor {
483 Diagnostic &Diags;
484 ASTContext *Ctx;
485 public:
486 UninitValsVisitor(Diagnostic &diags) : Diags(diags) {}
487 virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
488 Ctx = &Context;
489 }
490
491 virtual void VisitCFG(CFG& C) { CheckUninitializedValues(C, *Ctx, Diags); }
492 virtual bool printFuncDeclStart() { return false; }
493 };
494} // end anonymous namespace
495
496ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
497 return new UninitValsVisitor(Diags);
498}
499
500//===----------------------------------------------------------------------===//
Chris Lattner129758d2007-09-16 19:46:59 +0000501// LLVM Emitter
502
503#include "clang/Basic/Diagnostic.h"
Devang Patela8fccb82007-10-31 20:01:01 +0000504#include "clang/Basic/TargetInfo.h"
Chris Lattner129758d2007-09-16 19:46:59 +0000505#include "clang/CodeGen/ModuleBuilder.h"
506#include "llvm/Module.h"
Devang Patela8fccb82007-10-31 20:01:01 +0000507#include "llvm/Target/TargetData.h"
508#include "llvm/Target/TargetMachine.h"
Chris Lattner129758d2007-09-16 19:46:59 +0000509#include <iostream>
510
511namespace {
512 class LLVMEmitter : public ASTConsumer {
513 Diagnostic &Diags;
514 llvm::Module *M;
Devang Patela8fccb82007-10-31 20:01:01 +0000515 const llvm::TargetData *TD;
Chris Lattner129758d2007-09-16 19:46:59 +0000516 ASTContext *Ctx;
Chris Lattner07f44dc2007-11-13 18:16:41 +0000517 CodeGen::CodeGenModule *Builder;
Chris Lattner129758d2007-09-16 19:46:59 +0000518 public:
519 LLVMEmitter(Diagnostic &diags) : Diags(diags) {}
520 virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
521 Ctx = &Context;
522 M = new llvm::Module("foo");
Devang Patela8fccb82007-10-31 20:01:01 +0000523 M->setTargetTriple(Ctx->Target.getTargetTriple());
524 TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
525 Builder = CodeGen::Init(Context, *M, *TD);
Chris Lattner129758d2007-09-16 19:46:59 +0000526 }
527
528 virtual void HandleTopLevelDecl(Decl *D) {
529 // If an error occurred, stop code generation, but continue parsing and
530 // semantic analysis (to ensure all warnings and errors are emitted).
531 if (Diags.hasErrorOccurred())
532 return;
533
534 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
535 CodeGen::CodeGenFunction(Builder, FD);
536 } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
537 CodeGen::CodeGenGlobalVar(Builder, FVD);
538 } else {
539 assert(isa<TypedefDecl>(D) && "Only expected typedefs here");
540 // don't codegen for now, eventually pass down for debug info.
541 //std::cerr << "Read top-level typedef decl: '" << D->getName() << "'\n";
542 }
543 }
544
545 ~LLVMEmitter() {
546 CodeGen::Terminate(Builder);
547
548 // Print the generated code.
549 M->print(std::cout);
550 delete M;
551 }
552 };
553} // end anonymous namespace
554
555ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags) {
556 return new LLVMEmitter(Diags);
557}
558