ParseAST.cpp revision 2b5289b6fd7e3d9899868410a498c081c9595662
1//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the clang::ParseAST method. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Parse/ParseAST.h" 15#include "clang/Sema/Sema.h" 16#include "clang/Sema/CodeCompleteConsumer.h" 17#include "clang/Sema/SemaConsumer.h" 18#include "clang/Sema/ExternalSemaSource.h" 19#include "clang/AST/ASTConsumer.h" 20#include "clang/AST/ExternalASTSource.h" 21#include "clang/AST/Stmt.h" 22#include "clang/Parse/Parser.h" 23#include <cstdio> 24 25using namespace clang; 26 27static void DumpRecordLayouts(ASTContext &C) { 28 for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end(); 29 I != E; ++I) { 30 const RecordType *RT = dyn_cast<RecordType>(*I); 31 if (!RT) 32 continue; 33 34 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 35 if (!RD || RD->isImplicit() || RD->isDependentType() || 36 RD->isInvalidDecl() || !RD->getDefinition()) 37 continue; 38 39 // FIXME: Do we really need to hard code this? 40 if (RD->getQualifiedNameAsString() == "__va_list_tag") 41 continue; 42 43 C.DumpRecordLayout(RD, llvm::errs()); 44 } 45} 46 47//===----------------------------------------------------------------------===// 48// Public interface to the file 49//===----------------------------------------------------------------------===// 50 51/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as 52/// the file is parsed. This inserts the parsed decls into the translation unit 53/// held by Ctx. 54/// 55void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, 56 ASTContext &Ctx, bool PrintStats, 57 bool CompleteTranslationUnit, 58 CodeCompleteConsumer *CompletionConsumer) { 59 Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer); 60 ParseAST(S, PrintStats); 61} 62 63void clang::ParseAST(Sema &S, bool PrintStats) { 64 // Collect global stats on Decls/Stmts (until we have a module streamer). 65 if (PrintStats) { 66 Decl::CollectingStats(true); 67 Stmt::CollectingStats(true); 68 } 69 70 ASTConsumer *Consumer = &S.getASTConsumer(); 71 72 Parser P(S.getPreprocessor(), S); 73 S.getPreprocessor().EnterMainSourceFile(); 74 P.Initialize(); 75 S.Initialize(); 76 77 if (ExternalASTSource *External = S.getASTContext().getExternalSource()) 78 External->StartTranslationUnit(Consumer); 79 80 Parser::DeclGroupPtrTy ADecl; 81 82 while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file. 83 // If we got a null return and something *was* parsed, ignore it. This 84 // is due to a top-level semicolon, an action override, or a parse error 85 // skipping something. 86 if (ADecl) 87 Consumer->HandleTopLevelDecl(ADecl.get()); 88 }; 89 // Check for any pending objective-c implementation decl. 90 while ((ADecl = P.FinishPendingObjCActions())) 91 Consumer->HandleTopLevelDecl(ADecl.get()); 92 93 // Process any TopLevelDecls generated by #pragma weak. 94 for (llvm::SmallVector<Decl*,2>::iterator 95 I = S.WeakTopLevelDecls().begin(), 96 E = S.WeakTopLevelDecls().end(); I != E; ++I) 97 Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); 98 99 // Dump record layouts, if requested. 100 if (S.getLangOptions().DumpRecordLayouts) 101 DumpRecordLayouts(S.getASTContext()); 102 103 Consumer->HandleTranslationUnit(S.getASTContext()); 104 105 if (PrintStats) { 106 fprintf(stderr, "\nSTATISTICS:\n"); 107 P.getActions().PrintStats(); 108 S.getASTContext().PrintStats(); 109 Decl::PrintStats(); 110 Stmt::PrintStats(); 111 Consumer->PrintStats(); 112 } 113} 114