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"
15d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose#include "clang/Parse/ParseDiagnostic.h"
16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Sema.h"
1781b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor#include "clang/Sema/CodeCompleteConsumer.h"
18e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor#include "clang/Sema/SemaConsumer.h"
19668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor#include "clang/Sema/ExternalSemaSource.h"
20556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner#include "clang/AST/ASTConsumer.h"
21478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer#include "clang/AST/ASTContext.h"
22384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
23fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor#include "clang/AST/ExternalASTSource.h"
24e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/Stmt.h"
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h"
26934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek#include "llvm/ADT/OwningPtr.h"
27965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek#include "llvm/Support/CrashRecoveryContext.h"
28f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin#include <cstdio>
29f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Public interface to the file
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
36556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
373599dbe94ed8229b4a0eca0b066129e381ccb277Chris Lattner/// the file is parsed.  This inserts the parsed decls into the translation unit
383599dbe94ed8229b4a0eca0b066129e381ccb277Chris Lattner/// held by Ctx.
39d3db40151868df39b14d2ef8ffacf19e8c36331fDaniel Dunbar///
4046157b59646e3fd4252747c679fda529b8bf46afTed Kremenekvoid clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
41f807fe0d1a865f4c6ba7e494cf4ae360c4173521Douglas Gregor                     ASTContext &Ctx, bool PrintStats,
42467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                     TranslationUnitKind TUKind,
436a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen                     CodeCompleteConsumer *CompletionConsumer,
446a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen                     bool SkipFunctionBodies) {
45934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek
466f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer,
47467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                                   TUKind,
48934a57194c9ee3db2dc38fc0222296621c4d2c8aTed Kremenek                                   CompletionConsumer));
49965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek
50965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek  // Recover resources if we crash before exiting this method.
516a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get());
52965fe844ceb6b840f79c7987deaed48ee30d070dTed Kremenek
536a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  ParseAST(*S.get(), PrintStats, SkipFunctionBodies);
5446ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor}
5546ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
566a91d385618ea4d28236c496f540a26877c95525Erik Verbruggenvoid clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
57556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  // Collect global stats on Decls/Stmts (until we have a module streamer).
58556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  if (PrintStats) {
5902892a65b18875a04c7ed5eadb3a13be801ab477Daniel Dunbar    Decl::EnableStatistics();
6002892a65b18875a04c7ed5eadb3a13be801ab477Daniel Dunbar    Stmt::EnableStatistics();
61556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  }
6246157b59646e3fd4252747c679fda529b8bf46afTed Kremenek
635d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  // Also turn on collection of stats inside of the Sema object.
645d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  bool OldCollectStats = PrintStats;
655d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  std::swap(OldCollectStats, S.CollectStats);
665d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
6746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  ASTConsumer *Consumer = &S.getASTConsumer();
68d69fd7f34fd2de35845e834e987009efec09b937John McCall
696a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen  OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
706a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen                                       SkipFunctionBodies));
71614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  Parser &P = *ParseOP.get();
72614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
73614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  PrettyStackTraceParserEntry CrashInfo(P);
74614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
75614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  // Recover resources if we crash before exiting this method.
76614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<Parser>
776a91d385618ea4d28236c496f540a26877c95525Erik Verbruggen    CleanupParser(ParseOP.get());
78614f96a7cf94805c2d336639300b62dc2f54e9e0Ted Kremenek
7946ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  S.getPreprocessor().EnterMainSourceFile();
80d69fd7f34fd2de35845e834e987009efec09b937John McCall  P.Initialize();
8146ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  S.Initialize();
82d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose
83d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  // C11 6.9p1 says translation units must have at least one top-level
84d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  // declaration. C++ doesn't have this restriction. We also don't want to
85d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  // complain if we have a precompiled header, although technically if the PCH
86d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  // is empty we should still emit the (pedantic) diagnostic.
87682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  Parser::DeclGroupPtrTy ADecl;
889416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge  ExternalASTSource *External = S.getASTContext().getExternalSource();
899416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge  if (External)
909416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge    External->StartTranslationUnit(Consumer);
9188c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis
929416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge  if (P.ParseTopLevelDecl(ADecl)) {
939416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge    if (!External && !S.getLangOpts().CPlusPlus)
949416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge      P.Diag(diag::ext_empty_translation_unit);
95d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  } else {
969416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge    do {
97d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose      // If we got a null return and something *was* parsed, ignore it.  This
98d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose      // is due to a top-level semicolon, an action override, or a parse error
99d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose      // skipping something.
1009416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge      if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
1019416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge	return;
1029416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge    } while (!P.ParseTopLevelDecl(ADecl));
103d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose  }
1049416d42468eacaae0ea85ab8ed134f5df1a1d142Meador Inge
105ec2a4ed278a1112ebf84fdcb80ed66f53d8ec8baDaniel Dunbar  // Process any TopLevelDecls generated by #pragma weak.
1065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVector<Decl*,2>::iterator
10746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor       I = S.WeakTopLevelDecls().begin(),
10846ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor       E = S.WeakTopLevelDecls().end(); I != E; ++I)
1097b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
11046ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor
11146ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor  Consumer->HandleTranslationUnit(S.getASTContext());
1125d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
1135d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  std::swap(OldCollectStats, S.CollectStats);
114556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  if (PrintStats) {
115cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    llvm::errs() << "\nSTATISTICS:\n";
116a0e328f9953e2d8e83227ffa601f5a606b7aa062Chris Lattner    P.getActions().PrintStats();
11746ea32a4b54481b7575499cb9f8d275f1d4cdd54Douglas Gregor    S.getASTContext().PrintStats();
118556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Decl::PrintStats();
119556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner    Stmt::PrintStats();
12031e6c7ddfeeefe05b67220bc87fa23d4338d1056Chris Lattner    Consumer->PrintStats();
121556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner  }
122556beb71b8820ed5243e385ffcc91433a494c170Chris Lattner}
123