ParseAST.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. #include "clang/Parse/ParseAST.h"
  14. #include "clang/Parse/ParseDiagnostic.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/ASTContext.h"
  21. #include "clang/AST/DeclCXX.h"
  22. #include "clang/AST/ExternalASTSource.h"
  23. #include "clang/AST/Stmt.h"
  24. #include "clang/Parse/Parser.h"
  25. #include "llvm/ADT/OwningPtr.h"
  26. #include "llvm/Support/CrashRecoveryContext.h"
  27. #include <cstdio>
  28. using namespace clang;
  29. //===----------------------------------------------------------------------===//
  30. // Public interface to the file
  31. //===----------------------------------------------------------------------===//
  32. /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
  33. /// the file is parsed. This inserts the parsed decls into the translation unit
  34. /// held by Ctx.
  35. ///
  36. void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
  37. ASTContext &Ctx, bool PrintStats,
  38. TranslationUnitKind TUKind,
  39. CodeCompleteConsumer *CompletionConsumer,
  40. bool SkipFunctionBodies) {
  41. OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer,
  42. TUKind,
  43. CompletionConsumer));
  44. // Recover resources if we crash before exiting this method.
  45. llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get());
  46. ParseAST(*S.get(), PrintStats, SkipFunctionBodies);
  47. }
  48. void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
  49. // Collect global stats on Decls/Stmts (until we have a module streamer).
  50. if (PrintStats) {
  51. Decl::EnableStatistics();
  52. Stmt::EnableStatistics();
  53. }
  54. // Also turn on collection of stats inside of the Sema object.
  55. bool OldCollectStats = PrintStats;
  56. std::swap(OldCollectStats, S.CollectStats);
  57. ASTConsumer *Consumer = &S.getASTConsumer();
  58. OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
  59. SkipFunctionBodies));
  60. Parser &P = *ParseOP.get();
  61. PrettyStackTraceParserEntry CrashInfo(P);
  62. // Recover resources if we crash before exiting this method.
  63. llvm::CrashRecoveryContextCleanupRegistrar<Parser>
  64. CleanupParser(ParseOP.get());
  65. S.getPreprocessor().EnterMainSourceFile();
  66. P.Initialize();
  67. S.Initialize();
  68. // C11 6.9p1 says translation units must have at least one top-level
  69. // declaration. C++ doesn't have this restriction. We also don't want to
  70. // complain if we have a precompiled header, although technically if the PCH
  71. // is empty we should still emit the (pedantic) diagnostic.
  72. Parser::DeclGroupPtrTy ADecl;
  73. ExternalASTSource *External = S.getASTContext().getExternalSource();
  74. if (External)
  75. External->StartTranslationUnit(Consumer);
  76. if (P.ParseTopLevelDecl(ADecl)) {
  77. if (!External && !S.getLangOpts().CPlusPlus)
  78. P.Diag(diag::ext_empty_translation_unit);
  79. } else {
  80. do {
  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 && !Consumer->HandleTopLevelDecl(ADecl.get()))
  85. return;
  86. } while (!P.ParseTopLevelDecl(ADecl));
  87. }
  88. // Process any TopLevelDecls generated by #pragma weak.
  89. for (SmallVector<Decl*,2>::iterator
  90. I = S.WeakTopLevelDecls().begin(),
  91. E = S.WeakTopLevelDecls().end(); I != E; ++I)
  92. Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
  93. Consumer->HandleTranslationUnit(S.getASTContext());
  94. std::swap(OldCollectStats, S.CollectStats);
  95. if (PrintStats) {
  96. llvm::errs() << "\nSTATISTICS:\n";
  97. P.getActions().PrintStats();
  98. S.getASTContext().PrintStats();
  99. Decl::PrintStats();
  100. Stmt::PrintStats();
  101. Consumer->PrintStats();
  102. }
  103. }