text: #ifndef TYPELIBBUILDER_H
  #define TYPELIBBUILDER_H
  
  #include <typelib/registry.hh>
  #include <string>
  
  namespace clang {
  class CXXRecordDecl;
  class BuiltinType;
  class TypeDecl;
  class EnumDecl;
  class Type;
  class ConstantArrayType;
  class ASTContext;
  class TypedefNameDecl;
  class Decl;
  }
  
  class TypelibBuilder
  {
  public:
  
      Typelib::Type const *
      registerTypedefNameDecl(const clang::TypedefNameDecl *decl);
  
      Typelib::Type const *registerTypeDecl(const clang::TypeDecl *decl);
  
      /** fill properties of a decl into Opaque of registry
       *
       * if a type was found in the parsed headers which is to be added as a
       * opaque. Will also fill some metadata of the Type:
       *
       * - 'source_file_line' the "path/to/file:columnNumber" of the opaque
       * - 'opaque_is_typedef' a bool saying wether this opaque is a typedef. If
       *   it is, an alias to the underlying type is also added to the registry.
       * - 'base_classes' if the opaque is a CXXRecord, all inherited
       *   child-classes will be noted in the registry
       *
       * this function expects the Opaques to be pre-loaded into the registry, by
       * loading the respective tlb-file for example.
       *
       * @param decl decl of the declaration to be added to the database as opaque
       */
      void registerOpaque(const clang::TypeDecl *decl);
  
      /** fill the internal registry-database with informations extracted from a tlb-file
       *
       * should be used to pre-load opaque-informations. might throw if something
       * fishy detected.
       *
       * @param filename path to tlb-file to load
       */
      void loadRegistry(const std::string &filename);
  
      /** write internal registry to file
       *
       * @param filename path to tlb-file to save
       */
      void saveRegistry(const std::string &filename);
  
      /** accessor for internal registry
       *
       * @return const-ref of internal registry, for exporting for example
       */
      const Typelib::Registry &getRegistry()
      {
          return registry;
      }
  
  private:
      Typelib::Type const *registerType(const std::string &canonicalTypeName,
                                      const clang::Type *type,
                                      clang::ASTContext &context);
  
      /** add builtins to database: basically ints+floats as Typelib::Numeric
       *
       * attention, will silently rename "char" into "[u]int8_t" depending on
       * signedness and create the apropriate alias.
       *
       * @param canonicalTypeName
       * @param builtin
       * @param context
       * @return NULL if nothing was added
       */
      Typelib::Type const *registerBuiltIn(const std::string &canonicalTypeName,
                                           const clang::BuiltinType *builtin,
                                           clang::ASTContext &context);
  
      /** add members and base-classes of a class to the given compound
       *
       * calls itself recursively for all the base-classes.
       *
       * does not test for private-ness anywhere.
       *
       * @return true if everything worked. false if some member-variable failed to be added
       */
      bool addMembersOfClassToCompound(Typelib::Compound &compound,
                                       const std::string &canonicalTypeName,
                                       const clang::CXXRecordDecl *decl);
  
      Typelib::Type const *addRecord(const std::string &canonicalTypeName,
                                     const clang::CXXRecordDecl *decl);
  
      /** add enum to database
       *
       * also add string-value pairs and some metadata
       *
       * @return ptr to added Type in database
       */
      Typelib::Type const *addEnum(const std::string &canonicalTypeName,
                                   const clang::EnumDecl *decl);
  
      /** add array to database if the element-type can be added
       *
       * @return true if smth was added to database
       */
      Typelib::Type const *addArray(const std::string &canonicalTypeName,
                                    const clang::ConstantArrayType *type,
                                    clang::ASTContext &context);
  
      /** add entry to database if the given type is a "Typelib::Container"
       *
       * a "Typelib::Container" handle a small number of special records in typelib like
       * "std::vector" or "std::string".
       * fields or records containing these should be added to the database nevertheless.
       *
       * @return true if the given decl could be added as "Container"
       */
      Typelib::Type const *
      checkRegisterContainer(const std::string &canonicalTypeName,
                             const clang::CXXRecordDecl *decl);
  
      Typelib::Registry registry;
  };
  
  #endif // TYPELIBBUILDER_H
  