blob: 8e5adcad5132de6c06d5e1240e0931c0656fab52 [file] [log] [blame]
Chris Lattner73709ed2006-08-17 06:28:25 +00001//===--- ASTStreamer.cpp - Provide streaming interface to ASTs ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ASTStreamer interface.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattnera8a2c822007-05-21 17:38:36 +000014#include "clang/Sema/ASTStreamer.h"
Steve Naroff2c055d22007-02-28 19:32:13 +000015#include "clang/AST/ASTContext.h"
Chris Lattner75e0c8c2007-09-15 22:56:56 +000016#include "clang/AST/ASTConsumer.h"
Chris Lattnerddd6fc82006-11-10 04:58:55 +000017#include "Sema.h"
Chris Lattner73709ed2006-08-17 06:28:25 +000018#include "clang/Parse/Action.h"
19#include "clang/Parse/Parser.h"
Chris Lattner73709ed2006-08-17 06:28:25 +000020using namespace clang;
21
Chris Lattner75e0c8c2007-09-15 22:56:56 +000022ASTConsumer::~ASTConsumer() {}
23
Chris Lattner73709ed2006-08-17 06:28:25 +000024namespace {
25 class ASTStreamer {
Chris Lattner73709ed2006-08-17 06:28:25 +000026 Parser P;
Chris Lattner2dacc3f2006-10-16 00:33:54 +000027 std::vector<Decl*> LastInGroupList;
Chris Lattner73709ed2006-08-17 06:28:25 +000028 public:
Steve Naroff2c055d22007-02-28 19:32:13 +000029 ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID)
30 : P(pp, *new Sema(pp, ctxt, LastInGroupList)) {
Steve Naroff38d31b42007-02-28 01:22:02 +000031 pp.EnterSourceFile(MainFileID, 0, true);
Chris Lattner73709ed2006-08-17 06:28:25 +000032
Chris Lattner38ba3362006-08-17 07:04:37 +000033 // Initialize the parser.
34 P.Initialize();
Chris Lattner73709ed2006-08-17 06:28:25 +000035 }
36
37 /// ReadTopLevelDecl - Parse and return the next top-level declaration.
Chris Lattner4eb445d2007-01-26 01:27:23 +000038 Decl *ReadTopLevelDecl();
Chris Lattner38ba3362006-08-17 07:04:37 +000039
Chris Lattner4eb445d2007-01-26 01:27:23 +000040 void PrintStats() const;
41
Chris Lattner38ba3362006-08-17 07:04:37 +000042 ~ASTStreamer() {
43 P.Finalize();
Chris Lattnerc11438c2006-08-18 05:17:52 +000044 delete &P.getActions();
Chris Lattner73709ed2006-08-17 06:28:25 +000045 }
46 };
47}
48
Chris Lattner4eb445d2007-01-26 01:27:23 +000049/// ReadTopLevelDecl - Parse and return the next top-level declaration.
50///
51Decl *ASTStreamer::ReadTopLevelDecl() {
52 Parser::DeclTy *Result;
53
54 /// If the previous time through we read something like 'int X, Y', return
55 /// the next declarator.
56 if (!LastInGroupList.empty()) {
57 Result = LastInGroupList.back();
58 LastInGroupList.pop_back();
59 return static_cast<Decl*>(Result);
60 }
61
62 do {
63 if (P.ParseTopLevelDecl(Result))
64 return 0; // End of file.
65
66 // If we got a null return and something *was* parsed, try again. This
67 // is due to a top-level semicolon, an action override, or a parse error
68 // skipping something.
69 } while (Result == 0);
70
71 // If we parsed a declspec with multiple declarators, reverse the list and
72 // return the first one.
73 if (!LastInGroupList.empty()) {
74 LastInGroupList.push_back((Decl*)Result);
75 std::reverse(LastInGroupList.begin(), LastInGroupList.end());
76 Result = LastInGroupList.back();
77 LastInGroupList.pop_back();
78 }
79
80 return static_cast<Decl*>(Result);
81}
Chris Lattner73709ed2006-08-17 06:28:25 +000082
Chris Lattner4eb445d2007-01-26 01:27:23 +000083void ASTStreamer::PrintStats() const {
Chris Lattner4eb445d2007-01-26 01:27:23 +000084}
Chris Lattner73709ed2006-08-17 06:28:25 +000085
86//===----------------------------------------------------------------------===//
87// Public interface to the file
88//===----------------------------------------------------------------------===//
89
Chris Lattner75e0c8c2007-09-15 22:56:56 +000090/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
91/// the file is parsed.
92void clang::ParseAST(Preprocessor &PP, unsigned MainFileID,
93 ASTConsumer &Consumer, bool PrintStats) {
94 // Collect global stats on Decls/Stmts (until we have a module streamer).
95 if (PrintStats) {
96 Decl::CollectingStats(true);
97 Stmt::CollectingStats(true);
98 }
99
100 ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(),
Steve Narofff73590d2007-09-27 14:38:14 +0000101 PP.getIdentifierTable(), PP.getSelectorTable());
Chris Lattner75e0c8c2007-09-15 22:56:56 +0000102
103 ASTStreamer Streamer(PP, Context, MainFileID);
104
105 Consumer.Initialize(Context, MainFileID);
106
107 while (Decl *D = Streamer.ReadTopLevelDecl())
108 Consumer.HandleTopLevelDecl(D);
109
110 if (PrintStats) {
111 fprintf(stderr, "\nSTATISTICS:\n");
112 Streamer.PrintStats();
113 Context.PrintStats();
114 Decl::PrintStats();
115 Stmt::PrintStats();
116 Consumer.PrintStats();
117
118 Decl::CollectingStats(false);
119 Stmt::CollectingStats(false);
120 }
121}