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.

llvm-svn: 69595
This commit is contained in:
Douglas Gregor 2009-04-20 15:53:59 +00:00
parent 04f2d14d6a
commit 162dd0245e
6 changed files with 78 additions and 8 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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<SemaConsumer>(Consumer))
SC->InitializeSema(S);
if (Ctx.getExternalSource())
Ctx.getExternalSource()->StartTranslationUnit(Consumer);

View File

@ -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;