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