cling/lib/Interpreter/DeclCollector.h
Yuka Takahashi 98719ad352 Preloading modules and autoloading libraries by deserialized decls
Preloading all the modules has several advantages. 1. We do not have to
rely on rootmap files which don't support some features (namespaces and
templates) 2. Lookup would be faster because we don't have to do
trampoline via rootmap files.

Autoloading libraries when decls are deserialized gives us correctness.
However we still need to optimize the performance by reducing the amount
of loaded libraries and improving Clang performance.
2018-05-18 10:14:30 +02:00

130 lines
4.2 KiB
C++

//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#ifndef CLING_DECL_COLLECTOR_H
#define CLING_DECL_COLLECTOR_H
#include "clang/AST/ASTConsumer.h"
#include "clang/Serialization/ASTDeserializationListener.h"
#include "ASTTransformer.h"
#include <vector>
#include <memory>
namespace clang {
class ASTContext;
class CodeGenerator;
class Decl;
class DeclGroupRef;
class Preprocessor;
class Token;
class Module;
}
namespace cling {
class ASTTransformer;
class WrapperTransformer;
class DeclCollector;
class IncrementalParser;
class Transaction;
///\brief Collects declarations and fills them in cling::Transaction.
///
/// cling::Transaction becomes is a main building block in the interpreter.
/// cling::DeclCollector is responsible for appending all the declarations
/// seen by clang.
///
class DeclCollector : public clang::ASTConsumer , public clang::ASTDeserializationListener {
/// \brief PPCallbacks overrides/ Macro support
class PPAdapter;
///\brief Contains the transaction AST transformers.
///
std::vector<std::unique_ptr<ASTTransformer>> m_TransactionTransformers;
///\brief Contains the AST transformers operating on the wrapper.
///
std::vector<std::unique_ptr<WrapperTransformer>> m_WrapperTransformers;
IncrementalParser* m_IncrParser;
clang::ASTConsumer* m_Consumer;
Transaction* m_CurTransaction;
/// Whether Transform() is active; prevents recursion.
bool m_Transforming = false;
///\brief Test whether the first decl of the DeclGroupRef comes from an AST
/// file.
///
bool comesFromASTReader(clang::DeclGroupRef DGR) const;
bool comesFromASTReader(const clang::Decl* D) const;
bool Transform(clang::DeclGroupRef& DGR);
///\brief Runs AST transformers on a transaction.
///
///\param[in] D - the decl to be transformed.
///
ASTTransformer::Result TransformDecl(clang::Decl* D) const;
public:
DeclCollector() :
m_IncrParser(0), m_Consumer(0), m_CurTransaction(0) {}
virtual ~DeclCollector();
void SetTransformers(std::vector<std::unique_ptr<ASTTransformer>>&& allTT,
std::vector<std::unique_ptr<WrapperTransformer>>&& allWT){
m_TransactionTransformers.swap(allTT);
m_WrapperTransformers.swap(allWT);
for (auto&& TT: m_TransactionTransformers)
TT->SetConsumer(this);
for (auto&& WT: m_WrapperTransformers)
WT->SetConsumer(this);
}
void Setup(IncrementalParser* IncrParser, ASTConsumer* Consumer,
clang::Preprocessor& PP);
/// \{
/// \name ASTConsumer overrides
bool HandleTopLevelDecl(clang::DeclGroupRef DGR) final;
void HandleInterestingDecl(clang::DeclGroupRef DGR) final;
void HandleTagDeclDefinition(clang::TagDecl* TD) final;
void HandleInvalidTagDeclDefinition(clang::TagDecl* TD) final;
void HandleVTable(clang::CXXRecordDecl* RD) final;
void CompleteTentativeDefinition(clang::VarDecl* VD) final;
void HandleTranslationUnit(clang::ASTContext& Ctx) final;
void HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl *D) final;
void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) final;
/// \}
/// \{
/// \name Transaction Support
Transaction* getTransaction() { return m_CurTransaction; }
const Transaction* getTransaction() const { return m_CurTransaction; }
void setTransaction(Transaction* curT) { m_CurTransaction = curT; }
/// \}
// dyn_cast/isa support
static bool classof(const clang::ASTConsumer*) { return true; }
static bool classof(const clang::ASTDeserializationListener*) { return true; }
///\brief ASTDeserializationListener function which gets callback when a decl is deserialized
void DeclRead(clang::serialization::DeclID, const clang::Decl *D) final;
};
} // namespace cling
#endif // CLING_DECL_COLLECTOR_H