ParseAST.cpp revision cd92a65edc7cbbbb7e3aee8d31008594de90fa51
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/DeclCXX.h"
21#include "clang/AST/ExternalASTSource.h"
22#include "clang/AST/Stmt.h"
23#include "clang/Parse/Parser.h"
24#include "llvm/ADT/OwningPtr.h"
25#include "llvm/Support/CrashRecoveryContext.h"
26#include <cstdio>
27
28using namespace clang;
29
30//===----------------------------------------------------------------------===//
31// Public interface to the file
32//===----------------------------------------------------------------------===//
33
34/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
35/// the file is parsed.  This inserts the parsed decls into the translation unit
36/// held by Ctx.
37///
38void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
39                     ASTContext &Ctx, bool PrintStats,
40                     bool CompleteTranslationUnit,
41                     CodeCompleteConsumer *CompletionConsumer) {
42
43  llvm::OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer,
44                                   CompleteTranslationUnit,
45                                   CompletionConsumer));
46
47  // Recover resources if we crash before exiting this method.
48  llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleaupSema(S.get());
49
50  ParseAST(*S.get(), PrintStats);
51}
52
53void clang::ParseAST(Sema &S, bool PrintStats) {
54  // Collect global stats on Decls/Stmts (until we have a module streamer).
55  if (PrintStats) {
56    Decl::CollectingStats(true);
57    Stmt::CollectingStats(true);
58  }
59
60  ASTConsumer *Consumer = &S.getASTConsumer();
61
62  llvm::OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S));
63  Parser &P = *ParseOP.get();
64
65  PrettyStackTraceParserEntry CrashInfo(P);
66
67  // Recover resources if we crash before exiting this method.
68  llvm::CrashRecoveryContextCleanupRegistrar<Parser>
69    CleaupParser(ParseOP.get());
70
71  S.getPreprocessor().EnterMainSourceFile();
72  P.Initialize();
73  S.Initialize();
74
75  if (ExternalASTSource *External = S.getASTContext().getExternalSource())
76    External->StartTranslationUnit(Consumer);
77
78  Parser::DeclGroupPtrTy ADecl;
79
80  while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
81    // If we got a null return and something *was* parsed, ignore it.  This
82    // is due to a top-level semicolon, an action override, or a parse error
83    // skipping something.
84    if (ADecl)
85      Consumer->HandleTopLevelDecl(ADecl.get());
86  };
87  // Check for any pending objective-c implementation decl.
88  while ((ADecl = P.FinishPendingObjCActions()))
89    Consumer->HandleTopLevelDecl(ADecl.get());
90
91  // Process any TopLevelDecls generated by #pragma weak.
92  for (llvm::SmallVector<Decl*,2>::iterator
93       I = S.WeakTopLevelDecls().begin(),
94       E = S.WeakTopLevelDecls().end(); I != E; ++I)
95    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
96
97  Consumer->HandleTranslationUnit(S.getASTContext());
98
99  if (PrintStats) {
100    llvm::errs() << "\nSTATISTICS:\n";
101    P.getActions().PrintStats();
102    S.getASTContext().PrintStats();
103    Decl::PrintStats();
104    Stmt::PrintStats();
105    Consumer->PrintStats();
106  }
107}
108