233 lines
8.0 KiB
C++
233 lines
8.0 KiB
C++
//===--- ExternalASTSource.h - Abstract External AST 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 the ExternalASTSource interface, which enables
|
|
// construction of AST nodes from some external source.x
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|
|
#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|
|
|
|
#include <cassert>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
template <class T> class SmallVectorImpl;
|
|
}
|
|
|
|
namespace clang {
|
|
|
|
class ASTConsumer;
|
|
class Decl;
|
|
class DeclContext;
|
|
class DeclContextLookupResult;
|
|
class DeclarationName;
|
|
class ExternalSemaSource; // layering violation required for downcasting
|
|
class NamedDecl;
|
|
class Selector;
|
|
class Stmt;
|
|
|
|
/// \brief Abstract interface for external sources of AST nodes.
|
|
///
|
|
/// External AST sources provide AST nodes constructed from some
|
|
/// external source, such as a precompiled header. External AST
|
|
/// sources can resolve types and declarations from abstract IDs into
|
|
/// actual type and declaration nodes, and read parts of declaration
|
|
/// contexts.
|
|
class ExternalASTSource {
|
|
/// \brief Whether this AST source also provides information for
|
|
/// semantic analysis.
|
|
bool SemaSource;
|
|
|
|
friend class ExternalSemaSource;
|
|
|
|
public:
|
|
ExternalASTSource() : SemaSource(false) { }
|
|
|
|
virtual ~ExternalASTSource();
|
|
|
|
/// \brief RAII class for safely pairing a StartedDeserializing call
|
|
/// with FinishedDeserializing.
|
|
class Deserializing {
|
|
ExternalASTSource *Source;
|
|
public:
|
|
explicit Deserializing(ExternalASTSource *source) : Source(source) {
|
|
assert(Source);
|
|
Source->StartedDeserializing();
|
|
}
|
|
~Deserializing() {
|
|
Source->FinishedDeserializing();
|
|
}
|
|
};
|
|
|
|
/// \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.
|
|
virtual Decl *GetExternalDecl(uint32_t ID) = 0;
|
|
|
|
/// \brief Resolve a selector ID into a selector.
|
|
///
|
|
/// This operation only needs to be implemented if the AST source
|
|
/// returns non-zero for GetNumKnownSelectors().
|
|
virtual Selector GetExternalSelector(uint32_t ID) = 0;
|
|
|
|
/// \brief Returns the number of selectors known to the external AST
|
|
/// source.
|
|
virtual uint32_t GetNumExternalSelectors() = 0;
|
|
|
|
/// \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.
|
|
virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
|
|
|
|
/// \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.
|
|
virtual DeclContextLookupResult
|
|
FindExternalVisibleDeclsByName(const DeclContext *DC,
|
|
DeclarationName Name) = 0;
|
|
|
|
/// \brief Deserialize all the visible declarations from external storage.
|
|
///
|
|
/// Name lookup deserializes visible declarations lazily, thus a DeclContext
|
|
/// may not have a complete name lookup table. This function deserializes
|
|
/// the rest of visible declarations from the external storage and completes
|
|
/// the name lookup table of the DeclContext.
|
|
virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
|
|
|
|
/// \brief Finds all declarations lexically contained within the given
|
|
/// DeclContext.
|
|
///
|
|
/// \return true if an error occurred
|
|
virtual bool FindExternalLexicalDecls(const DeclContext *DC,
|
|
llvm::SmallVectorImpl<Decl*> &Result) = 0;
|
|
|
|
/// \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();
|
|
|
|
protected:
|
|
static DeclContextLookupResult
|
|
SetExternalVisibleDeclsForName(const DeclContext *DC,
|
|
DeclarationName Name,
|
|
llvm::SmallVectorImpl<NamedDecl*> &Decls);
|
|
|
|
static DeclContextLookupResult
|
|
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
|
|
DeclarationName Name);
|
|
|
|
void MaterializeVisibleDeclsForName(const DeclContext *DC,
|
|
DeclarationName Name,
|
|
llvm::SmallVectorImpl<NamedDecl*> &Decls);
|
|
};
|
|
|
|
/// \brief A lazy pointer to an AST node (of base type T) that resides
|
|
/// within an external AST source.
|
|
///
|
|
/// The AST node is identified within the external AST source by a
|
|
/// 63-bit offset, and can be retrieved via an operation on the
|
|
/// external AST source itself.
|
|
template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
|
|
struct LazyOffsetPtr {
|
|
/// \brief Either a pointer to an AST node or the offset within the
|
|
/// external AST source where the AST node can be found.
|
|
///
|
|
/// If the low bit is clear, a pointer to the AST node. If the low
|
|
/// bit is set, the upper 63 bits are the offset.
|
|
mutable uint64_t Ptr;
|
|
|
|
public:
|
|
LazyOffsetPtr() : Ptr(0) { }
|
|
|
|
explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
|
|
explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
|
|
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
|
|
if (Offset == 0)
|
|
Ptr = 0;
|
|
}
|
|
|
|
LazyOffsetPtr &operator=(T *Ptr) {
|
|
this->Ptr = reinterpret_cast<uint64_t>(Ptr);
|
|
return *this;
|
|
}
|
|
|
|
LazyOffsetPtr &operator=(uint64_t Offset) {
|
|
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
|
|
if (Offset == 0)
|
|
Ptr = 0;
|
|
else
|
|
Ptr = (Offset << 1) | 0x01;
|
|
|
|
return *this;
|
|
}
|
|
|
|
/// \brief Whether this pointer is non-NULL.
|
|
///
|
|
/// This operation does not require the AST node to be deserialized.
|
|
operator bool() const { return Ptr != 0; }
|
|
|
|
/// \brief Whether this pointer is currently stored as an offset.
|
|
bool isOffset() const { return Ptr & 0x01; }
|
|
|
|
/// \brief Retrieve the pointer to the AST node that this lazy pointer
|
|
///
|
|
/// \param Source the external AST source.
|
|
///
|
|
/// \returns a pointer to the AST node.
|
|
T* get(ExternalASTSource *Source) const {
|
|
if (isOffset()) {
|
|
assert(Source &&
|
|
"Cannot deserialize a lazy pointer without an AST source");
|
|
Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
|
|
}
|
|
return reinterpret_cast<T*>(Ptr);
|
|
}
|
|
};
|
|
|
|
/// \brief A lazy pointer to a statement.
|
|
typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
|
|
LazyDeclStmtPtr;
|
|
|
|
/// \brief A lazy pointer to a declaration.
|
|
typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
|
|
LazyDeclPtr;
|
|
|
|
} // end namespace clang
|
|
|
|
#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
|