blob: 5e78e033c9b5d193bd25830665e130d2dc955c56 [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"
Chris Lattner4b009652007-07-25 00:24:17 +000017#include "clang/Lex/Preprocessor.h"
18#include "clang/Sema/ASTStreamer.h"
Chris Lattner95578782007-08-08 22:51:59 +000019using namespace clang;
Chris Lattner4b009652007-07-25 00:24:17 +000020
21void clang::BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
22 // collect global stats on Decls/Stmts (until we have a module streamer)
23 if (Stats) {
24 Decl::CollectingStats(true);
25 Stmt::CollectingStats(true);
26 }
27
28 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
29 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
30
31 while (ASTStreamer_ReadTopLevelDecl(Streamer))
32 /* keep reading */;
33
34 if (Stats) {
35 fprintf(stderr, "\nSTATISTICS:\n");
36 ASTStreamer_PrintStats(Streamer);
37 Context.PrintStats();
38 Decl::PrintStats();
39 Stmt::PrintStats();
40 }
41
42 ASTStreamer_Terminate(Streamer);
43}
44
Chris Lattner95578782007-08-08 22:51:59 +000045
46
47static void PrintFunctionDeclStart(FunctionDecl *FD) {
Chris Lattner4b009652007-07-25 00:24:17 +000048 bool HasBody = FD->getBody();
49
Chris Lattner987058a2007-08-26 04:02:13 +000050 fprintf(stderr, "\n");
51
52 switch (FD->getStorageClass()) {
53 default: assert(0 && "Unknown storage class");
54 case FunctionDecl::None: break;
55 case FunctionDecl::Extern: fprintf(stderr, "extern "); break;
56 case FunctionDecl::Static: fprintf(stderr, "static "); break;
57 }
58
59 if (FD->isInline())
60 fprintf(stderr, "inline ");
61
Chris Lattner4b009652007-07-25 00:24:17 +000062 std::string Proto = FD->getName();
63 FunctionType *AFT = cast<FunctionType>(FD->getType());
64
65 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
66 Proto += "(";
67 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
68 if (i) Proto += ", ";
69 std::string ParamStr;
70 if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
71
72 FT->getArgType(i).getAsStringInternal(ParamStr);
73 Proto += ParamStr;
74 }
75
76 if (FT->isVariadic()) {
77 if (FD->getNumParams()) Proto += ", ";
78 Proto += "...";
79 }
80 Proto += ")";
81 } else {
82 assert(isa<FunctionTypeNoProto>(AFT));
83 Proto += "()";
84 }
85
86 AFT->getResultType().getAsStringInternal(Proto);
Chris Lattner987058a2007-08-26 04:02:13 +000087 fprintf(stderr, "%s", Proto.c_str());
Chris Lattner4b009652007-07-25 00:24:17 +000088
Chris Lattner95578782007-08-08 22:51:59 +000089 if (!FD->getBody())
Chris Lattner4b009652007-07-25 00:24:17 +000090 fprintf(stderr, ";\n");
Chris Lattner95578782007-08-08 22:51:59 +000091 // Doesn't print the body.
Chris Lattner4b009652007-07-25 00:24:17 +000092}
93
Chris Lattner95578782007-08-08 22:51:59 +000094static void PrintTypeDefDecl(TypedefDecl *TD) {
Chris Lattner4b009652007-07-25 00:24:17 +000095 std::string S = TD->getName();
96 TD->getUnderlyingType().getAsStringInternal(S);
97 fprintf(stderr, "typedef %s;\n", S.c_str());
98}
99
100void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
101 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
102 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
103
104 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
105 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Chris Lattner95578782007-08-08 22:51:59 +0000106 PrintFunctionDeclStart(FD);
107
108 if (FD->getBody()) {
109 fprintf(stderr, " ");
110 FD->getBody()->dumpPretty();
111 fprintf(stderr, "\n");
112 }
Chris Lattner4b009652007-07-25 00:24:17 +0000113 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
114 PrintTypeDefDecl(TD);
115 } else {
116 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
117 }
118 }
119
120 if (Stats) {
121 fprintf(stderr, "\nSTATISTICS:\n");
122 ASTStreamer_PrintStats(Streamer);
123 Context.PrintStats();
124 }
125
126 ASTStreamer_Terminate(Streamer);
127}
Chris Lattner95578782007-08-08 22:51:59 +0000128
129void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
130 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
131 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
132
133 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
134 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
135 PrintFunctionDeclStart(FD);
136
137 if (FD->getBody()) {
138 fprintf(stderr, "\n");
139 FD->getBody()->dumpAll();
140 fprintf(stderr, "\n");
141 }
142 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
143 PrintTypeDefDecl(TD);
144 } else {
145 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
146 }
147 }
148
149 if (Stats) {
150 fprintf(stderr, "\nSTATISTICS:\n");
151 ASTStreamer_PrintStats(Streamer);
152 Context.PrintStats();
153 }
154
155 ASTStreamer_Terminate(Streamer);
156}
157
Ted Kremenekb3bb91b2007-08-29 21:56:09 +0000158void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID,
159 bool Stats, bool use_graphviz)
160{
Ted Kremenek97f75312007-08-21 21:42:03 +0000161 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
162 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
163
164 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
165 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
166 if (FD->getBody()) {
167 PrintFunctionDeclStart(FD);
168 fprintf(stderr,"\n");
Ted Kremenekb3bb91b2007-08-29 21:56:09 +0000169 if (CFG* C = CFG::buildCFG(FD->getBody())) {
170 if (use_graphviz) C->viewCFG(); else C->dump();
171 }
Ted Kremenek97f75312007-08-21 21:42:03 +0000172 else
173 fprintf(stderr," Error processing CFG.\n");
174 }
175 }
176 }
177
178 if (Stats) {
179 fprintf(stderr, "\nSTATISTICS:\n");
180 ASTStreamer_PrintStats(Streamer);
181 Context.PrintStats();
182 }
183
184 ASTStreamer_Terminate(Streamer);
185}
186
Chris Lattner95578782007-08-08 22:51:59 +0000187