ParseAST.cpp revision 31e6c7ddfeeefe05b67220bc87fa23d4338d1056
1//===--- 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" 16#include "clang/AST/ASTConsumer.h" 17#include "Sema.h" 18#include "clang/Parse/Action.h" 19#include "clang/Parse/Parser.h" 20using namespace clang; 21 22ASTConsumer::~ASTConsumer() {} 23 24namespace { 25 class ASTStreamer { 26 Parser P; 27 std::vector<Decl*> LastInGroupList; 28 public: 29 ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID) 30 : P(pp, *new Sema(pp, ctxt, LastInGroupList)) { 31 pp.EnterMainSourceFile(MainFileID); 32 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. 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} 82 83void ASTStreamer::PrintStats() const { 84 P.getActions().PrintStats(); 85} 86 87//===----------------------------------------------------------------------===// 88// Public interface to the file 89//===----------------------------------------------------------------------===// 90 91/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as 92/// the file is parsed. This takes ownership of the ASTConsumer and 93/// ultimately deletes it. 94void clang::ParseAST(Preprocessor &PP, unsigned MainFileID, 95 ASTConsumer *Consumer, bool PrintStats) { 96 // Collect global stats on Decls/Stmts (until we have a module streamer). 97 if (PrintStats) { 98 Decl::CollectingStats(true); 99 Stmt::CollectingStats(true); 100 } 101 102 ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), 103 PP.getIdentifierTable(), PP.getSelectorTable()); 104 105 ASTStreamer Streamer(PP, Context, MainFileID); 106 107 Consumer->Initialize(Context, MainFileID); 108 109 while (Decl *D = Streamer.ReadTopLevelDecl()) 110 Consumer->HandleTopLevelDecl(D); 111 112 if (PrintStats) { 113 fprintf(stderr, "\nSTATISTICS:\n"); 114 Streamer.PrintStats(); 115 Context.PrintStats(); 116 Decl::PrintStats(); 117 Stmt::PrintStats(); 118 Consumer->PrintStats(); 119 120 Decl::CollectingStats(false); 121 Stmt::CollectingStats(false); 122 } 123 124 delete Consumer; 125} 126