From e7785040107266d01ebdcc066365f70b7ace371f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 20 Apr 2009 15:53:59 +0000 Subject: [PATCH] Introduce the notion of a SemaConsumer, which is an ASTConsumer that also gets access to the Sema object performing semantic analysis. This will be used by the PCH writer to serialize Sema state. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69595 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTConsumer.h | 16 +++++++++-- include/clang/Frontend/PCHWriter.h | 5 ++-- include/clang/Sema/SemaConsumer.h | 45 ++++++++++++++++++++++++++++++ lib/Frontend/PCHWriter.cpp | 6 +++- lib/Sema/ParseAST.cpp | 4 +++ tools/clang-cc/GeneratePCH.cpp | 10 +++++-- 6 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 include/clang/Sema/SemaConsumer.h diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index cafeecbae4..fd79bf59ea 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -19,16 +19,25 @@ namespace clang { class DeclGroupRef; class TagDecl; class HandleTagDeclDefinition; - + class SemaConsumer; // layering violation required for safe SemaConsumer + /// 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 { + /// \brief Whether this AST consumer also requires information about + /// semantic analysis. + bool SemaConsumer; + + friend class SemaConsumer; + public: + ASTConsumer() : SemaConsumer(false) { } + virtual ~ASTConsumer() {} /// Initialize - This is called to initialize the consumer, providing the - /// ASTContext. + /// ASTContext and the Action. virtual void Initialize(ASTContext &Context) {} /// HandleTopLevelDecl - Handle the specified top-level declaration. This is @@ -50,6 +59,9 @@ public: /// PrintStats - If desired, print any statistics. virtual void PrintStats() { } + + // Support isa/cast/dyn_cast + static bool classof(const ASTConsumer *) { return true; } }; } // end namespace clang. diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index ee101b54f7..a7397750db 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -34,6 +34,7 @@ namespace clang { class ASTContext; class LabelStmt; class Preprocessor; +class Sema; class SourceManager; class SwitchCase; class TargetInfo; @@ -137,8 +138,8 @@ public: /// the given bitstream. PCHWriter(llvm::BitstreamWriter &Stream); - /// \brief Write a precompiled header for the given AST context. - void WritePCH(ASTContext &Context, const Preprocessor &PP); + /// \brief Write a precompiled header for the given semantic analysis. + void WritePCH(Sema &SemaRef); /// \brief Emit a source location. void AddSourceLocation(SourceLocation Loc, RecordData &Record); diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h new file mode 100644 index 0000000000..25d4253390 --- /dev/null +++ b/include/clang/Sema/SemaConsumer.h @@ -0,0 +1,45 @@ +//===--- SemaConsumer.h - Abstract interface for AST semantics --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the SemaConsumer class, a subclass of +// ASTConsumer that is used by AST clients that also require +// additional semantic analysis. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SEMA_SEMACONSUMER_H +#define LLVM_CLANG_SEMA_SEMACONSUMER_H + +#include "clang/AST/ASTConsumer.h" + +namespace clang { + class Sema; + + /// \brief An abstract interface that should be implemented by + /// clients that read ASTs and then require further semantic + /// analysis of the entities in those ASTs. + class SemaConsumer : public ASTConsumer { + public: + explicit SemaConsumer() { + ASTConsumer::SemaConsumer = true; + } + + /// \brief Initialize the semantic consumer with the Sema instance + /// being used to perform semantic analysis on the abstract syntax + /// tree. + virtual void InitializeSema(Sema &S) {} + + // isa/cast/dyn_cast support + static bool classof(const ASTConsumer *Consumer) { + return Consumer->SemaConsumer; + } + static bool classof(const SemaConsumer *) { return true; } + }; +} + +#endif diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 6aea7a5372..afe77aebf8 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/PCHWriter.h" +#include "../Sema/Sema.h" // FIXME: move header into include/clang/Sema #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclContextInternals.h" @@ -1760,7 +1761,10 @@ void PCHWriter::AddString(const std::string &Str, RecordData &Record) { PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream) : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS), NumStatements(0) { } -void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) { +void PCHWriter::WritePCH(Sema &SemaRef) { + ASTContext &Context = SemaRef.Context; + Preprocessor &PP = SemaRef.PP; + // Emit the file header. Stream.Emit((unsigned)'C', 8); Stream.Emit((unsigned)'P', 8); diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp index b27734745a..448556092f 100644 --- a/lib/Sema/ParseAST.cpp +++ b/lib/Sema/ParseAST.cpp @@ -13,6 +13,7 @@ #include "clang/Sema/ParseAST.h" #include "Sema.h" +#include "clang/Sema/SemaConsumer.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/Stmt.h" @@ -46,6 +47,9 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, Consumer->Initialize(Ctx); + if (SemaConsumer *SC = dyn_cast(Consumer)) + SC->InitializeSema(S); + if (Ctx.getExternalSource()) Ctx.getExternalSource()->StartTranslationUnit(Consumer); diff --git a/tools/clang-cc/GeneratePCH.cpp b/tools/clang-cc/GeneratePCH.cpp index 9b86514086..4265c816f0 100644 --- a/tools/clang-cc/GeneratePCH.cpp +++ b/tools/clang-cc/GeneratePCH.cpp @@ -14,6 +14,7 @@ #include "ASTConsumers.h" #include "clang/Frontend/PCHWriter.h" +#include "clang/Sema/SemaConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTConsumer.h" #include "clang/Lex/Preprocessor.h" @@ -28,14 +29,16 @@ using namespace clang; using namespace llvm; namespace { - class VISIBILITY_HIDDEN PCHGenerator : public ASTConsumer { + class VISIBILITY_HIDDEN PCHGenerator : public SemaConsumer { const Preprocessor &PP; std::string OutFile; + Sema *SemaPtr; public: explicit PCHGenerator(const Preprocessor &PP, const std::string &OutFile) - : PP(PP), OutFile(OutFile) { } + : PP(PP), OutFile(OutFile), SemaPtr(0) { } + virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); }; } @@ -50,7 +53,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { PCHWriter Writer(Stream); // Emit the PCH file - Writer.WritePCH(Ctx, PP); + assert(SemaPtr && "No Sema?"); + Writer.WritePCH(*SemaPtr); // Open up the PCH file. std::string ErrMsg; -- 2.40.0