v5 of patches.
Remaining: * callfunc issues finding functions * vtable issues (likely related) * in stressHistogram: Test 3: Projection with Range for Histograms and Profiles................OK Error in <TStreamerInfo::Build>: TProfile, unknown type: EErrorType fErrorMode git-svn-id: http://root.cern.ch/svn/root/branches/dev/root6-pch@48858 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
03cac10cfd
commit
77ba6929b0
@ -1,21 +1,25 @@
|
||||
//--------------------------------------------------------------------*- C++ -*-
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
// version: $Id$
|
||||
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef CLING_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
#define CLING_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- 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 ExternalSemaSource interface, dispatching to all clients
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
|
||||
#include "clang/Sema/ExternalSemaSource.h"
|
||||
#include "clang/Sema/Weak.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CXXConstructorDecl;
|
||||
class CXXRecordDecl;
|
||||
class DeclaratorDecl;
|
||||
@ -27,44 +31,227 @@ namespace clang {
|
||||
class TypedefNameDecl;
|
||||
class ValueDecl;
|
||||
class VarDecl;
|
||||
}
|
||||
|
||||
namespace cling {
|
||||
|
||||
/// \brief An abstract interface that should be implemented by
|
||||
/// external AST sources that also provide information for semantic
|
||||
/// analysis.
|
||||
class MultiplexExternalSemaSource : public clang::ExternalSemaSource {
|
||||
class MultiplexExternalSemaSource : public ExternalSemaSource {
|
||||
|
||||
private:
|
||||
llvm::SmallVector<ExternalSemaSource*, 4> m_Sources; // doesn't own them.
|
||||
llvm::SmallVector<ExternalSemaSource*, 2> Sources; // doesn't own them.
|
||||
|
||||
public:
|
||||
|
||||
///\brief Constructs the external source with given elements.
|
||||
|
||||
///\brief Constructs a new multiplexing external sema source and appends the
|
||||
/// given element to it.
|
||||
///
|
||||
///\param[in] sources - Array of ExternalSemaSources.
|
||||
///\param[in] s1 - A non-null (old) ExternalSemaSource.
|
||||
///\param[in] s2 - A non-null (new) ExternalSemaSource.
|
||||
///
|
||||
MultiplexExternalSemaSource(llvm::ArrayRef<ExternalSemaSource*> sources);
|
||||
MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2);
|
||||
|
||||
~MultiplexExternalSemaSource();
|
||||
|
||||
///\brief Appends new source to the source list.
|
||||
///
|
||||
///\param[in] source - An ExternalSemaSource.
|
||||
///
|
||||
void addSource(ExternalSemaSource &source);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// ExternalASTSource.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// \brief Resolve a declaration ID into a declaration, potentially
|
||||
/// building a new declaration.
|
||||
///
|
||||
/// This method only needs to be implemented if the AST source ever
|
||||
/// passes back decl sets as VisibleDeclaration objects.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Decl *GetExternalDecl(uint32_t ID);
|
||||
|
||||
/// \brief Resolve a selector ID into a selector.
|
||||
///
|
||||
/// This operation only needs to be implemented if the AST source
|
||||
/// returns non-zero for GetNumKnownSelectors().
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Selector GetExternalSelector(uint32_t ID);
|
||||
|
||||
/// \brief Returns the number of selectors known to the external AST
|
||||
/// source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual uint32_t GetNumExternalSelectors();
|
||||
|
||||
/// \brief Resolve the offset of a statement in the decl stream into
|
||||
/// a statement.
|
||||
///
|
||||
/// This operation is meant to be used via a LazyOffsetPtr. It only
|
||||
/// needs to be implemented if the AST source uses methods like
|
||||
/// FunctionDecl::setLazyBody when building decls.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
|
||||
|
||||
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
|
||||
/// stream into an array of specifiers.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
|
||||
|
||||
/// \brief Finds all declarations with the given name in the
|
||||
/// given context.
|
||||
///
|
||||
/// Generally the final step of this method is either to call
|
||||
/// SetExternalVisibleDeclsForName or to recursively call lookup on
|
||||
/// the DeclContext after calling SetExternalVisibleDecls.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual DeclContextLookupResult
|
||||
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
|
||||
|
||||
/// \brief Ensures that the table of all visible declarations inside this
|
||||
/// context is up to date.
|
||||
///
|
||||
/// The default implementation of this functino is a no-op.
|
||||
virtual void completeVisibleDeclsMap(const DeclContext *DC);
|
||||
|
||||
/// \brief Finds all declarations lexically contained within the given
|
||||
/// DeclContext, after applying an optional filter predicate.
|
||||
///
|
||||
/// \param isKindWeWant a predicate function that returns true if the passed
|
||||
/// declaration kind is one we are looking for. If NULL, all declarations
|
||||
/// are returned.
|
||||
///
|
||||
/// \return an indication of whether the load succeeded or failed.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
bool (*isKindWeWant)(Decl::Kind),
|
||||
SmallVectorImpl<Decl*> &Result);
|
||||
|
||||
/// \brief Finds all declarations lexically contained within the given
|
||||
/// DeclContext.
|
||||
///
|
||||
/// \return true if an error occurred
|
||||
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, 0, Result);
|
||||
}
|
||||
|
||||
template <typename DeclTy>
|
||||
ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
|
||||
SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
|
||||
}
|
||||
|
||||
/// \brief Get the decls that are contained in a file in the Offset/Length
|
||||
/// range. \p Length can be 0 to indicate a point at \p Offset instead of
|
||||
/// a range.
|
||||
virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
|
||||
SmallVectorImpl<Decl *> &Decls);
|
||||
|
||||
/// \brief Gives the external AST source an opportunity to complete
|
||||
/// an incomplete type.
|
||||
virtual void CompleteType(TagDecl *Tag);
|
||||
|
||||
/// \brief Gives the external AST source an opportunity to complete an
|
||||
/// incomplete Objective-C class.
|
||||
///
|
||||
/// This routine will only be invoked if the "externally completed" bit is
|
||||
/// set on the ObjCInterfaceDecl via the function
|
||||
/// \c ObjCInterfaceDecl::setExternallyCompleted().
|
||||
virtual void CompleteType(ObjCInterfaceDecl *Class);
|
||||
|
||||
/// \brief Loads comment ranges.
|
||||
virtual void ReadComments();
|
||||
|
||||
/// \brief Notify ExternalASTSource that we started deserialization of
|
||||
/// a decl or type so until FinishedDeserializing is called there may be
|
||||
/// decls that are initializing. Must be paired with FinishedDeserializing.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void StartedDeserializing();
|
||||
|
||||
/// \brief Notify ExternalASTSource that we finished the deserialization of
|
||||
/// a decl or type. Must be paired with StartedDeserializing.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void FinishedDeserializing();
|
||||
|
||||
/// \brief Function that will be invoked when we begin parsing a new
|
||||
/// translation unit involving this external AST source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void StartTranslationUnit(ASTConsumer *Consumer);
|
||||
|
||||
/// \brief Print any statistics that have been gathered regarding
|
||||
/// the external AST source.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void PrintStats();
|
||||
|
||||
|
||||
/// \brief Perform layout on the given record.
|
||||
///
|
||||
/// This routine allows the external AST source to provide an specific
|
||||
/// layout for a record, overriding the layout that would normally be
|
||||
/// constructed. It is intended for clients who receive specific layout
|
||||
/// details rather than source code (such as LLDB). The client is expected
|
||||
/// to fill in the field offsets, base offsets, virtual base offsets, and
|
||||
/// complete object size.
|
||||
///
|
||||
/// \param Record The record whose layout is being requested.
|
||||
///
|
||||
/// \param Size The final size of the record, in bits.
|
||||
///
|
||||
/// \param Alignment The final alignment of the record, in bits.
|
||||
///
|
||||
/// \param FieldOffsets The offset of each of the fields within the record,
|
||||
/// expressed in bits. All of the fields must be provided with offsets.
|
||||
///
|
||||
/// \param BaseOffsets The offset of each of the direct, non-virtual base
|
||||
/// classes. If any bases are not given offsets, the bases will be laid
|
||||
/// out according to the ABI.
|
||||
///
|
||||
/// \param VirtualBaseOffsets The offset of each of the virtual base classes
|
||||
/// (either direct or not). If any bases are not given offsets, the bases will
|
||||
/// be laid out according to the ABI.
|
||||
///
|
||||
/// \returns true if the record layout was provided, false otherwise.
|
||||
virtual bool
|
||||
layoutRecordType(const RecordDecl *Record,
|
||||
uint64_t &Size, uint64_t &Alignment,
|
||||
llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
|
||||
|
||||
/// Return the amount of memory used by memory buffers, breaking down
|
||||
/// by heap-backed versus mmap'ed memory.
|
||||
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// ExternalSemaSource.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// \brief Initialize the semantic source with the Sema instance
|
||||
/// being used to perform semantic analysis on the abstract syntax
|
||||
/// tree.
|
||||
virtual void InitializeSema(clang::Sema& S);
|
||||
virtual void InitializeSema(Sema &S);
|
||||
|
||||
/// \brief Inform the semantic consumer that Sema is no longer available.
|
||||
virtual void ForgetSema();
|
||||
|
||||
/// \brief Load the contents of the global method pool for a given
|
||||
/// selector.
|
||||
virtual void ReadMethodPool(clang::Selector Sel);
|
||||
virtual void ReadMethodPool(Selector Sel);
|
||||
|
||||
/// \brief Load the set of namespaces that are known to the external source,
|
||||
/// which will be used during typo correction.
|
||||
virtual void ReadKnownNamespaces(
|
||||
clang::SmallVectorImpl<clang::NamespaceDecl*>& Namespaces);
|
||||
virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
|
||||
|
||||
/// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
/// Sema cannot find.
|
||||
@ -74,7 +261,7 @@ public:
|
||||
/// \param S the Scope of the identifier occurrence.
|
||||
///
|
||||
/// \return true to tell Sema to recover using the LookupResult.
|
||||
virtual bool LookupUnqualified(clang::LookupResult& R, clang::Scope* S);
|
||||
virtual bool LookupUnqualified(LookupResult &R, Scope *S);
|
||||
|
||||
/// \brief Read the set of tentative definitions known to the external Sema
|
||||
/// source.
|
||||
@ -83,8 +270,7 @@ public:
|
||||
/// given vector of tentative definitions. Note that this routine may be
|
||||
/// invoked multiple times; the external source should take care not to
|
||||
/// introduce the same declarations repeatedly.
|
||||
virtual void ReadTentativeDefinitions(
|
||||
clang::SmallVectorImpl<clang::VarDecl*>& TentativeDefs);
|
||||
virtual void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs);
|
||||
|
||||
/// \brief Read the set of unused file-scope declarations known to the
|
||||
/// external Sema source.
|
||||
@ -94,7 +280,7 @@ public:
|
||||
/// invoked multiple times; the external source should take care not to
|
||||
/// introduce the same declarations repeatedly.
|
||||
virtual void ReadUnusedFileScopedDecls(
|
||||
clang::SmallVectorImpl<const clang::DeclaratorDecl*>& Decls);
|
||||
SmallVectorImpl<const DeclaratorDecl*> &Decls);
|
||||
|
||||
/// \brief Read the set of delegating constructors known to the
|
||||
/// external Sema source.
|
||||
@ -104,7 +290,7 @@ public:
|
||||
/// invoked multiple times; the external source should take care not to
|
||||
/// introduce the same declarations repeatedly.
|
||||
virtual void ReadDelegatingConstructors(
|
||||
clang::SmallVectorImpl<clang::CXXConstructorDecl*>& Decls);
|
||||
SmallVectorImpl<CXXConstructorDecl*> &Decls);
|
||||
|
||||
/// \brief Read the set of ext_vector type declarations known to the
|
||||
/// external Sema source.
|
||||
@ -113,8 +299,7 @@ public:
|
||||
/// the given vector of declarations. Note that this routine may be
|
||||
/// invoked multiple times; the external source should take care not to
|
||||
/// introduce the same declarations repeatedly.
|
||||
virtual void ReadExtVectorDecls(
|
||||
clang::SmallVectorImpl<clang::TypedefNameDecl*>& Decls);
|
||||
virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls);
|
||||
|
||||
/// \brief Read the set of dynamic classes known to the external Sema source.
|
||||
///
|
||||
@ -122,8 +307,7 @@ public:
|
||||
/// the given vector of declarations. Note that this routine may be
|
||||
/// invoked multiple times; the external source should take care not to
|
||||
/// introduce the same declarations repeatedly.
|
||||
virtual void ReadDynamicClasses(
|
||||
clang::SmallVectorImpl<clang::CXXRecordDecl*>& Decls);
|
||||
virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls);
|
||||
|
||||
/// \brief Read the set of locally-scoped external declarations known to the
|
||||
/// external Sema source.
|
||||
@ -132,8 +316,7 @@ public:
|
||||
/// declarations to the given vector of declarations. Note that this routine
|
||||
/// may be invoked multiple times; the external source should take care not
|
||||
/// to introduce the same declarations repeatedly.
|
||||
virtual void ReadLocallyScopedExternalDecls(
|
||||
clang::SmallVectorImpl<clang::NamedDecl*>& Decls);
|
||||
virtual void ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl*>&Decls);
|
||||
|
||||
/// \brief Read the set of referenced selectors known to the
|
||||
/// external Sema source.
|
||||
@ -142,9 +325,8 @@ public:
|
||||
/// given vector of selectors. Note that this routine
|
||||
/// may be invoked multiple times; the external source should take care not
|
||||
/// to introduce the same selectors repeatedly.
|
||||
virtual void ReadReferencedSelectors(
|
||||
clang::SmallVectorImpl<std::pair<clang::Selector,
|
||||
clang::SourceLocation> >& Sels);
|
||||
virtual void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
|
||||
SourceLocation> > &Sels);
|
||||
|
||||
/// \brief Read the set of weak, undeclared identifiers known to the
|
||||
/// external Sema source.
|
||||
@ -154,15 +336,14 @@ public:
|
||||
/// the external source should take care not to introduce the same identifiers
|
||||
/// repeatedly.
|
||||
virtual void ReadWeakUndeclaredIdentifiers(
|
||||
clang::SmallVectorImpl<std::pair<clang::IdentifierInfo*,
|
||||
clang::WeakInfo> >& WI);
|
||||
SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI);
|
||||
|
||||
/// \brief Read the set of used vtables known to the external Sema source.
|
||||
///
|
||||
/// The external source should append its own used vtables to the given
|
||||
/// vector. Note that this routine may be invoked multiple times; the external
|
||||
/// source should take care not to introduce the same vtables repeatedly.
|
||||
virtual void ReadUsedVTables(clang::SmallVectorImpl<clang::ExternalVTableUse>& VTables);
|
||||
virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
|
||||
|
||||
/// \brief Read the set of pending instantiations known to the external
|
||||
/// Sema source.
|
||||
@ -172,13 +353,13 @@ public:
|
||||
/// external source should take care not to introduce the same instantiations
|
||||
/// repeatedly.
|
||||
virtual void ReadPendingInstantiations(
|
||||
clang::SmallVectorImpl<std::pair<clang::ValueDecl*,
|
||||
clang::SourceLocation> >& Pending);
|
||||
SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending);
|
||||
|
||||
// isa/cast/dyn_cast support
|
||||
static bool classof(const MultiplexExternalSemaSource*) { return true; }
|
||||
//static bool classof(const ExternalSemaSource*) { return true; }
|
||||
};
|
||||
|
||||
} // end namespace cling
|
||||
} // end namespace clang
|
||||
|
||||
#endif // CLING_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
|
@ -81,7 +81,7 @@ namespace cling {
|
||||
///
|
||||
NestedTransactions m_NestedTransactions;
|
||||
|
||||
unsigned m_State : 2;
|
||||
unsigned m_State : 3;
|
||||
|
||||
unsigned m_IssuedDiags : 2;
|
||||
|
||||
@ -119,6 +119,7 @@ namespace cling {
|
||||
kUnknown,
|
||||
kRolledBack,
|
||||
kRolledBackWithErrors,
|
||||
kCommitting,
|
||||
kCommitted
|
||||
};
|
||||
|
||||
@ -143,6 +144,7 @@ namespace cling {
|
||||
|
||||
typedef NestedTransactions::const_iterator const_nested_iterator;
|
||||
typedef NestedTransactions::const_reverse_iterator const_reverse_nested_iterator;
|
||||
// FIXME: misnomer, doesn't iterate over decls!
|
||||
const_nested_iterator nested_decls_begin() const {
|
||||
return m_NestedTransactions.begin();
|
||||
}
|
||||
@ -235,6 +237,14 @@ namespace cling {
|
||||
m_NestedTransactions.push_back(nested);
|
||||
}
|
||||
|
||||
///\brief Direct access.
|
||||
///
|
||||
const DelayCallInfo& operator[](size_t I) const { return m_DeclQueue[I]; }
|
||||
|
||||
///\brief Direct access, non-const.
|
||||
///
|
||||
DelayCallInfo& operator[](size_t I) { return m_DeclQueue[I]; }
|
||||
|
||||
///\brief Returns the declaration count.
|
||||
///
|
||||
size_t size() const { return m_DeclQueue.size(); }
|
||||
|
@ -24,11 +24,14 @@ namespace cling {
|
||||
if (!getTransaction()->getCompilationOpts().Debug)
|
||||
return;
|
||||
|
||||
for (Transaction::const_iterator I = getTransaction()->decls_begin(),
|
||||
E = getTransaction()->decls_end(); I != E; ++I)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J)
|
||||
// FIXME: Size might change in the loop!
|
||||
for (size_t Idx = 0; Idx < getTransaction()->size(); ++Idx) {
|
||||
// Copy DCI; it might get relocated below.
|
||||
Transaction::DelayCallInfo I = (*getTransaction())[Idx];
|
||||
for (DeclGroupRef::const_iterator J = I.m_DGR.begin(),
|
||||
JE = I.m_DGR.end(); J != JE; ++J)
|
||||
printDecl(*J);
|
||||
}
|
||||
}
|
||||
|
||||
void ASTDumper::printDecl(Decl* D) {
|
||||
|
@ -84,11 +84,13 @@ namespace cling {
|
||||
// if (!getTransaction()->getCompilationOpts().ResultEvaluation)
|
||||
// return;
|
||||
AutoFixer autoFixer(m_Sema);
|
||||
for (Transaction::const_iterator I = getTransaction()->decls_begin(),
|
||||
E = getTransaction()->decls_end(); I != E; ++I)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J)
|
||||
// size can change in the loop!
|
||||
for (size_t Idx = 0; Idx < getTransaction()->size(); ++Idx) {
|
||||
Transaction::DelayCallInfo I = (*getTransaction())[Idx];
|
||||
for (DeclGroupRef::const_iterator J = I.m_DGR.begin(),
|
||||
JE = I.m_DGR.end(); J != JE; ++J)
|
||||
if ((*J)->hasBody())
|
||||
autoFixer.Fix(cast<CompoundStmt>((*J)->getBody()));
|
||||
}
|
||||
}
|
||||
} // end namespace cling
|
||||
|
@ -205,6 +205,7 @@ namespace cling {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
|
||||
Invocation->getTargetOpts()));
|
||||
if (!CI->hasTarget()) {
|
||||
@ -212,6 +213,7 @@ namespace cling {
|
||||
CI = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CI->getTarget().setForcedLangOptions(CI->getLangOpts());
|
||||
SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget());
|
||||
if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) {
|
||||
@ -234,6 +236,28 @@ namespace cling {
|
||||
// Set up the memory buffer
|
||||
if (buffer)
|
||||
CI->getSourceManager().createMainFileIDForMemBuffer(buffer);
|
||||
else {
|
||||
// As main file we want
|
||||
// * a virtual file that is claiming to be huge
|
||||
// * with an empty memory buffer attached (to bring the content)
|
||||
SourceManager& SM = CI->getSourceManager();
|
||||
FileManager& FM = SM.getFileManager();
|
||||
// Build the virtual file
|
||||
const char* Filename = "InteractiveInputLineIncluder.h";
|
||||
const std::string& CGOptsMainFileName
|
||||
= CI->getInvocation().getCodeGenOpts().MainFileName;
|
||||
if (!CGOptsMainFileName.empty())
|
||||
Filename = CGOptsMainFileName.c_str();
|
||||
const FileEntry* FE
|
||||
= FM.getVirtualFile(Filename, 1U << 15U, time(0));
|
||||
FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User);
|
||||
const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID);
|
||||
const SrcMgr::ContentCache* MainFileCC
|
||||
= MainFileSLocE.getFile().getContentCache();
|
||||
llvm::MemoryBuffer* MainFileMB
|
||||
= llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n");
|
||||
const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB);
|
||||
}
|
||||
|
||||
// Set up the preprocessor
|
||||
CI->createPreprocessor();
|
||||
@ -265,11 +289,12 @@ namespace cling {
|
||||
// the JIT to crash
|
||||
// When asserts are on, TURN ON not compare the VerifyModule
|
||||
assert(CI->getCodeGenOpts().VerifyModule = 1);
|
||||
|
||||
return CI;
|
||||
}
|
||||
|
||||
void CIFactory::SetClingCustomLangOpts(LangOptions& Opts) {
|
||||
Opts.EmitAllDecls = 1;
|
||||
Opts.EmitAllDecls = 0;
|
||||
Opts.Exceptions = 1;
|
||||
Opts.CXXExceptions = 1;
|
||||
Opts.Deprecated = 1;
|
||||
|
@ -216,10 +216,12 @@ namespace cling {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
for (Transaction::const_iterator I = getTransaction()->decls_begin(),
|
||||
E = getTransaction()->decls_end(); I != E; ++I)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J)
|
||||
// size can change in the loop!
|
||||
for (size_t Idx = 0; Idx < getTransaction()->size(); ++Idx) {
|
||||
// Copy DCI, might get reallocated below.
|
||||
Transaction::DelayCallInfo I = (*getTransaction())[Idx];
|
||||
for (DeclGroupRef::const_iterator J = I.m_DGR.begin(),
|
||||
JE = I.m_DGR.end(); J != JE; ++J)
|
||||
if (ShouldVisit(*J) && (*J)->hasBody()) {
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*J)) {
|
||||
// Set the decl context, which is needed by Evaluate.
|
||||
@ -230,6 +232,7 @@ namespace cling {
|
||||
assert ((!isa<BlockDecl>(*J) || !isa<ObjCMethodDecl>(*J))
|
||||
&& "Not implemented yet!");
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Check for error before returning.
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "clang/AST/DeclGroup.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/CodeGen/CodeGenModule.h"
|
||||
#include "clang/CodeGen/ModuleBuilder.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
@ -50,7 +51,7 @@ namespace cling {
|
||||
m_LastTransaction(0) {
|
||||
|
||||
CompilerInstance* CI
|
||||
= CIFactory::createCI(llvm::MemoryBuffer::getMemBuffer("", "CLING"),
|
||||
= CIFactory::createCI(0 /*llvm::MemoryBuffer::getMemBuffer("", "CLING")*/,
|
||||
argc, argv, llvmdir);
|
||||
assert(CI && "CompilerInstance is (null)!");
|
||||
|
||||
@ -77,16 +78,40 @@ namespace cling {
|
||||
m_TTransformers.push_back(new ReturnSynthesizer(TheSema));
|
||||
m_TTransformers.push_back(new ASTDumper());
|
||||
m_TTransformers.push_back(new DeclExtractor(TheSema));
|
||||
}
|
||||
void IncrementalParser::Initialize() {
|
||||
// pull in PCHs
|
||||
if (getCodeGenerator())
|
||||
getCodeGenerator()->Initialize(getCI()->getASTContext());
|
||||
const std::string& PCHFileName
|
||||
= m_CI->getInvocation ().getPreprocessorOpts().ImplicitPCHInclude;
|
||||
if (!PCHFileName.empty()) {
|
||||
CompilationOptions CO;
|
||||
CO.DeclarationExtraction = 0;
|
||||
CO.ValuePrinting = CompilationOptions::VPDisabled;
|
||||
CO.CodeGeneration = hasCodeGenerator();
|
||||
beginTransaction(CO);
|
||||
m_CI->createPCHExternalASTSource(PCHFileName,
|
||||
true /*DisablePCHValidation*/,
|
||||
true /*DisableStatCache*/,
|
||||
true /*AllowPCHWithCompilerErrors*/,
|
||||
0 /*DeserializationListener*/);
|
||||
commitTransaction(endTransaction());
|
||||
}
|
||||
|
||||
|
||||
m_Parser.reset(new Parser(CI->getPreprocessor(), *TheSema,
|
||||
Sema* TheSema = &m_CI->getSema();
|
||||
m_Parser.reset(new Parser(m_CI->getPreprocessor(), *TheSema,
|
||||
false /*skipFuncBodies*/));
|
||||
CI->getPreprocessor().EnterMainSourceFile();
|
||||
m_CI->getPreprocessor().EnterMainSourceFile();
|
||||
// Initialize the parser after we have entered the main source file.
|
||||
m_Parser->Initialize();
|
||||
// Perform initialization that occurs after the parser has been initialized
|
||||
// but before it parses anything. Initializes the consumers too.
|
||||
CI->getSema().Initialize();
|
||||
TheSema->Initialize();
|
||||
|
||||
ExternalASTSource *External = TheSema->getASTContext().getExternalSource();
|
||||
if (External)
|
||||
External->StartTranslationUnit(m_Consumer);
|
||||
}
|
||||
|
||||
IncrementalParser::~IncrementalParser() {
|
||||
@ -179,6 +204,8 @@ namespace cling {
|
||||
//Transaction* CurT = m_Consumer->getTransaction();
|
||||
assert(T->isCompleted() && "Transaction not ended!?");
|
||||
|
||||
T->setState(Transaction::kCommitting);
|
||||
|
||||
// Check for errors...
|
||||
if (T->getIssuedDiags() == Transaction::kErrors) {
|
||||
rollbackTransaction(T);
|
||||
@ -215,7 +242,8 @@ namespace cling {
|
||||
|
||||
if (T->getCompilationOpts().CodeGeneration && hasCodeGenerator()) {
|
||||
// Reset the module builder to clean up global initializers, c'tors, d'tors
|
||||
getCodeGenerator()->Initialize(getCI()->getASTContext());
|
||||
CodeGen::CodeGenModule* CGM = getCodeGenerator()->GetBuilder();
|
||||
CGM->Release();
|
||||
|
||||
// codegen the transaction
|
||||
if (T->getCompilationOpts().CodeGenerationForModule) {
|
||||
@ -233,11 +261,13 @@ namespace cling {
|
||||
|
||||
llvm::SmallVector<FunctionDecl*, 32> inlines;
|
||||
InlineCollector IC(inlines);
|
||||
for (Transaction::iterator I = T->decls_begin(), E = T->decls_end();
|
||||
I != E; ++I) {
|
||||
if (I->m_Call == Transaction::kCCIHandleTopLevelDecl)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J) {
|
||||
// FIXME: Size might change in the loop!
|
||||
for (size_t Idx = 0; Idx < T->size(); ++Idx) {
|
||||
// Copy DCI; it might get relocated below.
|
||||
Transaction::DelayCallInfo I = (*T)[Idx];
|
||||
if (I.m_Call == Transaction::kCCIHandleTopLevelDecl)
|
||||
for (DeclGroupRef::const_iterator J = I.m_DGR.begin(),
|
||||
JE = I.m_DGR.end(); J != JE; ++J) {
|
||||
|
||||
// Traverse the TagDecl to find the inlined members.
|
||||
inlines.clear();
|
||||
@ -249,33 +279,38 @@ namespace cling {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else for (Transaction::iterator I = T->decls_begin(), E = T->decls_end();
|
||||
I != E; ++I) {
|
||||
if (I->m_Call == Transaction::kCCIHandleTopLevelDecl)
|
||||
getCodeGenerator()->HandleTopLevelDecl(I->m_DGR);
|
||||
else if (I->m_Call == Transaction::kCCIHandleInterestingDecl)
|
||||
getCodeGenerator()->HandleInterestingDecl(I->m_DGR);
|
||||
else if(I->m_Call == Transaction::kCCIHandleTagDeclDefinition) {
|
||||
TagDecl* TD = cast<TagDecl>(I->m_DGR.getSingleDecl());
|
||||
} else for (size_t Idx = 0; Idx < T->size() /*can change in the loop!*/;
|
||||
++Idx) {
|
||||
// Copy DCI; it might get relocated below.
|
||||
Transaction::DelayCallInfo I = (*T)[Idx];
|
||||
if (I.m_Call == Transaction::kCCIHandleTopLevelDecl)
|
||||
getCodeGenerator()->HandleTopLevelDecl(I.m_DGR);
|
||||
else if (I.m_Call == Transaction::kCCIHandleInterestingDecl) {
|
||||
// Usually through BackendConsumer which doesn't implement
|
||||
// HandleInterestingDecl() and thus calls
|
||||
// ASTConsumer::HandleInterestingDecl()
|
||||
getCodeGenerator()->HandleTopLevelDecl(I.m_DGR);
|
||||
} else if(I.m_Call == Transaction::kCCIHandleTagDeclDefinition) {
|
||||
TagDecl* TD = cast<TagDecl>(I.m_DGR.getSingleDecl());
|
||||
getCodeGenerator()->HandleTagDeclDefinition(TD);
|
||||
}
|
||||
else if (I->m_Call == Transaction::kCCIHandleVTable) {
|
||||
CXXRecordDecl* CXXRD = cast<CXXRecordDecl>(I->m_DGR.getSingleDecl());
|
||||
else if (I.m_Call == Transaction::kCCIHandleVTable) {
|
||||
CXXRecordDecl* CXXRD = cast<CXXRecordDecl>(I.m_DGR.getSingleDecl());
|
||||
getCodeGenerator()->HandleVTable(CXXRD, /*isRequired*/true);
|
||||
}
|
||||
else if (I->m_Call
|
||||
else if (I.m_Call
|
||||
== Transaction::kCCIHandleCXXImplicitFunctionInstantiation) {
|
||||
FunctionDecl* FD = cast<FunctionDecl>(I->m_DGR.getSingleDecl());
|
||||
FunctionDecl* FD = cast<FunctionDecl>(I.m_DGR.getSingleDecl());
|
||||
getCodeGenerator()->HandleCXXImplicitFunctionInstantiation(FD);
|
||||
}
|
||||
else if (I->m_Call
|
||||
else if (I.m_Call
|
||||
== Transaction::kCCIHandleCXXStaticMemberVarInstantiation) {
|
||||
VarDecl* VD = cast<VarDecl>(I->m_DGR.getSingleDecl());
|
||||
VarDecl* VD = cast<VarDecl>(I.m_DGR.getSingleDecl());
|
||||
getCodeGenerator()->HandleCXXStaticMemberVarInstantiation(VD);
|
||||
|
||||
|
||||
}
|
||||
else if (I->m_Call == Transaction::kCCINone)
|
||||
else if (I.m_Call == Transaction::kCCINone)
|
||||
; // We use that internally as delimiter in the Transaction.
|
||||
else
|
||||
llvm_unreachable("We shouldn't have decl without call info.");
|
||||
@ -290,11 +325,23 @@ namespace cling {
|
||||
}
|
||||
}
|
||||
|
||||
T->setState(Transaction::kCommitted);
|
||||
InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks();
|
||||
|
||||
if (callbacks)
|
||||
if (callbacks) {
|
||||
callbacks->TransactionCommitted(*T);
|
||||
if (T->hasNestedTransactions()) {
|
||||
Transaction* SubTransactionWhileCommitting = *T->rnested_decls_begin();
|
||||
if (SubTransactionWhileCommitting->getState()
|
||||
== Transaction::kUnknown) {
|
||||
// A nested transaction was created while committing this
|
||||
// transaction; commit it now.
|
||||
SubTransactionWhileCommitting->setCompleted();
|
||||
commitTransaction(SubTransactionWhileCommitting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T->setState(Transaction::kCommitted);
|
||||
}
|
||||
|
||||
void IncrementalParser::rollbackTransaction(Transaction* T) const {
|
||||
@ -348,11 +395,13 @@ namespace cling {
|
||||
//
|
||||
void IncrementalParser::CreateSLocOffsetGenerator() {
|
||||
SourceManager& SM = getCI()->getSourceManager();
|
||||
#if 0
|
||||
FileManager& FM = SM.getFileManager();
|
||||
const FileEntry* FE
|
||||
= FM.getVirtualFile("InteractiveInputLineIncluder.h", 1U << 15U, time(0));
|
||||
m_VirtualFileID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
|
||||
|
||||
#endif
|
||||
m_VirtualFileID = SM.getMainFileID();
|
||||
assert(!m_VirtualFileID.isInvalid() && "No VirtualFileID created?");
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ namespace cling {
|
||||
const char* llvmdir);
|
||||
~IncrementalParser();
|
||||
|
||||
void Initialize();
|
||||
clang::CompilerInstance* getCI() const { return m_CI.get(); }
|
||||
clang::Parser* getParser() const { return m_Parser.get(); }
|
||||
clang::CodeGenerator* getCodeGenerator() const { return m_CodeGen.get(); }
|
||||
|
@ -144,6 +144,8 @@ namespace cling {
|
||||
|
||||
m_ExecutionContext.reset(new ExecutionContext());
|
||||
|
||||
m_IncrParser->Initialize();
|
||||
|
||||
// Add path to interpreter's include files
|
||||
// Try to find the headers in the src folder first
|
||||
#ifdef CLING_SRCDIR_INCL
|
||||
@ -196,12 +198,19 @@ namespace cling {
|
||||
declare("#include \"cling/Interpreter/RuntimeUniverse.h\"");
|
||||
declare("#include \"cling/Interpreter/ValuePrinter.h\"");
|
||||
|
||||
// Set up the gCling variable
|
||||
std::stringstream initializer;
|
||||
initializer << "namespace cling {namespace runtime { "
|
||||
"cling::Interpreter *gCling=(cling::Interpreter*)"
|
||||
<< (uintptr_t)this << ";} }";
|
||||
declare(initializer.str());
|
||||
if (getCodeGenerator()) {
|
||||
// Set up the gCling variable if it can be used
|
||||
std::stringstream initializer;
|
||||
initializer << "namespace cling {namespace runtime { "
|
||||
"cling::Interpreter *gCling=(cling::Interpreter*)"
|
||||
<< (uintptr_t)this << ";} }";
|
||||
declare(initializer.str());
|
||||
#if 0
|
||||
initializer << "cling::runtime::gCling=(cling::Interpreter*)"
|
||||
<< (uintptr_t)this << ";";
|
||||
execute(initializer.str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
declare("#include \"cling/Interpreter/CValuePrinter.h\"");
|
||||
|
@ -1,112 +1,270 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
// version: $Id$
|
||||
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "cling/Interpreter/MultiplexExternalSemaSource.h"
|
||||
|
||||
//===--- MultiplexExternalSemaSource.cpp ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the event dispatching to the subscribed clients.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "clang/Sema/MultiplexExternalSemaSource.h"
|
||||
#include "clang/AST/DeclContextInternals.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
namespace cling {
|
||||
MultiplexExternalSemaSource::MultiplexExternalSemaSource(
|
||||
llvm::ArrayRef<ExternalSemaSource*> sources) {
|
||||
for (size_t i = 0; i < sources.size(); ++i)
|
||||
m_Sources.push_back(sources[i]);
|
||||
///\brief Constructs a new multiplexing external sema source and appends the
|
||||
/// given element to it.
|
||||
///
|
||||
///\param[in] source - An ExternalSemaSource.
|
||||
///
|
||||
MultiplexExternalSemaSource::MultiplexExternalSemaSource(ExternalSemaSource &s1,
|
||||
ExternalSemaSource &s2){
|
||||
Sources.push_back(&s1);
|
||||
Sources.push_back(&s2);
|
||||
}
|
||||
|
||||
// pin the vtable here.
|
||||
MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {}
|
||||
|
||||
///\brief Appends new source to the source list.
|
||||
///
|
||||
///\param[in] source - An ExternalSemaSource.
|
||||
///
|
||||
void MultiplexExternalSemaSource::addSource(ExternalSemaSource &source) {
|
||||
Sources.push_back(&source);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExternalASTSource.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
if (Decl *Result = Sources[i]->GetExternalDecl(ID))
|
||||
return Result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
|
||||
Selector Sel;
|
||||
for(size_t i = 0; i < Sources.size(); ++i) {
|
||||
Sel = Sources[i]->GetExternalSelector(ID);
|
||||
if (!Sel.isNull())
|
||||
return Sel;
|
||||
}
|
||||
return Sel;
|
||||
}
|
||||
|
||||
uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() {
|
||||
uint32_t total = 0;
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
total += Sources[i]->GetNumExternalSelectors();
|
||||
return total;
|
||||
}
|
||||
|
||||
// pin the vtable here.
|
||||
MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {}
|
||||
Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
|
||||
return Result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::InitializeSema(Sema& S) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->InitializeSema(S);
|
||||
CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers(
|
||||
uint64_t Offset){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
|
||||
return R;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DeclContextLookupResult MultiplexExternalSemaSource::
|
||||
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
|
||||
StoredDeclsList DeclsFound;
|
||||
for(size_t i = 0; i < Sources.size(); ++i) {
|
||||
DeclContext::lookup_result R =
|
||||
Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
|
||||
for (DeclContext::lookup_iterator I = R.first, E = R.second; I != E;
|
||||
++I) {
|
||||
if (!DeclsFound.HandleRedeclaration(*I))
|
||||
DeclsFound.AddSubsequentDecl(*I);
|
||||
}
|
||||
}
|
||||
return DeclsFound.getLookupResult();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ForgetSema() {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ForgetSema();
|
||||
}
|
||||
void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->completeVisibleDeclsMap(DC);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadMethodPool(Sel);
|
||||
}
|
||||
ExternalLoadResult MultiplexExternalSemaSource::
|
||||
FindExternalLexicalDecls(const DeclContext *DC,
|
||||
bool (*isKindWeWant)(Decl::Kind),
|
||||
SmallVectorImpl<Decl*> &Result) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
// FIXME: The semantics of the return result is unclear to me...
|
||||
Sources[i]->FindExternalLexicalDecls(DC, isKindWeWant, Result);
|
||||
|
||||
void MultiplexExternalSemaSource::ReadKnownNamespaces(
|
||||
SmallVectorImpl<NamespaceDecl*>& Namespaces){
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadKnownNamespaces(Namespaces);
|
||||
}
|
||||
return ELR_Success;
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File,
|
||||
unsigned Offset,
|
||||
unsigned Length,
|
||||
SmallVectorImpl<Decl *> &Decls){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->CompleteType(Tag);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->CompleteType(Class);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadComments() {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadComments();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::StartedDeserializing() {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->StartedDeserializing();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::FinishedDeserializing() {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->FinishedDeserializing();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->StartTranslationUnit(Consumer);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::PrintStats() {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->PrintStats();
|
||||
}
|
||||
|
||||
bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record,
|
||||
uint64_t &Size,
|
||||
uint64_t &Alignment,
|
||||
llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
|
||||
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
|
||||
BaseOffsets, VirtualBaseOffsets))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::
|
||||
getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->getMemoryBufferSizes(sizes);
|
||||
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExternalSemaSource.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
void MultiplexExternalSemaSource::InitializeSema(Sema &S) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->InitializeSema(S);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ForgetSema() {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ForgetSema();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadMethodPool(Sel);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadKnownNamespaces(
|
||||
SmallVectorImpl<NamespaceDecl*> &Namespaces){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadKnownNamespaces(Namespaces);
|
||||
}
|
||||
|
||||
bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult& R, Scope* S){
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->LookupUnqualified(R, S);
|
||||
|
||||
return !R.empty();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadTentativeDefinitions(
|
||||
SmallVectorImpl<VarDecl*>& TentativeDefs) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadTentativeDefinitions(TentativeDefs);
|
||||
}
|
||||
bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->LookupUnqualified(R, S);
|
||||
|
||||
void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
|
||||
SmallVectorImpl<const DeclaratorDecl*>& Decls) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadUnusedFileScopedDecls(Decls);
|
||||
}
|
||||
return !R.empty();
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadTentativeDefinitions(
|
||||
SmallVectorImpl<VarDecl*> &TentativeDefs) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadTentativeDefinitions(TentativeDefs);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadDelegatingConstructors(
|
||||
SmallVectorImpl<CXXConstructorDecl*>& Decls) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadDelegatingConstructors(Decls);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
|
||||
SmallVectorImpl<const DeclaratorDecl*> &Decls) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadUnusedFileScopedDecls(Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadDelegatingConstructors(
|
||||
SmallVectorImpl<CXXConstructorDecl*> &Decls) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadDelegatingConstructors(Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadExtVectorDecls(
|
||||
SmallVectorImpl<TypedefNameDecl*>& Decls) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadExtVectorDecls(Decls);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadExtVectorDecls(
|
||||
SmallVectorImpl<TypedefNameDecl*> &Decls) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadExtVectorDecls(Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadDynamicClasses(
|
||||
SmallVectorImpl<CXXRecordDecl*>& Decls) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadDynamicClasses(Decls);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadDynamicClasses(
|
||||
SmallVectorImpl<CXXRecordDecl*> &Decls) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadDynamicClasses(Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadLocallyScopedExternalDecls(
|
||||
SmallVectorImpl<NamedDecl*>& Decls) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadLocallyScopedExternalDecls(Decls);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadLocallyScopedExternalDecls(
|
||||
SmallVectorImpl<NamedDecl*> &Decls) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadLocallyScopedExternalDecls(Decls);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadReferencedSelectors(
|
||||
SmallVectorImpl<std::pair<Selector, SourceLocation> >& Sels) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadReferencedSelectors(Sels);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadReferencedSelectors(
|
||||
SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadReferencedSelectors(Sels);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
|
||||
SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> >& WI) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
|
||||
SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadUsedVTables(
|
||||
SmallVectorImpl<ExternalVTableUse>& VTables) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadUsedVTables(VTables);
|
||||
}
|
||||
void MultiplexExternalSemaSource::ReadUsedVTables(
|
||||
SmallVectorImpl<ExternalVTableUse> &VTables) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadUsedVTables(VTables);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadPendingInstantiations(
|
||||
void MultiplexExternalSemaSource::ReadPendingInstantiations(
|
||||
SmallVectorImpl<std::pair<ValueDecl*,
|
||||
SourceLocation> >& Pending) {
|
||||
for(size_t i = 0; i < m_Sources.size(); ++i)
|
||||
m_Sources[i]->ReadPendingInstantiations(Pending);
|
||||
}
|
||||
} // end namespace cling
|
||||
SourceLocation> > &Pending) {
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadPendingInstantiations(Pending);
|
||||
}
|
||||
|
@ -27,6 +27,30 @@ namespace cling {
|
||||
// return;
|
||||
// }
|
||||
// register the wrapper if any.
|
||||
|
||||
if (getState() == kCommitting) {
|
||||
// We are committing and getting enw decls in.
|
||||
// Move them into a sub transaction that will be processed
|
||||
// recursively at the end of of commitTransaction.
|
||||
Transaction* subTransactionWhileCommitting = 0;
|
||||
if (hasNestedTransactions()
|
||||
&& m_NestedTransactions.back()->getState() == kUnknown)
|
||||
subTransactionWhileCommitting = m_NestedTransactions.back();
|
||||
else {
|
||||
// FIXME: is this correct (Axel says "yes")
|
||||
CompilationOptions Opts(getCompilationOpts());
|
||||
Opts.DeclarationExtraction = 0;
|
||||
Opts.ValuePrinting = CompilationOptions::VPDisabled;
|
||||
Opts.ResultEvaluation = 0;
|
||||
Opts.DynamicScoping = 0;
|
||||
subTransactionWhileCommitting
|
||||
= new Transaction(Opts, getModule());
|
||||
addNestedTransaction(subTransactionWhileCommitting);
|
||||
}
|
||||
subTransactionWhileCommitting->append(DCI);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DCI.m_DGR.isSingleDecl()) {
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(DCI.m_DGR.getSingleDecl()))
|
||||
if (utils::Analyze::IsWrapper(FD)) {
|
||||
|
Loading…
Reference in New Issue
Block a user