98719ad352
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.
130 lines
4.2 KiB
C++
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
|