1e91c134d8fee0179d4e88235fe3ac721bb467cd8Chris Lattner//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
10e91c134d8fee0179d4e88235fe3ac721bb467cd8Chris Lattner// This file implements the clang::ParseAST method.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Parse/ParseAST.h"
15e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Sema.h"
1681b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor#include "clang/Sema/CodeCompleteConsumer.h"
17e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor#include "clang/Sema/SemaConsumer.h"
18668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor#include "clang/Sema/ExternalSemaSource.h"
19556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner#include "clang/AST/ASTConsumer.h"
20384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
21fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor#include "clang/AST/ExternalASTSource.h"
22e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/Stmt.h"
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h"
24934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek#include "llvm/ADT/OwningPtr.h"
25965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek#include "llvm/Support/CrashRecoveryContext.h"
26f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin#include <cstdio>
27f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Public interface to the file
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
34556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
353599dbe94ed8229b4a0eca0b066129e381ccb277Chris Lattner/// the file is parsed.  This inserts the parsed decls into the translation unit
363599dbe94ed8229b4a0eca0b066129e381ccb277Chris Lattner/// held by Ctx.
37d3db40151868df39b14d2ef8ffacf19e8c36331fDaniel Dunbar///
3846157b59646e3fd4252747c679fda529b8bf46afTed Kremenekvoid clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
39f807fe0d1a865f4c6ba7e494cf4ae360c4173521Douglas Gregor                     ASTContext &Ctx, bool PrintStats,
40467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                     TranslationUnitKind TUKind,
413a2838d14251427089c39caec90c8abbc27f7a14Daniel Dunbar                     CodeCompleteConsumer *CompletionConsumer) {
42934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek
43934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek  llvm::OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer,
44467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                                   TUKind,
45934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek                                   CompletionConsumer));
46965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek
47965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek  // Recover resources if we crash before exiting this method.
48614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleaupSema(S.get());
49965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek
50934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek  ParseAST(*S.get(), PrintStats);
5146ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor}
5246ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
5346ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregorvoid clang::ParseAST(Sema &S, bool PrintStats) {
54556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  // Collect global stats on Decls/Stmts (until we have a module streamer).
55556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  if (PrintStats) {
56556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Decl::CollectingStats(true);
57556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Stmt::CollectingStats(true);
58556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  }
5946157b59646e3fd4252747c679fda529b8bf46afTed Kremenek
605d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  // Also turn on collection of stats inside of the Sema object.
615d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  bool OldCollectStats = PrintStats;
625d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  std::swap(OldCollectStats, S.CollectStats);
635d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
6446ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  ASTConsumer *Consumer = &S.getASTConsumer();
65d69fd7f34fd2de35845e834e987009efec09b937John McCall
66614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  llvm::OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S));
67614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  Parser &P = *ParseOP.get();
68614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
69614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  PrettyStackTraceParserEntry CrashInfo(P);
70614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
71614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  // Recover resources if we crash before exiting this method.
72614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<Parser>
73614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek    CleaupParser(ParseOP.get());
74614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
7546ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  S.getPreprocessor().EnterMainSourceFile();
76d69fd7f34fd2de35845e834e987009efec09b937John McCall  P.Initialize();
7746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  S.Initialize();
7846ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
7946ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  if (ExternalASTSource *External = S.getASTContext().getExternalSource())
80668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor    External->StartTranslationUnit(Consumer);
8146ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
82682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  Parser::DeclGroupPtrTy ADecl;
8346ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
84a0e328f9953e2d8e83227ffa601f5a606b7aa062Chris Lattner  while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
85d69fd7f34fd2de35845e834e987009efec09b937John McCall    // If we got a null return and something *was* parsed, ignore it.  This
86d69fd7f34fd2de35845e834e987009efec09b937John McCall    // is due to a top-level semicolon, an action override, or a parse error
87d69fd7f34fd2de35845e834e987009efec09b937John McCall    // skipping something.
88682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ADecl)
892b5289b6fd7e3d9899868410a498c081c9595662John McCall      Consumer->HandleTopLevelDecl(ADecl.get());
90a0e328f9953e2d8e83227ffa601f5a606b7aa062Chris Lattner  };
9163e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian  // Check for any pending objective-c implementation decl.
923fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  while ((ADecl = P.FinishPendingObjCActions()))
932b5289b6fd7e3d9899868410a498c081c9595662John McCall    Consumer->HandleTopLevelDecl(ADecl.get());
9446ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
95ec2a4ed278a1112ebf84fdcb80ed66f53d8ec8baDaniel Dunbar  // Process any TopLevelDecls generated by #pragma weak.
965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVector<Decl*,2>::iterator
9746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor       I = S.WeakTopLevelDecls().begin(),
9846ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor       E = S.WeakTopLevelDecls().end(); I != E; ++I)
997b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
10046ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
10146ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  Consumer->HandleTranslationUnit(S.getASTContext());
1025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
1035d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  std::swap(OldCollectStats, S.CollectStats);
104556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  if (PrintStats) {
105cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    llvm::errs() << "\nSTATISTICS:\n";
106a0e328f9953e2d8e83227ffa601f5a606b7aa062Chris Lattner    P.getActions().PrintStats();
10746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor    S.getASTContext().PrintStats();
108556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Decl::PrintStats();
109556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Stmt::PrintStats();
11031e6c7ddfeeefe05b67220bc87fa23d4338d1056Chris Lattner    Consumer->PrintStats();
111556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  }
112556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner}
113