Home | History | Annotate | Download | only in Expression
      1 //===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef liblldb_ClangASTSource_h_
     11 #define liblldb_ClangASTSource_h_
     12 
     13 #include <set>
     14 
     15 #include "clang/Basic/IdentifierTable.h"
     16 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
     17 #include "lldb/Symbol/ClangASTImporter.h"
     18 #include "lldb/Target/Target.h"
     19 
     20 #include "llvm/ADT/SmallSet.h"
     21 
     22 namespace lldb_private {
     23 
     24 //----------------------------------------------------------------------
     25 /// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
     26 /// @brief Provider for named objects defined in the debug info for Clang
     27 ///
     28 /// As Clang parses an expression, it may encounter names that are not
     29 /// defined inside the expression, including variables, functions, and
     30 /// types.  Clang knows the name it is looking for, but nothing else.
     31 /// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
     32 /// to Clang for these names, consulting the ClangExpressionDeclMap to do
     33 /// the actual lookups.
     34 //----------------------------------------------------------------------
     35 class ClangASTSource :
     36     public ClangExternalASTSourceCommon,
     37     public ClangASTImporter::MapCompleter
     38 {
     39 public:
     40     //------------------------------------------------------------------
     41     /// Constructor
     42     ///
     43     /// Initializes class variables.
     44     ///
     45     /// @param[in] declMap
     46     ///     A reference to the LLDB object that handles entity lookup.
     47     //------------------------------------------------------------------
     48 	ClangASTSource (const lldb::TargetSP &target) :
     49         m_import_in_progress (false),
     50         m_lookups_enabled (false),
     51         m_target (target),
     52         m_ast_context (NULL),
     53         m_active_lookups ()
     54     {
     55         m_ast_importer = m_target->GetClangASTImporter();
     56     }
     57 
     58     //------------------------------------------------------------------
     59     /// Destructor
     60     //------------------------------------------------------------------
     61 	~ClangASTSource();
     62 
     63     //------------------------------------------------------------------
     64     /// Interface stubs.
     65     //------------------------------------------------------------------
     66     clang::Decl *GetExternalDecl (uint32_t)         {   return NULL;                }
     67     clang::Stmt *GetExternalDeclStmt (uint64_t)     {   return NULL;                }
     68 	clang::Selector GetExternalSelector (uint32_t)  {   return clang::Selector();   }
     69     uint32_t GetNumExternalSelectors ()             {   return 0;                   }
     70     clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset)
     71                                                     {   return NULL;                }
     72     void MaterializeVisibleDecls (const clang::DeclContext *DC)
     73                                                     {   return;                     }
     74 
     75     void InstallASTContext (clang::ASTContext *ast_context)
     76     {
     77         m_ast_context = ast_context;
     78         m_ast_importer->InstallMapCompleter(ast_context, *this);
     79     }
     80 
     81     //
     82     // APIs for ExternalASTSource
     83     //
     84 
     85     //------------------------------------------------------------------
     86     /// Look up all Decls that match a particular name.  Only handles
     87     /// Identifiers and DeclContexts that are either NamespaceDecls or
     88     /// TranslationUnitDecls.  Calls SetExternalVisibleDeclsForName with
     89     /// the result.
     90     ///
     91     /// The work for this function is done by
     92     /// void FindExternalVisibleDecls (NameSearchContext &);
     93     ///
     94     /// @param[in] DC
     95     ///     The DeclContext to register the found Decls in.
     96     ///
     97     /// @param[in] Name
     98     ///     The name to find entries for.
     99     ///
    100     /// @return
    101     ///     Whatever SetExternalVisibleDeclsForName returns.
    102     //------------------------------------------------------------------
    103     bool
    104     FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
    105                                     clang::DeclarationName Name);
    106 
    107     //------------------------------------------------------------------
    108     /// Enumerate all Decls in a given lexical context.
    109     ///
    110     /// @param[in] DC
    111     ///     The DeclContext being searched.
    112     ///
    113     /// @param[in] isKindWeWant
    114     ///     If non-NULL, a callback function that returns true given the
    115     ///     DeclKinds of desired Decls, and false otherwise.
    116     ///
    117     /// @param[in] Decls
    118     ///     A vector that is filled in with matching Decls.
    119     //------------------------------------------------------------------
    120     clang::ExternalLoadResult
    121     FindExternalLexicalDecls (const clang::DeclContext *DC,
    122                               bool (*isKindWeWant)(clang::Decl::Kind),
    123                               llvm::SmallVectorImpl<clang::Decl*> &Decls);
    124 
    125     //------------------------------------------------------------------
    126     /// Specify the layout of the contents of a RecordDecl.
    127     ///
    128     /// @param[in] Record
    129     ///     The record (in the parser's AST context) that needs to be
    130     ///     laid out.
    131     ///
    132     /// @param[out] Size
    133     ///     The total size of the record in bits.
    134     ///
    135     /// @param[out] Alignment
    136     ///     The alignment of the record in bits.
    137     ///
    138     /// @param[in] FieldOffsets
    139     ///     A map that must be populated with pairs of the record's
    140     ///     fields (in the parser's AST context) and their offsets
    141     ///     (measured in bits).
    142     ///
    143     /// @param[in] BaseOffsets
    144     ///     A map that must be populated with pairs of the record's
    145     ///     C++ concrete base classes (in the parser's AST context,
    146     ///     and only if the record is a CXXRecordDecl and has base
    147     ///     classes) and their offsets (measured in bytes).
    148     ///
    149     /// @param[in] VirtualBaseOffsets
    150     ///     A map that must be populated with pairs of the record's
    151     ///     C++ virtual base classes (in the parser's AST context,
    152     ///     and only if the record is a CXXRecordDecl and has base
    153     ///     classes) and their offsets (measured in bytes).
    154     ///
    155     /// @return
    156     ///     True <=> the layout is valid.
    157     //-----------------------------------------------------------------
    158     bool
    159     layoutRecordType(const clang::RecordDecl *Record,
    160                      uint64_t &Size,
    161                      uint64_t &Alignment,
    162                      llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
    163                      llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
    164                      llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets);
    165 
    166     //------------------------------------------------------------------
    167     /// Complete a TagDecl.
    168     ///
    169     /// @param[in] Tag
    170     ///     The Decl to be completed in place.
    171     //------------------------------------------------------------------
    172     virtual void
    173     CompleteType (clang::TagDecl *Tag);
    174 
    175     //------------------------------------------------------------------
    176     /// Complete an ObjCInterfaceDecl.
    177     ///
    178     /// @param[in] Class
    179     ///     The Decl to be completed in place.
    180     //------------------------------------------------------------------
    181     virtual void
    182     CompleteType (clang::ObjCInterfaceDecl *Class);
    183 
    184     //------------------------------------------------------------------
    185     /// Called on entering a translation unit.  Tells Clang by calling
    186     /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
    187     /// that this object has something to say about undefined names.
    188     ///
    189     /// @param[in] ASTConsumer
    190     ///     Unused.
    191     //------------------------------------------------------------------
    192     void StartTranslationUnit (clang::ASTConsumer *Consumer);
    193 
    194     //
    195     // APIs for NamespaceMapCompleter
    196     //
    197 
    198     //------------------------------------------------------------------
    199     /// Look up the modules containing a given namespace and put the
    200     /// appropriate entries in the namespace map.
    201     ///
    202     /// @param[in] namespace_map
    203     ///     The map to be completed.
    204     ///
    205     /// @param[in] name
    206     ///     The name of the namespace to be found.
    207     ///
    208     /// @param[in] parent_map
    209     ///     The map for the namespace's parent namespace, if there is
    210     ///     one.
    211     //------------------------------------------------------------------
    212     void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
    213                                const ConstString &name,
    214                                ClangASTImporter::NamespaceMapSP &parent_map) const;
    215 
    216     //
    217     // Helper APIs
    218     //
    219 
    220     clang::NamespaceDecl *
    221     AddNamespace (NameSearchContext &context,
    222                   ClangASTImporter::NamespaceMapSP &namespace_decls);
    223 
    224     //------------------------------------------------------------------
    225     /// The worker function for FindExternalVisibleDeclsByName.
    226     ///
    227     /// @param[in] context
    228     ///     The NameSearchContext to use when filing results.
    229     //------------------------------------------------------------------
    230     virtual void FindExternalVisibleDecls (NameSearchContext &context);
    231 
    232     void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
    233     bool GetImportInProgress () { return m_import_in_progress; }
    234 
    235     void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
    236     bool GetLookupsEnabled () { return m_lookups_enabled; }
    237 
    238     //----------------------------------------------------------------------
    239     /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
    240     /// @brief Proxy for ClangASTSource
    241     ///
    242     /// Clang AST contexts like to own their AST sources, so this is a
    243     /// state-free proxy object.
    244     //----------------------------------------------------------------------
    245     class ClangASTSourceProxy : public ClangExternalASTSourceCommon
    246     {
    247     public:
    248         ClangASTSourceProxy (ClangASTSource &original) :
    249             m_original(original)
    250         {
    251         }
    252 
    253         bool
    254         FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
    255                                         clang::DeclarationName Name)
    256         {
    257             return m_original.FindExternalVisibleDeclsByName(DC, Name);
    258         }
    259 
    260         clang::ExternalLoadResult
    261         FindExternalLexicalDecls (const clang::DeclContext *DC,
    262                                   bool (*isKindWeWant)(clang::Decl::Kind),
    263                                   llvm::SmallVectorImpl<clang::Decl*> &Decls)
    264         {
    265             return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls);
    266         }
    267 
    268         void
    269         CompleteType (clang::TagDecl *Tag)
    270         {
    271             return m_original.CompleteType(Tag);
    272         }
    273 
    274         void
    275         CompleteType (clang::ObjCInterfaceDecl *Class)
    276         {
    277             return m_original.CompleteType(Class);
    278         }
    279 
    280         bool
    281         layoutRecordType(const clang::RecordDecl *Record,
    282                          uint64_t &Size,
    283                          uint64_t &Alignment,
    284                          llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
    285                          llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
    286                          llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
    287         {
    288             return m_original.layoutRecordType(Record,
    289                                                Size,
    290                                                Alignment,
    291                                                FieldOffsets,
    292                                                BaseOffsets,
    293                                                VirtualBaseOffsets);
    294         }
    295 
    296         void StartTranslationUnit (clang::ASTConsumer *Consumer)
    297         {
    298             return m_original.StartTranslationUnit(Consumer);
    299         }
    300 
    301         ClangASTMetadata *
    302         GetMetadata(const void * object)
    303         {
    304             return m_original.GetMetadata(object);
    305         }
    306 
    307         void
    308         SetMetadata(const void * object, ClangASTMetadata &metadata)
    309         {
    310             return m_original.SetMetadata(object, metadata);
    311         }
    312 
    313         bool
    314         HasMetadata(const void * object)
    315         {
    316             return m_original.HasMetadata(object);
    317         }
    318     private:
    319         ClangASTSource &m_original;
    320     };
    321 
    322     clang::ExternalASTSource *CreateProxy()
    323     {
    324         return new ClangASTSourceProxy(*this);
    325     }
    326 
    327 protected:
    328     //------------------------------------------------------------------
    329     /// Look for the complete version of an Objective-C interface, and
    330     /// return it if found.
    331     ///
    332     /// @param[in] interface_decl
    333     ///     An ObjCInterfaceDecl that may not be the complete one.
    334     ///
    335     /// @return
    336     ///     NULL if the complete interface couldn't be found;
    337     ///     the complete interface otherwise.
    338     //------------------------------------------------------------------
    339     clang::ObjCInterfaceDecl *
    340     GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
    341 
    342     //------------------------------------------------------------------
    343     /// Find all entities matching a given name in a given module,
    344     /// using a NameSearchContext to make Decls for them.
    345     ///
    346     /// @param[in] context
    347     ///     The NameSearchContext that can construct Decls for this name.
    348     ///
    349     /// @param[in] module
    350     ///     If non-NULL, the module to query.
    351     ///
    352     /// @param[in] namespace_decl
    353     ///     If valid and module is non-NULL, the parent namespace.
    354     ///
    355     /// @param[in] current_id
    356     ///     The ID for the current FindExternalVisibleDecls invocation,
    357     ///     for logging purposes.
    358     ///
    359     /// @return
    360     ///     True on success; false otherwise.
    361     //------------------------------------------------------------------
    362     void
    363     FindExternalVisibleDecls (NameSearchContext &context,
    364                               lldb::ModuleSP module,
    365                               ClangNamespaceDecl &namespace_decl,
    366                               unsigned int current_id);
    367 
    368     //------------------------------------------------------------------
    369     /// Find all Objective-C methods matching a given selector.
    370     ///
    371     /// @param[in] context
    372     ///     The NameSearchContext that can construct Decls for this name.
    373     ///     Its m_decl_name contains the selector and its m_decl_context
    374     ///     is the containing object.
    375     //------------------------------------------------------------------
    376     void
    377     FindObjCMethodDecls (NameSearchContext &context);
    378 
    379     //------------------------------------------------------------------
    380     /// Find all Objective-C properties and ivars with a given name.
    381     ///
    382     /// @param[in] context
    383     ///     The NameSearchContext that can construct Decls for this name.
    384     ///     Its m_decl_name contains the name and its m_decl_context
    385     ///     is the containing object.
    386     //------------------------------------------------------------------
    387     void
    388     FindObjCPropertyAndIvarDecls (NameSearchContext &context);
    389 
    390     //------------------------------------------------------------------
    391     /// A wrapper for ClangASTContext::CopyType that sets a flag that
    392     /// indicates that we should not respond to queries during import.
    393     ///
    394     /// @param[in] dest_context
    395     ///     The target AST context, typically the parser's AST context.
    396     ///
    397     /// @param[in] source_context
    398     ///     The source AST context, typically the AST context of whatever
    399     ///     symbol file the type was found in.
    400     ///
    401     /// @param[in] clang_type
    402     ///     The source type.
    403     ///
    404     /// @return
    405     ///     The imported type.
    406     //------------------------------------------------------------------
    407     ClangASTType
    408     GuardedCopyType (const ClangASTType &src_type);
    409 
    410     friend struct NameSearchContext;
    411 
    412     bool                    m_import_in_progress;
    413     bool                    m_lookups_enabled;
    414 
    415     const lldb::TargetSP                m_target;           ///< The target to use in finding variables and types.
    416 	clang::ASTContext                  *m_ast_context;      ///< The AST context requests are coming in for.
    417     ClangASTImporter                   *m_ast_importer;     ///< The target's AST importer.
    418     std::set<const char *>              m_active_lookups;
    419 };
    420 
    421 //----------------------------------------------------------------------
    422 /// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
    423 /// @brief Container for all objects relevant to a single name lookup
    424 ///
    425 /// LLDB needs to create Decls for entities it finds.  This class communicates
    426 /// what name is being searched for and provides helper functions to construct
    427 /// Decls given appropriate type information.
    428 //----------------------------------------------------------------------
    429 struct NameSearchContext {
    430     ClangASTSource &m_ast_source;                               ///< The AST source making the request
    431     llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls;          ///< The list of declarations already constructed
    432     ClangASTImporter::NamespaceMapSP m_namespace_map;           ///< The mapping of all namespaces found for this request back to their modules
    433     const clang::DeclarationName &m_decl_name;                  ///< The name being looked for
    434     const clang::DeclContext *m_decl_context;                   ///< The DeclContext to put declarations into
    435     llvm::SmallSet <ClangASTType, 5> m_function_types;    ///< All the types of functions that have been reported, so we don't report conflicts
    436 
    437     struct {
    438         bool variable                   : 1;
    439         bool function_with_type_info    : 1;
    440         bool function                   : 1;
    441     } m_found;
    442 
    443     //------------------------------------------------------------------
    444     /// Constructor
    445     ///
    446     /// Initializes class variables.
    447     ///
    448     /// @param[in] astSource
    449     ///     A reference to the AST source making a request.
    450     ///
    451     /// @param[in] decls
    452     ///     A reference to a list into which new Decls will be placed.  This
    453     ///     list is typically empty when the function is called.
    454     ///
    455     /// @param[in] name
    456     ///     The name being searched for (always an Identifier).
    457     ///
    458     /// @param[in] dc
    459     ///     The DeclContext to register Decls in.
    460     //------------------------------------------------------------------
    461     NameSearchContext (ClangASTSource &astSource,
    462                        llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
    463                        clang::DeclarationName &name,
    464                        const clang::DeclContext *dc) :
    465         m_ast_source(astSource),
    466         m_decls(decls),
    467         m_decl_name(name),
    468         m_decl_context(dc)
    469     {
    470         memset(&m_found, 0, sizeof(m_found));
    471     }
    472 
    473     //------------------------------------------------------------------
    474     /// Create a VarDecl with the name being searched for and the provided
    475     /// type and register it in the right places.
    476     ///
    477     /// @param[in] type
    478     ///     The opaque QualType for the VarDecl being registered.
    479     //------------------------------------------------------------------
    480     clang::NamedDecl *AddVarDecl(const ClangASTType &type);
    481 
    482     //------------------------------------------------------------------
    483     /// Create a FunDecl with the name being searched for and the provided
    484     /// type and register it in the right places.
    485     ///
    486     /// @param[in] type
    487     ///     The opaque QualType for the FunDecl being registered.
    488     //------------------------------------------------------------------
    489     clang::NamedDecl *AddFunDecl(const ClangASTType &type);
    490 
    491     //------------------------------------------------------------------
    492     /// Create a FunDecl with the name being searched for and generic
    493     /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
    494     /// right places.
    495     //------------------------------------------------------------------
    496     clang::NamedDecl *AddGenericFunDecl();
    497 
    498     //------------------------------------------------------------------
    499     /// Create a TypeDecl with the name being searched for and the provided
    500     /// type and register it in the right places.
    501     ///
    502     /// @param[in] type
    503     ///     The opaque QualType for the TypeDecl being registered.
    504     //------------------------------------------------------------------
    505     clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type);
    506 
    507 
    508     //------------------------------------------------------------------
    509     /// Add Decls from the provided DeclContextLookupResult to the list
    510     /// of results.
    511     ///
    512     /// @param[in] result
    513     ///     The DeclContextLookupResult, usually returned as the result
    514     ///     of querying a DeclContext.
    515     //------------------------------------------------------------------
    516     void AddLookupResult (clang::DeclContextLookupConstResult result);
    517 
    518     //------------------------------------------------------------------
    519     /// Add a NamedDecl to the list of results.
    520     ///
    521     /// @param[in] decl
    522     ///     The NamedDecl, usually returned as the result
    523     ///     of querying a DeclContext.
    524     //------------------------------------------------------------------
    525     void AddNamedDecl (clang::NamedDecl *decl);
    526 };
    527 
    528 }
    529 
    530 #endif
    531