//--------------------------------------------------------------------*- C++ -*- // CLING - the C++ LLVM-based InterpreterG :) // author: Vassil Vassilev // // 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_EXTRACTOR_H #define CLING_DECL_EXTRACTOR_H #include "TransactionTransformer.h" #include "llvm/ADT/SmallVector.h" #include namespace clang { class ASTContext; class DeclContext; class FunctionDecl; class LookupResult; class NamedDecl; class Scope; class Sema; class Stmt; class TagDecl; } namespace cling { class DeclExtractor : public TransactionTransformer { private: clang::ASTContext* m_Context; /// \brief Counter used when we need unique names. unsigned long long m_UniqueNameCounter; public: DeclExtractor(clang::Sema* S); virtual ~DeclExtractor(); ///\brief Iterates over the transaction and finds cling specific wrappers. /// Scans the wrappers for declarations and extracts them onto the global /// scope. /// virtual void Transform(); private: ///\brief Tries to extract the declaration on the global scope (translation /// unit scope). /// ///\param D[in] - The function declaration to extract from. ///\returns true on success. /// bool ExtractDecl(clang::FunctionDecl* FD); /// \brief Creates unique name (eg. of a variable). Used internally for /// AST node synthesis. /// void createUniqueName(std::string& out); ///\brief Enforces semantically correct initialization order. /// /// If we consider \code int i = 1; i++; int j = i; \endcode the code /// snippet will be transformed into /// \code int i; int j = i; void __cling_wrapper() { int++ } \endcode and /// the result of will be 1 and not 2. This function scans whether there is /// more than one declaration and generates: /// \code /// int i = 1; /// int __fd_init_order__cling_Un1Qu30() { /// i++; /// } /// int __vd_init_order__cling_Un1Qu31 = __fd_init_order__cling_Un1Qu30(); /// int j = i; /// \endcode /// ///\param[in] Stmts - Collection for which have to run as part of the /// static initialization. /// void EnforceInitOrder(llvm::SmallVectorImpl& Stmts); ///\brief Checks for clashing names when trying to extract a declaration. /// ///\returns true if there is another declaration with the same name /// bool CheckForClashingNames( const llvm::SmallVector& Decls, clang::DeclContext* DC, clang::Scope* S); ///\brief Performs semantic checking on a newly-extracted tag declaration. /// /// This routine performs all of the type-checking required for a tag /// declaration once it has been built. It is used both to check tags before /// they have been moved onto the global scope. /// /// Sets NewTD->isInvalidDecl if an error was encountered. /// ///\returns true if the tag declaration is redeclaration. /// bool CheckTagDeclaration(clang::TagDecl* NewTD, clang::LookupResult& Previous); }; } // namespace cling #endif // CLING_DECL_EXTRACTOR_H