blob: 170c593afad0309b04e5c491740e020508f5c144 [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"
Reid Spencer5f016e22007-07-11 17:01:13 +000017#include "clang/Lex/Preprocessor.h"
18#include "clang/Sema/ASTStreamer.h"
Chris Lattner6000dac2007-08-08 22:51:59 +000019using namespace clang;
Reid Spencer5f016e22007-07-11 17:01:13 +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 Lattner6000dac2007-08-08 22:51:59 +000045
46
47static void PrintFunctionDeclStart(FunctionDecl *FD) {
Reid Spencer5f016e22007-07-11 17:01:13 +000048 bool HasBody = FD->getBody();
49
50 std::string Proto = FD->getName();
51 FunctionType *AFT = cast<FunctionType>(FD->getType());
52
53 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
54 Proto += "(";
55 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
56 if (i) Proto += ", ";
57 std::string ParamStr;
58 if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
59
60 FT->getArgType(i).getAsStringInternal(ParamStr);
61 Proto += ParamStr;
62 }
63
64 if (FT->isVariadic()) {
65 if (FD->getNumParams()) Proto += ", ";
66 Proto += "...";
67 }
68 Proto += ")";
69 } else {
70 assert(isa<FunctionTypeNoProto>(AFT));
71 Proto += "()";
72 }
73
74 AFT->getResultType().getAsStringInternal(Proto);
75 fprintf(stderr, "\n%s", Proto.c_str());
76
Chris Lattner6000dac2007-08-08 22:51:59 +000077 if (!FD->getBody())
Reid Spencer5f016e22007-07-11 17:01:13 +000078 fprintf(stderr, ";\n");
Chris Lattner6000dac2007-08-08 22:51:59 +000079 // Doesn't print the body.
Reid Spencer5f016e22007-07-11 17:01:13 +000080}
81
Chris Lattner6000dac2007-08-08 22:51:59 +000082static void PrintTypeDefDecl(TypedefDecl *TD) {
Reid Spencer5f016e22007-07-11 17:01:13 +000083 std::string S = TD->getName();
84 TD->getUnderlyingType().getAsStringInternal(S);
85 fprintf(stderr, "typedef %s;\n", S.c_str());
86}
87
88void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
89 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
90 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
91
92 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
93 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Chris Lattner6000dac2007-08-08 22:51:59 +000094 PrintFunctionDeclStart(FD);
95
96 if (FD->getBody()) {
97 fprintf(stderr, " ");
98 FD->getBody()->dumpPretty();
99 fprintf(stderr, "\n");
100 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000101 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
102 PrintTypeDefDecl(TD);
103 } else {
104 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
105 }
106 }
107
108 if (Stats) {
109 fprintf(stderr, "\nSTATISTICS:\n");
110 ASTStreamer_PrintStats(Streamer);
111 Context.PrintStats();
112 }
113
114 ASTStreamer_Terminate(Streamer);
115}
Chris Lattner6000dac2007-08-08 22:51:59 +0000116
117void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
118 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
119 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
120
121 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
122 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
123 PrintFunctionDeclStart(FD);
124
125 if (FD->getBody()) {
126 fprintf(stderr, "\n");
127 FD->getBody()->dumpAll();
128 fprintf(stderr, "\n");
129 }
130 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
131 PrintTypeDefDecl(TD);
132 } else {
133 fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
134 }
135 }
136
137 if (Stats) {
138 fprintf(stderr, "\nSTATISTICS:\n");
139 ASTStreamer_PrintStats(Streamer);
140 Context.PrintStats();
141 }
142
143 ASTStreamer_Terminate(Streamer);
144}
145
Ted Kremenekfddd5182007-08-21 21:42:03 +0000146void clang::DumpCFGs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
147 ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
148 ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
149
150 while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
151 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
152 if (FD->getBody()) {
153 PrintFunctionDeclStart(FD);
154 fprintf(stderr,"\n");
155 if (CFG* C = CFG::BuildCFG(FD->getBody()))
156 C->dump();
157 else
158 fprintf(stderr," Error processing CFG.\n");
159 }
160 }
161 }
162
163 if (Stats) {
164 fprintf(stderr, "\nSTATISTICS:\n");
165 ASTStreamer_PrintStats(Streamer);
166 Context.PrintStats();
167 }
168
169 ASTStreamer_Terminate(Streamer);
170}
171
Chris Lattner6000dac2007-08-08 22:51:59 +0000172