blob: 5a372da088ea03b9b44bdbd40c9c13c2f523a8dc [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +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
14#include "clang/Sema/ASTStreamer.h"
15#include "clang/AST/ASTContext.h"
Chris Lattner556beb72007-09-15 22:56:56 +000016#include "clang/AST/ASTConsumer.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000017#include "Sema.h"
18#include "clang/Parse/Action.h"
19#include "clang/Parse/Parser.h"
20using namespace clang;
21
Chris Lattner556beb72007-09-15 22:56:56 +000022ASTConsumer::~ASTConsumer() {}
23
Reid Spencer5f016e22007-07-11 17:01:13 +000024namespace {
25 class ASTStreamer {
26 Parser P;
Steve Naroff1f644322007-11-28 22:54:11 +000027 std::vector<Decl*> TopLevelDeclList;
Reid Spencer5f016e22007-07-11 17:01:13 +000028 public:
29 ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID)
Steve Naroff1f644322007-11-28 22:54:11 +000030 : P(pp, *new Sema(pp, ctxt, TopLevelDeclList)) {
Chris Lattner53b0dab2007-10-09 22:10:18 +000031 pp.EnterMainSourceFile(MainFileID);
Reid Spencer5f016e22007-07-11 17:01:13 +000032
33 // Initialize the parser.
34 P.Initialize();
35 }
36
37 /// ReadTopLevelDecl - Parse and return the next top-level declaration.
38 Decl *ReadTopLevelDecl();
39
40 void PrintStats() const;
41
42 ~ASTStreamer() {
43 P.Finalize();
44 delete &P.getActions();
45 }
46 };
47}
48
49/// 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.
Steve Naroff1f644322007-11-28 22:54:11 +000056 if (!TopLevelDeclList.empty()) {
57 Result = TopLevelDeclList.back();
58 TopLevelDeclList.pop_back();
Reid Spencer5f016e22007-07-11 17:01:13 +000059 return static_cast<Decl*>(Result);
60 }
61
62 do {
Steve Naroff1f644322007-11-28 22:54:11 +000063 if (P.ParseTopLevelDecl())
Reid Spencer5f016e22007-07-11 17:01:13 +000064 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.
Steve Naroff1f644322007-11-28 22:54:11 +000069 } while (TopLevelDeclList.size() == 0);
Reid Spencer5f016e22007-07-11 17:01:13 +000070
71 // If we parsed a declspec with multiple declarators, reverse the list and
72 // return the first one.
Steve Naroff1f644322007-11-28 22:54:11 +000073 if (TopLevelDeclList.size() > 1)
74 std::reverse(TopLevelDeclList.begin(), TopLevelDeclList.end());
75
76 Result = TopLevelDeclList.back();
77 TopLevelDeclList.pop_back();
Reid Spencer5f016e22007-07-11 17:01:13 +000078
79 return static_cast<Decl*>(Result);
80}
81
82void ASTStreamer::PrintStats() const {
Steve Naroff58ff9e82007-10-14 00:58:41 +000083 P.getActions().PrintStats();
Reid Spencer5f016e22007-07-11 17:01:13 +000084}
85
86//===----------------------------------------------------------------------===//
87// Public interface to the file
88//===----------------------------------------------------------------------===//
89
Chris Lattner556beb72007-09-15 22:56:56 +000090/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
Chris Lattner31e6c7d2007-11-03 06:24:16 +000091/// the file is parsed. This takes ownership of the ASTConsumer and
92/// ultimately deletes it.
Chris Lattner556beb72007-09-15 22:56:56 +000093void clang::ParseAST(Preprocessor &PP, unsigned MainFileID,
Chris Lattner31e6c7d2007-11-03 06:24:16 +000094 ASTConsumer *Consumer, bool PrintStats) {
Chris Lattner556beb72007-09-15 22:56:56 +000095 // Collect global stats on Decls/Stmts (until we have a module streamer).
96 if (PrintStats) {
97 Decl::CollectingStats(true);
98 Stmt::CollectingStats(true);
99 }
100
101 ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(),
Steve Naroff68d331a2007-09-27 14:38:14 +0000102 PP.getIdentifierTable(), PP.getSelectorTable());
Chris Lattner556beb72007-09-15 22:56:56 +0000103
104 ASTStreamer Streamer(PP, Context, MainFileID);
105
Chris Lattner31e6c7d2007-11-03 06:24:16 +0000106 Consumer->Initialize(Context, MainFileID);
Chris Lattner556beb72007-09-15 22:56:56 +0000107
108 while (Decl *D = Streamer.ReadTopLevelDecl())
Chris Lattner31e6c7d2007-11-03 06:24:16 +0000109 Consumer->HandleTopLevelDecl(D);
Fariborz Jahanian26e4cd32007-10-26 19:46:17 +0000110
Chris Lattner556beb72007-09-15 22:56:56 +0000111 if (PrintStats) {
112 fprintf(stderr, "\nSTATISTICS:\n");
113 Streamer.PrintStats();
114 Context.PrintStats();
115 Decl::PrintStats();
116 Stmt::PrintStats();
Chris Lattner31e6c7d2007-11-03 06:24:16 +0000117 Consumer->PrintStats();
Chris Lattner556beb72007-09-15 22:56:56 +0000118
119 Decl::CollectingStats(false);
120 Stmt::CollectingStats(false);
121 }
Chris Lattner31e6c7d2007-11-03 06:24:16 +0000122
123 delete Consumer;
Chris Lattner556beb72007-09-15 22:56:56 +0000124}