From: Chris Lattner Date: Sat, 15 Sep 2007 22:56:56 +0000 (+0000) Subject: add a new ASTConsumer consumer to simplify stuff in the driver. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=556beb71b8820ed5243e385ffcc91433a494c170;p=clang add a new ASTConsumer consumer to simplify stuff in the driver. Switch -parse-ast over to it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41991 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp index b60a99440d..b3517dfaef 100644 --- a/Driver/ASTStreamers.cpp +++ b/Driver/ASTStreamers.cpp @@ -20,32 +20,6 @@ #include "clang/Sema/ASTStreamer.h" using namespace clang; -void clang::BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) { - // collect global stats on Decls/Stmts (until we have a module streamer) - if (Stats) { - Decl::CollectingStats(true); - Stmt::CollectingStats(true); - } - - ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), - PP.getIdentifierTable()); - ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID); - - while (ASTStreamer_ReadTopLevelDecl(Streamer)) - /* keep reading */; - - if (Stats) { - fprintf(stderr, "\nSTATISTICS:\n"); - ASTStreamer_PrintStats(Streamer); - Context.PrintStats(); - Decl::PrintStats(); - Stmt::PrintStats(); - } - - ASTStreamer_Terminate(Streamer); -} - - static void PrintFunctionDeclStart(FunctionDecl *FD) { bool HasBody = FD->getBody(); diff --git a/Driver/ASTStreamers.h b/Driver/ASTStreamers.h index f568e8e866..e21c1c9aa0 100644 --- a/Driver/ASTStreamers.h +++ b/Driver/ASTStreamers.h @@ -19,8 +19,8 @@ namespace clang { class Preprocessor; class FunctionDecl; class TypedefDecl; +class ASTConsumer; -void BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); void PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); void DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); diff --git a/Driver/DiagChecker.cpp b/Driver/DiagChecker.cpp index e2efd96cce..3b08924d4f 100644 --- a/Driver/DiagChecker.cpp +++ b/Driver/DiagChecker.cpp @@ -14,6 +14,8 @@ #include "clang.h" #include "ASTStreamers.h" #include "TextDiagnosticBuffer.h" +#include "clang/Sema/ASTStreamer.h" +#include "clang/AST/ASTConsumer.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Preprocessor.h" using namespace clang; @@ -223,8 +225,12 @@ static bool CheckResults(Preprocessor &PP, /// CheckDiagnostics - Implement the -parse-ast-check diagnostic verifier. bool clang::CheckDiagnostics(Preprocessor &PP, unsigned MainFileID) { - // Parse the specified input file. - BuildASTs(PP, MainFileID, false); + // Parse the specified input file, building ASTs and performing sema, but + // doing nothing else. +{ + ASTConsumer NullConsumer; + ParseAST(PP, MainFileID, NullConsumer); +} // Gather the set of expected diagnostics. DiagList ExpectedErrors, ExpectedWarnings; diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 79a09f1761..d6f4da8a87 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -26,6 +26,8 @@ #include "ASTStreamers.h" #include "TextDiagnosticBuffer.h" #include "TextDiagnosticPrinter.h" +#include "clang/Sema/ASTStreamer.h" +#include "clang/AST/ASTConsumer.h" #include "clang/Parse/Parser.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Basic/FileManager.h" @@ -51,7 +53,7 @@ enum ProgActions { ParseASTPrint, // Parse ASTs and print them. ParseASTDump, // Parse ASTs and dump them. ParseASTCheck, // Parse ASTs and check diagnostics. - ParseAST, // Parse ASTs. + BuildAST, // Parse ASTs. ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs. ParseCFGView, // Parse ASTS. Build CFGs. View CFGs. AnalysisLiveVariables, // Print results of live-variable analysis. @@ -80,7 +82,7 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, "Run parser and perform semantic analysis"), clEnumValN(ParsePrintCallbacks, "parse-print-callbacks", "Run parser and print each callback invoked"), - clEnumValN(ParseAST, "parse-ast", + clEnumValN(BuildAST, "parse-ast", "Run parser and build ASTs"), clEnumValN(ParseASTPrint, "parse-ast-print", "Run parser, build ASTs, then print ASTs"), @@ -837,9 +839,11 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID, ClearSourceMgr = true; break; case ParseSyntaxOnly: // -fsyntax-only - case ParseAST: - BuildASTs(PP, MainFileID, Stats); + case BuildAST: { + ASTConsumer NullConsumer; + ParseAST(PP, MainFileID, NullConsumer, Stats); break; + } case ParseASTPrint: PrintASTs(PP, MainFileID, Stats); break; diff --git a/Sema/ASTStreamer.cpp b/Sema/ASTStreamer.cpp index c0f4cae735..f96621da2c 100644 --- a/Sema/ASTStreamer.cpp +++ b/Sema/ASTStreamer.cpp @@ -13,11 +13,14 @@ #include "clang/Sema/ASTStreamer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConsumer.h" #include "Sema.h" #include "clang/Parse/Action.h" #include "clang/Parse/Parser.h" using namespace clang; +ASTConsumer::~ASTConsumer() {} + namespace { class ASTStreamer { Parser P; @@ -84,6 +87,39 @@ void ASTStreamer::PrintStats() const { // Public interface to the file //===----------------------------------------------------------------------===// +/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as +/// the file is parsed. +void clang::ParseAST(Preprocessor &PP, unsigned MainFileID, + ASTConsumer &Consumer, bool PrintStats) { + // Collect global stats on Decls/Stmts (until we have a module streamer). + if (PrintStats) { + Decl::CollectingStats(true); + Stmt::CollectingStats(true); + } + + ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), + PP.getIdentifierTable()); + + ASTStreamer Streamer(PP, Context, MainFileID); + + Consumer.Initialize(Context, MainFileID); + + while (Decl *D = Streamer.ReadTopLevelDecl()) + Consumer.HandleTopLevelDecl(D); + + if (PrintStats) { + fprintf(stderr, "\nSTATISTICS:\n"); + Streamer.PrintStats(); + Context.PrintStats(); + Decl::PrintStats(); + Stmt::PrintStats(); + Consumer.PrintStats(); + + Decl::CollectingStats(false); + Stmt::CollectingStats(false); + } +} + /// ASTStreamer_Init - Create an ASTStreamer with the specified preprocessor /// and FileID. ASTStreamerTy *clang::ASTStreamer_Init(Preprocessor &pp, ASTContext &ctxt, diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h new file mode 100644 index 0000000000..160260f030 --- /dev/null +++ b/include/clang/AST/ASTConsumer.h @@ -0,0 +1,44 @@ +//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTConsumer class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTCONSUMER_H +#define LLVM_CLANG_AST_ASTCONSUMER_H + +namespace clang { + class ASTContext; + +/// ASTConsumer - This is an abstract interface that should be implemented by +/// clients that read ASTs. This abstraction layer allows the client to be +/// independent of the AST producer (e.g. parser vs AST dump file reader, etc). +class ASTConsumer { +public: + virtual ~ASTConsumer(); + + /// Initialize - This is called to initialize the consumer, providing the + /// ASTContext and the file ID of the primary file. + virtual void Initialize(ASTContext &Context, unsigned MainFileID) { + } + + /// HandleTopLevelDecl - Handle the specified top-level declaration. + /// + virtual void HandleTopLevelDecl(Decl *D) { + } + + /// PrintStats - If desired, print any statistics. + virtual void PrintStats() { + } +}; + +} // end namespace clang. + +#endif diff --git a/include/clang/Sema/ASTStreamer.h b/include/clang/Sema/ASTStreamer.h index f55f8710ce..02c9bba9a5 100644 --- a/include/clang/Sema/ASTStreamer.h +++ b/include/clang/Sema/ASTStreamer.h @@ -18,6 +18,13 @@ namespace clang { class Preprocessor; class ASTContext; class Decl; + class ASTConsumer; + + /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as + /// the file is parsed. This does not take ownership of the ASTConsumer. + void ParseAST(Preprocessor &pp, unsigned MainFileID, + ASTConsumer &C, bool PrintStats = false); + /// ASTStreamerTy - This is an opaque type used to reference ASTStreamer /// objects.