[API CHANGE] Remove deprecated idlc and regmerge from the SDK

* Client code must replace uses of idlc and regmerge with uses of unoidl-write,
  see the changes to odk/examples/ and ure/source/uretext/ in
  40f2aee6584eafcf4cd1d95fcf1f775e5435440d "Provide unoidl-write also for the
  SDK" for examples.

* The new types.rdb format is not compatible with LibreOffice < 4.1.  Clients
  generating extensions containing such files are advised to use appropriate
  LibreOffice-minimal-version elements.

* For compatibility with old extensions, reading the legacy types.rdb format is
  still supported.

* The SDK no longer ships an idl/ sub-directory containing the udkap and offapi
  .idl files (as, unlike idlc, unoidl-write does not need them).
  odk/config/cfgWin.js had to be adapted to look (somewhat arbitrarily) for an
  examples/ sub-directory instead of idl/ when checking for "an sdk folder".
  gb_UnoApi_package_idlfiles became unused and has been removed.

* The idlc and regmerge executables have been removed.  Module idlc has been
  removed except for idlc/test/parser/, which is also used by
  CustomTarget_unoidl/unoidl-write_test, and which may eventually be moved into
  module unoidl.  Module external/ucpp and the corresponding configure options
  have also been removed.

Change-Id: I42a0231699b863b5ebe2bee63bc32c8f79278cc1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122363
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
diff --git a/Makefile.fetch b/Makefile.fetch
index ccb3860..8f9b4ba 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -215,7 +215,6 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S
		$(call fetch_Optional,SKIA,SKIA_TARBALL) \
		$(call fetch_Optional,STAROFFICE,STAROFFICE_TARBALL) \
		$(if $(filter WNT,$(OS)),TWAIN_DSM_TARBALL) \
		$(call fetch_Optional,UCPP,UCPP_TARBALL) \
		$(call fetch_Optional,VISIO,VISIO_TARBALL) \
		$(call fetch_Optional,WPD,WPD_TARBALL) \
		$(call fetch_Optional,WPG,WPG_TARBALL) \
diff --git a/Repository.mk b/Repository.mk
index 5ee1546..47a2f9c 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -88,10 +88,8 @@ $(eval $(call gb_Helper_register_executables,NONE, \
$(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \
	$(if $(filter MSC,$(COM)),$(if $(filter-out AARCH64,$(CPUNAME)),climaker)) \
	cppumaker \
	idlc \
	javamaker \
    $(call gb_CondExeSp2bv,sp2bv) \
	$(if $(filter UCPP,$(BUILD_TYPE)),ucpp) \
	$(if $(filter ODK,$(BUILD_TYPE)),unoapploader) \
	unoidl-read \
	unoidl-write \
@@ -249,7 +247,6 @@ endif
$(eval $(call gb_Helper_register_executables_for_install,UREBIN,ure,\
	$(if $(and $(ENABLE_JAVA),$(filter-out HAIKU MACOSX WNT,$(OS)),$(filter DESKTOP,$(BUILD_TYPE))),javaldx) \
    $(call gb_CondExeRegistryTools, \
        regmerge \
        regview \
    ) \
    $(call gb_CondExeUno,uno) \
@@ -907,8 +904,6 @@ $(eval $(call gb_Helper_register_packages_for_install,sdk,\
	odk_html \
	odk_settings \
	odk_settings_generated \
	offapi_idl \
	udkapi_idl \
	$(if $(ENABLE_JAVA), \
		odk_javadoc \
		odk_uno_loader_classes \
@@ -1162,7 +1157,6 @@ $(eval $(call gb_ExternalExecutable_register_executables,\
	genccode \
	gencmn \
	python \
	ucpp \
	xmllint \
	xsltproc \
))
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 2b20634..938fc6b 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -3929,12 +3929,6 @@ endef

endif

define gb_Executable__register_idlc
$(call gb_Executable_add_runtime_dependencies,idlc,\
	$(call gb_ExternalExecutable_get_dependencies,ucpp) \
)
endef

define gb_Executable__register_localize
$(call gb_Executable_add_runtime_dependencies,localize,\
	$(foreach exec,cfgex helpex propex treex ulfex xrmex,\
@@ -4005,19 +3999,6 @@ endef

endif # SYSTEM_LIBXSLT_FOR_BUILD

ifneq (,$(SYSTEM_UCPP))

gb_ExternalExecutable__register_ucpp :=

else # ! SYSTEM_UCPP

define gb_ExternalExecutable__register_ucpp
$(call gb_ExternalExecutable_set_internal,ucpp,$(INSTDIR_FOR_BUILD)/$(SDKDIRNAME)/bin/ucpp$(gb_Executable_EXT_for_build))

endef

endif # SYSTEM_UCPP

ifeq (,$(PYTHON_FOR_BUILD))

define gb_ExternalExecutable__register_python
diff --git a/RepositoryModule_host.mk b/RepositoryModule_host.mk
index 376f3d1..287bd12 100644
--- a/RepositoryModule_host.mk
+++ b/RepositoryModule_host.mk
@@ -94,7 +94,6 @@ $(eval $(call gb_Module_add_moduledirs,libreoffice,\
	i18npool \
	i18nutil \
	idl \
	$(call gb_Helper_optional,DESKTOP,idlc) \
	instsetoo_native \
	io \
	javaunohelper \
diff --git a/compilerplugins/clang/shouldreturnbool.cxx b/compilerplugins/clang/shouldreturnbool.cxx
index bc232b4..fa1bd4c 100644
--- a/compilerplugins/clang/shouldreturnbool.cxx
+++ b/compilerplugins/clang/shouldreturnbool.cxx
@@ -47,9 +47,6 @@ public:
        // false +, slightly odd usage, but not wrong
        if (loplugin::isSamePathname(fn, SRCDIR "/libreofficekit/qa/tilebench/tilebench.cxx"))
            return;
        // uses the Unix convention of "non-zero return indicates error"
        if (loplugin::isSamePathname(fn, SRCDIR "/idlc/source/idlcproduce.cxx"))
            return;
        // template magic
        if (loplugin::isSamePathname(fn, SRCDIR "/vcl/source/gdi/bmpfast.cxx"))
            return;
diff --git a/compilerplugins/clang/unnecessaryparen.cxx b/compilerplugins/clang/unnecessaryparen.cxx
index 29a7907..3b9e5f1 100644
--- a/compilerplugins/clang/unnecessaryparen.cxx
+++ b/compilerplugins/clang/unnecessaryparen.cxx
@@ -83,8 +83,6 @@ public:
        // fixing this, makes the source in the .y files look horrible
        if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/unoidl/source/sourceprovider-parser.cxx"))
            return false;
        if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/idlc/source/parser.cxx"))
            return false;
        return true;
    }
    virtual void run() override
diff --git a/compilerplugins/clang/useuniqueptr.cxx b/compilerplugins/clang/useuniqueptr.cxx
index c0ef34b..cf4853f 100644
--- a/compilerplugins/clang/useuniqueptr.cxx
+++ b/compilerplugins/clang/useuniqueptr.cxx
@@ -463,9 +463,6 @@ void UseUniquePtr::CheckDeleteLocalVar(const FunctionDecl* functionDecl, const C
    // complicated
    if (fn == SRCDIR "/svx/source/sdr/contact/objectcontact.cxx")
        return;
    // memory management in this module is a mess
    if (fn == SRCDIR "/idlc/source/aststack.cxx")
        return;
    // complicated
    if (fn == SRCDIR "/cui/source/customize/cfg.cxx")
        return;
@@ -728,9 +725,6 @@ void UseUniquePtr::CheckLoopDelete(const FunctionDecl* functionDecl, const CXXDe
        if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qa/"))
            return;
        // linked list
        if (fn == SRCDIR "/registry/source/reflwrit.cxx")
            return;
        // linked list
        if (fn == SRCDIR "/tools/source/generic/config.cxx")
            return;
        // linked lists
@@ -848,9 +842,6 @@ void UseUniquePtr::CheckCXXForRangeStmt(const FunctionDecl* functionDecl, const 
        if (!fieldDecl)
            return;

        // appears to just randomly leak stuff, and it involves some lex/yacc stuff
        if (fn == SRCDIR "/idlc/source/aststack.cxx")
            return;
        // complicated
        if (fn == SRCDIR "/vcl/source/gdi/print.cxx")
            return;
@@ -1092,9 +1083,6 @@ bool UseUniquePtr::TraverseConstructorInitializer(CXXCtorInitializer * ctorInit)
        return true;

    StringRef fn = getFilenameOfLocation(compiler.getSourceManager().getSpellingLoc(ctorInit->getSourceLocation()));
    // don't feel like fiddling with the yacc parser
    if (loplugin::hasPathnamePrefix(fn, SRCDIR "/idlc/"))
        return true;
    // cannot change URE
    if (loplugin::hasPathnamePrefix(fn, SRCDIR "/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx"))
        return true;
diff --git a/compilerplugins/clang/writeonlyvars.cxx b/compilerplugins/clang/writeonlyvars.cxx
index f5051c9..3ea5356 100644
--- a/compilerplugins/clang/writeonlyvars.cxx
+++ b/compilerplugins/clang/writeonlyvars.cxx
@@ -185,9 +185,6 @@ void WriteOnlyVars::run()
        // false+
        if (loplugin::isSamePathname(fn, SRCDIR "/store/source/storpage.cxx"))
            return;
        // yydebug?
        if (loplugin::isSamePathname(fn, SRCDIR "/idlc/source/idlccompile.cxx"))
            return;
        if (fn.contains("/qa/"))
            return;
        if (fn.contains("/vcl/workben/"))
diff --git a/config_host.mk.in b/config_host.mk.in
index 019e1a6..c924c13 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -678,8 +678,6 @@ export SYSTEM_REDLAND=@SYSTEM_REDLAND@
export SYSTEM_REVENGE=@SYSTEM_REVENGE@
export SYSTEM_RHINO=@SYSTEM_RHINO@
export SYSTEM_STAROFFICE=@SYSTEM_STAROFFICE@
export SYSTEM_UCPP=@SYSTEM_UCPP@
export SYSTEM_UCPP_IS_GCC=@SYSTEM_UCPP_IS_GCC@
export SYSTEM_VISIO=@SYSTEM_VISIO@
export SYSTEM_WPD=@SYSTEM_WPD@
export SYSTEM_WPG=@SYSTEM_WPG@
diff --git a/configure.ac b/configure.ac
index 2ff842f..11e697c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2214,11 +2214,6 @@ AC_ARG_WITH(system-libxml,
        [Use libxml/libxslt already on system.]),,
    [with_system_libxml=auto])

AC_ARG_WITH(system-ucpp,
    AS_HELP_STRING([--with-system-ucpp],
        [Use ucpp already on system.]),,
    [])

AC_ARG_WITH(system-openldap,
    AS_HELP_STRING([--with-system-openldap],
        [Use the OpenLDAP LDAP SDK already on system.]),,
@@ -2738,11 +2733,6 @@ AC_ARG_WITH(os-version,
        [For FreeBSD users, use this option to override the detected OSVERSION.]),
,)

AC_ARG_WITH(idlc-cpp,
    AS_HELP_STRING([--with-idlc-cpp=<cpp/ucpp>],
        [Specify the C Preprocessor to use for idlc. Default is ucpp.]),
,)

AC_ARG_WITH(parallelism,
    AS_HELP_STRING([--with-parallelism],
        [Number of jobs to run simultaneously during build. Parallel builds can
@@ -9058,40 +9048,6 @@ else
fi

dnl ===================================================================
dnl Check for C preprocessor to use
dnl ===================================================================
AC_MSG_CHECKING([which C preprocessor to use in idlc])
SYSTEM_UCPP_IS_GCC=
if test -n "$with_idlc_cpp"; then
    AC_MSG_RESULT([$with_idlc_cpp])
    AC_PATH_PROG(SYSTEM_UCPP, $with_idlc_cpp)
    AC_MSG_CHECKING([if $with_idlc_cpp is GCC CPP])
    # ucpp will accept -v (to output version), warn about the others as unknown
    # and return 1 (due to -v)
    # gcc will accept -v (as verbose), --version (to output version) and -nostdinc
    # and return 0 (due to --version ) if all options are supported
    $SYSTEM_UCPP -v --version -nostdinc >/dev/null 2>/dev/null
    if test $? -eq 0;  then
        SYSTEM_UCPP_IS_GCC=TRUE
        AC_MSG_RESULT([yes])
    else
        AC_MSG_RESULT([no])
    fi
else
    AC_MSG_RESULT([ucpp])
    AC_MSG_CHECKING([which ucpp to use])
    if test -n "$with_system_ucpp" -a "$with_system_ucpp" != "no"; then
        AC_MSG_RESULT([external])
        AC_PATH_PROG(SYSTEM_UCPP, ucpp)
    else
        AC_MSG_RESULT([internal])
        BUILD_TYPE="$BUILD_TYPE UCPP"
    fi
fi
AC_SUBST(SYSTEM_UCPP)
AC_SUBST(SYSTEM_UCPP_IS_GCC)

dnl ===================================================================
dnl Check for epm (not needed for Windows)
dnl ===================================================================
AC_MSG_CHECKING([whether to enable EPM for packing])
diff --git a/download.lst b/download.lst
index 257c124..fc18292d 100644
--- a/download.lst
+++ b/download.lst
@@ -240,8 +240,6 @@ export SWING_SHA256SUM := 64585ac36a81291a58269ec5347e7e3e2e8596dbacb9221015c208
export SWING_TARBALL := 35c94d2df8893241173de1d16b6034c0-swingExSrc.zip
export TWAIN_DSM_SHA256SUM := 82c818be771f242388457aa8c807e4b52aa84dc22b21c6c56184a6b4cbb085e6
export TWAIN_DSM_TARBALL := twaindsm_2.4.1.orig.tar.gz
export UCPP_SHA256SUM := 983941d31ee8d366085cadf28db75eb1f5cb03ba1e5853b98f12f7f51c63b776
export UCPP_TARBALL := 0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz
export VISIO_SHA256SUM := 8faf8df870cb27b09a787a1959d6c646faa44d0d8ab151883df408b7166bea4c
export VISIO_TARBALL := libvisio-0.1.7.tar.xz
export WPD_SHA256SUM := 2465b0b662fdc5d4e3bebcdc9a79027713fb629ca2bff04a3c9251fdec42dd09
diff --git a/external/Module_external.mk b/external/Module_external.mk
index c8ad9ae..ed8f490 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -94,7 +94,6 @@ $(eval $(call gb_Module_add_moduledirs,external,\
	$(call gb_Helper_optional,SKIA,skia) \
	$(call gb_Helper_optional,STAROFFICE,libstaroffice) \
	$(if $(filter WNT,$(OS)),twain_dsm) \
	$(call gb_Helper_optional,UCPP,ucpp) \
	$(call gb_Helper_optional,VISIO,libvisio) \
	$(call gb_Helper_optional,WPD,libwpd) \
	$(call gb_Helper_optional,WPG,libwpg) \
diff --git a/external/ucpp/Executable_ucpp.mk b/external/ucpp/Executable_ucpp.mk
deleted file mode 100644
index a4be71c..0000000
--- a/external/ucpp/Executable_ucpp.mk
+++ /dev/null
@@ -1,33 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_Executable_Executable,ucpp))

$(eval $(call gb_Executable_set_warnings_disabled,ucpp))

$(eval $(call gb_Executable_use_unpacked,ucpp,ucpp))

$(eval $(call gb_Executable_add_defs,ucpp,\
	-DNO_UCPP_BUF \
	-DUCPP_CONFIG \
	-DSTAND_ALONE \
))

$(eval $(call gb_Executable_add_generated_cobjects,ucpp,\
	UnpackedTarball/ucpp/assert \
	UnpackedTarball/ucpp/cpp \
	UnpackedTarball/ucpp/eval \
	UnpackedTarball/ucpp/hash \
	UnpackedTarball/ucpp/lexer \
	UnpackedTarball/ucpp/macro \
	UnpackedTarball/ucpp/mem \
	UnpackedTarball/ucpp/nhash \
))

# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/Makefile b/external/ucpp/Makefile
deleted file mode 100644
index 569ad8a..0000000
--- a/external/ucpp/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))

include $(module_directory)/../../solenv/gbuild/partial_build.mk

# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/Module_ucpp.mk b/external/ucpp/Module_ucpp.mk
deleted file mode 100644
index dc4c02f..0000000
--- a/external/ucpp/Module_ucpp.mk
+++ /dev/null
@@ -1,20 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_Module_Module,ucpp))

# if not cross-compiling or we need ucpp for ODK
ifneq (,$(if $(CROSS_COMPILING),,T)$(filter ODK,$(BUILD_TYPE)))
$(eval $(call gb_Module_add_targets,ucpp,\
	Executable_ucpp \
	UnpackedTarball_ucpp \
))
endif

# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/README b/external/ucpp/README
deleted file mode 100644
index 9246c70..0000000
--- a/external/ucpp/README
+++ /dev/null
@@ -1,3 +0,0 @@
ucpp is a C99 preprocessor

Used to be hosted at https://code.google.com/p/ucpp/ - not sure where it's gone
diff --git a/external/ucpp/UnpackedTarball_ucpp.mk b/external/ucpp/UnpackedTarball_ucpp.mk
deleted file mode 100644
index 04d7113..0000000
--- a/external/ucpp/UnpackedTarball_ucpp.mk
+++ /dev/null
@@ -1,20 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_UnpackedTarball_UnpackedTarball,ucpp))

$(eval $(call gb_UnpackedTarball_set_tarball,ucpp,$(UCPP_TARBALL)))

$(eval $(call gb_UnpackedTarball_set_patchlevel,ucpp,0))

$(eval $(call gb_UnpackedTarball_add_patches,ucpp,\
    external/ucpp/ucpp.patch \
))

# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/ucpp.patch b/external/ucpp/ucpp.patch
deleted file mode 100644
index c9c4b92..0000000
--- a/external/ucpp/ucpp.patch
+++ /dev/null
@@ -1,11 +0,0 @@
--- cpp.c
+++ cpp.c
@@ -2464,7 +2464,7 @@
 			warning(-1, "unknown option '%s'", argv[i]);
 	} else {
 		if (filename != 0) {
-			error(-1, "spurious filename '%s'", argv[i]);
+			error(-1, "spurious duplicate filename '%s' - vs. '%s' ", argv[i], filename);
 			return 2;
 		}
 		filename = argv[i];
diff --git a/idlc/CustomTarget_parser_test.mk b/idlc/CustomTarget_parser_test.mk
deleted file mode 100644
index f8c7632..0000000
--- a/idlc/CustomTarget_parser_test.mk
+++ /dev/null
@@ -1,91 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_CustomTarget_CustomTarget,idlc/parser_test))

# this target is phony to run it every time
.PHONY : $(call gb_CustomTarget_get_target,idlc/parser_test)

$(call gb_CustomTarget_get_target,idlc/parser_test) : \
            $(call gb_Executable_get_runtime_dependencies,idlc) \
            $(SRCDIR)/solenv/bin/exectest.pl \
            $(SRCDIR)/idlc/test/parser/attribute.tests \
            $(SRCDIR)/idlc/test/parser/constant.tests \
            $(SRCDIR)/idlc/test/parser/constructor.tests \
            $(SRCDIR)/idlc/test/parser/conversion.tests \
            $(SRCDIR)/idlc/test/parser/interfaceinheritance.tests \
            $(SRCDIR)/idlc/test/parser/methodoverload.tests \
            $(SRCDIR)/idlc/test/parser/polystruct.tests \
            $(SRCDIR)/idlc/test/parser/published.tests \
            $(SRCDIR)/idlc/test/parser/struct.tests \
            $(SRCDIR)/idlc/test/parser/typedef.tests \
            | $(call gb_CustomTarget_get_workdir,idlc/parser_test)/.dir
ifneq ($(gb_SUPPRESS_TESTS),)
	@true
else
	$(call gb_Helper_abbreviate_dirs,( \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/attribute.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/constant.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/constructor.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/conversion.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/interfaceinheritance.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/methodoverload.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/oldstyle.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/polystruct.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/published.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/struct.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {} && \
            $(PERL) $(SRCDIR)/solenv/bin/exectest.pl \
                $(SRCDIR)/idlc/test/parser/typedef.tests \
                $(call gb_CustomTarget_get_workdir,idlc/parser_test)/in.idl 0 \
                $(call gb_Executable_get_command,idlc) \
                -O $(call gb_CustomTarget_get_workdir,idlc/parser_test) {}) \
            > $@.log 2>&1 || (cat $@.log && false))
endif

# vim: set noet sw=4 ts=4:
diff --git a/idlc/Executable_idlc.mk b/idlc/Executable_idlc.mk
deleted file mode 100644
index 8af0c40..0000000
--- a/idlc/Executable_idlc.mk
+++ /dev/null
@@ -1,81 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_Executable_Executable,idlc))

$(eval $(call gb_Executable_set_include,idlc,\
    -I$(SRCDIR)/idlc/inc \
    -I$(SRCDIR)/idlc/source \
    $$(INCLUDE) \
))

$(eval $(call gb_Executable_use_externals,idlc,\
	boost_headers \
))

$(eval $(call gb_Executable_use_libraries,idlc,\
    reg \
    $(if $(filter TRUE,$(DISABLE_DYNLOADING)),store) \
    sal \
    salhelper \
))

$(eval $(call gb_Executable_add_grammars,idlc,\
    idlc/source/parser \
))

$(eval $(call gb_Executable_add_scanners,idlc,\
    idlc/source/scanner \
))

ifneq (,$(SYSTEM_UCPP))

$(eval $(call gb_Executable_add_defs,idlc,\
    -DSYSTEM_UCPP \
    -DUCPP=\"file://$(SYSTEM_UCPP)\" \
))

ifneq ($(SYSTEM_UCPP_IS_GCC),)
$(eval $(call gb_Executable_add_defs,idlc,\
    -DSYSTEM_UCPP_IS_GCC \
))
endif

endif

$(eval $(call gb_Executable_add_exception_objects,idlc,\
    idlc/source/idlcmain \
    idlc/source/idlc \
    idlc/source/idlccompile \
    idlc/source/idlcproduce \
    idlc/source/errorhandler \
    idlc/source/options \
    idlc/source/fehelper \
    idlc/source/astdeclaration \
    idlc/source/astscope \
    idlc/source/aststack \
    idlc/source/astdump \
    idlc/source/astinterface \
    idlc/source/aststruct \
    idlc/source/aststructinstance \
    idlc/source/astoperation \
    idlc/source/astconstant \
    idlc/source/astenum \
    idlc/source/astexpression \
    idlc/source/astservice \
))

# Without this, e.g. 'make clean; make CustomTarget_idlc/parser_test' may fail on Windows localized
# to something other than listed in Impl_getTextEncodingData, because osl_getThreadTextEncoding()
# returns Windows ACP, calling FullTextEncodingData ctor which loads the not-yet-built library
$(call gb_Executable_add_runtime_dependencies,idlc, \
    $(call gb_CondLibSalTextenc,$(call gb_Library_get_target,sal_textenc)) \
)

# vim:set noet sw=4 ts=4:
diff --git a/idlc/Makefile b/idlc/Makefile
deleted file mode 100644
index 0997e62..0000000
--- a/idlc/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))

include $(module_directory)/../solenv/gbuild/partial_build.mk

# vim: set noet sw=4 ts=4:
diff --git a/idlc/Module_idlc.mk b/idlc/Module_idlc.mk
deleted file mode 100644
index a20d105..0000000
--- a/idlc/Module_idlc.mk
+++ /dev/null
@@ -1,25 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_Module_Module,idlc))

# if not cross-compiling or we need this for ODK
ifneq (,$(if $(CROSS_COMPILING),,T)$(filter ODK,$(BUILD_TYPE)))

$(eval $(call gb_Module_add_targets,idlc,\
	Executable_idlc \
))

$(eval $(call gb_Module_add_check_targets,idlc,\
	CustomTarget_parser_test \
))

endif

# vim:set noet sw=4 ts=4:
diff --git a/idlc/README.md b/idlc/README.md
deleted file mode 100644
index 621a767..0000000
--- a/idlc/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
# UNO IDL Compiler (idlc)

Contains the UNO IDL compiler: `idlc`, depends on preprocessor: `ucpp`

This compiler generates binary RDB fragments that can be assembled
into a RDB (UNO type library) with the `regmerge` tool, as is done
primarily in the `offapi` and `udkapi` directories.
diff --git a/idlc/inc/astattribute.hxx b/idlc/inc/astattribute.hxx
deleted file mode 100644
index b9a799f..0000000
--- a/idlc/inc/astattribute.hxx
+++ /dev/null
@@ -1,107 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTATTRIBUTE_HXX
#define INCLUDED_IDLC_INC_ASTATTRIBUTE_HXX

#include "astdeclaration.hxx"
#include "astscope.hxx"

#include <registry/types.hxx>
#include <rtl/ustring.hxx>

namespace typereg { class Writer; }

class AstAttribute final : public AstDeclaration, public AstScope {
public:
    AstAttribute(
        sal_uInt32 flags, AstType const * type, OString const & name,
        AstScope * scope):
        AstDeclaration(NT_attribute, name, scope),
        AstScope(NT_attribute), m_flags(flags), m_pType(type)
    {}

    AstAttribute(NodeType nodeType, sal_uInt32 flags, AstType const * pType, const OString& name, AstScope* pScope)
        : AstDeclaration(nodeType, name, pScope), AstScope(nodeType)
        , m_flags(flags)
        , m_pType(pType)
        {}

    void setExceptions(
        OUString const * getDoc, DeclList const * getExc,
        OUString const * setDoc, DeclList const * setExc)
    {
        if (getDoc != nullptr) {
            m_getDocumentation = *getDoc;
        }
        if (getExc != nullptr) {
            m_getExceptions = *getExc;
        }
        if (setDoc != nullptr) {
            m_setDocumentation = *setDoc;
        }
        if (setExc != nullptr) {
            m_setExceptions = *setExc;
        }
    }

    DeclList::size_type getGetExceptionCount() const
    { return m_getExceptions.size(); }

    DeclList::size_type getSetExceptionCount() const
    { return m_setExceptions.size(); }

    bool isReadonly() const
        { return ((m_flags & AF_READONLY) == AF_READONLY); }
    bool isOptional() const
        { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); }
    bool isBound() const
        { return ((m_flags & AF_BOUND) == AF_BOUND); }
    bool isMayBeVoid() const
        { return ((m_flags & AF_MAYBEVOID) == AF_MAYBEVOID); }
    bool isConstrained() const
        { return ((m_flags & AF_CONSTRAINED) == AF_CONSTRAINED); }
    bool isTransient() const
        { return ((m_flags & AF_TRANSIENT) == AF_TRANSIENT); }
    bool isMayBeAmbiguous() const
        { return ((m_flags & AF_MAYBEAMBIGUOUS) == AF_MAYBEAMBIGUOUS); }
    bool isMayBeDefault() const
        { return ((m_flags & AF_MAYBEDEFAULT) == AF_MAYBEDEFAULT); }
    bool isRemoveable() const
        { return ((m_flags & AF_REMOVABLE) == AF_REMOVABLE); }

    void dumpBlob(
        typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex) const;

private:
    void dumpExceptions(
        typereg::Writer & writer, OUString const & documentation,
        DeclList const & exceptions, RTMethodMode flags,
        sal_uInt16 * methodIndex) const;

    const sal_uInt32    m_flags;
    AstType const * m_pType;
    OUString m_getDocumentation;
    DeclList m_getExceptions;
    OUString m_setDocumentation;
    DeclList m_setExceptions;
};

#endif // INCLUDED_IDLC_INC_ASTATTRIBUTE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astbasetype.hxx b/idlc/inc/astbasetype.hxx
deleted file mode 100644
index 0b488c8..0000000
--- a/idlc/inc/astbasetype.hxx
+++ /dev/null
@@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#pragma once

#include "asttype.hxx"
#include "astexpression.hxx"


class AstBaseType final : public AstType
{
public:
    AstBaseType(const ExprType type, const OString& name, AstScope* pScope)
        : AstType(NT_predefined, name, pScope)
        , m_exprType(type)
        {}

    virtual bool isUnsigned() const override {
        switch (m_exprType) {
        case ET_ushort:
        case ET_ulong:
        case ET_uhyper:
            return true;
        default:
            return false;
        }
    }

    ExprType getExprType() const
        { return m_exprType; }
private:
    const ExprType m_exprType;
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astconstant.hxx b/idlc/inc/astconstant.hxx
deleted file mode 100644
index fb8b417..0000000
--- a/idlc/inc/astconstant.hxx
+++ /dev/null
@@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTCONSTANT_HXX
#define INCLUDED_IDLC_INC_ASTCONSTANT_HXX

#include "astdeclaration.hxx"
#include "astexpression.hxx"

namespace typereg { class Writer; }

class AstConstant final : public AstDeclaration
{
public:
    AstConstant(const ExprType type, const NodeType nodeType,
                AstExpression* pExpr, const OString& name, AstScope* pScope);
    AstConstant(const ExprType type, AstExpression* pExpr,
                const OString& name, AstScope* pScope);
    virtual ~AstConstant() override;

    AstExpression* getConstValue()
        { return m_pConstValue; }
    ExprType getConstValueType() const
        { return m_constValueType; }

    bool dumpBlob(
        typereg::Writer & rBlob, sal_uInt16 index, bool published);
private:
    AstExpression*                  m_pConstValue;
    const ExprType  m_constValueType;
};

#endif // INCLUDED_IDLC_INC_ASTCONSTANT_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astconstants.hxx b/idlc/inc/astconstants.hxx
deleted file mode 100644
index 6add23a..0000000
--- a/idlc/inc/astconstants.hxx
+++ /dev/null
@@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTCONSTANTS_HXX
#define INCLUDED_IDLC_INC_ASTCONSTANTS_HXX

#include "astmodule.hxx"

class AstConstants final : public AstModule
{
public:
    AstConstants(const OString& name, AstScope* pScope)
        : AstModule(NT_constants, name, pScope)
    {
    }
};

#endif // INCLUDED_IDLC_INC_ASTCONSTANTS_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astdeclaration.hxx b/idlc/inc/astdeclaration.hxx
deleted file mode 100644
index 0707dbc..0000000
--- a/idlc/inc/astdeclaration.hxx
+++ /dev/null
@@ -1,136 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTDECLARATION_HXX
#define INCLUDED_IDLC_INC_ASTDECLARATION_HXX

#include "idlc.hxx"
#include <registry/registry.hxx>

class AstScope;

// Enum defining the different kinds of Ast nodes
enum NodeType
{
    NT_service,             // Denotes a service
    NT_interface_member,    // Denotes an interface which is exported from object
    NT_service_member,      // Denotes a service which is exported from object
    NT_observes,            // Denotes an observed interface
    NT_needs,               // Denotes a needed service
    NT_module,              // Denotes a module
    NT_root,                // Denotes the root of AST
    NT_interface,           // Denotes an interface
    NT_constants,           // Denotes a constant group
    NT_const,               // Denotes a constant
    NT_exception,           // Denotes an exception
    NT_attribute,           // Denotes an attribute
    NT_property,            // Denotes a property
    NT_operation,           // Denotes an operation
    NT_parameter,           // Denotes an op. parameter
    NT_struct,              // Denotes either a plain struct type, or a
                            // polymorphic struct type template
    NT_type_parameter,      // Denotes a type parameter of a polymorphic struct
                            // type template
    NT_instantiated_struct, // Denotes an instantiated polymorphic struct type
    NT_member,              // Denotes a member in structure, exception
    NT_enum,                // Denotes an enumeration
    NT_enum_val,            // Denotes an enum. value
    NT_sequence,            // Denotes an IDL sequence
    NT_typedef,             // Denotes a typedef
    NT_predefined,          // Denotes a predefined type
    NT_singleton            // Denotes a singleton
};

class AstDeclaration
{
public:
    // Constructors
    AstDeclaration(NodeType type, const OString& name, AstScope* pScope);
    virtual ~AstDeclaration();

    AstDeclaration(AstDeclaration const &) = default;
    AstDeclaration(AstDeclaration &&) = default;
    AstDeclaration & operator =(AstDeclaration const &) = default;
    AstDeclaration & operator =(AstDeclaration &&) = default;

    // Data access
    const OString& getLocalName() const
        { return m_localName; }
    const OString&   getScopedName() const
        { return m_scopedName; }
    const OString&   getFullName() const
        { return m_fullName; }
    virtual const char* getRelativName() const
        { return m_fullName.getStr()+1; }
    AstScope* getScope()
        { return m_pScope; }
    const AstScope* getScope() const
        { return m_pScope; }
    NodeType getNodeType() const
        { return m_nodeType; }
    bool isInMainfile() const
        { return m_bInMainFile; }
    void setInMainfile(bool bInMainfile)
        { m_bInMainFile = bInMainfile; }
    bool isImported() const
        { return m_bImported; }
    void setImported(bool bImported)
        { m_bImported = bImported; }
    sal_Int32 getLineNumber() const
        { return m_lineNumber; }
    void setLineNumber(sal_Int32 lineNumber)
        { m_lineNumber = lineNumber; }
    const OString& getFileName() const
        { return m_fileName; }
    void setFileName(const OString& rFileName)
        { m_fileName = rFileName; }
    const OUString& getDocumentation() const
        { return m_documentation; }
    void setDocumentation(const OUString& rDocumentation)
        { m_documentation = rDocumentation; }

    virtual bool isType() const;

    bool hasAncestor(AstDeclaration* pDecl);

    void setPublished() { m_bPublished = true; }
    bool isPublished() const { return m_bPublished; }

    virtual bool dump(RegistryKey& rKey);

    bool isPredefined() const { return m_bPredefined; }
    void setPredefined(bool bPredefined);

protected:
    OString      m_localName;
    OString      m_scopedName;       // full qualified name
    OString      m_fullName;         // full qualified name with '/' as separator
    AstScope*           m_pScope;
    NodeType            m_nodeType;
    bool            m_bImported;        // imported ?
    bool            m_bInMainFile;      // defined in main file
    bool                m_bPublished;
    bool                m_bPredefined;
    sal_Int32           m_lineNumber;       // line number defined in
    OString      m_fileName;         // fileName defined in
    OUString     m_documentation;    // fileName defined in
};

#endif // INCLUDED_IDLC_INC_ASTDECLARATION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astenum.hxx b/idlc/inc/astenum.hxx
deleted file mode 100644
index dc89d43..0000000
--- a/idlc/inc/astenum.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTENUM_HXX
#define INCLUDED_IDLC_INC_ASTENUM_HXX

#include "asttype.hxx"
#include "astscope.hxx"
#include "astconstant.hxx"

class AstEnum final : public AstType, public AstScope
{
public:
    AstEnum(const OString& name, AstScope* pScope);

    virtual ~AstEnum() override;

    sal_Int32 getEnumValueCount() { return m_enumValueCount++; }

    AstConstant* checkValue(AstExpression* pExpr);

    virtual bool dump(RegistryKey& rKey) override;

private:
    sal_Int32 m_enumValueCount;
};

#endif // INCLUDED_IDLC_INC_ASTENUM_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astexception.hxx b/idlc/inc/astexception.hxx
deleted file mode 100644
index 6c2d549..0000000
--- a/idlc/inc/astexception.hxx
+++ /dev/null
@@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTEXCEPTION_HXX
#define INCLUDED_IDLC_INC_ASTEXCEPTION_HXX

#include "aststruct.hxx"

class AstException final : public AstStruct
{
public:
    AstException(const OString& name, AstException const* pBaseType, AstScope* pScope)
        : AstStruct(NT_exception, name, pBaseType, pScope)
    {
    }
};

#endif // INCLUDED_IDLC_INC_ASTEXCEPTION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astexpression.hxx b/idlc/inc/astexpression.hxx
deleted file mode 100644
index 05d20ba..0000000
--- a/idlc/inc/astexpression.hxx
+++ /dev/null
@@ -1,139 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTEXPRESSION_HXX
#define INCLUDED_IDLC_INC_ASTEXPRESSION_HXX

#include <sal/config.h>

#include <memory>

#include "idlc.hxx"
#include <optional>

// Enum to define all the different operators to combine expressions
enum class ExprComb
{
    Add,     // '+'
    Minus,   // '-'
    Mul,     // '*'
    Div,     // '/'
    Mod,     // '%'
    Or,      // '|'
    Xor,     // '^'
    And,     // '&'
    Left,    // '<<'
    Right,   // '>>'
    UPlus,   // unary '+'
    UMinus,  // unary '-'
    NONE,    // No operator (missing)
    Symbol   // a symbol (function or constant name)
};

// Enum to define expression type
enum ExprType
{
    ET_short,       // Expression value is short
    ET_ushort,      // Expression value is unsigned short
    ET_long,        // Expression value is long
    ET_ulong,       // Expression value is unsigned long
    ET_hyper,       // Expression value is hyper (64 bit)
    ET_uhyper,      // Expression value is unsigned hyper
    ET_float,       // Expression value is 32-bit float
    ET_double,      // Expression value is 64-bit float
    ET_char,        // Expression value is char
    ET_byte,        // Expression value is byte
    ET_boolean,     // Expression value is boolean
    ET_string,      // Expression value is char *
    ET_any,         // Expression value is any of above
    ET_void,        // Expression value is void (absent)
    ET_type,        // Expression value is type
    ET_none         // Expression value is missing
};

// Structure to describe value of constant expression and its type
struct AstExprValue
{
    union
    {
        sal_uInt8       byval;      // Contains byte expression value
        sal_Int16       sval;       // Contains short expression value
        sal_uInt16      usval;      // Contains unsigned short expr value
        sal_Int32       lval;       // Contains long expression value
        sal_uInt32      ulval;      // Contains unsigned long expr value
        sal_Int64       hval;       // Contains hyper expression value
        sal_uInt64      uhval;      // Contains unsigned hyper expr value
        bool            bval;       // Contains boolean expression value
        float           fval;       // Contains 32-bit float expr value
        double          dval;       // Contains 64-bit float expr value
    } u;
    ExprType et;
};

const char* exprTypeToString(ExprType t);

class AstExpression final
{
public:
    // Constructor(s)
    AstExpression(ExprComb c, AstExpression *pExpr1, AstExpression *pExpr2);

    AstExpression(sal_Int32         l);
    AstExpression(sal_Int32         l, ExprType et);
    AstExpression(sal_Int64         h);
    AstExpression(sal_uInt64        uh);
    AstExpression(double            d);
    AstExpression(OString* scopedName);

    ~AstExpression();

    // Data Accessors
    AstExprValue* getExprValue()
        { return m_exprValue.get(); }

    // Evaluation and value coercion
    bool coerce(ExprType type);

    // Evaluate then store value inside this AstExpression
    void evaluate();

    // Compare LONG AstExpression values
    bool compareLong(AstExpression *pExpr);

    OString toString();
private:
    // Evaluate different sets of operators
    std::unique_ptr<AstExprValue> eval_bin_op();
    std::unique_ptr<AstExprValue> eval_bit_op();
    std::unique_ptr<AstExprValue> eval_un_op();
    std::unique_ptr<AstExprValue> eval_symbol();

    ExprComb        m_combOperator;
    std::unique_ptr<AstExpression>
                    m_subExpr1;
    std::unique_ptr<AstExpression>
                    m_subExpr2;
    std::unique_ptr<AstExprValue>
                    m_exprValue;
    std::optional<OString>
                    m_xSymbolicName;
};

#endif // INCLUDED_IDLC_INC_ASTEXPRESSION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astinterface.hxx b/idlc/inc/astinterface.hxx
deleted file mode 100644
index 03c5f22..0000000
--- a/idlc/inc/astinterface.hxx
+++ /dev/null
@@ -1,129 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTINTERFACE_HXX
#define INCLUDED_IDLC_INC_ASTINTERFACE_HXX

#include "asttype.hxx"
#include "astscope.hxx"
#include "inheritedinterface.hxx"

#include <map>
#include <vector>

class AstInterface : public AstType
                   , public AstScope
{
public:
    typedef std::vector< InheritedInterface > InheritedInterfaces;

    struct DoubleMemberDeclaration {
        AstDeclaration const * first;
        AstDeclaration const * second;
    };

    typedef std::vector< DoubleMemberDeclaration > DoubleMemberDeclarations;

    struct DoubleDeclarations {
        std::vector< AstInterface const * > interfaces;
        DoubleMemberDeclarations members;
    };

    AstInterface(
        const OString& name, AstInterface const * pInherits,
        AstScope* pScope);
    virtual ~AstInterface() override;

    AstInterface(AstInterface const &) = default;
    AstInterface(AstInterface &&) = default;
    AstInterface & operator =(AstInterface const &) = default;
    AstInterface & operator =(AstInterface &&) = default;

    InheritedInterfaces const & getAllInheritedInterfaces() const
    { return m_inheritedInterfaces; }

    bool hasMandatoryInheritedInterfaces() const
    { return m_mandatoryInterfaces > 0; }

    void setDefined() { m_bIsDefined = true; }
    bool isDefined() const
        { return m_bIsDefined; }

    bool usesSingleInheritance() const { return m_bSingleInheritance; }

    DoubleDeclarations checkInheritedInterfaceClashes(
        AstInterface const * ifc, bool optional) const;

    void addInheritedInterface(
        AstType const * ifc, bool optional,
        OUString const & documentation);

    DoubleMemberDeclarations checkMemberClashes(
        AstDeclaration const * member) const;

    void addMember(AstDeclaration /*TODO: const*/ * member);

    void forwardDefined(AstInterface const & def);

    virtual bool dump(RegistryKey& rKey) override;

private:
    enum InterfaceKind {
        INTERFACE_INDIRECT_OPTIONAL, INTERFACE_DIRECT_OPTIONAL,
        INTERFACE_INDIRECT_MANDATORY, INTERFACE_DIRECT_MANDATORY };

    struct VisibleMember {
        explicit VisibleMember(AstDeclaration const * theMandatory = nullptr):
            mandatory(theMandatory) {}

        typedef std::map< OString, AstDeclaration const * > Optionals;

        AstDeclaration const * mandatory;
        Optionals optionals;
    };

    typedef std::map< OString, InterfaceKind > VisibleInterfaces;
    typedef std::map< OString, VisibleMember > VisibleMembers;

    void checkInheritedInterfaceClashes(
        DoubleDeclarations & doubleDeclarations,
        std::set< OString > & seenInterfaces, AstInterface const * ifc,
        bool direct, bool optional, bool mainOptional) const;

    void checkMemberClashes(
        DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member,
        bool checkOptional) const;

    void addVisibleInterface(
        AstInterface const * ifc, bool direct, bool optional);

    void addOptionalVisibleMembers(AstInterface const * ifc);

    bool increment(sal_uInt16 * counter, char const * sort) const;

    InheritedInterfaces m_inheritedInterfaces;
    InheritedInterfaces::size_type m_mandatoryInterfaces;
    bool    m_bIsDefined;
    bool m_bSingleInheritance;
    VisibleInterfaces m_visibleInterfaces;
    VisibleMembers m_visibleMembers;
};

#endif // INCLUDED_IDLC_INC_ASTINTERFACE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astinterfacemember.hxx b/idlc/inc/astinterfacemember.hxx
deleted file mode 100644
index 0e290e1..0000000
--- a/idlc/inc/astinterfacemember.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTINTERFACEMEMBER_HXX
#define INCLUDED_IDLC_INC_ASTINTERFACEMEMBER_HXX

#include "astinterface.hxx"

class AstInterfaceMember final : public AstDeclaration
{
public:
    AstInterfaceMember(const sal_uInt32 flags, AstInterface* pRealInterface,
                       const OString& name, AstScope* pScope)
        : AstDeclaration(NT_interface_member, name, pScope)
        , m_flags(flags)
        , m_pRealInterface(pRealInterface)
        {}

    AstInterface* getRealInterface()
        { return m_pRealInterface; }
    bool isOptional() const
        { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); }
private:
    const sal_uInt32    m_flags;
    AstInterface*       m_pRealInterface;
};

#endif // INCLUDED_IDLC_INC_ASTINTERFACEMEMBER_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astmember.hxx b/idlc/inc/astmember.hxx
deleted file mode 100644
index 43597d1..0000000
--- a/idlc/inc/astmember.hxx
+++ /dev/null
@@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_INC_ASTMEMBER_HXX
#define INCLUDED_IDLC_INC_ASTMEMBER_HXX

#include "astdeclaration.hxx"

class AstScope;
class AstType;

class AstMember: public AstDeclaration {
public:
    AstMember(
        AstType const * pType, OString const & name, AstScope * pScope):
        AstDeclaration(NT_member, name, pScope), m_pType(pType) {}

    AstType const * getType() const { return m_pType; }

protected:
    AstMember(
        NodeType type, AstType const * pType, OString const & name,
        AstScope * pScope):
        AstDeclaration(type, name, pScope), m_pType(pType) {}

private:
    AstType const * m_pType;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astmodule.hxx b/idlc/inc/astmodule.hxx
deleted file mode 100644
index 6178cfb..0000000
--- a/idlc/inc/astmodule.hxx
+++ /dev/null
@@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTMODULE_HXX
#define INCLUDED_IDLC_INC_ASTMODULE_HXX

#include "astdeclaration.hxx"
#include "astscope.hxx"

class AstModule : public AstDeclaration, public AstScope
{
public:
    AstModule(const OString& name, AstScope* pScope)
        : AstDeclaration(NT_module, name, pScope)
        , AstScope(NT_module)
    {
    }
    AstModule(NodeType type, const OString& name, AstScope* pScope)
        : AstDeclaration(type, name, pScope)
        , AstScope(type)
    {
    }

    virtual bool dump(RegistryKey& rKey) override;
};

#endif // INCLUDED_IDLC_INC_ASTMODULE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astneeds.hxx b/idlc/inc/astneeds.hxx
deleted file mode 100644
index 13d2dbb..0000000
--- a/idlc/inc/astneeds.hxx
+++ /dev/null
@@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTNEEDS_HXX
#define INCLUDED_IDLC_INC_ASTNEEDS_HXX

#include "astservice.hxx"

class AstNeeds final : public AstDeclaration
{
public:
    AstNeeds(AstService* pRealService, const OString& name, AstScope* pScope)
        : AstDeclaration(NT_needs, name, pScope)
        , m_pRealService(pRealService)
    {
    }

    AstService* getRealService() { return m_pRealService; }

private:
    AstService* m_pRealService;
};

#endif // INCLUDED_IDLC_INC_ASTNEEDS_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astobserves.hxx b/idlc/inc/astobserves.hxx
deleted file mode 100644
index 11bb5a6..0000000
--- a/idlc/inc/astobserves.hxx
+++ /dev/null
@@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTOBSERVES_HXX
#define INCLUDED_IDLC_INC_ASTOBSERVES_HXX

#include "astinterface.hxx"

class AstObserves final : public AstDeclaration
{
public:
    AstObserves(AstInterface* pRealInterface, const OString& name, AstScope* pScope)
        : AstDeclaration(NT_observes, name, pScope)
        , m_pRealInterface(pRealInterface)
    {
    }

    AstInterface* getRealInterface() { return m_pRealInterface; }

private:
    AstInterface* m_pRealInterface;
};

#endif // INCLUDED_IDLC_INC_ASTOBSERVES_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astoperation.hxx b/idlc/inc/astoperation.hxx
deleted file mode 100644
index e3e0335..0000000
--- a/idlc/inc/astoperation.hxx
+++ /dev/null
@@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTOPERATION_HXX
#define INCLUDED_IDLC_INC_ASTOPERATION_HXX

#include "astdeclaration.hxx"
#include "astscope.hxx"

namespace typereg { class Writer; }

class AstType;

class AstOperation final : public AstDeclaration
                   , public AstScope
{
public:
    AstOperation(AstType const * pReturnType, const OString& name, AstScope* pScope)
        : AstDeclaration(NT_operation, name, pScope)
        , AstScope(NT_operation)
        , m_pReturnType(pReturnType)
        {}

    bool isVariadic() const;

    bool isConstructor() const { return m_pReturnType == nullptr; }

    void setExceptions(DeclList const * pExceptions);

    void dumpBlob(typereg::Writer & rBlob, sal_uInt16 index);

private:
    AstType const * m_pReturnType;
    DeclList    m_exceptions;
};

#endif // INCLUDED_IDLC_INC_ASTOPERATION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astparameter.hxx b/idlc/inc/astparameter.hxx
deleted file mode 100644
index cfee342..0000000
--- a/idlc/inc/astparameter.hxx
+++ /dev/null
@@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_INC_ASTPARAMETER_HXX
#define INCLUDED_IDLC_INC_ASTPARAMETER_HXX

#include "astmember.hxx"

enum Direction { DIR_IN, DIR_OUT, DIR_INOUT };

class AstParameter final : public AstMember {
public:
    AstParameter(
        Direction direction, bool rest, AstType const * type,
        OString const & name, AstScope * scope):
        AstMember(NT_parameter, type, name, scope), m_direction(direction),
        m_rest(rest) {}

    Direction getDirection() const { return m_direction; }

    bool isRest() const { return m_rest; }

private:
    Direction m_direction;
    bool m_rest;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astscope.hxx b/idlc/inc/astscope.hxx
deleted file mode 100644
index be7b038..0000000
--- a/idlc/inc/astscope.hxx
+++ /dev/null
@@ -1,73 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTSCOPE_HXX
#define INCLUDED_IDLC_INC_ASTSCOPE_HXX

#include <sal/config.h>

#include <string_view>
#include "idlc.hxx"
#include "astdeclaration.hxx"
#include "astexpression.hxx"

class AstExpression;

class AstScope
{
public:
    AstScope(NodeType nodeType);
    virtual ~AstScope();

    AstScope(AstScope const&) = default;
    AstScope(AstScope&&) = default;
    AstScope& operator=(AstScope const&) = default;
    AstScope& operator=(AstScope&&) = default;

    NodeType getScopeNodeType() const { return m_nodeType; }

    AstDeclaration* addDeclaration(AstDeclaration* pDecl);

    sal_uInt32 nMembers() const { return static_cast<sal_uInt32>(m_declarations.size()); }
    DeclList::const_iterator getIteratorBegin() const { return m_declarations.begin(); }
    DeclList::const_iterator getIteratorEnd() const { return m_declarations.end(); }
    sal_uInt16 getNodeCount(NodeType nType) const;

    // Name look up mechanism
    AstDeclaration* lookupByName(const OString& scopedName);
    // Look up the identifier 'name' specified only in the local scope
    AstDeclaration* lookupByNameLocal(std::string_view name) const;

    AstDeclaration* lookupInInherited(const OString& scopedName) const;

    // Look up a predefined type by its ExprType
    AstDeclaration* lookupPrimitiveType(ExprType type);

    AstDeclaration* lookupForAdd(AstDeclaration const* pDecl) const;

protected:
    AstDeclaration const* getLast() const { return m_declarations.back(); }

private:
    DeclList m_declarations;
    NodeType m_nodeType;
};

#endif // INCLUDED_IDLC_INC_ASTSCOPE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astsequence.hxx b/idlc/inc/astsequence.hxx
deleted file mode 100644
index e8a2850..0000000
--- a/idlc/inc/astsequence.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTSEQUENCE_HXX
#define INCLUDED_IDLC_INC_ASTSEQUENCE_HXX

#include "asttype.hxx"

class AstSequence final : public AstType
{
public:
    AstSequence(AstType const* pMemberType, AstScope* pScope)
        : AstType(NT_sequence, OString::Concat("[]") + pMemberType->getScopedName(), pScope)
        , m_pMemberType(pMemberType)
    {
    }

    AstType const* getMemberType() const { return m_pMemberType; }

    virtual bool isUnsigned() const override
    {
        return m_pMemberType != nullptr && m_pMemberType->isUnsigned();
    }

    virtual const char* getRelativName() const override;

private:
    AstType const* m_pMemberType;
    mutable std::optional<OString> m_xRelativName;
};

#endif // INCLUDED_IDLC_INC_ASTSEQUENCE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astservice.hxx b/idlc/inc/astservice.hxx
deleted file mode 100644
index 4ad769c..0000000
--- a/idlc/inc/astservice.hxx
+++ /dev/null
@@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTSERVICE_HXX
#define INCLUDED_IDLC_INC_ASTSERVICE_HXX

#include "astdeclaration.hxx"
#include "astscope.hxx"

class AstService final : public AstDeclaration
                 , public AstScope
{
public:
    AstService(const OString& name, AstScope* pScope)
        : AstDeclaration(NT_service, name, pScope)
        , AstScope(NT_service)
        , m_singleInterfaceBasedService(false)
        , m_defaultConstructor(false)
        {}
    AstService(const NodeType type, const OString& name, AstScope* pScope)
        : AstDeclaration(type, name, pScope)
        , AstScope(type)
        , m_singleInterfaceBasedService(false)
        , m_defaultConstructor(false)
        {}

    virtual bool dump(RegistryKey& rKey) override;

    void setSingleInterfaceBasedService()
    { m_singleInterfaceBasedService = true; }

    void setDefaultConstructor(bool b) { m_defaultConstructor = b; }

    bool isSingleInterfaceBasedService() const
    { return m_singleInterfaceBasedService; }

    bool checkLastConstructor() const;

private:
    bool m_singleInterfaceBasedService;
    bool m_defaultConstructor;
};

#endif // INCLUDED_IDLC_INC_ASTSERVICE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/astservicemember.hxx b/idlc/inc/astservicemember.hxx
deleted file mode 100644
index 380449b..0000000
--- a/idlc/inc/astservicemember.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTSERVICEMEMBER_HXX
#define INCLUDED_IDLC_INC_ASTSERVICEMEMBER_HXX

#include "astservice.hxx"

class AstServiceMember final : public AstDeclaration
{
public:
    AstServiceMember(const sal_uInt32 flags, AstService* pRealService,
                     const OString& name, AstScope* pScope)
        : AstDeclaration(NT_service_member, name, pScope)
        , m_flags(flags)
        , m_pRealService(pRealService)
        {}

    AstService* getRealService()
        { return m_pRealService; }
    bool isOptional() const
        { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); }
private:
    const sal_uInt32    m_flags;
    AstService*         m_pRealService;
};

#endif // INCLUDED_IDLC_INC_ASTSERVICEMEMBER_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/aststack.hxx b/idlc/inc/aststack.hxx
deleted file mode 100644
index d36bd4e4..0000000
--- a/idlc/inc/aststack.hxx
+++ /dev/null
@@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#pragma once

#include <sal/types.h>
#include <vector>

class AstScope;

class AstStack final
{
public:
    AstStack();
    ~AstStack();

    sal_uInt32 depth() const { return m_stack.size(); }
    AstScope* top();
    AstScope* bottom();
    AstScope* nextToTop();
    AstScope* topNonNull();
    AstStack* push(AstScope* pScope);
    void pop();
    void clear();

private:
    std::vector<AstScope*> m_stack;
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/aststruct.hxx b/idlc/inc/aststruct.hxx
deleted file mode 100644
index 5e037d1..0000000
--- a/idlc/inc/aststruct.hxx
+++ /dev/null
@@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTSTRUCT_HXX
#define INCLUDED_IDLC_INC_ASTSTRUCT_HXX

#include <sal/config.h>

#include <string_view>

#include "asttype.hxx"
#include "astscope.hxx"
#include "idlctypes.hxx"

class AstStruct;

class AstStruct : public AstType
                , public AstScope
{
public:
    AstStruct(
        const OString& name,
        std::vector< OString > const & typeParameters,
        AstStruct const* pBaseType, AstScope* pScope);

    AstStruct(const NodeType type,
              const OString& name,
              AstStruct const* pBaseType,
              AstScope* pScope);
    virtual ~AstStruct() override;

    std::size_t getTypeParameterCount() const
    { return m_typeParameters.size(); }

    AstDeclaration const * findTypeParameter(std::string_view name) const;

    virtual bool isType() const override;

    virtual bool dump(RegistryKey& rKey) override;
private:
    AstStruct const* m_pBaseType;
    std::vector<std::unique_ptr<AstDeclaration>> m_typeParameters;
};

#endif // INCLUDED_IDLC_INC_ASTSTRUCT_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/aststructinstance.hxx b/idlc/inc/aststructinstance.hxx
deleted file mode 100644
index 1357aa35..0000000
--- a/idlc/inc/aststructinstance.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_INC_ASTSTRUCTINSTANCE_HXX
#define INCLUDED_IDLC_INC_ASTSTRUCTINSTANCE_HXX

#include "asttype.hxx"
#include "idlctypes.hxx"

class AstScope;

class AstStructInstance final : public AstType {
public:
    AstStructInstance(
        AstType const * typeTemplate, DeclList const * typeArguments,
        AstScope * scope);

    AstType const * getTypeTemplate() const { return m_typeTemplate; }

    DeclList::const_iterator getTypeArgumentsBegin() const
    { return m_typeArguments.begin(); }

    DeclList::const_iterator getTypeArgumentsEnd() const
    { return m_typeArguments.end(); }

private:
    AstType const * m_typeTemplate;
    DeclList m_typeArguments;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/asttype.hxx b/idlc/inc/asttype.hxx
deleted file mode 100644
index 8627429..0000000
--- a/idlc/inc/asttype.hxx
+++ /dev/null
@@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTTYPE_HXX
#define INCLUDED_IDLC_INC_ASTTYPE_HXX

#include "astdeclaration.hxx"

class AstType : public AstDeclaration
{
public:
    AstType(const NodeType type, const OString& name, AstScope* pScope)
        : AstDeclaration(type, name, pScope)
    {
    }

    virtual bool isUnsigned() const { return false; }
};

#endif // INCLUDED_IDLC_INC_ASTTYPE_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/asttypedef.hxx b/idlc/inc/asttypedef.hxx
deleted file mode 100644
index 427d633..0000000
--- a/idlc/inc/asttypedef.hxx
+++ /dev/null
@@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ASTTYPEDEF_HXX
#define INCLUDED_IDLC_INC_ASTTYPEDEF_HXX

#include "asttype.hxx"

class AstTypeDef final : public AstType
{
public:
    AstTypeDef(
        AstType const * baseType, OString const & name, AstScope * scope):
        AstType(NT_typedef, name, scope), m_pBaseType(baseType) {}

    AstType const * getBaseType() const
        { return m_pBaseType; }

    virtual bool isUnsigned() const override
    { return m_pBaseType != nullptr && m_pBaseType->isUnsigned(); }

    virtual bool dump(RegistryKey& rKey) override;
private:
    AstType const * m_pBaseType;
};

#endif // INCLUDED_IDLC_INC_ASTTYPEDEF_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/errorhandler.hxx b/idlc/inc/errorhandler.hxx
deleted file mode 100644
index 9b49f5d..0000000
--- a/idlc/inc/errorhandler.hxx
+++ /dev/null
@@ -1,118 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_ERRORHANDLER_HXX
#define INCLUDED_IDLC_INC_ERRORHANDLER_HXX

#include "astdeclaration.hxx"
#include "astexpression.hxx"
#include "astenum.hxx"

enum class ErrorCode
{
    SyntaxError,      // Syntax error in IDL input
                      // More details will be gleaned from examining
                      // the parse state
    RedefScope,       // Redefinition inside defining scope
    CoercionFailure,  // Coercion failure
    ScopeConflict,    // Between fwd declare and full declare
    IllegalAdd,       // Illegal add action
    IllegalRaises,    // Error in "raises" clause
    CantInherit,      // Cannot inherit from non-interface
    IdentNotFound,    // Identifier not found
    CannotInheritFromForward, // Cannot inherit from fwd decl interface
    ExpectedConstant,       // We got something else...
    Eval,                   // Error in evaluating expression
    ForwardDeclLookup,      // Tried to lookup in fwd declared intf
    RecursiveType,          // Illegal recursive use of type
    NotAType,               // Not a type
    InterfaceMemberLookup,  // interface is not defined or a fwd declaration not exists
    ServiceMemberLookup,
    DefinedAttributeFlag,
    WrongAttributeKeyword,
    MissingAttributeKeyword,
    BadAttributeFlags,
    ExpectedOptional,
    MixedInheritance,
    DoubleInheritance,
    DoubleMember,
    ConstructorParameterNotIn,
    ConstructorRestParameterNotFirst,
    RestParameterNotLast,
    RestParameterNotAny,
    MethodHasRestParameter,
    ReadOnlyAttributeSetExceptions,
    UnsignedTypeArgument,
    WrongNumberOfTypeArguments,
    InstantiatedStructTypeTypedef,
    IdenticalTypeParameters,
    StructTypeTemplateWithBase,
    PublishedForward,
    PublishedusesUnpublished,
    SimilarConstructors
};

enum class WarningCode
{
    WrongNamingConvention    // type or identifier doesn't fulfill the UNO naming convention
};

class ErrorHandler
{
public:
    // Report errors with varying numbers of arguments
    static void error0(ErrorCode e);
    static void error1(ErrorCode e, AstDeclaration const * d);
    static void error2(
        ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2);
    static void error3(ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2, AstDeclaration const * d3);

    // Warning
    static void warning0(WarningCode e, const char* warningmsg);

    // Report a syntax error in IDL input
    static void syntaxError(ParseState state, sal_Int32 lineNumber, const char* errmsg);

    // Report an unsuccessful coercion attempt
    static void coercionError(AstExpression *pExpr, ExprType et);

    // Report a failed name lookup attempt
    static void lookupError(const OString& n);
    // Report a failed name lookup attempt
    static void lookupError(ErrorCode e, const OString& n, AstDeclaration const * pScope);


    // Report a type error
    static void noTypeError(AstDeclaration const * pDecl);

    static void inheritanceError(NodeType nodeType, const OString* name, AstDeclaration const * pDecl);

    static void flagError(ErrorCode e, sal_uInt32 flag);

    static void forwardLookupError(const AstDeclaration* pForward, const OString& name);

    static void constantExpected(AstDeclaration const * pDecl, const OString& name);

    static void evalError(AstExpression* pExpr);

    static bool checkPublished(AstDeclaration const * decl, bool bOptional=false);
};

#endif // INCLUDED_IDLC_INC_ERRORHANDLER_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/fehelper.hxx b/idlc/inc/fehelper.hxx
deleted file mode 100644
index be401de..0000000
--- a/idlc/inc/fehelper.hxx
+++ /dev/null
@@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_IDLC_INC_FEHELPER_HXX
#define INCLUDED_IDLC_INC_FEHELPER_HXX

#include "asttype.hxx"
#include "astinterface.hxx"

#include <vector>

class FeDeclarator final
{
public:
    FeDeclarator(const OString& name);
    ~FeDeclarator();
    const OString& getName() const
        { return m_name; }
    bool checkType(AstDeclaration const * pType) const;
    static AstType const * compose(AstDeclaration const * pDecl);
private:
    OString  m_name;
};

typedef ::std::list< FeDeclarator* > FeDeclList;

class FeInheritanceHeader final
{
public:
    FeInheritanceHeader(
        NodeType nodeType, OString* pName, OString const * pInherits,
        std::vector< OString > const * typeParameters);

    NodeType getNodeType() const
        { return m_nodeType; }
    OString* getName()
        { return m_pName.get(); }
    AstDeclaration* getInherits()
        { return m_pInherits; }

    std::vector< OString > const & getTypeParameters() const
    { return m_typeParameters; }

private:
    void initializeInherits(OString const * pinherits);

    NodeType        m_nodeType;
    std::unique_ptr<OString> m_pName;
    AstDeclaration* m_pInherits;
    std::vector< OString > m_typeParameters;
};

#endif // INCLUDED_IDLC_INC_FEHELPER_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/idlc.hxx b/idlc/inc/idlc.hxx
deleted file mode 100644
index 1be11b1..0000000
--- a/idlc/inc/idlc.hxx
+++ /dev/null
@@ -1,164 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#pragma once

#include "idlctypes.hxx"
#include "aststack.hxx"
#include "options.hxx"
#include <memory>
#include <string_view>

#ifdef SAL_UNX
#define SEPARATOR '/'
#define PATH_SEPARATOR "/"
#else
#define SEPARATOR '\\'
#define PATH_SEPARATOR "\\"
#endif

class AstInterface;
class AstModule;
class AstType;
class Options;
class ErrorHandler;

class Idlc final
{
public:
    Idlc(Options* pOptions);
    ~Idlc();

    void init();

    bool dumpDeps(std::string_view rDepFile,
                  OString const& rTarget);

    Options* getOptions()
        { return m_pOptions; }
    AstStack* scopes()
        { return m_pScopes.get(); }
    AstModule* getRoot()
        { return m_pRoot.get(); }
    const OString& getFileName() const
        { return m_fileName; }
    void setFileName(const OString& fileName)
        { m_fileName = fileName; addInclude(fileName); }
    const OString& getMainFileName() const
        { return m_mainFileName; }
    void setMainFileName(const OString& mainFileName)
        { m_mainFileName = mainFileName; }
    const OString& getRealFileName() const
        { return m_realFileName; }
    void setRealFileName(const OString& realFileName)
        { m_realFileName = realFileName; }
    const OString& getDocumentation()
        {
            m_bIsDocValid = false;
            return m_documentation;
        }
    void setDocumentation(const OString& documentation)
        {
            m_documentation = documentation;
            m_bIsDocValid = true;
        }
    OUString processDocumentation();
    bool isInMainFile() const
        { return m_bIsInMainfile; }
    void setInMainfile(bool bInMainfile)
        { m_bIsInMainfile = bInMainfile; }
    sal_uInt32 getErrorCount() const
        { return m_errorCount; }
    void incErrorCount()
        { m_errorCount++; }
    sal_uInt32 getWarningCount() const
        { return m_warningCount; }
    void incWarningCount()
        { m_warningCount++; }
    sal_uInt32 getLineNumber() const
        { return m_lineNumber; }
    sal_uInt32 getOffsetStart() const
        { return m_offsetStart; }
    sal_uInt32 getOffsetEnd() const
        { return m_offsetEnd; }
    void setOffset( sal_uInt32 start, sal_uInt32 end)
        { m_offsetStart = start; m_offsetEnd = end; }
    void setLineNumber(sal_uInt32 lineNumber)
        { m_lineNumber = lineNumber; }
    void incLineNumber()
        { m_lineNumber++; }
    ParseState getParseState() const
        { return m_parseState; }
    void setParseState(ParseState parseState)
        { m_parseState = parseState; }

    void addInclude(const OString& inc)
        { m_includes.insert(inc); }

    void setPublished(bool published) { m_published = published; }
    bool isPublished() const { return m_published; }

    void reset();
private:
    Options*            m_pOptions;
    std::unique_ptr<AstStack>  m_pScopes;
    std::unique_ptr<AstModule> m_pRoot;
    OString      m_fileName;
    OString      m_mainFileName;
    OString      m_realFileName;
    OString      m_documentation;
    bool            m_bIsDocValid;
    bool            m_bGenerateDoc;
    bool            m_bIsInMainfile;
    bool                m_published;
    sal_uInt32          m_errorCount;
    sal_uInt32          m_warningCount;
    sal_uInt32          m_lineNumber;
    sal_uInt32          m_offsetStart;
    sal_uInt32          m_offsetEnd;
    ParseState          m_parseState;
    std::set< OString >           m_includes;
};


typedef ::std::pair< OString, OString > sPair_t;
sal_Int32 compileFile(const OString * pathname);
    // a null pathname means stdin
sal_Int32 produceFile(const OString& filenameBase,
        sPair_t const*const pDepFile);
    // filenameBase is filename without ".idl"
void removeIfExists(std::string_view pathname);

bool copyFile(const OString* source, const OString& target);
    // a null source means stdin

bool isFileUrl(std::string_view fileName);
OString convertToAbsoluteSystemPath(const OString& fileName);
OString convertToFileUrl(const OString& fileName);

Idlc* idlc();
Idlc* setIdlc(Options* pOptions);

AstDeclaration const * resolveTypedefs(AstDeclaration const * type);

AstDeclaration const * deconstructAndResolveTypedefs(
    AstDeclaration const * type, sal_Int32 * rank);

AstInterface const * resolveInterfaceTypedefs(AstType const * type);

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/idlctypes.hxx b/idlc/inc/idlctypes.hxx
deleted file mode 100644
index a2dadfe..0000000
--- a/idlc/inc/idlctypes.hxx
+++ /dev/null
@@ -1,189 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#pragma once

#include <stdio.h>

#include <list>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include <sal/types.h>
#include <rtl/ustring.hxx>


class AstDeclaration;

typedef std::list< AstDeclaration* > DeclList;

class AstScope;
AstDeclaration* scopeAsDecl(AstScope* pScope);
AstScope* declAsScope(AstDeclaration* pDecl);

// flags used for attributes, properties and services
#define AF_INVALID          0x0000
#define AF_READONLY         0x0001
#define AF_OPTIONAL         0x0002
#define AF_MAYBEVOID        0x0004
#define AF_BOUND            0x0008
#define AF_CONSTRAINED      0x0010
#define AF_TRANSIENT        0x0020
#define AF_MAYBEAMBIGUOUS   0x0040
#define AF_MAYBEDEFAULT     0x0080
#define AF_REMOVABLE        0x0100
#define AF_ATTRIBUTE        0x0200
#define AF_PROPERTY         0x0400

enum ParseState
{
    PS_NoState,
    PS_TypeDeclSeen,        // Seen complete typedef declaration
    PS_ConstantDeclSeen,    // Seen complete const declaration
    PS_ExceptionDeclSeen,   // Seen complete exception declaration
    PS_InterfaceDeclSeen,   // Seen complete interface declaration
    PS_ServiceDeclSeen,     // Seen complete service declaration
    PS_SingletonDeclSeen,   // Seen complete singleton declaration
    PS_ModuleDeclSeen,      // Seen complete module declaration
    PS_AttributeDeclSeen,   // Seen complete attribute declaration
    PS_PropertyDeclSeen,    // Seen complete property declaration
    PS_OperationDeclSeen,   // Seen complete operation declaration
    PS_InterfaceInheritanceDeclSeen, // Seen complete interface inheritance decl
    PS_ConstantsDeclSeen,   // Seen complete constants declaration

    PS_ServiceSeen,         // Seen a SERVICE keyword
    PS_ServiceIDSeen,       // Seen the service ID
    PS_ServiceSqSeen,       // '{' seen for service
    PS_ServiceQsSeen,       // '}' seen for service
    PS_ServiceBodySeen,     // Seen complete service body
    PS_ServiceMemberSeen,   // Seen a service member
    PS_ServiceIFHeadSeen,   // Seen an interface member header
    PS_ServiceSHeadSeen,    // Seen a service member header

    PS_SingletonSeen,       // Seen a SINGLETON keyword
    PS_SingletonIDSeen,     // Seen the singleton ID
    PS_SingletonSqSeen,     // '{' seen for singleton
    PS_SingletonQsSeen,     // '}' seen for singleton
    PS_SingletonBodySeen,   // Seen complete singleton body

    PS_ModuleSeen,          // Seen a MODULE keyword
    PS_ModuleIDSeen,        // Seen the module ID
    PS_ModuleSqSeen,        // '{' seen for module
    PS_ModuleQsSeen,        // '}' seen for module
    PS_ModuleBodySeen,      // Seen complete module body

    PS_ConstantsSeen,       // Seen a CONSTANTS keyword
    PS_ConstantsIDSeen,     // Seen the constants ID
    PS_ConstantsSqSeen,     // '{' seen for constants
    PS_ConstantsQsSeen,     // '}' seen for constants
    PS_ConstantsBodySeen,   // Seen complete constants body

    PS_InterfaceSeen,       // Seen an INTERFACE keyword
    PS_InterfaceIDSeen,     // Seen the interface ID
    PS_InterfaceHeadSeen,   // Seen the interface head
    PS_InheritSpecSeen,     // Seen a complete inheritance spec
    PS_ForwardDeclSeen,     // Forward interface decl seen
    PS_InterfaceSqSeen,     // '{' seen for interface
    PS_InterfaceQsSeen,     // '}' seen for interface
    PS_InterfaceBodySeen,   // Seen an interface body
    PS_InheritColonSeen,    // Seen ':' in inheritance list

    PS_SNListCommaSeen,     // Seen ',' in list of scoped names
    PS_ScopedNameSeen,      // Seen a complete scoped name
    PS_SN_IDSeen,           // Seen an identifier as part of a scoped name
    PS_ScopeDelimSeen,      // Seen a scope delim as party of a scoped name

    PS_ConstSeen,           // Seen a CONST keyword
    PS_ConstTypeSeen,       // Parsed the type of a constant
    PS_ConstIDSeen,         // Seen the constant ID
    PS_ConstAssignSeen,     // Seen the '='
    PS_ConstExprSeen,       // Seen the constant value expression

    PS_TypedefSeen,         // Seen a TYPEDEF keyword
    PS_TypeSpecSeen,        // Seen a complete type specification
    PS_DeclaratorsSeen,     // Seen a complete list of declarators

    PS_StructSeen,          // Seen a STRUCT keyword
    PS_StructHeaderSeen,    // Seen struct header
    PS_StructIDSeen,        // Seen the struct ID
    PS_StructSqSeen,        // '{' seen for struct
    PS_StructQsSeen,        // '}' seen for struct
    PS_StructBodySeen,      // Seen complete body of struct decl

    PS_MemberTypeSeen,      // Seen type of struct or except member
    PS_MemberDeclsSeen,     // Seen decls of struct or except members
    PS_MemberDeclsCompleted,// Completed one struct or except member to ';'

    PS_EnumSeen,            // Seen an ENUM keyword
    PS_EnumIDSeen,          // Seen the enum ID
    PS_EnumSqSeen,          // Seen '{' for enum
    PS_EnumQsSeen,          // Seen '}' for enum
    PS_EnumBodySeen,        // Seen complete enum body
    PS_EnumCommaSeen,       // Seen ',' in list of enumerators

    PS_SequenceSeen,        // Seen a SEQUENCE keyword
    PS_SequenceSqSeen,      // Seen '<' for sequence
    PS_SequenceQsSeen,      // Seen '>' for sequence
    PS_SequenceTypeSeen,    // Seen type decl for sequence

    PS_FlagHeaderSeen,      // Seen the attribute|property|interface member head
    PS_AttrSeen,            // Seen ATTRIBUTE keyword
    PS_AttrTypeSeen,        // Seen type decl for attribute
    PS_AttrCompleted,       // Seen complete attribute declaration
    PS_ReadOnlySeen,        // Seen READONLY keyword
    PS_OptionalSeen,        // Seen OPTIONAL keyword
    PS_MayBeVoidSeen,       // Seen MAYBEVOID yword
    PS_BoundSeen,           // Seen BOUND  keyword
    PS_ConstrainedSeen,     // Seen CONSTRAINED keyword
    PS_TransientSeen,       // Seen TRANSIENT keyword
    PS_MayBeAmbiguousSeen,  // Seen MAYBEAMBIGUOUS keyword
    PS_MayBeDefaultSeen,    // Seen MAYBEDEFAULT keyword
    PS_RemoveableSeen,      // Seen REMOVABLE keyword

    PS_PropertySeen,        // Seen PROPERTY keyword
    PS_PropertyTypeSeen,    // Seen type decl for property
    PS_PropertyCompleted,   // Seen complete property declaration

    PS_ExceptSeen,          // Seen EXCEPTION keyword
    PS_ExceptHeaderSeen,    // Seen exception header keyword
    PS_ExceptIDSeen,        // Seen exception identifier
    PS_ExceptSqSeen,        // Seen '{' for exception
    PS_ExceptQsSeen,        // Seen '}' for exception
    PS_ExceptBodySeen,      // Seen complete exception body

    PS_OpTypeSeen,          // Seen operation return type
    PS_OpIDSeen,            // Seen operation ID
    PS_OpParsCompleted,     // Completed operation param list
    PS_OpSqSeen,            // Seen '(' for operation
    PS_OpQsSeen,            // Seen ')' for operation
    PS_OpParCommaSeen,      // Seen ',' in list of op params
    PS_OpParDirSeen,        // Seen parameter direction
    PS_OpParTypeSeen,       // Seen parameter type
    PS_OpParDeclSeen,       // Seen parameter declaration

    PS_RaiseSeen,           // Seen RAISES keyword
    PS_RaiseSqSeen,         // Seen '(' for RAISES
    PS_RaiseQsSeen,         // Seen ')' for RAISES

    PS_DeclsCommaSeen,      // Seen ',' in declarators list
    PS_DeclsDeclSeen        // Seen complete decl in decls list
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/inheritedinterface.hxx b/idlc/inc/inheritedinterface.hxx
deleted file mode 100644
index 16462b4..0000000
--- a/idlc/inc/inheritedinterface.hxx
+++ /dev/null
@@ -1,56 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_INC_INHERITEDINTERFACE_HXX
#define INCLUDED_IDLC_INC_INHERITEDINTERFACE_HXX

#include "idlc.hxx"

#include <rtl/ustring.hxx>
#include <utility>

class AstInterface;
class AstType;

class InheritedInterface {
public:
    InheritedInterface(
        AstType const * theInterface, bool theOptional,
        OUString theDocumentation):
        interface(theInterface), optional(theOptional),
        documentation(std::move(theDocumentation)) {}

    AstType const * getInterface() const { return interface; }

    AstInterface const * getResolved() const
    { return resolveInterfaceTypedefs(interface); }

    bool isOptional() const { return optional; }

    const OUString& getDocumentation() const { return documentation; }

private:
    AstType const * interface;
    bool optional;
    OUString documentation;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/inc/options.hxx b/idlc/inc/options.hxx
deleted file mode 100644
index c3a0949..0000000
--- a/idlc/inc/options.hxx
+++ /dev/null
@@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_INC_OPTIONS_HXX
#define INCLUDED_IDLC_INC_OPTIONS_HXX

#include "idlctypes.hxx"
#include <utility>

typedef std::unordered_map< OString, OString > OptionMap;

class IllegalArgument
{
public:
    IllegalArgument(OString msg) : m_message(std::move(msg)) {}

    OString  m_message;
};


class Options
{
public:
    explicit Options(char const * progname);
    ~Options();

    static bool checkArgument(std::vector< std::string > & rArgs, char const * arg, size_t len);
    static bool checkCommandFile(std::vector< std::string > & rArgs, char const * filename);

    /// @throws IllegalArgument
    bool initOptions(std::vector< std::string > & rArgs);
    /// @throws IllegalArgument
    static bool badOption(char const * reason, std::string const & rArg);
    bool setOption(char const * option, std::string const & rArg);

    OString prepareHelp() const;
    OString prepareVersion() const;

    const OString&   getProgramName() const { return m_program;}
    bool                isValid(const OString& option) const;
    /// @throws IllegalArgument
    const OString&   getOption(const OString& option);

    const std::vector< OString >& getInputFiles() const { return m_inputFiles; }
    bool readStdin() const { return m_stdin; }
    bool verbose() const { return m_verbose; }
    bool quiet() const { return m_quiet; }

protected:
    OString  m_program;
    std::vector< OString >    m_inputFiles;
    bool            m_stdin;
    bool            m_verbose;
    bool            m_quiet;
    OptionMap       m_options;
};

#endif // INCLUDED_IDLC_INC_OPTIONS_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astconstant.cxx b/idlc/source/astconstant.cxx
deleted file mode 100644
index 54d235f..0000000
--- a/idlc/source/astconstant.cxx
+++ /dev/null
@@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astconstant.hxx>
#include <astscope.hxx>

#include <registry/writer.hxx>

AstConstant::AstConstant(const ExprType type,
                         const NodeType nodeType,
                         AstExpression* pExpr,
                         const OString& name,
                         AstScope* pScope)
    : AstDeclaration(nodeType, name, pScope)
    , m_pConstValue(pExpr)
    , m_constValueType(type)
{
}

AstConstant::AstConstant(const ExprType type,
                         AstExpression* pExpr,
                         const OString& name,
                         AstScope* pScope)
    : AstDeclaration(NT_const, name, pScope)
    , m_pConstValue(pExpr)
    , m_constValueType(type)
{
}

AstConstant::~AstConstant()
{

}

bool AstConstant::dumpBlob(
    typereg::Writer & rBlob, sal_uInt16 index, bool published)
{
    RTConstValue    aConst;

    AstExprValue *exprVal = getConstValue()->getExprValue();
    switch (getConstValueType())
    {
        case ET_short:
            aConst.m_type = RT_TYPE_INT16;
            aConst.m_value.aShort = exprVal->u.sval;
            break;
        case ET_ushort:
            aConst.m_type = RT_TYPE_UINT16;
            aConst.m_value.aUShort = exprVal->u.usval;
            break;
        case ET_long:
            aConst.m_type = RT_TYPE_INT32;
            aConst.m_value.aLong = exprVal->u.lval;
            break;
        case ET_ulong:
            aConst.m_type = RT_TYPE_UINT32;
            aConst.m_value.aULong = exprVal->u.ulval;
            break;
        case ET_hyper:
            aConst.m_type = RT_TYPE_INT64;
            aConst.m_value.aHyper = exprVal->u.hval;
            break;
        case ET_uhyper:
            aConst.m_type = RT_TYPE_UINT64;
            aConst.m_value.aUHyper = exprVal->u.uhval;
            break;
        case ET_float:
            aConst.m_type = RT_TYPE_FLOAT;
            aConst.m_value.aFloat = exprVal->u.fval;
            break;
        case ET_double:
            aConst.m_type = RT_TYPE_DOUBLE;
            aConst.m_value.aDouble = exprVal->u.dval;
            break;
        case ET_byte:
            aConst.m_type = RT_TYPE_BYTE;
            aConst.m_value.aByte = exprVal->u.byval;
            break;
        case ET_boolean:
            aConst.m_type = RT_TYPE_BOOL;
            aConst.m_value.aBool = exprVal->u.bval;
            break;
        default:
            {
                fprintf(stderr, "%s: exprtype to const type: cannot convert ExprType\n",
                        idlc()->getOptions()->getProgramName().getStr());
                return false;
            }
    }

    OString name = getLocalName();

    OUString type;
    if ( getNodeType() != NT_enum_val )
    {
        type = OStringToOUString(exprTypeToString(getConstValueType()), RTL_TEXTENCODING_UTF8);
    }

    rBlob.setFieldData(
        index, getDocumentation(), OUString(),
        RTFieldAccess::CONST | (published ? RTFieldAccess::PUBLISHED : RTFieldAccess::NONE),
        OStringToOUString(name, RTL_TEXTENCODING_UTF8), type, aConst);

    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astdeclaration.cxx b/idlc/source/astdeclaration.cxx
deleted file mode 100644
index 980e7dd..0000000
--- a/idlc/source/astdeclaration.cxx
+++ /dev/null
@@ -1,164 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astdeclaration.hxx>
#include <astscope.hxx>
#include <rtl/strbuf.hxx>
#include <o3tl/string_view.hxx>
#include <osl/diagnose.h>

constexpr OStringLiteral sGlobal("::");

static OString convertName(std::string_view name)
{
    OStringBuffer nameBuffer(name.size()+1);
    sal_Int32 nIndex = 0;
    do
    {
        std::string_view token( o3tl::getToken(name, 0, ':', nIndex ) );
        if( !token.empty() )
        {
            nameBuffer.append('/');
            nameBuffer.append( token );
        }
    } while( nIndex != -1 );
    return nameBuffer.makeStringAndClear();
}

AstDeclaration::AstDeclaration(NodeType type, const OString& name, AstScope* pScope)
    : m_localName(name)
    , m_pScope(pScope)
    , m_nodeType(type)
    , m_bImported(false)
    , m_bInMainFile(false)
    , m_bPredefined(false)
    , m_lineNumber(0)
{
    if ( m_pScope )
    {
        AstDeclaration* pDecl = scopeAsDecl(m_pScope);
        if (pDecl)
        {
            m_scopedName = pDecl->getScopedName();
            if (!m_scopedName.isEmpty())
                m_scopedName += sGlobal;
            m_scopedName += m_localName;
        }
    } else
    {
        m_scopedName = m_localName;
    }
    m_fullName = convertName(m_scopedName);

    if ( idlc()->getFileName() == idlc()->getRealFileName() )
    {
        m_fileName = idlc()->getMainFileName();
        m_bInMainFile = true;
    } else
    {
        m_fileName = idlc()->getFileName();
        m_bImported = true;
    }

    m_documentation = idlc()->processDocumentation();

    m_bPublished = idlc()->isPublished();
}


AstDeclaration::~AstDeclaration()
{

}

void AstDeclaration::setPredefined(bool bPredefined)
{
    m_bPredefined = bPredefined;
    if ( m_bPredefined )
    {
        m_fileName.clear();
        m_bInMainFile = false;
    }
}

bool AstDeclaration::isType() const {
    switch (m_nodeType) {
    case NT_interface:
    case NT_instantiated_struct:
    case NT_enum:
    case NT_sequence:
    case NT_typedef:
    case NT_predefined:
    case NT_type_parameter:
        return true;

    default:
        OSL_ASSERT(m_nodeType != NT_struct); // see AstStruct::isType
        return false;
    }
}

bool AstDeclaration::hasAncestor(AstDeclaration* pDecl)
{
    if (this == pDecl)
        return true;
    if ( !m_pScope )
        return false;
    return scopeAsDecl(m_pScope)->hasAncestor(pDecl);
}

bool AstDeclaration::dump(RegistryKey& rKey)
{
    AstScope* pScope = declAsScope(this);
    if ( !pScope )
        return true;

    bool bRet = true;
    DeclList::const_iterator iter = pScope->getIteratorBegin();
    DeclList::const_iterator end = pScope->getIteratorEnd();
    AstDeclaration* pDecl = nullptr;
    while ( iter != end && bRet)
    {
        pDecl = *iter;
        if ( pDecl->isInMainfile() )
        {
            switch ( pDecl->getNodeType() )
            {
                case NT_module:
                case NT_constants:
                case NT_interface:
                case NT_struct:
                case NT_exception:
                case NT_enum:
                case NT_typedef:
                case NT_service:
                case NT_singleton:
                    bRet = pDecl->dump(rKey);
                    break;
                default:
                    break;
            }
        }

        ++iter;
    }
    return bRet;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astdump.cxx b/idlc/source/astdump.cxx
deleted file mode 100644
index 79613e1..0000000
--- a/idlc/source/astdump.cxx
+++ /dev/null
@@ -1,420 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astmodule.hxx>
#include <asttypedef.hxx>
#include <astservice.hxx>
#include <astconstant.hxx>
#include <astattribute.hxx>
#include <astinterfacemember.hxx>
#include <astservicemember.hxx>
#include <astobserves.hxx>
#include <astneeds.hxx>
#include <astsequence.hxx>
#include <astoperation.hxx>

#include <osl/diagnose.h>

#include <registry/version.h>
#include <registry/writer.hxx>

bool AstModule::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if ( getNodeType() == NT_root )
    {
        localKey = rKey;
    }else
    {
        if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey) != RegError::NO_ERROR)
        {
            fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                    idlc()->getOptions()->getProgramName().getStr(),
                    getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
            return false;
        }
    }

    sal_uInt16          nConst = getNodeCount(NT_const);

    if ( nConst > 0 )
    {
        RTTypeClass typeClass = RT_TYPE_MODULE;
        if ( getNodeType() == NT_constants )
            typeClass = RT_TYPE_CONSTANTS;

        typereg::Writer aBlob(
            m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
            getDocumentation(), "", typeClass,
            m_bPublished,
            OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0,
            nConst, 0, 0);

        DeclList::const_iterator iter = getIteratorBegin();
        DeclList::const_iterator end = getIteratorEnd();
        sal_uInt16 index = 0;
        while ( iter != end )
        {
            AstDeclaration* pDecl = *iter;
            if ( pDecl->getNodeType() == NT_const &&
                 pDecl->isInMainfile() )
            {
                static_cast<AstConstant*>(pDecl)->dumpBlob(
                    aBlob, index++,
                    getNodeType() == NT_module && pDecl->isPublished());
            }
            ++iter;
        }

        sal_uInt32 aBlobSize;
        void const * pBlob = aBlob.getBlob(&aBlobSize);

        if (localKey.setValue("", RegValueType::BINARY,
                                const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
        {
            fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                    idlc()->getOptions()->getProgramName().getStr(),
                    getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
            return false;
        }
    } else
    {
        RTTypeClass typeClass = RT_TYPE_MODULE;
        if ( getNodeType() == NT_constants )
            typeClass = RT_TYPE_CONSTANTS;

        typereg::Writer aBlob(
            m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
            getDocumentation(), "", typeClass, m_bPublished,
            OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, 0, 0,
            0);

        sal_uInt32 aBlobSize;
        void const * pBlob = aBlob.getBlob(&aBlobSize);

        if ( getNodeType() != NT_root )
        {
            if (localKey.setValue("", RegValueType::BINARY,
                                    const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
            {
                fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                        idlc()->getOptions()->getProgramName().getStr(),
                        getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
                return false;
            }
        }
    }
    if ( getNodeType() == NT_root )
    {
        localKey.releaseKey();
    }
    return AstDeclaration::dump(rKey);
}

bool AstTypeDef::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    typereg::Writer aBlob(
        m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
        getDocumentation(), "", RT_TYPE_TYPEDEF, m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, 0, 0, 0);
    aBlob.setSuperTypeName(
        0,
        OStringToOUString(
            getBaseType()->getRelativName(), RTL_TEXTENCODING_UTF8));

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue("", RegValueType::BINARY, const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    return true;
}

bool AstService::dump(RegistryKey& rKey)
{
    typereg_Version version = m_bPublished
        ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0;
    OString superName;
    sal_uInt16 constructors = 0;
    sal_uInt16 properties = 0;
    sal_uInt16 references = 0;
    for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
         ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_interface:
        case NT_typedef:
            version = TYPEREG_VERSION_1;
            OSL_ASSERT(superName.isEmpty());
            superName = (*i)->getRelativName();
            break;

        case NT_operation:
            OSL_ASSERT(getNodeType() == NT_service);
            ++constructors;
            break;

        case NT_property:
            OSL_ASSERT(getNodeType() == NT_service);
            ++properties;
            break;

        case NT_service_member:
            if (getNodeType() == NT_singleton) {
                OSL_ASSERT(superName.isEmpty());
                superName = static_cast<AstServiceMember *>(*i)->
                    getRealService()->getRelativName();
                break;
            }
            [[fallthrough]];
        case NT_interface_member:
        case NT_observes:
        case NT_needs:
            OSL_ASSERT(getNodeType() == NT_service);
            ++references;
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }
    OSL_ASSERT(constructors == 0 || !m_defaultConstructor);
    if (m_defaultConstructor) {
        constructors = 1;
    }
    RegistryKey localKey;
    if (rKey.createKey(
            OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8),
            localKey) != RegError::NO_ERROR) {
        fprintf(
            stderr, "%s: warning, could not create key '%s' in '%s'\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getFullName().getStr(),
            OUStringToOString(
                rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }
    typereg::Writer writer(
        version, getDocumentation(), "",
        getNodeType() == NT_singleton ? RT_TYPE_SINGLETON : RT_TYPE_SERVICE,
        m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8),
        superName.isEmpty() ? 0 : 1, properties, constructors,
        references);
    if (!superName.isEmpty()) {
        writer.setSuperTypeName(
            0, OStringToOUString(superName, RTL_TEXTENCODING_UTF8));
    }
    sal_uInt16 constructorIndex = 0;
    sal_uInt16 propertyIndex = 0;
    sal_uInt16 referenceIndex = 0;
    for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_operation:
            static_cast<AstOperation *>(*i)->dumpBlob(writer, constructorIndex++);
            break;

        case NT_property:
            static_cast<AstAttribute *>(*i)->dumpBlob(writer, propertyIndex++, nullptr);
            break;

        case NT_interface_member:
        {
            AstInterfaceMember * decl = static_cast<AstInterfaceMember *>(*i);
            writer.setReferenceData(
                referenceIndex++, decl->getDocumentation(), RTReferenceType::SUPPORTS,
                (decl->isOptional() ? RTFieldAccess::OPTIONAL : RTFieldAccess::INVALID),
                OStringToOUString( decl->getRealInterface()->getRelativName(),
                                        RTL_TEXTENCODING_UTF8));
            break;
        }

        case NT_service_member:
            if (getNodeType() == NT_service)
            {
                AstServiceMember * decl = static_cast<AstServiceMember *>(*i);
                writer.setReferenceData(referenceIndex++, decl->getDocumentation(), RTReferenceType::EXPORTS,
                    (decl->isOptional() ? RTFieldAccess::OPTIONAL : RTFieldAccess::INVALID),
                    OStringToOUString(decl->getRealService()->getRelativName(),
                                           RTL_TEXTENCODING_UTF8));
            }
            break;

        case NT_observes:
            {
                AstObserves * decl = static_cast<AstObserves *>(*i);
                writer.setReferenceData(referenceIndex++, decl->getDocumentation(), RTReferenceType::OBSERVES,
                    RTFieldAccess::INVALID,
                    OStringToOUString( decl->getRealInterface()->getRelativName(),
                                            RTL_TEXTENCODING_UTF8));
                break;
            }

        case NT_needs:
            {
                AstNeeds * decl = static_cast<AstNeeds *>(*i);
                writer.setReferenceData( referenceIndex++, decl->getDocumentation(), RTReferenceType::NEEDS,
                    RTFieldAccess::INVALID,
                    OStringToOUString( decl->getRealService()->getRelativName(),
                                            RTL_TEXTENCODING_UTF8));
                break;
            }

        default:
            OSL_ASSERT( (*i)->getNodeType() == NT_interface || (*i)->getNodeType() == NT_typedef);
            break;
        }
    }
    if (m_defaultConstructor) {
        writer.setMethodData(
            constructorIndex++, "", RTMethodMode::TWOWAY,
            "", "void",
            0, 0);
    }
    sal_uInt32 size;
    void const * blob = writer.getBlob(&size);
    if (localKey.setValue(
            "", RegValueType::BINARY, const_cast< void * >(blob),
            size) != RegError::NO_ERROR)
    {
        fprintf(
            stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getFullName().getStr(),
            OUStringToOString(
                localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }
    return true;
}

void AstAttribute::dumpBlob(
    typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex) const
{
    RTFieldAccess accessMode = RTFieldAccess::INVALID;

    if (isReadonly())
    {
        accessMode |= RTFieldAccess::READONLY;
    } else
    {
        accessMode |= RTFieldAccess::READWRITE;
    }
    if (isOptional())
    {
        accessMode |= RTFieldAccess::OPTIONAL;
    }
    if (isBound())
    {
        accessMode |= RTFieldAccess::BOUND;
    }
    if (isMayBeVoid())
    {
        accessMode |= RTFieldAccess::MAYBEVOID;
    }
    if (isConstrained())
    {
        accessMode |= RTFieldAccess::CONSTRAINED;
    }
    if (isTransient())
    {
        accessMode |= RTFieldAccess::TRANSIENT;
    }
    if (isMayBeAmbiguous())
    {
        accessMode |= RTFieldAccess::MAYBEAMBIGUOUS;
    }
    if (isMayBeDefault())
    {
        accessMode |= RTFieldAccess::MAYBEDEFAULT;
    }
    if (isRemoveable())
    {
        accessMode |= RTFieldAccess::REMOVABLE;
    }

    OUString name(OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8));
    rBlob.setFieldData(
        index, getDocumentation(), OUString(), accessMode, name,
        OStringToOUString(m_pType->getRelativName(), RTL_TEXTENCODING_UTF8),
        RTConstValue());
    dumpExceptions(
        rBlob, m_getDocumentation, m_getExceptions, RTMethodMode::ATTRIBUTE_GET,
        methodIndex);
    dumpExceptions(
        rBlob, m_setDocumentation, m_setExceptions, RTMethodMode::ATTRIBUTE_SET,
        methodIndex);
}

void AstAttribute::dumpExceptions(
    typereg::Writer & writer, OUString const & documentation,
    DeclList const & exceptions, RTMethodMode flags, sal_uInt16 * methodIndex) const
{
    if (exceptions.empty())
        return;

    OSL_ASSERT(methodIndex != nullptr);
    sal_uInt16 idx = (*methodIndex)++;
    // exceptions.size() <= SAL_MAX_UINT16 already checked in
    // AstInterface::dump:
    writer.setMethodData(
        idx, documentation, flags,
        OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8),
        "void", 0,
        static_cast< sal_uInt16 >(exceptions.size()));
    sal_uInt16 exceptionIndex = 0;
    for (auto const& elem : exceptions)
    {
        writer.setMethodExceptionTypeName(
            idx, exceptionIndex++,
            OStringToOUString(
                elem->getRelativName(), RTL_TEXTENCODING_UTF8));
    }
}

const char* AstSequence::getRelativName() const
{
    if ( !m_xRelativName )
    {
        m_xRelativName = OString("[]");
        AstDeclaration const * pType = resolveTypedefs( m_pMemberType );
        *m_xRelativName += pType->getRelativName();
    }

    return m_xRelativName->getStr();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astenum.cxx b/idlc/source/astenum.cxx
deleted file mode 100644
index 7dff49d3..0000000
--- a/idlc/source/astenum.cxx
+++ /dev/null
@@ -1,105 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sal/config.h>

#include <algorithm>

#include <astenum.hxx>

#include <registry/version.h>
#include <registry/writer.hxx>

AstEnum::AstEnum(const OString& name, AstScope* pScope)
    : AstType(NT_enum, name, pScope)
    , AstScope(NT_enum)
    , m_enumValueCount(0)
{
}

AstEnum::~AstEnum()
{
}

AstConstant* AstEnum::checkValue(AstExpression* pExpr)
{
    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();

    iter = std::find_if(iter, end, [&pExpr](AstDeclaration* pDecl) {
        return static_cast<AstConstant*>(pDecl)->getConstValue()->compareLong(pExpr); });

    if (iter != end)
        return static_cast<AstConstant*>(*iter);

    if ( pExpr->getExprValue()->u.lval > m_enumValueCount )
        m_enumValueCount = pExpr->getExprValue()->u.lval + 1;

    return nullptr;
}

bool AstEnum::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    sal_uInt16 nConst = getNodeCount(NT_enum_val);
    if ( nConst <= 0 )
        return true;

    typereg::Writer aBlob(
        m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
        getDocumentation(), "", RT_TYPE_ENUM, m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0,
        nConst, 0, 0);

    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    sal_uInt16 index = 0;
    while ( iter != end )
    {
        AstDeclaration* pDecl = *iter;
        if ( pDecl->getNodeType() == NT_enum_val )
            static_cast<AstConstant*>(pDecl)->dumpBlob(aBlob, index++, false);

        ++iter;
    }

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue("", RegValueType::BINARY,
                            const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astexpression.cxx b/idlc/source/astexpression.cxx
deleted file mode 100644
index 1afa91d..0000000
--- a/idlc/source/astexpression.cxx
+++ /dev/null
@@ -1,1327 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astexpression.hxx>
#include <astconstant.hxx>
#include <astscope.hxx>
#include <errorhandler.hxx>

#include <o3tl/float_int_conversion.hxx>
#include <osl/diagnose.h>

#include <limits.h>
#include <float.h>
#include <memory>

AstExpression::AstExpression(ExprComb c, AstExpression* pExpr1, AstExpression* pExpr2)
    : m_combOperator(c)
    , m_subExpr1(pExpr1)
    , m_subExpr2(pExpr2)
{
}

AstExpression::AstExpression(sal_Int32 l)
    : m_combOperator(ExprComb::NONE)
{
    m_exprValue.reset(new AstExprValue);
    m_exprValue->et = ET_long;
    m_exprValue->u.lval = l;
}

AstExpression::AstExpression(sal_Int32 l, ExprType et)
    : m_combOperator(ExprComb::NONE)
{
    m_exprValue.reset(new AstExprValue);
    m_exprValue->et = et;
    m_exprValue->u.lval = l;
}

AstExpression::AstExpression(sal_Int64 h)
    : m_combOperator(ExprComb::NONE)
{
    m_exprValue.reset(new AstExprValue);
    m_exprValue->et = ET_hyper;
    m_exprValue->u.hval = h;
}

AstExpression::AstExpression(sal_uInt64 uh)
    : m_combOperator(ExprComb::NONE)
{
    m_exprValue.reset(new AstExprValue);
    m_exprValue->et = ET_uhyper;
    m_exprValue->u.uhval = uh;
}

AstExpression::AstExpression(double d)
    : m_combOperator(ExprComb::NONE)
{
    m_exprValue.reset(new AstExprValue);
    m_exprValue->et = ET_double;
    m_exprValue->u.dval = d;
}

AstExpression::AstExpression(OString* scopedName)
    : m_combOperator(ExprComb::Symbol)
{
    if (scopedName)
        m_xSymbolicName = *scopedName;
}

AstExpression::~AstExpression() {}

/*
 * Perform the coercion from the given AstExprValue to the requested
 * ExprType. Return an AstExprValue if successful, NULL if failed.
 * must be done for hyper, uhyper
 */
static bool coerce_value(AstExprValue* ev, ExprType t)
{
    if (ev == nullptr)
        return false;

    switch (t)
    {
        case ET_short:
            switch (ev->et)
            {
                case ET_short:
                    return true;
                case ET_ushort:
                {
                    if (ev->u.usval > SAL_MAX_INT16)
                        return false;
                    auto tmp = static_cast<sal_Int16>(ev->u.usval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_long:
                {
                    if (ev->u.lval < SAL_MIN_INT16 || ev->u.lval > SAL_MAX_INT16)
                        return false;
                    auto tmp = static_cast<sal_Int16>(ev->u.lval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_ulong:
                {
                    if (ev->u.ulval > SAL_MAX_INT16)
                        return false;
                    auto tmp = static_cast<sal_Int16>(ev->u.ulval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_hyper:
                {
                    if (ev->u.hval < SAL_MIN_INT16 || ev->u.hval > SAL_MAX_INT16)
                        return false;
                    auto tmp = static_cast<sal_Int16>(ev->u.hval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_INT16)
                        return false;
                    auto tmp = static_cast<sal_Int16>(ev->u.uhval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_Int16>(ev->u.bval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_float:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT16)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT16)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int16>(ev->u.fval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_double:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT16)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT16)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int16>(ev->u.dval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_Int16>(ev->u.byval);
                    ev->u.sval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_ushort:
            switch (ev->et)
            {
                case ET_short:
                {
                    if (ev->u.sval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt16>(ev->u.sval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                case ET_ushort:
                    return true;
                case ET_long:
                {
                    if (ev->u.lval < 0 || ev->u.lval > SAL_MAX_UINT16)
                        return false;
                    auto tmp = static_cast<sal_uInt16>(ev->u.lval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                case ET_ulong:
                {
                    if (ev->u.ulval > SAL_MAX_UINT16)
                        return false;
                    auto tmp = static_cast<sal_uInt16>(ev->u.ulval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                case ET_hyper:
                {
                    if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT16)
                        return false;
                    auto tmp = static_cast<sal_uInt16>(ev->u.hval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_UINT16)
                        return false;
                    auto tmp = static_cast<sal_uInt16>(ev->u.uhval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_uInt16>(ev->u.bval);
                    ev->u.usval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_float:
                {
                    if (ev->u.fval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT16))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt16>(ev->u.fval);
                    ev->u.usval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_double:
                {
                    if (ev->u.dval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT16))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt16>(ev->u.dval);
                    ev->u.usval = tmp;
                    ev->et = ET_short;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_uInt16>(ev->u.byval);
                    ev->u.usval = tmp;
                    ev->et = ET_ushort;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_long:
            switch (ev->et)
            {
                case ET_short:
                {
                    auto tmp = static_cast<sal_Int32>(ev->u.sval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<sal_Int32>(ev->u.usval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_long:
                    return true;
                case ET_ulong:
                {
                    if (ev->u.ulval > SAL_MAX_INT32)
                        return false;
                    auto tmp = static_cast<sal_Int32>(ev->u.ulval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_hyper:
                {
                    if (ev->u.hval < SAL_MIN_INT32 || ev->u.hval > SAL_MAX_INT32)
                        return false;
                    auto tmp = static_cast<sal_Int32>(ev->u.hval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_INT32)
                        return false;
                    auto tmp = static_cast<sal_Int32>(ev->u.uhval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_Int32>(ev->u.bval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_float:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT32)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT32)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int32>(ev->u.fval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_double:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT32)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT32)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int32>(ev->u.dval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_Int32>(ev->u.byval);
                    ev->u.lval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_ulong:
            switch (ev->et)
            {
                case ET_short:
                {
                    if (ev->u.sval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt32>(ev->u.sval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<sal_uInt32>(ev->u.usval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_long:
                {
                    if (ev->u.lval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt32>(ev->u.lval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_ulong:
                    return true;
                case ET_hyper:
                {
                    if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT32)
                        return false;
                    auto tmp = static_cast<sal_uInt32>(ev->u.hval);
                    ev->u.lval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_UINT32)
                        return false;
                    auto tmp = static_cast<sal_uInt32>(ev->u.uhval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_uInt32>(ev->u.bval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_float:
                {
                    if (ev->u.fval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT32))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt32>(ev->u.fval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_double:
                {
                    if (ev->u.dval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT32))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt32>(ev->u.dval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_uInt32>(ev->u.byval);
                    ev->u.ulval = tmp;
                    ev->et = ET_ulong;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_hyper:
            switch (ev->et)
            {
                case ET_short:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.sval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.usval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_long:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.lval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_ulong:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.ulval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_hyper:
                    return true;
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_INT64)
                        return false;
                    auto tmp = static_cast<sal_Int64>(ev->u.uhval);
                    ev->u.hval = tmp;
                    ev->et = ET_long;
                    return true;
                }
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.bval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_float:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT64)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT64)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int64>(ev->u.fval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_double:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT64)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT64)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_Int64>(ev->u.dval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_Int64>(ev->u.byval);
                    ev->u.hval = tmp;
                    ev->et = ET_hyper;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_uhyper:
            switch (ev->et)
            {
                case ET_short:
                {
                    if (ev->u.sval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt64>(ev->u.sval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<sal_uInt64>(ev->u.usval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_long:
                {
                    if (ev->u.lval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt64>(ev->u.lval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_ulong:
                {
                    auto tmp = static_cast<sal_uInt64>(ev->u.ulval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_hyper:
                {
                    if (ev->u.hval < 0)
                        return false;
                    auto tmp = static_cast<sal_uInt64>(ev->u.hval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_uhyper:
                    return true;
                case ET_boolean:
                {
                    auto tmp = static_cast<sal_uInt64>(ev->u.bval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_float:
                {
                    if (ev->u.fval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT64))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt64>(ev->u.fval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_double:
                {
                    if (ev->u.dval < 0.0
                        || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT64))
                    {
                        return false;
                    }
                    auto tmp = static_cast<sal_uInt64>(ev->u.dval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<sal_uInt64>(ev->u.byval);
                    ev->u.uhval = tmp;
                    ev->et = ET_uhyper;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_boolean:
            switch (ev->et)
            {
                case ET_short:
                    ev->u.bval = ev->u.sval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_ushort:
                    ev->u.bval = ev->u.usval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_long:
                    ev->u.bval = ev->u.lval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_ulong:
                    ev->u.bval = ev->u.ulval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_hyper:
                    ev->u.bval = ev->u.hval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_uhyper:
                    ev->u.bval = ev->u.uhval != 0;
                    ev->et = ET_boolean;
                    return true;
                case ET_boolean:
                    return true;
                case ET_float:
                    ev->u.bval = ev->u.fval != 0.0;
                    ev->et = ET_boolean;
                    return true;
                case ET_double:
                    ev->u.bval = ev->u.dval != 0.0;
                    ev->et = ET_boolean;
                    return true;
                case ET_byte:
                    ev->u.bval = ev->u.byval != 0;
                    ev->et = ET_boolean;
                    return true;
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_float:
            switch (ev->et)
            {
                case ET_short:
                {
                    auto tmp = static_cast<float>(ev->u.sval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<float>(ev->u.usval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_long:
                {
                    auto tmp = static_cast<float>(ev->u.lval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_ulong:
                {
                    auto tmp = static_cast<float>(ev->u.ulval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_hyper:
                {
                    auto tmp = static_cast<float>(ev->u.hval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_uhyper:
                {
                    if (static_cast<float>(ev->u.ulval) > FLT_MAX)
                        return false;
                    auto tmp = static_cast<float>(ev->u.ulval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_boolean:
                    ev->u.fval = ev->u.bval ? 1.0f : 0.0f;
                    ev->et = ET_float;
                    return true;
                case ET_float:
                    return true;
                case ET_double:
                {
                    if (static_cast<float>(ev->u.dval) > FLT_MAX
                        || static_cast<float>(ev->u.dval) < -FLT_MAX)
                        return false;
                    auto tmp = static_cast<float>(ev->u.dval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                case ET_byte:
                {
                    auto tmp = static_cast<float>(ev->u.byval);
                    ev->u.fval = tmp;
                    ev->et = ET_float;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_double:
            switch (ev->et)
            {
                case ET_short:
                {
                    auto tmp = static_cast<double>(ev->u.sval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_ushort:
                {
                    auto tmp = static_cast<double>(ev->u.usval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_long:
                {
                    auto tmp = static_cast<double>(ev->u.lval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_ulong:
                {
                    auto tmp = static_cast<double>(ev->u.ulval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_hyper:
                {
                    auto tmp = static_cast<double>(ev->u.hval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.dval > FLT_MAX || ev->u.dval < -FLT_MAX)
                        return false;
                    auto tmp = static_cast<double>(ev->u.ulval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_boolean:
                    ev->u.dval = ev->u.bval ? 1.0 : 0.0;
                    ev->et = ET_double;
                    return true;
                case ET_float:
                {
                    auto tmp = static_cast<double>(ev->u.fval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                case ET_double:
                    return true;
                case ET_byte:
                {
                    auto tmp = static_cast<double>(ev->u.byval);
                    ev->u.dval = tmp;
                    ev->et = ET_double;
                    return true;
                }
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        case ET_byte:
            switch (ev->et)
            {
                case ET_short:
                {
                    if (ev->u.sval < SAL_MIN_INT8 || ev->u.sval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.sval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_ushort:
                {
                    if (ev->u.usval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.usval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_long:
                {
                    if (ev->u.lval < SAL_MIN_INT8 || ev->u.lval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.lval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_ulong:
                {
                    if (ev->u.ulval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.ulval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_hyper:
                {
                    if (ev->u.hval < SAL_MIN_INT8 || ev->u.hval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.hval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_uhyper:
                {
                    if (ev->u.uhval > SAL_MAX_UINT8)
                        return false;
                    auto tmp = static_cast<unsigned char>(ev->u.uhval);
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_boolean:
                    ev->u.byval = ev->u.bval ? 1 : 0;
                    ev->et = ET_byte;
                    return true;
                case ET_float:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT8)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT8)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<unsigned char>(static_cast<sal_Int32>(ev->u.fval));
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_double:
                {
                    if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT8)
                          && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT8)))
                    {
                        return false;
                    }
                    auto tmp = static_cast<unsigned char>(static_cast<sal_Int32>(ev->u.dval));
                    ev->u.byval = tmp;
                    ev->et = ET_byte;
                    return true;
                }
                case ET_byte:
                    return true;
                default:
                    OSL_ASSERT(false);
                    return false;
            }
        default:
            OSL_ASSERT(false);
            return false;
    }
}

bool AstExpression::coerce(ExprType t)
{
    /*
     * Is it already of the right type?
     */
    if (m_exprValue != nullptr && m_exprValue->et == t)
        return true;
    /*
     * OK, must coerce
     *
     * First, evaluate it, then try to coerce result type
     * If already evaluated, return the result
     */
    evaluate();
    if (m_exprValue == nullptr)
        return false;

    if (!coerce_value(m_exprValue.get(), t))
        m_exprValue.reset();

    return m_exprValue != nullptr;
}

bool AstExpression::compareLong(AstExpression* pExpr)
{
    bool bRet = false;
    if (m_combOperator != pExpr->m_combOperator)
        return bRet;
    evaluate();
    pExpr->evaluate();
    if (m_exprValue == nullptr || pExpr->getExprValue() == nullptr)
        return bRet;
    if (m_exprValue->et != pExpr->getExprValue()->et)
        return bRet;
    switch (m_exprValue->et)
    {
        case ET_long:
            bRet = m_exprValue->u.lval == pExpr->getExprValue()->u.lval;
            break;
        default:
            OSL_ASSERT(false);
            bRet = false;
            break;
    }
    return bRet;
}

void AstExpression::evaluate()
{
    /*
     * Already evaluated?
     */
    if (m_exprValue != nullptr)
        return;
    /*
     * OK, must evaluate operator
     */
    switch (m_combOperator)
    {
        case ExprComb::Add:
        case ExprComb::Minus:
        case ExprComb::Mul:
        case ExprComb::Div:
        case ExprComb::Mod:
            m_exprValue = eval_bin_op();
            break;
        case ExprComb::Or:
        case ExprComb::Xor:
        case ExprComb::And:
        case ExprComb::Left:
        case ExprComb::Right:
            m_exprValue = eval_bit_op();
            break;
        case ExprComb::UPlus:
        case ExprComb::UMinus:
            m_exprValue = eval_un_op();
            break;
        case ExprComb::Symbol:
            m_exprValue = eval_symbol();
            break;
        case ExprComb::NONE:
            break;
    }
}

std::unique_ptr<AstExprValue> AstExpression::eval_bin_op()
{
    ExprType eType = ET_double;

    if (m_combOperator == ExprComb::Mod)
        eType = ET_hyper;

    if (m_subExpr1 == nullptr || m_subExpr2 == nullptr)
        return nullptr;
    m_subExpr1->evaluate();
    if (m_subExpr1->getExprValue() == nullptr)
        return nullptr;
    if (!m_subExpr1->coerce(eType))
        return nullptr;
    m_subExpr2->evaluate();
    if (m_subExpr2->getExprValue() == nullptr)
        return nullptr;
    if (!m_subExpr2->coerce(eType))
        return nullptr;

    std::unique_ptr<AstExprValue> retval(new AstExprValue);
    retval->et = eType;

    switch (m_combOperator)
    {
        case ExprComb::Mod:
            if (m_subExpr2->getExprValue()->u.hval == 0)
                return nullptr;
            retval->u.hval
                = m_subExpr1->getExprValue()->u.hval % m_subExpr2->getExprValue()->u.hval;
            break;
        case ExprComb::Add:
            retval->u.dval
                = m_subExpr1->getExprValue()->u.dval + m_subExpr2->getExprValue()->u.dval;
            break;
        case ExprComb::Minus:
            retval->u.dval
                = m_subExpr1->getExprValue()->u.dval - m_subExpr2->getExprValue()->u.dval;
            break;
        case ExprComb::Mul:
            retval->u.dval
                = m_subExpr1->getExprValue()->u.dval * m_subExpr2->getExprValue()->u.dval;
            break;
        case ExprComb::Div:
            if (m_subExpr2->getExprValue()->u.dval == 0.0)
                return nullptr;
            retval->u.dval
                = m_subExpr1->getExprValue()->u.dval / m_subExpr2->getExprValue()->u.dval;
            break;
        default:
            return nullptr;
    }

    return retval;
}

std::unique_ptr<AstExprValue> AstExpression::eval_bit_op()
{
    if (m_subExpr1 == nullptr || m_subExpr2 == nullptr)
        return nullptr;
    m_subExpr1->evaluate();
    if (m_subExpr1->getExprValue() == nullptr)
        return nullptr;
    if (!m_subExpr1->coerce(ET_long))
        return nullptr;
    m_subExpr2->evaluate();
    if (m_subExpr2->getExprValue() == nullptr)
        return nullptr;
    if (!m_subExpr2->coerce(ET_long))
        return nullptr;

    std::unique_ptr<AstExprValue> retval(new AstExprValue);
    retval->et = ET_long;

    switch (m_combOperator)
    {
        case ExprComb::Or:
            retval->u.lval
                = m_subExpr1->getExprValue()->u.lval | m_subExpr2->getExprValue()->u.lval;
            break;
        case ExprComb::Xor:
            retval->u.lval
                = m_subExpr1->getExprValue()->u.lval ^ m_subExpr2->getExprValue()->u.lval;
            break;
        case ExprComb::And:
            retval->u.lval
                = m_subExpr1->getExprValue()->u.lval & m_subExpr2->getExprValue()->u.lval;
            break;
        case ExprComb::Left:
            retval->u.lval = m_subExpr1->getExprValue()->u.lval
                             << m_subExpr2->getExprValue()->u.lval;
            break;
        case ExprComb::Right:
            retval->u.lval
                = m_subExpr1->getExprValue()->u.lval >> m_subExpr2->getExprValue()->u.lval;
            break;
        default:
            return nullptr;
    }

    return retval;
}

std::unique_ptr<AstExprValue> AstExpression::eval_un_op()
{
    if (m_subExpr1 == nullptr)
        return nullptr;
    m_subExpr1->evaluate();
    if (m_subExpr1->getExprValue() == nullptr)
        return nullptr;
    if (!m_subExpr1->coerce(ET_double))
        return nullptr;

    std::unique_ptr<AstExprValue> retval(new AstExprValue);
    retval->et = ET_double;

    switch (m_combOperator)
    {
        case ExprComb::UPlus:
            retval->u.lval = m_subExpr1->getExprValue()->u.lval;
            break;
        case ExprComb::UMinus:
            retval->u.lval = -(m_subExpr1->getExprValue()->u.lval);
            break;
        default:
            return nullptr;
    }

    return retval;
}

std::unique_ptr<AstExprValue> AstExpression::eval_symbol()
{
    AstScope* pScope = nullptr;
    AstDeclaration* pDecl;
    AstConstant* pConst;

    /*
     * Is there a symbol stored?
     */
    if (!m_xSymbolicName)
    {
        ErrorHandler::evalError(this);
        return nullptr;
    }
    /*
     * Get current scope for lookup
     */
    if (idlc()->scopes()->depth() > 0)
        pScope = idlc()->scopes()->topNonNull();
    if (!pScope)
    {
        ErrorHandler::lookupError(*m_xSymbolicName);
        return nullptr;
    }
    /*
     * Do lookup
     */
    pDecl = pScope->lookupByName(*m_xSymbolicName);
    if (pDecl == nullptr)
    {
        ErrorHandler::lookupError(*m_xSymbolicName);
        return nullptr;
    }
    /*
     * Is it a constant?
     */
    if (pDecl->getNodeType() != NT_const && pDecl->getNodeType() != NT_enum_val)
    {
        ErrorHandler::constantExpected(pDecl, *m_xSymbolicName);
        return nullptr;
    }
    if (!ErrorHandler::checkPublished(pDecl))
    {
        return nullptr;
    }
    /*
     * OK, now evaluate the constant we just got, to produce its value
     */
    pConst = static_cast<AstConstant*>(pDecl);
    pConst->getConstValue()->evaluate();
    auto const val = pConst->getConstValue()->getExprValue();
    return val == nullptr ? nullptr : std::make_unique<AstExprValue>(*val);
}

OString AstExpression::toString()
{
    OString exprStr;
    if (m_combOperator == ExprComb::Symbol)
        return m_xSymbolicName ? *m_xSymbolicName : OString("<Undefined Name>");

    if (m_exprValue)
    {
        switch (m_exprValue->et)
        {
            case ET_short:
                return OString::number(m_exprValue->u.sval);
            case ET_ushort:
                return OString::number(m_exprValue->u.usval);
            case ET_long:
                return OString::number(m_exprValue->u.lval);
            case ET_ulong:
                return OString::number(m_exprValue->u.ulval);
            case ET_hyper:
                return OString::number(m_exprValue->u.hval);
            case ET_uhyper:
                return OString::number(m_exprValue->u.uhval);
            case ET_float:
                return OString::number(m_exprValue->u.fval);
            case ET_double:
                return OString::number(m_exprValue->u.dval);
            case ET_byte:
                return OString::number(m_exprValue->u.byval);
            case ET_boolean:
                if (m_exprValue->u.lval == 0)
                    return "FALSE";
                else
                    return "TRUE";
            default:
                OSL_ASSERT(false);
                return OString();
        }
    }

    switch (m_combOperator)
    {
        case ExprComb::UPlus:
            exprStr += "+";
            break;
        case ExprComb::UMinus:
            exprStr += "-";
            break;
        default:
            break;
    }
    if (m_subExpr1)
        exprStr += m_subExpr1->toString();
    switch (m_combOperator)
    {
        case ExprComb::Add:
            exprStr += " + ";
            break;
        case ExprComb::Minus:
            exprStr += " - ";
            break;
        case ExprComb::Mul:
            exprStr += " * ";
            break;
        case ExprComb::Div:
            exprStr += " / ";
            break;
        case ExprComb::Mod:
            exprStr += " % ";
            break;
        case ExprComb::Or:
            exprStr += " | ";
            break;
        case ExprComb::Xor:
            exprStr += " ^ ";
            break;
        case ExprComb::And:
            exprStr += " & ";
            break;
        case ExprComb::Left:
            exprStr += " << ";
            break;
        case ExprComb::Right:
            exprStr += " >> ";
            break;
        default:
            break;
    }

    if (m_subExpr2)
        exprStr += m_subExpr2->toString();

    return exprStr;
}

// Convert the type of an AST_Expression to a char *
const char* exprTypeToString(ExprType t)
{
    switch (t)
    {
        case ET_short:
            return "short";
        case ET_ushort:
            return "unsigned short";
        case ET_long:
            return "long";
        case ET_ulong:
            return "unsigned long";
        case ET_hyper:
            return "hyper";
        case ET_uhyper:
            return "unsigned hyper";
        case ET_float:
            return "float";
        case ET_double:
            return "double";
        case ET_char:
            return "char";
        case ET_byte:
            return "byte";
        case ET_boolean:
            return "boolean";
        case ET_string:
            return "string";
        case ET_any:
            return "any";
        case ET_type:
            return "type";
        case ET_void:
            return "void";
        case ET_none:
            return "none";
    }

    return "unknown";
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astinterface.cxx b/idlc/source/astinterface.cxx
deleted file mode 100644
index 50e24d1..0000000
--- a/idlc/source/astinterface.cxx
+++ /dev/null
@@ -1,399 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astinterface.hxx>
#include <astattribute.hxx>
#include <astoperation.hxx>
#include <idlc.hxx>

#include <registry/version.h>
#include <registry/writer.hxx>

#include <osl/diagnose.h>

AstInterface::AstInterface(const OString& name,
                           AstInterface const * pInherits,
                           AstScope* pScope)
    : AstType(NT_interface, name, pScope)
    , AstScope(NT_interface)
    , m_mandatoryInterfaces(0)
    , m_bIsDefined(false)
    , m_bSingleInheritance(pInherits != nullptr)
{
    if (pInherits != nullptr) {
        addInheritedInterface(pInherits, false, OUString());
    }
}

AstInterface::~AstInterface()
{
}

AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes(
    AstInterface const * ifc, bool optional) const
{
    DoubleDeclarations doubleDecls;
    std::set< OString > seen;
    checkInheritedInterfaceClashes(
        doubleDecls, seen, ifc, true, optional, optional);
    return doubleDecls;
}

void AstInterface::addInheritedInterface(
    AstType const * ifc, bool optional, OUString const & documentation)
{
    m_inheritedInterfaces.emplace_back(ifc, optional, documentation);
    if (!optional) {
        ++m_mandatoryInterfaces;
    }
    AstInterface const * resolved = resolveInterfaceTypedefs(ifc);
    addVisibleInterface(resolved, true, optional);
    if (optional) {
        addOptionalVisibleMembers(resolved);
    }
}

AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes(
    AstDeclaration const * member) const
{
    DoubleMemberDeclarations doubleMembers;
    checkMemberClashes(doubleMembers, member, true);
    return doubleMembers;
}

void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) {
    addDeclaration(member);
    m_visibleMembers.emplace(member->getLocalName(), VisibleMember(member));
}

void AstInterface::forwardDefined(AstInterface const & def)
{
    setImported(def.isImported());
    setInMainfile(def.isInMainfile());
    setLineNumber(def.getLineNumber());
    setFileName(def.getFileName());
    setDocumentation(def.getDocumentation());
    m_inheritedInterfaces = def.m_inheritedInterfaces;
    m_mandatoryInterfaces = def.m_mandatoryInterfaces;
    m_bIsDefined = true;
}

bool AstInterface::dump(RegistryKey& rKey)
{
    if ( !isDefined() )
        return true;

    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    if (m_mandatoryInterfaces > SAL_MAX_UINT16
        || m_inheritedInterfaces.size() - m_mandatoryInterfaces
            > SAL_MAX_UINT16)
    {
        fprintf(
            stderr, "%s: interface %s has too many direct base interfaces\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr());
        return false;
    }
    sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces);
    sal_uInt16 nAttributes = 0;
    sal_uInt16 nMethods = 0;
    sal_uInt16 nReferences = static_cast< sal_uInt16 >(
        m_inheritedInterfaces.size() - m_mandatoryInterfaces);
    typereg_Version version
        = (nBaseTypes <= 1 && nReferences == 0 && !m_bPublished
           ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1);
    for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            {
                if (!increment(&nAttributes, "attributes")) {
                    return false;
                }
                AstAttribute * attr = static_cast<AstAttribute *>(*i);
                if (attr->isBound()) {
                    version = TYPEREG_VERSION_1;
                }
                DeclList::size_type getCount = attr->getGetExceptionCount();
                if (getCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of getter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (getCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                DeclList::size_type setCount = attr->getSetExceptionCount();
                if (setCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of setter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (setCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                break;
            }

        case NT_operation:
            if (!increment(&nMethods, "methods")) {
                return false;
            }
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }

    typereg::Writer aBlob(
        version, getDocumentation(), "", RT_TYPE_INTERFACE, m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes,
        nAttributes, nMethods, nReferences);

    sal_uInt16 superTypeIndex = 0;
    sal_uInt16 referenceIndex = 0;
    for (auto const& elem : m_inheritedInterfaces)
    {
        if (elem.isOptional()) {
            aBlob.setReferenceData(
                referenceIndex++, elem.getDocumentation(), RTReferenceType::SUPPORTS,
                RTFieldAccess::OPTIONAL,
                OStringToOUString(
                    elem.getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        } else {
            aBlob.setSuperTypeName(
                superTypeIndex++,
                OStringToOUString(
                    elem.getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        }
    }

    sal_uInt16 attributeIndex = 0;
    sal_uInt16 methodIndex = 0;
    for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            static_cast<AstAttribute *>(*i)->dumpBlob(
                aBlob, attributeIndex++, &methodIndex);
            break;

        case NT_operation:
            static_cast<AstOperation *>(*i)->dumpBlob(aBlob, methodIndex++);
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue("", RegValueType::BINARY, const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    return true;
}

void AstInterface::checkInheritedInterfaceClashes(
    DoubleDeclarations & doubleDeclarations,
    std::set< OString > & seenInterfaces, AstInterface const * ifc,
    bool direct, bool optional, bool mainOptional) const
{
    if (!(direct || optional
        || seenInterfaces.insert(ifc->getScopedName()).second))
        return;

    VisibleInterfaces::const_iterator visible(
        m_visibleInterfaces.find(ifc->getScopedName()));
    if (visible != m_visibleInterfaces.end()) {
        switch (visible->second) {
        case INTERFACE_INDIRECT_OPTIONAL:
            if (direct && optional) {
                doubleDeclarations.interfaces.push_back(ifc);
                return;
            }
            break;

        case INTERFACE_DIRECT_OPTIONAL:
            if (direct || !mainOptional) {
                doubleDeclarations.interfaces.push_back(ifc);
            }
            return;

        case INTERFACE_INDIRECT_MANDATORY:
            if (direct) {
                doubleDeclarations.interfaces.push_back(ifc);
            }
            return;

        case INTERFACE_DIRECT_MANDATORY:
            if (direct || (!optional && !mainOptional)) {
                doubleDeclarations.interfaces.push_back(ifc);
            }
            return;
        }
    }
    if (!direct && optional)
        return;

    for (DeclList::const_iterator i(ifc->getIteratorBegin());
          i != ifc->getIteratorEnd(); ++i)
    {
        checkMemberClashes(
            doubleDeclarations.members, *i, !mainOptional);
    }
    for (auto const& elem : ifc->m_inheritedInterfaces)
    {
        checkInheritedInterfaceClashes(
            doubleDeclarations, seenInterfaces, elem.getResolved(),
            false, elem.isOptional(), mainOptional);
    }
}

void AstInterface::checkMemberClashes(
    DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member,
    bool checkOptional) const
{
    VisibleMembers::const_iterator i(
        m_visibleMembers.find(member->getLocalName()));
    if (i == m_visibleMembers.end())
        return;

    if (i->second.mandatory != nullptr) {
        if (i->second.mandatory->getScopedName() != member->getScopedName())
        {
            DoubleMemberDeclaration d;
            d.first = i->second.mandatory;
            d.second = member;
            doubleMembers.push_back(d);
        }
    } else if (checkOptional) {
        for (auto const& elem : i->second.optionals)
        {
            if (elem.second->getScopedName() != member->getScopedName()) {
                DoubleMemberDeclaration d;
                d.first = elem.second;
                d.second = member;
                doubleMembers.push_back(d);
            }
        }
    }
}

void AstInterface::addVisibleInterface(
    AstInterface const * ifc, bool direct, bool optional)
{
    InterfaceKind kind = optional
        ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL
        : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY;
    std::pair< VisibleInterfaces::iterator, bool > result(
        m_visibleInterfaces.emplace(ifc->getScopedName(), kind));
    bool seen = !result.second
        && result.first->second >= INTERFACE_INDIRECT_MANDATORY;
    if (!result.second && kind > result.first->second) {
        result.first->second = kind;
    }
    if (optional || seen)
        return;

    for (DeclList::const_iterator i(ifc->getIteratorBegin());
          i != ifc->getIteratorEnd(); ++i)
    {
        m_visibleMembers.emplace(
                (*i)->getLocalName(), VisibleMember(*i));
    }
    for (auto const& elem : ifc->m_inheritedInterfaces)
    {
        addVisibleInterface(elem.getResolved(), false, elem.isOptional());
    }
}

void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) {
    for (DeclList::const_iterator i(ifc->getIteratorBegin());
          i != ifc->getIteratorEnd(); ++i)
    {
        VisibleMembers::iterator visible(
            m_visibleMembers.find((*i)->getLocalName()));
        if (visible == m_visibleMembers.end()) {
            visible = m_visibleMembers.emplace(
                    (*i)->getLocalName(), VisibleMember()).first;
        }
        if (visible->second.mandatory == nullptr) {
            visible->second.optionals.emplace(ifc->getScopedName(), *i);
        }
    }
    for (auto const& elem : ifc->m_inheritedInterfaces)
    {
        if (!elem.isOptional()) {
            addOptionalVisibleMembers(elem.getResolved());
        }
    }
}

bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const {
    if (*counter == SAL_MAX_UINT16) {
        fprintf(
            stderr, "%s: interface %s has too many direct %s\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr(), sort);
        return false;
    }
    ++*counter;
    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astoperation.cxx b/idlc/source/astoperation.cxx
deleted file mode 100644
index 4dea375..0000000
--- a/idlc/source/astoperation.cxx
+++ /dev/null
@@ -1,115 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <astoperation.hxx>
#include <asttype.hxx>
#include <astbasetype.hxx>
#include <astparameter.hxx>
#include <errorhandler.hxx>

#include <registry/writer.hxx>

void AstOperation::setExceptions(DeclList const * pExceptions)
{
    if (pExceptions != nullptr) {
        m_exceptions = *pExceptions;
    }
}

bool AstOperation::isVariadic() const {
    DeclList::const_iterator i(getIteratorEnd());
    return i != getIteratorBegin()
        && static_cast< AstParameter const * >(*(--i))->isRest();
}

void AstOperation::dumpBlob(typereg::Writer & rBlob, sal_uInt16 index)
{
    sal_uInt16      nParam = getNodeCount(NT_parameter);
    sal_uInt16      nExcep = static_cast<sal_uInt16>(m_exceptions.size());

    OUString returnTypeName;
    if (m_pReturnType == nullptr) {
        returnTypeName = "void";
    } else {
        returnTypeName = OStringToOUString(
            m_pReturnType->getRelativName(), RTL_TEXTENCODING_UTF8);
    }
    rBlob.setMethodData(
        index, getDocumentation(), RTMethodMode::TWOWAY,
        OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8),
        returnTypeName, nParam, nExcep);

    if ( nParam )
    {
        DeclList::const_iterator iter = getIteratorBegin();
        DeclList::const_iterator end = getIteratorEnd();
        RTParamMode paramMode;
        sal_uInt16 paramIndex = 0;
        while ( iter != end )
        {
            AstDeclaration* pDecl = *iter;
            if ( pDecl->getNodeType() == NT_parameter )
            {
                AstParameter* pParam = static_cast<AstParameter*>(pDecl);
                switch (pParam->getDirection())
                {
                    case DIR_IN :
                        paramMode = RT_PARAM_IN;
                        break;
                    case DIR_OUT :
                        paramMode = RT_PARAM_OUT;
                        break;
                    case DIR_INOUT :
                        paramMode = RT_PARAM_INOUT;
                        break;
                    default:
                        paramMode = RT_PARAM_INVALID;
                        break;
                }
                if (pParam->isRest()) {
                    paramMode = static_cast< RTParamMode >(
                        paramMode | RT_PARAM_REST);
                }

                rBlob.setMethodParameterData(
                    index, paramIndex++, paramMode,
                    OStringToOUString(
                        pDecl->getLocalName(), RTL_TEXTENCODING_UTF8),
                    OStringToOUString(
                        pParam->getType()->getRelativName(),
                        RTL_TEXTENCODING_UTF8));
            }
            ++iter;
        }
    }

    if ( nExcep )
    {
        sal_uInt16 exceptIndex = 0;
        for (auto const& exception : m_exceptions)
        {
            rBlob.setMethodExceptionTypeName(
                index, exceptIndex++,
                OStringToOUString(
                    exception->getRelativName(), RTL_TEXTENCODING_UTF8));
        }
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astscope.cxx b/idlc/source/astscope.cxx
deleted file mode 100644
index f8309a7..0000000
--- a/idlc/source/astscope.cxx
+++ /dev/null
@@ -1,314 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sal/config.h>

#include <algorithm>
#include <string_view>

#include <astscope.hxx>
#include <astbasetype.hxx>
#include <astinterface.hxx>
#include <errorhandler.hxx>
#include <o3tl/string_view.hxx>
#include <osl/diagnose.h>


static bool isGlobal(std::string_view scopedName)
{
    return scopedName.empty() || o3tl::starts_with(scopedName, ":");
}

AstScope::AstScope(NodeType nodeType)
    : m_nodeType(nodeType)
{

}

AstScope::~AstScope()
{

}

AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
{
    AstDeclaration* pDeclaration = nullptr;

    if ((pDeclaration = lookupForAdd(pDecl)) != nullptr)
    {
        if ( pDecl->hasAncestor(pDeclaration) )
        {
            ErrorHandler::error2(ErrorCode::RedefScope, pDecl, pDeclaration);
            return nullptr;
        }
        if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
             (pDecl->getNodeType() == NT_sequence
              || pDecl->getNodeType() == NT_instantiated_struct) )
        {
            return pDeclaration;
        }
        if ( (pDeclaration->getNodeType() == NT_interface)
             && (pDecl->getNodeType() == NT_interface)
             && !(static_cast<AstInterface*>(pDeclaration)->isDefined()) )
        {
            m_declarations.push_back(pDecl);
            return pDecl;
        }
        if ( (NT_service == m_nodeType) &&
             ( ((pDecl->getNodeType() == NT_interface_member)
                && (pDeclaration->getNodeType() == NT_interface)) ||
               ((pDecl->getNodeType() == NT_service_member)
                && (pDeclaration->getNodeType() == NT_service)) )
            )
        {
            m_declarations.push_back(pDecl);
            return pDecl;
        }

        ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(this), pDecl);
        return nullptr;
    }

    m_declarations.push_back(pDecl);
    return pDecl;
}

sal_uInt16 AstScope::getNodeCount(NodeType nodeType) const
{
    return static_cast<sal_uInt16>(std::count_if(getIteratorBegin(), getIteratorEnd(),
        [&nodeType](const AstDeclaration* pDecl) { return pDecl->getNodeType() == nodeType; }));
}

AstDeclaration* AstScope::lookupByName(const OString& scopedName)
{
    AstDeclaration* pDecl = nullptr;
    AstScope*       pScope = nullptr;
    if (scopedName.isEmpty())
        return nullptr;

    // If name starts with "::" start look up in global scope
    if ( isGlobal(scopedName) )
    {
        pDecl = scopeAsDecl(this);
        if ( !pDecl )
            return nullptr;

        pScope = pDecl->getScope();
        // If this is the global scope ...
        if ( !pScope )
        {
            // look up the scopedName part after "::"
            OString subName = scopedName.copy(2);
            pDecl = lookupByName(subName);
            return pDecl;
            //return pScope->lookupByName();
        }
        // OK, not global scope yet, so simply iterate with parent scope
        pDecl = pScope->lookupByName(scopedName);
        return pDecl;
    }

    // The name does not start with "::"
    // Look up in the local scope and start with the first scope
    sal_Int32 nIndex = scopedName.indexOf(':');
    OString firstScope =  nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
    bool    bFindFirstScope = true;
    pDecl = lookupByNameLocal(firstScope);
    if ( !pDecl )
    {
        bFindFirstScope = false;

        // OK, not found. Go down parent scope chain
        pDecl = scopeAsDecl(this);
        if ( pDecl )
        {
            pScope = pDecl->getScope();
            if ( pScope )
                   pDecl = pScope->lookupByName(scopedName);
            else
                pDecl = nullptr;

             // Special case for scope which is an interface. We
             // have to look in the inherited interfaces as well.
            if ( !pDecl && m_nodeType == NT_interface )
                pDecl = lookupInInherited(scopedName);
        }
    }

    if ( !bFindFirstScope || (firstScope == scopedName) )
        return pDecl;

    sal_Int32 i = 0;
    sal_Int32 nOffset = 2;
    do
    {
        pScope = declAsScope(pDecl);
        if( pScope )
        {
            pDecl = pScope->lookupByNameLocal(o3tl::getToken(scopedName, nOffset, ':', i ));
            nOffset = 1;
        }
        if( !pDecl )
            break;
    } while( i != -1 );

    if ( !pDecl )
    {
        // last try if is not the global scope and the scopeName isn't specify global too
        pDecl = scopeAsDecl(this);
        if ( pDecl && !pDecl->getLocalName().isEmpty() )
        {
            pScope = pDecl->getScope();
            if ( pScope )
                pDecl = pScope->lookupByName(scopedName);
        } else
        {
            pDecl = nullptr;
        }
    }

    return pDecl;
}

AstDeclaration* AstScope::lookupByNameLocal(std::string_view name) const
{
    for (auto const& declaration : m_declarations)
    {
        if ( declaration->getLocalName() == name )
            return declaration;
    }
    return nullptr;
}

AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
{
    const AstInterface* pInterface = dynamic_cast<const AstInterface*>(this);

    if ( !pInterface )
        return nullptr;

    // Can't look in an interface which was not yet defined
    if ( !pInterface->getScope() )
    {
        ErrorHandler::forwardLookupError(pInterface, scopedName);
    }

    // OK, loop through inherited interfaces. Stop when you find it
    for (auto const& elem : pInterface->getAllInheritedInterfaces())
    {
        AstInterface const * resolved = elem.getResolved();
        AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
        if ( pDecl )
            return pDecl;
        pDecl = resolved->lookupInInherited(scopedName);
        if ( pDecl )
            return pDecl;
    }
    // Not found
    return nullptr;
}

AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
{
    AstDeclaration* pDecl = nullptr;
    AstScope*       pScope = nullptr;
    OString         typeName;
    pDecl = scopeAsDecl(this);
    if ( !pDecl )
        return nullptr;
    pScope = pDecl->getScope();
    if ( pScope)
        return pScope->lookupPrimitiveType(type);

    switch (type)
    {
        case ET_none:
            OSL_ASSERT(false);
            break;
        case ET_short:
            typeName = OString("short");
            break;
        case ET_ushort:
            typeName = OString("unsigned short");
            break;
        case ET_long:
            typeName = OString("long");
            break;
        case ET_ulong:
            typeName = OString("unsigned long");
            break;
        case ET_hyper:
            typeName = OString("hyper");
            break;
        case ET_uhyper:
            typeName = OString("unsigned hyper");
            break;
        case ET_float:
            typeName = OString("float");
            break;
        case ET_double:
            typeName = OString("double");
            break;
        case ET_char:
            typeName = OString("char");
            break;
        case ET_byte:
            typeName = OString("byte");
            break;
        case ET_boolean:
            typeName = OString("boolean");
            break;
        case ET_any:
            typeName = OString("any");
            break;
        case ET_void:
            typeName = OString("void");
            break;
        case ET_type:
            typeName = OString("type");
            break;
        case ET_string:
            typeName = OString("string");
            break;
    }

    pDecl = lookupByNameLocal(typeName);

    if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
    {
        AstBaseType* pBaseType = static_cast<AstBaseType*>(pDecl);

        if ( pBaseType->getExprType() == type )
            return pDecl;
    }

    return nullptr;
}

AstDeclaration* AstScope::lookupForAdd(AstDeclaration const * pDecl) const
{
    if ( !pDecl )
        return nullptr;

    AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());

    return pRetDecl;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/astservice.cxx b/idlc/source/astservice.cxx
deleted file mode 100644
index c90ded6..0000000
--- a/idlc/source/astservice.cxx
+++ /dev/null
@@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <sal/config.h>

#include <astmember.hxx>
#include <astoperation.hxx>
#include <astservice.hxx>
#include <asttype.hxx>

bool AstService::checkLastConstructor() const {
    AstOperation const * last = static_cast< AstOperation const * >(getLast());
    for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
         ++i)
    {
        if (*i != last && (*i)->getNodeType() == NT_operation) {
            AstOperation const * ctor = static_cast< AstOperation * >(*i);
            if (ctor->isVariadic() && last->isVariadic()) {
                return true;
            }
            sal_uInt32 n = ctor->nMembers();
            if (n == last->nMembers()) {
                return std::equal(ctor->getIteratorBegin(), ctor->getIteratorEnd(), last->getIteratorBegin(),
                    [](AstDeclaration* a, AstDeclaration* b) {
                        sal_Int32 r1;
                        AstDeclaration const * t1 = deconstructAndResolveTypedefs(static_cast< AstMember * >(a)->getType(), &r1);
                        sal_Int32 r2;
                        AstDeclaration const * t2 = deconstructAndResolveTypedefs(static_cast< AstMember * >(b)->getType(), &r2);
                        return r1 == r2 && t1->getScopedName() == t2->getScopedName();
                    });
            }
        }
    }
    return false;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/aststack.cxx b/idlc/source/aststack.cxx
deleted file mode 100644
index fcddc81..0000000
--- a/idlc/source/aststack.cxx
+++ /dev/null
@@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <rtl/alloc.h>
#include <aststack.hxx>
#include <astscope.hxx>

AstStack::AstStack() {}

AstStack::~AstStack()
{
    for (AstScope* p : m_stack)
        delete p;
}

AstScope* AstStack::top()
{
    if (m_stack.empty())
        return nullptr;
    return m_stack.back();
}

AstScope* AstStack::bottom()
{
    if (m_stack.empty())
        return nullptr;
    return m_stack.front();
}

AstScope* AstStack::nextToTop()
{
    if (m_stack.size() < 2)
        return nullptr;

    return m_stack[m_stack.size() - 2];
}

AstScope* AstStack::topNonNull()
{
    for (sal_uInt32 i = m_stack.size(); i > 0; i--)
    {
        if (m_stack[i - 1])
            return m_stack[i - 1];
    }
    return nullptr;
}

AstStack* AstStack::push(AstScope* pScope)
{
    m_stack.push_back(pScope);
    return this;
}

void AstStack::pop()
{
    if (m_stack.empty())
        return;
    m_stack.pop_back();
}

void AstStack::clear() { m_stack.clear(); }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/aststruct.cxx b/idlc/source/aststruct.cxx
deleted file mode 100644
index 00ac330..0000000
--- a/idlc/source/aststruct.cxx
+++ /dev/null
@@ -1,167 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <aststruct.hxx>
#include <astmember.hxx>

#include <registry/version.h>
#include <registry/writer.hxx>

AstStruct::AstStruct(
    const OString& name, std::vector< OString > const & typeParameters,
    AstStruct const* pBaseType, AstScope* pScope)
    : AstType(NT_struct, name, pScope)
    , AstScope(NT_struct)
    , m_pBaseType(pBaseType)
{
    for (auto const& elem : typeParameters)
    {
        m_typeParameters.emplace_back(
            new AstType(NT_type_parameter, elem, nullptr));
    }
}

AstStruct::AstStruct(const NodeType type,
                        const OString& name,
                       AstStruct const* pBaseType,
                     AstScope* pScope)
    : AstType(type, name, pScope)
    , AstScope(type)
    , m_pBaseType(pBaseType)
{
}

AstStruct::~AstStruct()
{
}

AstDeclaration const * AstStruct::findTypeParameter(std::string_view name)
    const
{
    for (auto const& elem : m_typeParameters)
    {
        if (elem->getLocalName() == name) {
            return elem.get();
        }
    }
    return nullptr;
}

bool AstStruct::isType() const {
    return getNodeType() == NT_struct
        ? getTypeParameterCount() == 0 : AstDeclaration::isType();
}

bool AstStruct::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    if (m_typeParameters.size() > SAL_MAX_UINT16) {
        fprintf(
            stderr,
            ("%s: polymorphic struct type template %s has too many type"
             " parameters\n"),
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr());
        return false;
    }

    sal_uInt16 nMember = getNodeCount(NT_member);

    RTTypeClass typeClass = RT_TYPE_STRUCT;
    if ( getNodeType() == NT_exception )
        typeClass = RT_TYPE_EXCEPTION;

    typereg::Writer aBlob(
        (m_typeParameters.empty() && !m_bPublished
         ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1),
        getDocumentation(), "", typeClass, m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8),
        m_pBaseType == nullptr ? 0 : 1, nMember, 0,
        static_cast< sal_uInt16 >(m_typeParameters.size()));
    if (m_pBaseType != nullptr) {
        aBlob.setSuperTypeName(
            0,
            OStringToOUString(
                m_pBaseType->getRelativName(), RTL_TEXTENCODING_UTF8));
    }

    if ( nMember > 0 )
    {
        DeclList::const_iterator iter = getIteratorBegin();
        DeclList::const_iterator end = getIteratorEnd();
        AstMember*  pMember = nullptr;
        sal_uInt16  index = 0;
        while ( iter != end )
        {
            AstDeclaration* pDecl = *iter;
            if ( pDecl->getNodeType() == NT_member )
            {
                pMember = static_cast<AstMember*>(pDecl);
                RTFieldAccess flags = RTFieldAccess::READWRITE;
                OString typeName;
                if (pMember->getType()->getNodeType() == NT_type_parameter) {
                    flags |= RTFieldAccess::PARAMETERIZED_TYPE;
                    typeName = pMember->getType()->getLocalName();
                } else {
                    typeName = pMember->getType()->getRelativName();
                }
                aBlob.setFieldData(
                    index++, pMember->getDocumentation(), "", flags,
                    OStringToOUString(
                        pMember->getLocalName(), RTL_TEXTENCODING_UTF8),
                    OStringToOUString(typeName, RTL_TEXTENCODING_UTF8),
                    RTConstValue());
            }
            ++iter;
        }
    }

    sal_uInt16 index = 0;
    for (auto const& elem : m_typeParameters)
    {
        aBlob.setReferenceData(
            index++, "", RTReferenceType::TYPE_PARAMETER, RTFieldAccess::INVALID,
            OStringToOUString(
                elem->getLocalName(), RTL_TEXTENCODING_UTF8));
    }

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue("", RegValueType::BINARY,
                            const_cast<RegValue>(pBlob), aBlobSize) != RegError::NO_ERROR)
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return false;
    }

    return true;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/aststructinstance.cxx b/idlc/source/aststructinstance.cxx
deleted file mode 100644
index 8787457..0000000
--- a/idlc/source/aststructinstance.cxx
+++ /dev/null
@@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <aststructinstance.hxx>

#include <asttype.hxx>
#include <idlctypes.hxx>

#include <rtl/strbuf.hxx>
#include <rtl/string.hxx>

namespace {

OString createName(
    AstType const * typeTemplate, DeclList const * typeArguments)
{
    OStringBuffer buf(64);
    buf.append(typeTemplate->getScopedName());
    if (typeArguments != nullptr) {
        buf.append('<');
        for (DeclList::const_iterator i(typeArguments->begin());
             i != typeArguments->end(); ++i)
        {
            if (i != typeArguments->begin()) {
                buf.append(',');
            }
            if (*i != nullptr) {
                buf.append((*i)->getScopedName());
            }
        }
        buf.append('>');
    }
    return buf.makeStringAndClear();
}

}

AstStructInstance::AstStructInstance(
    AstType const * typeTemplate, DeclList const * typeArguments,
    AstScope * scope):
    AstType(
        NT_instantiated_struct, createName(typeTemplate, typeArguments), scope),
    m_typeTemplate(typeTemplate), m_typeArguments(*typeArguments)
{}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/attributeexceptions.hxx b/idlc/source/attributeexceptions.hxx
deleted file mode 100644
index 82ce1cf1..0000000
--- a/idlc/source/attributeexceptions.hxx
+++ /dev/null
@@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_IDLC_SOURCE_ATTRIBUTEEXCEPTIONS_HXX
#define INCLUDED_IDLC_SOURCE_ATTRIBUTEEXCEPTIONS_HXX

#include <rtl/ustring.hxx>

struct AttributeExceptions
{
    struct Part
    {
        OUString const* documentation;
        DeclList const* exceptions;
    };
    Part get;
    Part set;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/errorhandler.cxx b/idlc/source/errorhandler.cxx
deleted file mode 100644
index aa2de56..0000000
--- a/idlc/source/errorhandler.cxx
+++ /dev/null
@@ -1,583 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <errorhandler.hxx>
#include <astinterface.hxx>

static const char* errorCodeToMessage(ErrorCode eCode)
{
    switch (eCode)
    {
    case ErrorCode::SyntaxError:
        return "";
    case ErrorCode::RedefScope:
        return "illegal redefinition in scope ";
    case ErrorCode::CoercionFailure:
        return "coercion failure ";
    case ErrorCode::ScopeConflict:
        return "definition scope is different than fwd declare scope, ";
    case ErrorCode::IllegalAdd:
        return "illegal add operation, ";
    case ErrorCode::IllegalRaises:
        return "non-exception type in raises(..) clause, ";
    case ErrorCode::CantInherit:
        return "cannot inherit ";
    case ErrorCode::IdentNotFound:
        return "error in lookup of symbol: ";
    case ErrorCode::CannotInheritFromForward:
        return "";
    case ErrorCode::ExpectedConstant:
        return "constant expected: ";
    case ErrorCode::Eval:
        return "expression evaluation error: ";
    case ErrorCode::ForwardDeclLookup:
        return "";
    case ErrorCode::RecursiveType:
        return "illegal recursive use of type: ";
    case ErrorCode::NotAType:
        return "specified symbol is not a type: ";
    case ErrorCode::InterfaceMemberLookup:
        return "error in lookup of symbol, expected interface is not defined and no forward exists: ";
    case ErrorCode::ServiceMemberLookup:
        return "error in lookup of symbol, expected service is not defined: ";
    case ErrorCode::DefinedAttributeFlag:
        return "flag is already set: ";
    case ErrorCode::WrongAttributeKeyword:
        return "keyword not allowed: ";
    case ErrorCode::MissingAttributeKeyword:
        return "missing keyword: ";
    case ErrorCode::BadAttributeFlags:
        return
            "the 'attribute' flag is mandatory, and only the 'bound' and"
            " 'readonly' optional flags are accepted: ";
    case ErrorCode::ExpectedOptional:
        return "only the 'optional' flag is accepted: ";
    case ErrorCode::MixedInheritance:
        return "interface inheritance declarations cannot appear in both an"
            " interface's header and its body";
    case ErrorCode::DoubleInheritance:
        return
            "interface is (directly or indirectly) inherited more than once: ";
    case ErrorCode::DoubleMember:
        return
            "member is (directly or indirectly) declared more than once: ";
    case ErrorCode::ConstructorParameterNotIn:
        return
            "a service constructor parameter may not be an out or inout"
            " parameter";
    case ErrorCode::ConstructorRestParameterNotFirst:
        return
            "no parameters may precede a rest parameter in a service"
            " constructor";
    case ErrorCode::RestParameterNotLast:
        return "no parameters may follow a rest parameter";
    case ErrorCode::RestParameterNotAny:
        return "a rest parameter must be of type any";
    case ErrorCode::MethodHasRestParameter:
        return "a rest parameter may not be used on an interface method";
    case ErrorCode::ReadOnlyAttributeSetExceptions:
        return "a readonly attribute may not have a setter raises clause";
    case ErrorCode::UnsignedTypeArgument:
        return "an unsigned type cannot be used as a type argument";
    case ErrorCode::WrongNumberOfTypeArguments:
        return
            "the number of given type arguments does not match the expected"
            " number of type parameters";
    case ErrorCode::InstantiatedStructTypeTypedef:
        return
            "an instantiated polymorphic struct type cannot be used in a"
            " typedef";
    case ErrorCode::IdenticalTypeParameters:
        return "two type parameters have the same name";
    case ErrorCode::StructTypeTemplateWithBase:
        return "a polymorphic struct type template may not have a base type";
    case ErrorCode::PublishedForward:
        return
            "a published forward declaration of an interface type cannot be"
            " followed by an unpublished declaration of that type";
    case ErrorCode::PublishedusesUnpublished:
        return
            "an unpublished entity cannot be used in the declaration of a"
            " published entity: ";
    case ErrorCode::SimilarConstructors:
        return "two constructors have identical lists of parameter types";
    }
    return "unknown error";
}

static const char* warningCodeToMessage(WarningCode wCode)
{
    switch (wCode)
    {
    case WarningCode::WrongNamingConvention:
        return "type or identifier doesn't fulfill the UNO naming convention: ";
    }
    return "unknown warning";
}

static const char* parseStateToMessage(ParseState state)
{
    switch (state)
    {
    case PS_NoState:
        return "Statement can not be parsed";
    case PS_TypeDeclSeen:
        return "Malformed type declaration";
    case PS_ConstantDeclSeen:
        return "Malformed const declaration";
    case PS_ExceptionDeclSeen:
        return "Malformed exception declaration";
    case PS_InterfaceDeclSeen:
        return "Malformed interface declaration";
    case PS_ServiceDeclSeen:
        return "Malformed service declaration";
    case PS_ModuleDeclSeen:
        return "Malformed module declaration";
    case PS_AttributeDeclSeen:
        return "Malformed attribute declaration";
    case PS_PropertyDeclSeen:
        return "Malformed property declaration";
    case PS_OperationDeclSeen:
        return "Malformed operation declaration";
    case PS_InterfaceInheritanceDeclSeen:
        return "Malformed interface inheritance declaration";
    case PS_ConstantsDeclSeen:
        return "Malformed constants declaration";
    case PS_ServiceSeen:
        return "Missing service identifier following SERVICE keyword";
    case PS_ServiceIDSeen:
        return "Missing '{' or illegal syntax following service identifier";
    case PS_ServiceSqSeen:
        return "Illegal syntax following service '{' opener";
    case PS_ServiceBodySeen:
        return "Illegal syntax following service '}' closer";
    case PS_ServiceMemberSeen:
        return "Illegal syntax following service member declaration";
    case PS_ServiceIFHeadSeen:
        return "Illegal syntax following header of an interface member";
    case PS_ServiceSHeadSeen:
        return "Illegal syntax following header of a service member";
    case PS_ModuleSeen:
        return "Missing module identifier following MODULE keyword";
    case PS_ModuleIDSeen:
        return "Missing '{' or illegal syntax following module identifier";
    case PS_ModuleSqSeen:
        return "Illegal syntax following module '{' opener";
    case PS_ModuleQsSeen:
        return "Illegal syntax following module '}' closer";
    case PS_ModuleBodySeen:
        return "Illegal syntax following module export(s)";
    case PS_ConstantsSeen:
        return "Missing constants identifier following CONSTANTS keyword";
    case PS_ConstantsIDSeen:
        return "Missing '{' or illegal syntax following constants identifier";
    case PS_ConstantsSqSeen:
        return "Illegal syntax following module '{' opener";
    case PS_ConstantsQsSeen:
        return "Illegal syntax following module '}' closer";
    case PS_ConstantsBodySeen:
        return "Illegal syntax following constants export(s)";
    case PS_InterfaceSeen:
        return "Missing interface identifier following INTERFACE keyword";
    case PS_InterfaceIDSeen:
        return "Illegal syntax following interface identifier";
    case PS_InterfaceHeadSeen:
        return "Illegal syntax following interface head";
    case PS_InheritSpecSeen:
        return "Missing '{' or illegal syntax following inheritance spec";
    case PS_ForwardDeclSeen:
        return "Missing ';' following forward interface declaration";
    case PS_InterfaceSqSeen:
        return "Illegal syntax following interface '{' opener";
    case PS_InterfaceQsSeen:
        return "Illegal syntax following interface '}' closer";
    case PS_InterfaceBodySeen:
        return "Illegal syntax following interface export(s)";
    case PS_InheritColonSeen:
        return "Illegal syntax following ':' starting inheritance list";
    case PS_SNListCommaSeen:
        return "Found illegal scoped name in scoped name list";
    case PS_ScopedNameSeen:
        return "Missing ',' following scoped name in scoped name list";
    case PS_SN_IDSeen:
        return "Illegal component in scoped name";
    case PS_ScopeDelimSeen:
        return "Illegal component in scoped name following '::'";
    case PS_ConstSeen:
        return "Missing type or illegal syntax following CONST keyword";
    case PS_ConstTypeSeen:
        return "Missing identifier or illegal syntax following const type";
    case PS_ConstIDSeen:
        return "Missing '=' or illegal syntax after const identifier";
    case PS_ConstAssignSeen:
        return "Missing value expr or illegal syntax following '='";
    case PS_ConstExprSeen:
        return "Missing ';' or illegal syntax following value expr in const";
    case PS_TypedefSeen:
        return "Missing type or illegal syntax following TYPEDEF keyword";
    case PS_TypeSpecSeen:
        return "Missing declarators or illegal syntax following type spec";
    case PS_DeclaratorsSeen:
        return "Illegal syntax following declarators in TYPEDEF declaration";
    case PS_StructSeen:
        return "Missing struct identifier following STRUCT keyword";
    case PS_StructHeaderSeen:
        return "Missing '{' or illegal syntax following struct inheritance spec";
    case PS_StructIDSeen:
        return "Missing '{' or illegal syntax following struct identifier";
    case PS_StructSqSeen:
        return "Illegal syntax following struct '{' opener";
    case PS_StructQsSeen:
        return "Illegal syntax following struct '}' closer";
    case PS_StructBodySeen:
        return "Illegal syntax following struct member(s)";
    case PS_MemberTypeSeen:
        return "Illegal syntax or missing identifier following member type";
    case PS_MemberDeclsSeen:
        return "Illegal syntax following member declarator(s)";
    case PS_MemberDeclsCompleted:
        return "Missing ',' between member decls of same type(?)";
    case PS_EnumSeen:
        return "Illegal syntax or missing identifier following ENUM keyword";
    case PS_EnumIDSeen:
        return "Illegal syntax or missing '{' following enum identifier";
    case PS_EnumSqSeen:
        return "Illegal syntax following enum '{' opener";
    case PS_EnumQsSeen:
        return "Illegal syntax following enum '}' closer";
    case PS_EnumBodySeen:
        return "Illegal syntax following enum enumerator(s)";
    case PS_EnumCommaSeen:
        return "Illegal syntax or missing identifier following ',' in enum";
    case PS_SequenceSeen:
        return "Illegal syntax or missing '<' following SEQUENCE keyword";
    case PS_SequenceSqSeen:
        return "Illegal syntax or missing type following '<' in sequence";
    case PS_SequenceQsSeen:
        return "Illegal syntax following '>' in sequence";
    case PS_SequenceTypeSeen:
        return "Illegal syntax following sequence type declaration";
    case PS_FlagHeaderSeen:
        return "Illegal syntax after flags";
    case PS_AttrSeen:
        return "Illegal syntax after ATTRIBUTE keyword";
    case PS_AttrTypeSeen:
        return "Illegal syntax after type in attribute declaration";
    case PS_AttrCompleted:
        return "Illegal syntax after attribute declaration";
    case PS_ReadOnlySeen:
        return "Illegal syntax after READONLY keyword";
    case PS_OptionalSeen:
        return "Illegal syntax after OPTIONAL keyword";
    case PS_MayBeVoidSeen:
        return "Illegal syntax after MAYBEVOID keyword";
    case PS_BoundSeen:
        return "Illegal syntax after BOUND keyword";
    case PS_ConstrainedSeen:
        return "Illegal syntax after CONSTRAINED keyword";
    case PS_TransientSeen:
        return "Illegal syntax after TRANSIENT keyword";
    case PS_MayBeAmbiguousSeen:
        return "Illegal syntax after MAYBEAMBIGUOUS keyword";
    case PS_MayBeDefaultSeen:
        return "Illegal syntax after MAYBEDEFAULT keyword";
    case PS_RemoveableSeen:
        return "Illegal syntax after REMOVABLE keyword";
    case PS_PropertySeen:
        return "Illegal syntax after PROPERTY keyword";
    case PS_PropertyTypeSeen:
        return "Illegal syntax after type in property declaration";
    case PS_PropertyCompleted:
        return "Illegal syntax after property declaration";
    case PS_ExceptSeen:
        return "Illegal syntax or missing identifier after EXCEPTION keyword";
    case PS_ExceptHeaderSeen:
        return "Missing '{' or illegal syntax following exception inheritance spec";
    case PS_ExceptIDSeen:
        return "Illegal syntax or missing '{' after exception identifier";
    case PS_ExceptSqSeen:
        return "Illegal syntax after exception '{' opener";
    case PS_ExceptQsSeen:
        return "Illegal syntax after exception '}' closer";
    case PS_ExceptBodySeen:
        return "Illegal syntax after exception member(s)";
    case PS_OpTypeSeen:
        return "Illegal syntax or missing identifier after operation type";
    case PS_OpIDSeen:
        return "Illegal syntax or missing '(' after operation identifier";
    case PS_OpParsCompleted:
        return "Illegal syntax after operation parameter list";
    case PS_OpSqSeen:
        return "Illegal syntax after operation parameter list '(' opener";
    case PS_OpQsSeen:
        return "Illegal syntax after operation parameter list ')' closer";
    case PS_OpParCommaSeen:
        return "Illegal syntax or missing direction in parameter declaration";
    case PS_OpParDirSeen:
        return "Illegal syntax or missing type in parameter declaration";
    case PS_OpParTypeSeen:
        return "Illegal syntax or missing declarator in parameter declaration";
    case PS_OpParDeclSeen:
        return "Illegal syntax following parameter declarator";
    case PS_RaiseSeen:
        return "Illegal syntax or missing '(' after RAISES keyword";
    case PS_RaiseSqSeen:
        return "Illegal syntax after RAISES '(' opener";
    case PS_RaiseQsSeen:
        return "Illegal syntax after RAISES ')' closer";
    case PS_DeclsCommaSeen:
        return "Illegal syntax after ',' in declarators list";
    case PS_DeclsDeclSeen:
        return "Illegal syntax after declarator in declarators list";
    default:
        return "no wider described syntax error";
    }
}

static OString flagToString(sal_uInt32 flag)
{
    OString flagStr;
    if ( (flag & AF_READONLY) == AF_READONLY )
        flagStr += "'readonly'";
    if ( (flag & AF_OPTIONAL) == AF_OPTIONAL )
        flagStr += "'optional'";
    if ( (flag & AF_MAYBEVOID) == AF_MAYBEVOID )
        flagStr += "'maybevoid'";
    if ( (flag & AF_BOUND) == AF_BOUND )
        flagStr += "'bound'";
    if ( (flag & AF_CONSTRAINED) == AF_CONSTRAINED )
        flagStr += "'constrained'";
    if ( (flag & AF_TRANSIENT) == AF_TRANSIENT )
            flagStr += "'transient'";
    if ( (flag & AF_MAYBEAMBIGUOUS) == AF_MAYBEAMBIGUOUS )
        flagStr += "'maybeambiguous'";
    if ( (flag & AF_MAYBEDEFAULT) == AF_MAYBEDEFAULT )
        flagStr += "'maybedefault'";
    if ( (flag & AF_REMOVABLE) == AF_REMOVABLE )
        flagStr += "'removable'";
    if ( (flag & AF_ATTRIBUTE) == AF_ATTRIBUTE )
        flagStr += "'attribute'";
    if ( (flag & AF_PROPERTY) == AF_PROPERTY )
        flagStr += "'property'";
    if ( flagStr.isEmpty() )
        flagStr += "'unknown'";

    return flagStr;
}

static void errorHeader(ErrorCode eCode, sal_Int32 lineNumber, sal_uInt32 start, sal_uInt32 end)
{
    OString file;
    if ( idlc()->getFileName() == idlc()->getRealFileName() )
        file = idlc()->getMainFileName();
    else
        file = idlc()->getFileName();

    fprintf(stderr, "%s:%" SAL_PRIdINT64 " [%" SAL_PRIdINT64 ":%" SAL_PRIdINT64 "] : %s", file.getStr(),
            sal_Int64(lineNumber),
            sal_Int64(start),
            sal_Int64(end),
            errorCodeToMessage(eCode));
}

static void errorHeader(ErrorCode eCode, sal_uInt32 lineNumber)
{
    errorHeader(eCode, lineNumber,
            idlc()->getOffsetStart(), idlc()->getOffsetEnd());
}

static void errorHeader(ErrorCode eCode)
{
    errorHeader(eCode, idlc()->getLineNumber(),
            idlc()->getOffsetStart(), idlc()->getOffsetEnd());
}

static void warningHeader(WarningCode wCode)
{
    OString file;
    if ( idlc()->getFileName() == idlc()->getRealFileName() )
        file = idlc()->getMainFileName();
    else
        file = idlc()->getFileName();

    fprintf(stderr, "%s(%" SAL_PRIdINT64 ") : WARNING, %s", file.getStr(),
            sal_Int64(idlc()->getLineNumber()),
            warningCodeToMessage(wCode));
}

void ErrorHandler::error0(ErrorCode e)
{
    errorHeader(e);
    fprintf(stderr, "\n");
    idlc()->incErrorCount();
}

void ErrorHandler::error1(ErrorCode e, AstDeclaration const * d)
{
    errorHeader(e);
    fprintf(stderr, "'%s'\n", d->getScopedName().getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::error2(
    ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2)
{
    errorHeader(e);
    fprintf(stderr, "'%s', '%s'\n", d1->getScopedName().getStr(),
            d2->getScopedName().getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::error3(ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2, AstDeclaration const * d3)
{
    errorHeader(e);
    fprintf(stderr, "'%s', '%s', '%s'\n", d1->getScopedName().getStr(),
            d2->getScopedName().getStr(), d3->getScopedName().getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::warning0(WarningCode w, const char* warningmsg)
{
    if ( idlc()->getOptions()->isValid("-w") || idlc()->getOptions()->isValid("-we") ) {
        warningHeader(w);
        fprintf(stderr, "%s\n", warningmsg);
    }

    if ( idlc()->getOptions()->isValid("-we") )
        idlc()->incErrorCount();
    else
        idlc()->incWarningCount();
}

void ErrorHandler::syntaxError(ParseState ps, sal_Int32 lineNumber, const char* errmsg)
{
    errorHeader(ErrorCode::SyntaxError, lineNumber);
    fprintf(stderr, "%s: %s\n", parseStateToMessage(ps), errmsg);
    idlc()->incErrorCount();
}

void ErrorHandler::coercionError(AstExpression *pExpr, ExprType et)
{
    errorHeader(ErrorCode::CoercionFailure);
    fprintf(stderr, "'%s' to '%s'\n", pExpr->toString().getStr(),
            exprTypeToString(et));
    idlc()->incErrorCount();
}

void ErrorHandler::lookupError(const OString& n)
{
    errorHeader(ErrorCode::IdentNotFound);
    fprintf(stderr, "'%s'\n", n.getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::lookupError(ErrorCode e, const OString& n, AstDeclaration const * pScope)
{
    errorHeader(e);
    fprintf(stderr, "'%s' in '%s'\n", n.getStr(), pScope->getFullName().getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::flagError(ErrorCode e, sal_uInt32 flag)
{
    errorHeader(e);
    fprintf(stderr, "'%s'\n", flagToString(flag).getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::noTypeError(AstDeclaration const * pDecl)
{
    errorHeader(ErrorCode::NotAType);
    fprintf(stderr, "'%s'\n", pDecl->getScopedName().getStr());
    idlc()->incErrorCount();
}

namespace {

char const * nodeTypeName(NodeType nodeType) {
    switch (nodeType) {
    case NT_interface:
        return "interface";

    case NT_exception:
        return "exception";

    case NT_struct:
        return "struct";

    default:
        return "";
    }
}

}

void ErrorHandler::inheritanceError(NodeType nodeType, const OString* name, AstDeclaration const * pDecl)
{
    if ( nodeType == NT_interface &&
         (pDecl->getNodeType() == NT_interface) &&
         !(static_cast<AstInterface const *>(pDecl)->isDefined()) )
    {
        errorHeader(ErrorCode::CannotInheritFromForward);
        fprintf(stderr, "interface '%s' cannot inherit from forward declared interface '%s'\n",
                name->getStr(), pDecl->getScopedName().getStr());
    } else
    {
        errorHeader(ErrorCode::CantInherit);
        fprintf(stderr, "%s '%s' from '%s'\n",
                nodeTypeName(nodeType), name->getStr(),
                pDecl->getScopedName().getStr());
    }
    idlc()->incErrorCount();
}

void ErrorHandler::forwardLookupError(const AstDeclaration* pForward,
                                      const OString& name)
{
    errorHeader(ErrorCode::ForwardDeclLookup);
    fprintf(stderr, "trying to look up '%s' in undefined forward declared interface '%s'\n",
            pForward->getScopedName().getStr(), name.getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::constantExpected(AstDeclaration const * pDecl,
                                    const OString& name)
{
    errorHeader(ErrorCode::ExpectedConstant);
    fprintf(stderr, "'%s' is bound to '%s'\n", name.getStr(), pDecl->getScopedName().getStr());
    idlc()->incErrorCount();
}

void ErrorHandler::evalError(AstExpression* pExpr)
{
    errorHeader(ErrorCode::Eval);
    fprintf(stderr, "'%s'\n", pExpr->toString().getStr());
    idlc()->incErrorCount();
}

bool ErrorHandler::checkPublished(AstDeclaration const * decl, bool bOptional) {
    if (idlc()->isPublished() && !decl->isPublished() && !bOptional) {
        error1(ErrorCode::PublishedusesUnpublished, decl);
        return false;
    } else {
        return true;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/fehelper.cxx b/idlc/source/fehelper.cxx
deleted file mode 100644
index 607f5a1..0000000
--- a/idlc/source/fehelper.cxx
+++ /dev/null
@@ -1,102 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <fehelper.hxx>
#include <errorhandler.hxx>
#include <idlc.hxx>

FeDeclarator::FeDeclarator(const OString& name)
    : m_name(name)
{
}

FeDeclarator::~FeDeclarator()
{
}

bool FeDeclarator::checkType(AstDeclaration const * type) const
{
    OString tmp(m_name);
    sal_Int32 count = m_name.lastIndexOf( ':' );
    if( count != -1 )
        tmp = m_name.copy( count+1 );

    return tmp != type->getLocalName();
}

AstType const * FeDeclarator::compose(AstDeclaration const * pDecl)
{
    if ( pDecl == nullptr )
    {
        return nullptr;
    }
    if ( !pDecl->isType() )
    {
        ErrorHandler::noTypeError(pDecl);
        return nullptr;
    }
    return static_cast<const AstType*>(pDecl);
}

FeInheritanceHeader::FeInheritanceHeader(
    NodeType nodeType, OString* pName, OString const * pInherits,
    std::vector< OString > const * typeParameters)
    : m_nodeType(nodeType)
    , m_pName(pName)
    , m_pInherits(nullptr)
{
    if (typeParameters != nullptr) {
        m_typeParameters = *typeParameters;
    }
    initializeInherits(pInherits);
}

void FeInheritanceHeader::initializeInherits(OString const * pInherits)
{
    if ( !pInherits )
        return;

    AstScope* pScope = idlc()->scopes()->topNonNull();
    AstDeclaration* pDecl = pScope->lookupByName(*pInherits);
    if ( pDecl )
    {
        AstDeclaration const * resolved = resolveTypedefs(pDecl);
        if ( resolved->getNodeType() == getNodeType()
             && (resolved->getNodeType() != NT_interface
                 || static_cast< AstInterface const * >(
                     resolved)->isDefined()) )
        {
            if ( ErrorHandler::checkPublished( pDecl ) )
            {
                m_pInherits = pDecl;
            }
        }
        else
        {
            ErrorHandler::inheritanceError(
                getNodeType(), getName(), pDecl);
        }
    }
    else
    {
        ErrorHandler::lookupError(*pInherits);
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/idlc.cxx b/idlc/source/idlc.cxx
deleted file mode 100644
index ca47b34..0000000
--- a/idlc/source/idlc.cxx
+++ /dev/null
@@ -1,400 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <idlc.hxx>
#include <errorhandler.hxx>
#include <astscope.hxx>
#include <astmodule.hxx>
#include <astservice.hxx>
#include <astconstants.hxx>
#include <astexception.hxx>
#include <astenum.hxx>
#include <astinterface.hxx>
#include <astoperation.hxx>
#include <astbasetype.hxx>
#include <astdeclaration.hxx>
#include <astparameter.hxx>
#include <astsequence.hxx>
#include <asttype.hxx>
#include <asttypedef.hxx>

#include <osl/diagnose.h>
#include <osl/file.hxx>
#include <osl/thread.h>

#include <algorithm>

AstDeclaration* scopeAsDecl(AstScope* pScope)
{
    if (pScope == nullptr) return nullptr;

    switch( pScope->getScopeNodeType() )
    {
        case NT_service:
        case NT_singleton:
            return static_cast<AstService*>(pScope);
        case NT_module:
        case NT_root:
            return static_cast<AstModule*>(pScope);
        case NT_constants:
            return static_cast<AstConstants*>(pScope);
        case NT_interface:
            return static_cast<AstInterface*>(pScope);
        case NT_operation:
            return static_cast<AstOperation*>(pScope);
        case NT_exception:
            return static_cast<AstException*>(pScope);
        case NT_struct:
            return static_cast<AstStruct*>(pScope);
        case NT_enum:
            return static_cast<AstEnum*>(pScope);
        default:
            return nullptr;
    }
}

AstScope* declAsScope(AstDeclaration* pDecl)
{
    if (pDecl == nullptr) return nullptr;

    switch(pDecl->getNodeType())
    {
        case NT_interface:
            return static_cast<AstInterface*>(pDecl);
        case NT_service:
        case NT_singleton:
            return static_cast<AstService*>(pDecl);
        case NT_module:
        case NT_root:
            return static_cast<AstModule*>(pDecl);
        case NT_constants:
            return static_cast<AstConstants*>(pDecl);
        case NT_exception:
            return static_cast<AstException*>(pDecl);
        case NT_struct:
            return static_cast<AstStruct*>(pDecl);
        case NT_enum:
            return static_cast<AstEnum*>(pDecl);
        case NT_operation:
            return static_cast<AstOperation*>(pDecl);
        default:
            return nullptr;
   }
}

static void predefineXInterface(AstModule* pRoot)
{
    // define the modules  com::sun::star::uno
    AstModule* pParentScope = pRoot;
    AstModule* pModule = new AstModule("com", pParentScope);
    pModule->setPredefined(true);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule("sun", pParentScope);
    pModule->setPredefined(true);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule("star", pParentScope);
    pModule->setPredefined(true);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule("uno", pParentScope);
    pModule->setPredefined(true);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;

    // define XInterface
    AstInterface* pInterface = new AstInterface("XInterface", nullptr, pParentScope);
    pInterface->setDefined();
    pInterface->setPredefined(true);
    pInterface->setPublished();
    pParentScope->addDeclaration(pInterface);

    // define XInterface::queryInterface
    AstOperation* pOp = new AstOperation(static_cast<AstType*>(pRoot->lookupPrimitiveType(ET_any)),
                                         "queryInterface", pInterface);
    AstParameter* pParam = new AstParameter(DIR_IN, false,
                                            static_cast<AstType*>(pRoot->lookupPrimitiveType(ET_type)),
                                            "aType", pOp);
    pOp->addDeclaration(pParam);
    pInterface->addMember(pOp);

    // define XInterface::acquire
    pOp = new AstOperation(static_cast<AstType*>(pRoot->lookupPrimitiveType(ET_void)),
                           "acquire", pInterface);
    pInterface->addMember(pOp);

    // define XInterface::release
    pOp = new AstOperation(static_cast<AstType*>(pRoot->lookupPrimitiveType(ET_void)),
                           "release", pInterface);
    pInterface->addMember(pOp);
}

static void initializePredefinedTypes(AstModule* pRoot)
{
    if ( !pRoot )
         return;

    AstBaseType* pPredefined = new AstBaseType(ET_long, "long", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_ulong, "unsigned long", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_hyper, "hyper", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_uhyper, "unsigned hyper", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_short, "short", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_ushort, "unsigned short", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_float, "float", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_double, "double", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_char, "char", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_byte, "byte", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_any, "any", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_string, "string", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_type, "type", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_boolean, "boolean", pRoot);
    pRoot->addDeclaration(pPredefined);

    pPredefined = new AstBaseType(ET_void, "void", pRoot);
    pRoot->addDeclaration(pPredefined);
}

Idlc::Idlc(Options* pOptions)
    : m_pOptions(pOptions)
    , m_bIsDocValid(false)
    , m_bIsInMainfile(true)
    , m_published(false)
    , m_errorCount(0)
    , m_warningCount(0)
    , m_lineNumber(0)
    , m_offsetStart(0)
    , m_offsetEnd(0)
    , m_parseState(PS_NoState)
{
    m_pScopes.reset( new AstStack() );
    // init root object after construction
    m_pRoot = nullptr;
    m_bGenerateDoc = m_pOptions->isValid("-C");
}

Idlc::~Idlc()
{
}

void Idlc::init()
{
    m_pRoot.reset(new AstModule(NT_root, OString(), nullptr));

    // push the root node on the stack
    m_pScopes->push(m_pRoot.get());
    initializePredefinedTypes(m_pRoot.get());
    predefineXInterface(m_pRoot.get());
}

void Idlc::reset()
{
    m_bIsDocValid = false;
    m_bIsInMainfile = true;
    m_published = false;

    m_errorCount = 0;
    m_warningCount = 0;
    m_lineNumber = 0;
    m_parseState = PS_NoState;

    m_fileName.clear();
    m_mainFileName.clear();
    m_realFileName.clear();
    m_documentation.clear();

    m_pScopes->clear();
    m_pRoot.reset( new AstModule(NT_root, OString(), nullptr) );

    // push the root node on the stack
    m_pScopes->push(m_pRoot.get());
    initializePredefinedTypes(m_pRoot.get());

    m_includes.clear();
}

OUString Idlc::processDocumentation()
{
    OUString doc;
    if (m_bIsDocValid) {
        OString raw(getDocumentation());
        if (m_bGenerateDoc) {
            doc = OStringToOUString(raw, RTL_TEXTENCODING_UTF8);
        } else if (raw.indexOf("@deprecated") != -1) {
            //TODO: this check is somewhat crude
            doc = "@deprecated";
        }
    }
    return doc;
}

static void lcl_writeString(::osl::File & rFile, ::osl::FileBase::RC & o_rRC,
        OString const& rString)
{
    if (::osl::FileBase::E_None == o_rRC) {
        sal_uInt64 nWritten(0);
        o_rRC = rFile.write(rString.getStr(), rString.getLength(), nWritten);
        if (static_cast<sal_uInt64>(rString.getLength()) != nWritten) {
            o_rRC = ::osl::FileBase::E_INVAL; //?
        }
    }
}

namespace {

struct WriteDep
{
    ::osl::File& m_rFile;
    ::osl::FileBase::RC & m_rRC;
    explicit WriteDep(::osl::File & rFile, ::osl::FileBase::RC & rRC)
        : m_rFile(rFile), m_rRC(rRC) { }
    void operator() (OString const& rEntry)
    {
        lcl_writeString(m_rFile, m_rRC, " \\\n ");
        lcl_writeString(m_rFile, m_rRC, rEntry);
    }
};

// write a dummy target for one included file, so the incremental build does
// not break with "No rule to make target" if the included file is removed
struct WriteDummy
{
    ::osl::File& m_rFile;
    ::osl::FileBase::RC & m_rRC;
    explicit WriteDummy(::osl::File & rFile, ::osl::FileBase::RC & rRC)
        : m_rFile(rFile), m_rRC(rRC) { }
    void operator() (OString const& rEntry)
    {
        lcl_writeString(m_rFile, m_rRC, rEntry);
        lcl_writeString(m_rFile, m_rRC, ":\n\n");
    }
};

}

bool
Idlc::dumpDeps(std::string_view rDepFile, OString const& rTarget)
{
    ::osl::File depFile(
            OStringToOUString(rDepFile, osl_getThreadTextEncoding()));
    ::osl::FileBase::RC rc =
        depFile.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
    if (::osl::FileBase::E_None != rc) {
        return false;
    }
    lcl_writeString(depFile, rc, rTarget);
    if (::osl::FileBase::E_None != rc) {
        return false;
    }
    lcl_writeString(depFile, rc, " :");
    if (::osl::FileBase::E_None != rc) {
        return false;
    }
    m_includes.erase(getRealFileName()); // eeek, that is a temp file...
    ::std::for_each(m_includes.begin(), m_includes.end(),
            WriteDep(depFile, rc));
    lcl_writeString(depFile, rc, "\n\n");
    ::std::for_each(m_includes.begin(), m_includes.end(),
            WriteDummy(depFile, rc));
    if (::osl::FileBase::E_None != rc) {
        return false;
    }
    rc = depFile.close();
    return ::osl::FileBase::E_None == rc;
}

static Idlc* pStaticIdlc = nullptr;

Idlc* idlc()
{
    return pStaticIdlc;
}

Idlc* setIdlc(Options* pOptions)
{
    delete pStaticIdlc;
    pStaticIdlc = new Idlc(pOptions);
    pStaticIdlc->init();
    return pStaticIdlc;
}

AstDeclaration const * resolveTypedefs(AstDeclaration const * type) {
    if (type != nullptr) {
        while (type->getNodeType() == NT_typedef) {
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
        }
    }
    return type;
}

AstDeclaration const * deconstructAndResolveTypedefs(
    AstDeclaration const * type, sal_Int32 * rank)
{
    *rank = 0;
    for (;;) {
        if (type == nullptr) {
            return nullptr;
        }
        switch (type->getNodeType()) {
        case NT_typedef:
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
            break;
        case NT_sequence:
            ++(*rank);
            type = static_cast< AstSequence const * >(type)->getMemberType();
            break;
        default:
            return type;
        }
    }
}

AstInterface const * resolveInterfaceTypedefs(AstType const * type) {
    AstDeclaration const * decl = resolveTypedefs(type);
    OSL_ASSERT(decl->getNodeType() == NT_interface);
    return static_cast< AstInterface const * >(decl);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/idlccompile.cxx b/idlc/source/idlccompile.cxx
deleted file mode 100644
index 5aec209..0000000
--- a/idlc/source/idlccompile.cxx
+++ /dev/null
@@ -1,394 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <idlc.hxx>
#include <rtl/alloc.h>
#include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
#include <osl/process.h>
#include <osl/diagnose.h>
#include <osl/thread.h>
#include <osl/file.hxx>

#if defined(_WIN32)
#include <io.h>
#endif

#ifdef  SAL_UNX
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#endif

#include <string.h>

using namespace ::osl;

extern int yyparse();
extern FILE* yyin;
extern int yydebug;

static char tmpFilePattern[512];

bool isFileUrl(std::string_view fileName)
{
    return o3tl::starts_with(fileName, "file://");
}

OString convertToAbsoluteSystemPath(const OString& fileName)
{
    OUString uSysFileName;
    OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
    if ( isFileUrl(fileName) )
    {
        if (FileBase::getSystemPathFromFileURL(uFileName, uSysFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    } else
    {
        OUString uWorkingDir, uUrlFileName, uTmp;
        if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
        {
            OSL_ASSERT(false);
        }
        if (FileBase::getFileURLFromSystemPath(uFileName, uTmp)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
        if (FileBase::getAbsoluteFileURL(uWorkingDir, uTmp, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
        if (FileBase::getSystemPathFromFileURL(uUrlFileName, uSysFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    }

    return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());
}

OString convertToFileUrl(const OString& fileName)
{
    if ( !isFileUrl(fileName) )
    {
        OString tmp = convertToAbsoluteSystemPath(fileName);
        OUString uFileName(tmp.getStr(), tmp.getLength(), osl_getThreadTextEncoding());
        OUString uUrlFileName;
        if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
        return OUStringToOString(uUrlFileName, osl_getThreadTextEncoding());
    }

    return fileName;
}

static OString makeTempName(const OString& prefix)
{
    OUString uTmpPath;
    OString tmpPath;

    if ( osl_getEnvironment(OUString("TMP").pData, &uTmpPath.pData) != osl_Process_E_None )
    {
        if ( osl_getEnvironment(OUString("TEMP").pData, &uTmpPath.pData) != osl_Process_E_None )
        {
#if defined(_WIN32)
            tmpPath = OString("c:\\temp");
#else
            tmpPath = OString("/tmp");
#endif
        }
    }

    if ( !uTmpPath.isEmpty() )
        tmpPath = OUStringToOString(uTmpPath, RTL_TEXTENCODING_UTF8);

#if defined(_WIN32) || defined(SAL_UNX)

    OSL_ASSERT( sizeof(tmpFilePattern) >
                o3tl::make_unsigned( tmpPath.getLength()
                           + RTL_CONSTASCII_LENGTH( PATH_SEPARATOR )
                           + prefix.getLength()
                           + RTL_CONSTASCII_LENGTH( "XXXXXX") ) );

    tmpFilePattern[ sizeof(tmpFilePattern)-1 ] = '\0';
    strncpy(tmpFilePattern, tmpPath.getStr(), sizeof(tmpFilePattern)-1);
    strncat(tmpFilePattern, PATH_SEPARATOR, sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
    strncat(tmpFilePattern, prefix.getStr(), sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
    strncat(tmpFilePattern, "XXXXXX", sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));

#ifdef SAL_UNX
    // coverity[secure_temp] - https://communities.coverity.com/thread/3179
    int nDescriptor = mkstemp(tmpFilePattern);
    if( -1 == nDescriptor )
    {
        fprintf(stderr, "idlc: mkstemp(\"%s\") failed: %s\n", tmpFilePattern, strerror(errno));
        exit( 1 );
    }
    // the file shall later be reopened by stdio functions
    close( nDescriptor );
#else
    (void) mktemp(tmpFilePattern);
#endif
#endif

    return tmpFilePattern;
}

bool copyFile(const OString* source, const OString& target)
{
    bool bRet = true;

    FILE* pSource = source == nullptr ? stdin : fopen(source->getStr(), "rb");
    if ( !pSource )
        return false;

    FILE* pTarget = fopen(target.getStr(), "wb");
    if ( !pTarget )
    {
        fclose(pSource);
        return false;
    }

    size_t const totalSize = 512;
    char   pBuffer[totalSize + 1];

    while ( !feof(pSource) )
    {
        size_t readSize = fread(pBuffer, 1, totalSize, pSource);
        if ( readSize > 0 && !ferror(pSource) )
        {
            if ( (fwrite(pBuffer, 1, readSize, pTarget)) != readSize || ferror(pTarget) )
            {
                if (source != nullptr) {
                    fclose(pSource);
                }
                fclose(pTarget);
                return false;
            }
        }
    }

    if (source != nullptr) {
        fclose(pSource);
    }
    if ( fclose(pTarget) )
        bRet = false;

    return bRet;
}

sal_Int32 compileFile(const OString * pathname)
{
    // preprocess input file
    OString tmpFile = makeTempName("idli_");
    OString preprocFile = makeTempName("idlf_");

    OString fileName;
    if (pathname == nullptr) {
        fileName = "stdin";
    } else {
        fileName = *pathname;
    }

    if ( !copyFile(pathname, tmpFile) )
    {
          fprintf(stderr, "%s: could not copy %s%s to %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                pathname == nullptr ? "" : "file ", fileName.getStr(),
                tmpFile.getStr());
          exit(99);
    }

    idlc()->setFileName(fileName);
    idlc()->setMainFileName(fileName);
    idlc()->setRealFileName(tmpFile);

    ::std::vector< OUString> lCppArgs;
    lCppArgs.emplace_back("-DIDL");
    lCppArgs.emplace_back("-C");
#ifdef SYSTEM_UCPP_IS_GCC
    // -nostdinc Do not search the standard system directories for header files
    lCppArgs.emplace_back("-nostdinc");
    // with gcc cpp, even when not explicitly including anything, /usr/include/stdc-predef.h
    // gets inserted without -nostdinc
#else
    // -zI Do not use the standard (compile-time) include path.
    lCppArgs.emplace_back("-zI");
#endif

    Options* pOptions = idlc()->getOptions();

    OString filePath;
    sal_Int32 index = fileName.lastIndexOf(SEPARATOR);

    if ( index > 0)
    {
        filePath = fileName.copy(0, index);

        if ( !filePath.isEmpty() )
        {
            OString cppArgs = "-I" + filePath;
            lCppArgs.push_back(OStringToOUString(
                cppArgs.replace('\\', '/'),
                RTL_TEXTENCODING_UTF8));
        }
    }

    if ( pOptions->isValid("-D") )
    {
        OString dOpt = pOptions->getOption("-D");
        sal_Int32 nIndex = 0;
        do
        {
            std::string_view token = o3tl::getToken(dOpt, 0, ' ', nIndex );
            if (token.size())
                lCppArgs.push_back("-D" + OStringToOUString(token, RTL_TEXTENCODING_UTF8));
        } while( nIndex != -1 );
    }

    if ( pOptions->isValid("-I") )
    {
        OString incOpt = pOptions->getOption("-I");
        sal_Int32 nIndex = 0;
        do
        {
            std::string_view token = o3tl::getToken(incOpt, 0, ' ', nIndex );
            if (token.size())
                lCppArgs.push_back("-I" + OStringToOUString(token, RTL_TEXTENCODING_UTF8));
        } while( nIndex != -1 );
    }

    lCppArgs.emplace_back("-o");

    lCppArgs.push_back(OStringToOUString(preprocFile, RTL_TEXTENCODING_UTF8));

    lCppArgs.push_back(OStringToOUString(tmpFile, RTL_TEXTENCODING_UTF8));

    OUString cpp;
    OUString startDir;
#ifndef SYSTEM_UCPP
    if (osl_getExecutableFile(&cpp.pData) != osl_Process_E_None) {
        OSL_ASSERT(false);
    }

    sal_Int32 idx= cpp.lastIndexOf("idlc");
    cpp = cpp.copy(0, idx);

#if defined(_WIN32)
    cpp += "ucpp.exe";
#else
    cpp += "ucpp";
#endif
#else // SYSTEM_UCPP
    cpp = OUString(UCPP);
#endif
    oslProcess      hProcess = nullptr;
    oslProcessError procError = osl_Process_E_None;

    const int nCmdArgs = lCppArgs.size();
    std::unique_ptr<rtl_uString*[]> pCmdArgs(new rtl_uString*[nCmdArgs]);

    int i = 0;
    for (auto const& elem : lCppArgs)
    {
        pCmdArgs[i++] = elem.pData;
    }

    procError = osl_executeProcess( cpp.pData, pCmdArgs.get(), nCmdArgs, osl_Process_WAIT,
                                    nullptr, startDir.pData, nullptr, 0, &hProcess );

    oslProcessInfo hInfo;
    hInfo.Size = sal_uInt32(sizeof(oslProcessInfo));
    if (osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &hInfo)
        != osl_Process_E_None)
    {
        OSL_ASSERT(false);
    }

    if ( procError || (hInfo.Code != 0) )
    {
        if ( procError != osl_Process_E_None )
            fprintf(stderr, "%s: starting preprocessor failed\n", pOptions->getProgramName().getStr());
        else
            fprintf(stderr, "%s: preprocessing %s%s failed\n",
                    pOptions->getProgramName().getStr(),
                    pathname == nullptr ? "" : "file ", fileName.getStr());

        osl_freeProcessHandle(hProcess);
        exit(hInfo.Code ? hInfo.Code : 99);
    }
    osl_freeProcessHandle(hProcess);

    if (unlink(tmpFile.getStr()) != 0)
    {
        fprintf(stderr, "%s: Could not remove cpp input file %s\n",
                 pOptions->getProgramName().getStr(), tmpFile.getStr());
        exit(99);
    }

    if ( pOptions->isValid("-E") )
    {
        if (unlink(preprocFile.getStr()) != 0)
        {
            fprintf(stderr, "%s: Could not remove parser input file %s\n",
                       pOptions->getProgramName().getStr(), preprocFile.getStr());
            exit(99);
        }
        exit(0);
    }

    // parse file
    yyin = fopen(preprocFile.getStr(), "r");
    if (yyin == nullptr)
    {
        fprintf(stderr, "%s: Could not open cpp output file %s\n",
                   pOptions->getProgramName().getStr(), preprocFile.getStr());
        exit(99);
    }

    //yydebug = 0 no trace information
    //yydebug = 1 parser produce trace information
    yydebug = 0;

    yyparse();
    sal_Int32 nErrors = idlc()->getErrorCount();

    fclose(yyin);
    if (unlink(preprocFile.getStr()) != 0)
    {
        fprintf(stderr, "%s: Could not remove parser input file %s\n",
                pOptions->getProgramName().getStr(), preprocFile.getStr());
        exit(99);
    }

    return nErrors;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/idlcmain.cxx b/idlc/source/idlcmain.cxx
deleted file mode 100644
index 742dc4e..0000000
--- a/idlc/source/idlcmain.cxx
+++ /dev/null
@@ -1,164 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <idlc.hxx>
#include <sal/main.h>

#include <string.h>

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
    std::vector< std::string > args;
    for (int i = 1; i < argc; i++)
    {
        if (!Options::checkArgument (args, argv[i], strlen(argv[i])))
            return 1;
    }

    Options options(argv[0]);
    sal_Int32 nErrors = 0;

    try
    {
        if (!options.initOptions(args))
           return 0;

        setIdlc(&options);

        if (options.readStdin()) {
            if ( !options.quiet() )
                fprintf(
                    stdout, "%s: Compiling stdin\n",
                    options.getProgramName().getStr());
            nErrors = compileFile(nullptr);
            if ( ( idlc()->getWarningCount() > 0 ) && !options.quiet() ) {
                fprintf(
                    stdout, "%s: detected %lu warnings compiling stdin\n",
                    options.getProgramName().getStr(),
                    sal::static_int_cast< unsigned long >(
                        idlc()->getWarningCount()));
            }
            OString outputUrl;
            if (options.isValid("-O")) {
                outputUrl = convertToFileUrl(options.getOption("-O"));
                if (!outputUrl.endsWith("/")) {
                    outputUrl += "/";
                }
                outputUrl += "stdin.urd";
            } else {
                outputUrl = convertToFileUrl("stdin.urd");
            }
            if (nErrors > 0) {
                removeIfExists(outputUrl);
            } else {
                nErrors = produceFile(outputUrl, nullptr);
            }
            idlc()->reset();
        }
        std::vector< OString > const & files = options.getInputFiles();
        if ( options.verbose() )
        {
            fprintf( stdout, "%s: compiling %i source files ... \n",
                options.getProgramName().getStr(), static_cast<int>(files.size()) );
            fflush( stdout );
        }
        for (auto const& elem : files)
        {
            if (nErrors)
                break;
            OString sysFileName( convertToAbsoluteSystemPath(elem) );

            if ( !options.quiet() )
                fprintf(stdout, "Compiling: %s\n", elem.getStr());
            nErrors = compileFile(&sysFileName);

            if ( idlc()->getWarningCount() && !options.quiet() )
                fprintf(stdout, "%s: detected %" SAL_PRIdINT64 " warnings compiling file '%s'\n",
                        options.getProgramName().getStr(),
                        sal_Int64(idlc()->getWarningCount()),
                        elem.getStr());

            // prepare output file name
            OString const strippedFileName(
                    sysFileName.copy(sysFileName.lastIndexOf(SEPARATOR) + 1));
            OString outputFile;
            if ( options.isValid("-O") )
            {
                outputFile = options.getOption("-O");
                if (!outputFile.endsWith("/")) {
                    outputFile += "/";
                }
                outputFile += strippedFileName.replaceAt(
                        strippedFileName.getLength() -3 , 3, "urd");
            } else {
                outputFile =
                    sysFileName.replaceAt(sysFileName.getLength() -3 , 3, "urd");
            }
            OString const outputFileUrl = convertToFileUrl(outputFile);

            OString depFileUrl;
            if (options.isValid("-M")) {
                depFileUrl = convertToFileUrl(options.getOption("-M"));
                if (!depFileUrl.endsWith("/")) {
                    depFileUrl += "/";
                }
                depFileUrl += strippedFileName.replaceAt(
                        strippedFileName.getLength() -3 , 3, "d");
            }

            if ( nErrors ) {
                if (options.isValid("-M")) {
                    removeIfExists(depFileUrl);
                }
                removeIfExists(outputFileUrl);
            } else {
                sPair_t const pair(depFileUrl, outputFile);
                nErrors = produceFile(outputFileUrl,
                            (options.isValid("-M")) ? &pair : nullptr);
            }

            idlc()->reset();
        }

        if ( nErrors > 0 )
        {
            fprintf(stderr, "%s: detected %" SAL_PRIdINT64 " errors%s",
                options.getProgramName().getStr(),
                sal_Int64(nErrors),
                options.prepareVersion().getStr());
        } else
        {
            if ( options.verbose() )
                fprintf(stdout, "%s: returned successful%s",
                    options.getProgramName().getStr(),
                    options.prepareVersion().getStr());
        }
    } catch(const IllegalArgument& e)
    {
        fprintf(stderr, "Illegal argument: %s\n%s",
            e.m_message.getStr(),
            options.prepareVersion().getStr());
        return 99;
    }

    return nErrors;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/idlcproduce.cxx b/idlc/source/idlcproduce.cxx
deleted file mode 100644
index 2592fe0d..0000000
--- a/idlc/source/idlcproduce.cxx
+++ /dev/null
@@ -1,242 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <idlc.hxx>
#include <astmodule.hxx>
#include <rtl/strbuf.hxx>
#include <osl/file.hxx>
#include <osl/thread.h>
#include <o3tl/string_view.hxx>

#if defined(_WIN32)
#include <io.h>
#include <direct.h>
#include <errno.h>
#endif

#ifdef SAL_UNX
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#endif

#include <string.h>

using namespace ::osl;

static std::list< OString > gaCreatedDirectories;

static bool checkOutputPath(const OString& completeName)
{
    OString sysPathName = convertToAbsoluteSystemPath(completeName);
    OStringBuffer buffer(sysPathName.getLength()+16);

    if ( sysPathName.indexOf( SEPARATOR ) == -1 )
        return true;

    sal_Int32 nIndex = 0;
    std::string_view token(o3tl::getToken(sysPathName, 0, SEPARATOR, nIndex));
    if (o3tl::starts_with(token, "..")
        || (token.size() >= 2 && token[1] == ':')
        || o3tl::starts_with(token, "."))
    {
        buffer.append(token);
        buffer.append(SEPARATOR);
    }
    else
        nIndex = 0;

    do
    {
        buffer.append(o3tl::getToken(sysPathName, 0, SEPARATOR, nIndex));

        if ( !buffer.isEmpty() && nIndex != -1 )
        {
#if defined(SAL_UNX)
            if (mkdir(buffer.getStr(), 0777) == -1)
#else
            if (mkdir(buffer.getStr()) == -1)
#endif
            {
                if (errno == ENOENT)
                {
                    fprintf(stderr, "%s: cannot create directory '%s'\n",
                            idlc()->getOptions()->getProgramName().getStr(), buffer.getStr());
                    return false;
                }
            }
            else
            {
                gaCreatedDirectories.push_front(buffer.getStr());
            }
        }
        buffer.append(SEPARATOR);
    } while( nIndex != -1 );
    return true;
}

static bool cleanPath()
{
    for (auto const& createdDirectory : gaCreatedDirectories)
    {
//#ifdef SAL_UNX
//      if (rmdir((char*)createdDirectory.getStr(), 0777) == -1)
//#else
        if (rmdir(createdDirectory.getStr()) == -1)
//#endif
        {
            fprintf(stderr, "%s: cannot remove directory '%s'\n",
                    idlc()->getOptions()->getProgramName().getStr(), createdDirectory.getStr());
            return false;
        }
    }
    gaCreatedDirectories.clear();
    return true;
}

void removeIfExists(std::string_view pathname)
{
    osl::File::remove(OStringToOUString(pathname, RTL_TEXTENCODING_UTF8));
}

sal_Int32
produceFile(const OString& regFileName, sPair_t const*const pDepFile)
{
    Options* pOptions = idlc()->getOptions();

    OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_");

    if ( !checkOutputPath(regFileName) )
    {
        fprintf(stderr, "%s: could not create path of registry file '%s'.\n",
                pOptions->getProgramName().getStr(), regFileName.getStr());
        return 1;
    }

    OString depTmpName;
    if (pDepFile)
    {
        depTmpName = pDepFile->first.replaceAt(
                        regFileName.getLength() -3, 3, "_idlc_");
        if ( !checkOutputPath(depTmpName) )
        {
            fprintf(stderr, "%s: could not create path of dep file '%s'.\n",
                pOptions->getProgramName().getStr(), pDepFile->first.getStr());
            return 1;
        }
        removeIfExists(depTmpName);
    }

    removeIfExists(regTmpName);
    OString urlRegTmpName = convertToFileUrl(regTmpName);

    Registry regFile;
    if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != RegError::NO_ERROR )
    {
        fprintf(stderr, "%s: could not create registry file '%s'\n",
                pOptions->getProgramName().getStr(), regTmpName.getStr());
        removeIfExists(regTmpName);
        removeIfExists(regFileName);
        cleanPath();
        return 1;
    }

    RegistryKey rootKey;
    if ( regFile.openRootKey(rootKey) != RegError::NO_ERROR )
    {
        fprintf(stderr, "%s: could not open root of registry file '%s'\n",
                pOptions->getProgramName().getStr(), regFileName.getStr());
        removeIfExists(regTmpName);
        removeIfExists(regFileName);
        cleanPath();
        return 1;
    }

    // produce registry file
    if ( !idlc()->getRoot()->dump(rootKey) )
    {
        rootKey.releaseKey();
        if (regFile.close() != RegError::NO_ERROR)
        {
            fprintf(stderr, "%s: could not close registry file '%s'\n",
                    pOptions->getProgramName().getStr(), regFileName.getStr());
        }
        regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8));
        removeIfExists(regFileName);
        cleanPath();
        return 1;
    }

    rootKey.releaseKey();
    if ( regFile.close() != RegError::NO_ERROR )
    {
        fprintf(stderr, "%s: could not close registry file '%s'\n",
                pOptions->getProgramName().getStr(), regFileName.getStr());
        removeIfExists(regTmpName);
        removeIfExists(regFileName);
        cleanPath();
        return 1;
    }

    if (pDepFile && !idlc()->dumpDeps(depTmpName, pDepFile->second))
    {
        fprintf(stderr, "%s: could not write dep file '%s'\n",
                pOptions->getProgramName().getStr(), pDepFile->first.getStr());
        removeIfExists(depTmpName);
        removeIfExists(pDepFile->first);
        removeIfExists(regTmpName);
        removeIfExists(regFileName);
        cleanPath();
        return 1;
    }

    removeIfExists(regFileName);

    if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()),
                    OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) {
        fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                regTmpName.getStr(), regFileName.getStr());
        removeIfExists(regTmpName);
        cleanPath();
        return 1;
    }
    removeIfExists(regTmpName);

    if (pDepFile)
    {
        removeIfExists(pDepFile->first);
        if ( File::move(OStringToOUString(depTmpName, osl_getThreadTextEncoding()),
                        OStringToOUString(pDepFile->first, osl_getThreadTextEncoding())) != FileBase::E_None ) {
            fprintf(stderr, "%s: cannot rename dep file '%s' to '%s'\n",
                    idlc()->getOptions()->getProgramName().getStr(),
                    depTmpName.getStr(), pDepFile->first.getStr());
            removeIfExists(depTmpName);
            removeIfExists(pDepFile->first);
            removeIfExists(regFileName);
            cleanPath();
            return 1;
        }
        removeIfExists(depTmpName);
    }

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/options.cxx b/idlc/source/options.cxx
deleted file mode 100644
index 0fd06cc..0000000
--- a/idlc/source/options.cxx
+++ /dev/null
@@ -1,424 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <sal/config.h>

#include <string_view>

#include <options.hxx>

#include <osl/diagnose.h>
#include <rtl/string.hxx>
#include <rtl/strbuf.hxx>

#include <rtl/ustring.hxx>
#include <osl/file.hxx>
#include <o3tl/char16_t2wchar_t.hxx>
#include <o3tl/string_view.hxx>

#ifdef _WIN32
#   if !defined WIN32_LEAN_AND_MEAN
#      define WIN32_LEAN_AND_MEAN
#   endif
#   include <windows.h>
#endif

#include <stdio.h>
#include <string.h>


Options::Options(char const * progname)
  : m_program(progname), m_stdin(false), m_verbose(false), m_quiet(false)
{
}

Options::~Options()
{
}

// static
bool Options::checkArgument (std::vector< std::string > & rArgs, char const * arg, size_t len)
{
  bool result = ((arg != nullptr) && (len > 0));
  OSL_PRECOND(result, "idlc::Options::checkArgument(): invalid arguments");
  if (!result)
      return false;

  switch(arg[0])
  {
  case '@':
    result = len > 1;
    if (result)
    {
      // "@<cmdfile>"
      result = Options::checkCommandFile (rArgs, &(arg[1]));
    }
    break;
  case '-':
    result = len > 1;
    if (result)
    {
      // "-<option>"
      switch (arg[1])
      {
      case 'O':
      case 'M':
      case 'I':
      case 'D':
        {
          // "-<option>[<param>]
          std::string option(&(arg[0]), 2);
          rArgs.push_back(option);
          if (len > 2)
          {
            // "-<option><param>"
            std::string param(&(arg[2]), len - 2);
            rArgs.push_back(param);
          }
          break;
        }
      default:
        // "-<option>" ([long] option, w/o param)
        rArgs.emplace_back(arg, len);
        break;
      }
    }
    break;
  default:
    // "<param>"
    rArgs.emplace_back(arg, len);
    break;
  }
  return result;
}

// static
bool Options::checkCommandFile (std::vector< std::string > & rArgs, char const * filename)
{
    FILE * fp = fopen(filename, "r");
    if (fp == nullptr)
    {
        fprintf(stderr, "ERROR: can't open command file \"%s\"\n", filename);
        return false;
    }

    std::string buffer;
    buffer.reserve(256);

    bool quoted = false;
    int c = EOF;
    while ((c = fgetc(fp)) != EOF)
    {
        switch(c)
        {
        case '\"':
          quoted = !quoted;
          break;
        case ' ':
        case '\t':
        case '\r':
        case '\n':
          if (!quoted)
          {
              if (!buffer.empty())
              {
                  // append current argument.
                  if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
                  {
                      (void) fclose(fp);
                      return false;
                  }
                  buffer.clear();
              }
              break;
          }
          [[fallthrough]];
        default:
          buffer.push_back(sal::static_int_cast<char>(c));
          break;
        }
    }
    if (!buffer.empty())
    {
        // append unterminated argument.
        if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
        {
            (void) fclose(fp);
            return false;
        }
        buffer.clear();
    }
    return (fclose(fp) == 0);
}

bool Options::badOption(char const * reason, std::string const & rArg)
{
  if (reason != nullptr)
  {
    OString message = OString::Concat(reason) + " option '" + rArg.c_str() + "'";
    throw IllegalArgument(message);
  }
  return false;
}

bool Options::setOption(char const * option, std::string const & rArg)
{
  bool result = (0 == strcmp(option, rArg.c_str()));
  if (result)
    m_options[rArg.c_str()] = OString(rArg.c_str(), rArg.size());
  return result;
}

#ifdef _WIN32
/* Helper function to convert windows paths including spaces, brackets etc. into
   a windows short Url. The ucpp preprocessor has problems with such paths and returns
   with error.
*/
static OString convertIncPathtoShortWindowsPath(const OString& incPath) {
    OUString path = OStringToOUString(incPath, RTL_TEXTENCODING_UTF8);

    std::vector<sal_Unicode> vec(path.getLength() + 1);
    //GetShortPathNameW only works if the file can be found!
    const DWORD len = GetShortPathNameW(
        o3tl::toW(path.getStr()), o3tl::toW(vec.data()), path.getLength() + 1);

    if (len > 0)
    {
        OUString ret(vec.data(), len);
        return OUStringToOString(ret, RTL_TEXTENCODING_UTF8);
    }

    return incPath;
}
#endif

bool Options::initOptions(std::vector< std::string > & rArgs)
{
  std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
  for (; first != last; ++first)
  {
    if ((*first)[0] != '-')
    {
      OString filename((*first).c_str(), (*first).size());
      OString tmp(filename.toAsciiLowerCase());
      if (tmp.lastIndexOf(".idl") != (tmp.getLength() - 4))
      {
        throw IllegalArgument("'" + filename + "' is not a valid input file, only '*.idl' files will be accepted");
      }
      m_inputFiles.push_back(filename);
      continue;
    }

    std::string const option(*first);
    switch((*first)[1])
    {
    case 'O':
      {
        if ((++first == last) || ((*first)[0] == '-'))
        {
          return badOption("invalid", option);
        }
        OString param((*first).c_str(), (*first).size());
        m_options["-O"] = param;
        break;
      }
    case 'M':
      {
        if ((++first == last) || ((*first)[0] == '-'))
        {
          return badOption("invalid", option);
        }
        OString param((*first).c_str(), (*first).size());
        m_options["-M"] = param;
        break;
      }
    case 'I':
      {
        if ((++first == last) || ((*first)[0] == '-'))
        {
          return badOption("invalid", option);
        }
        OString param((*first).c_str(), (*first).size());
        {
          // quote param token(s).
          OStringBuffer buffer;
          sal_Int32 k = 0;
          do
          {
            if (!buffer.isEmpty())
              buffer.append(' ');
//          buffer.append("-I\"");
#ifdef _WIN32
            OString incpath = convertIncPathtoShortWindowsPath(param.getToken(0, ';', k));
#else
            std::string_view incpath = o3tl::getToken(param, 0, ';', k);
#endif
            buffer.append(incpath);
//          buffer.append("\"");
          } while (k != -1);
          param = buffer.makeStringAndClear();
        }
        if (m_options.count("-I") > 0)
        {
          // append param.
          param = m_options["-I"] + " " + param;
        }
        m_options["-I"] = param;
        break;
      }
    case 'D':
      {
        if ((++first == last) || ((*first)[0] == '-'))
        {
          return badOption("invalid", option);
        }
        OString param = OString::Concat("-D") + std::string_view((*first).c_str(), (*first).size());
        if (m_options.count("-D") > 0)
        {
          param = m_options["-D"] + " " + param;
        }
        m_options["-D"] = param;
        break;
      }
    case 'C':
      {
        if (!setOption("-C", option))
        {
          return badOption("invalid", option);
        }
        break;
      }
    case 'c':
      {
        if (!setOption("-cid", option))
        {
          return badOption("invalid", option);
        }
        break;
      }
    case 'q':
      {
        if (!setOption("-quiet", option))
        {
          return badOption("invalid", option);
        }
        m_quiet = true;
        break;
      }
    case 'v':
      {
        if (!setOption("-verbose", option))
        {
          return badOption("invalid", option);
        }
        m_verbose = true;
        break;
      }
    case 'w':
      {
        if (!(setOption("-w", option) || setOption("-we", option)))
        {
          return badOption("invalid", option);
        }
        break;
      }
    case 'h':
    case '?':
      {
        if (!(setOption("-h", option) || setOption("-?", option)))
        {
          return badOption("invalid", option);
        }
        {
          (void) fprintf(stdout, "%s", prepareHelp().getStr());
          return false;
        }
        // break; // Unreachable
      }
    case 's':
      {
        if (!setOption("-stdin", option))
        {
          return badOption("invalid", option);
        }
        m_stdin = true;
        break;
      }
    default:
      return badOption("unknown", option);
    }
  }
  return true;
}

OString Options::prepareHelp() const
{
    OString help = "\nusing: " +
        m_program + " [-options] <file_1> ... <file_n> | @<filename> | -stdin\n"
         "    <file_n>    = file_n specifies one or more idl files.\n"
         "                  Only files with the extension '.idl' are valid.\n"
         "    @<filename> = filename specifies the name of a command file.\n"
         "    -stdin      = read idl file from standard input.\n"
         "  Options:\n"
         "    -O<path>    = path specifies the output directory.\n"
         "                  The generated output is a registry file with\n"
         "                  the same name as the idl input file (or 'stdin'\n"
         "                  for -stdin).\n"
         "    -M<path>    = path specifies the output directory for deps.\n"
         "                  Generate GNU make dependency files with the\n"
         "                  same name as the idl input file.\n"
         "    -I<path>    = path specifies a directory where include\n"
         "                  files will be searched by the preprocessor.\n"
         "                  Multiple directories can be combined with ';'.\n"
         "    -D<name>    = name defines a macro for the preprocessor.\n"
         "    -C          = generate complete type information, including\n"
         "                  documentation.\n"
         "    -cid        = check if identifiers fulfill the UNO naming\n"
         "                  requirements.\n"
         "    -quiet      = no output.\n"
         "    -verbose    = verbose output.\n"
         "    -w          = display warning messages.\n"
         "    -we         = treat warnings as errors.\n"
         "    -h|-?       = print this help message and exit.\n\n" +
        prepareVersion();

    return help;
}

OString Options::prepareVersion() const
{
    return m_program + " Version 1.1\n\n";
}


bool Options::isValid(const OString& option) const
{
    return (m_options.count(option) > 0);
}

const OString& Options::getOption(const OString& option)
{
    if (!isValid(option))
    {
        throw IllegalArgument("Option is not valid or currently not set.");
    }
    return m_options[option];
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/parser.y b/idlc/source/parser.y
deleted file mode 100644
index 29654c3..0000000
--- a/idlc/source/parser.y
+++ /dev/null
@@ -1,2737 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

/*
 * parser.yy - BISON grammar for IDLC 1.0
 */

%{
#include <string.h>

#include <idlc.hxx>
#include <errorhandler.hxx>
#include <fehelper.hxx>
#include <astexpression.hxx>
#include <astconstants.hxx>
#include <astconstant.hxx>
#include <astbasetype.hxx>
#include <asttypedef.hxx>
#include <astexception.hxx>
#include <astmember.hxx>
#include <astenum.hxx>
#include <astsequence.hxx>
#include <astattribute.hxx>
#include <astoperation.hxx>
#include <astparameter.hxx>
#include <astinterfacemember.hxx>
#include <astservicemember.hxx>
#include <astobserves.hxx>
#include <astneeds.hxx>

#include <aststructinstance.hxx>

#include "attributeexceptions.hxx"

#include <rtl/string.hxx>
#include <osl/diagnose.h>

#include <algorithm>
#include <vector>


#define YYDEBUG 1
#define YYERROR_VERBOSE 1

extern int yylex(void);
static void yyerror(char const *);

static void checkIdentifier(OString const * id)
{
    static short check = 0;
    if (check == 0) {
        if (idlc()->getOptions()->isValid("-cid"))
            check = 1;
        else
            check = 2;
    }

    if ( id->indexOf('_') >= 0 )
        if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
             || id->pData->buffer[0] == '_') {
            if (check == 1) {
                OString msg = "mismatched identifier '" + *id + "'";
                ErrorHandler::syntaxError(idlc()->getParseState(),
                                         idlc()->getLineNumber(),
                                         msg.getStr());
            }
            else
                ErrorHandler::warning0(WarningCode::WrongNamingConvention, id->getStr());
        }
}

static void reportDoubleMemberDeclarations(
    AstInterface::DoubleMemberDeclarations const & doubleMembers)
{
    for (auto const& doubleMember : doubleMembers)
    {
        ErrorHandler::error2(ErrorCode::DoubleMember, doubleMember.first, doubleMember.second);
    }
}

static void addInheritedInterface(
    AstInterface * ifc, OString const & name, bool optional,
    OUString const & documentation)
{
    AstDeclaration * decl = ifc->lookupByName(name);
    AstDeclaration const * resolved = resolveTypedefs(decl);
    if (resolved != nullptr && resolved->getNodeType() == NT_interface) {
        if (ErrorHandler::checkPublished(decl)) {
            if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
                ErrorHandler::inheritanceError(
                    NT_interface, &ifc->getScopedName(), decl);
            } else {
                AstInterface::DoubleDeclarations doubleDecls(
                    ifc->checkInheritedInterfaceClashes(
                        static_cast< AstInterface const * >(resolved),
                        optional));
                if (doubleDecls.interfaces.empty()
                    && doubleDecls.members.empty())
                {
                    ifc->addInheritedInterface(
                        static_cast< AstType * >(decl), optional,
                        documentation);
                } else {
                    for (auto const& elem : doubleDecls.interfaces)
                    {
                        ErrorHandler::error1(
                            ErrorCode::DoubleInheritance, elem);
                    }
                    reportDoubleMemberDeclarations(doubleDecls.members);
                }
            }
        }
    } else {
        ErrorHandler::lookupError(
            ErrorCode::InterfaceMemberLookup, name, scopeAsDecl(ifc));
    }
}

static AstDeclaration const * createNamedType(
    OString const * scopedName, DeclList const * typeArgs)
{
    AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
        *scopedName);
    AstDeclaration const * resolved = resolveTypedefs(decl);
    if (decl == nullptr) {
        ErrorHandler::lookupError(*scopedName);
    } else if (!ErrorHandler::checkPublished(decl)) {
        decl = nullptr;
    } else if (resolved->getNodeType() == NT_struct) {
        if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
            != (typeArgs == nullptr ? 0 : typeArgs->size()))
        {
            ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
            decl = nullptr;
        } else if (typeArgs != nullptr) {
            AstScope * global = idlc()->scopes()->bottom();
            AstDeclaration * inst = new AstStructInstance(
                static_cast< AstType * >(decl), typeArgs, global);
            decl = global->addDeclaration(inst);
            if (decl != inst) {
                delete inst;
            }
        }
    } else if (decl->isType()) {
        if (typeArgs != nullptr) {
            ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
            decl = nullptr;
        }
    } else {
        ErrorHandler::noTypeError(decl);
        decl = nullptr;
    }
    delete scopedName;
    delete typeArgs;
    return decl;
}

static bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
    OSL_ASSERT(type2 != nullptr);
    if (type1 != nullptr) {
        if (type1->getNodeType() == NT_instantiated_struct) {
            AstStructInstance const * inst
                = static_cast< AstStructInstance const * >(type1);
            if (inst->getTypeTemplate() == type2) {
                return true;
            }
            for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
                 i != inst->getTypeArgumentsEnd(); ++i)
            {
                if (includes(*i, type2)) {
                    return true;
                }
            }
        } else if (type1 == type2) {
            return true;
        }
    }
    return false;
}

// Suppress any warnings from generated code:
#if defined _MSC_VER
#pragma warning(disable: 4702) // unreachable code
#endif
%}
/*
 * Declare the type of values in the grammar
 */
%union {
    ExprType                etval;     /* Expression type */
    AstDeclaration*     dclval;    /* Declaration */
    AstDeclaration const * cdclval;
    DeclList * dclsval;
    AstExpression*      exval;      /* expression value */
    FeDeclarator*           fdval;      /* declarator value */
    FeDeclList*         dlval;      /* declarator list value */
    FeInheritanceHeader*    ihval;      /* inheritance header value */
    OString*     sval;       /* OString value */
    std::vector< OString > * svals;
    char*               strval; /* char* value */
    bool                bval;       /* sal_Boolean* value */
    sal_Int64               ival;       /* sal_Int64 value */
    sal_uInt64 uval; /* sal_uInt64 value */
    sal_uInt32          ulval;      /* sal_uInt32 value */
    double                  dval;       /* double value */
    float                   fval;       /* float value */
    std::list< OString >*         slval;      /* StringList value */
    AttributeExceptions::Part attexcpval;
    AttributeExceptions attexcval;
}

/*
 * Token types: These are returned by the lexer
 */

%token <sval>       IDL_IDENTIFIER
%token          IDL_ATTRIBUTE
%token              IDL_BOUND
%token          IDL_CONST
%token          IDL_CONSTANTS
%token              IDL_CONSTRAINED
%token          IDL_ENUM
%token          IDL_EXCEPTION
%token          IDL_INTERFACE
%token          IDL_MAYBEAMBIGUOUS
%token          IDL_MAYBEDEFAULT
%token          IDL_MAYBEVOID
%token          IDL_MODULE
%token          IDL_NEEDS
%token          IDL_OBSERVES
%token          IDL_OPTIONAL
%token          IDL_PROPERTY
%token          IDL_RAISES
%token          IDL_READONLY
%token          IDL_REMOVABLE
%token          IDL_SERVICE
%token          IDL_SEQUENCE
%token          IDL_SINGLETON
%token          IDL_STRUCT
%token          IDL_TYPEDEF
%token              IDL_TRANSIENT

%token          IDL_ANY
%token          IDL_CHAR
%token          IDL_BOOLEAN
%token          IDL_BYTE
%token          IDL_DOUBLE
%token          IDL_FLOAT
%token          IDL_HYPER
%token          IDL_LONG
%token          IDL_SHORT
%token          IDL_VOID
%token          IDL_STRING
%token          IDL_TYPE
%token          IDL_UNSIGNED

%token          IDL_TRUE
%token          IDL_FALSE

%token          IDL_IN
%token          IDL_OUT
%token          IDL_INOUT

%token IDL_GET
%token IDL_SET

%token IDL_PUBLISHED

%token IDL_ELLIPSIS

%token <strval> IDL_LEFTSHIFT
%token <strval> IDL_RIGHTSHIFT
%token <strval>     IDL_SCOPESEPARATOR

%token <ival>       IDL_INTEGER_LITERAL
%token <uval> IDL_INTEGER_ULITERAL
%token <dval>       IDL_FLOATING_PT_LITERAL

/*
 * These are production names:
 */
%type <dclval>  type_dcl
%type <dclval>  exception_name
%type <cdclval> constructed_type_spec enum_type op_type_spec
%type <cdclval> sequence_type_spec simple_type_spec struct_type
%type <cdclval> type_spec
%type <cdclval> fundamental_type type_arg type_or_parameter
%type <dclsval> opt_raises raises exception_list
%type <attexcpval> opt_attribute_get_raises attribute_get_raises
%type <attexcpval> opt_attribute_set_raises attribute_set_raises
%type <dclsval> opt_type_args type_args

%type <sval>    identifier
%type <sval>    interface_decl
%type <sval>    scoped_name inheritance_spec
%type <slval>   scoped_names at_least_one_scoped_name

%type <etval>   const_type integer_type char_type boolean_type
%type <etval>   floating_pt_type any_type signed_int string_type
%type <etval>   unsigned_int base_type_spec byte_type type_type

%type <exval>   expression const_expr or_expr xor_expr and_expr
%type <exval>   add_expr mult_expr unary_expr primary_expr shift_expr
%type <exval>   literal

%type <fdval>   declarator
%type <dlval>   declarators at_least_one_declarator

%type <ihval>   exception_header structure_header interfaceheader

%type <ulval>   flag_header opt_attrflags opt_attrflag
%type <ulval>   direction service_interface_header service_service_header

%type <bval>    optional_inherited_interface opt_rest opt_service_body

%type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises

%type <svals> opt_type_params type_params

%%
/*
 * Grammar start here
 */
start : definitions;

definitions :
    definition definitions
    | /* EMPTY */
    ;

definition :
    opt_published publishable_definition
    | module_dcl
    {
        idlc()->setParseState(PS_ModuleDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | error ';'
    {
        yyerror("definitions");
        yyerrok;
    }
    ;

opt_published:
    IDL_PUBLISHED { idlc()->setPublished(true); }
    | /* empty */ { idlc()->setPublished(false); }
    ;

publishable_definition:
    type_dcl
    {
        idlc()->setParseState(PS_TypeDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | exception_dcl
    {
        idlc()->setParseState(PS_ExceptionDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | interface
    {
        idlc()->setParseState(PS_InterfaceDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | service_dcl
    {
        idlc()->setParseState(PS_ServiceDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | singleton_dcl
    {
        idlc()->setParseState(PS_SingletonDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | constants_dcl
    {
        idlc()->setParseState(PS_ConstantsDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    ;

module_dcl :
    IDL_MODULE
    {
        idlc()->setParseState(PS_ModuleSeen);
        idlc()->setPublished(false);
    }
    identifier
    {
        idlc()->setParseState(PS_ModuleIDSeen);
        checkIdentifier($3);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstModule*      pModule = nullptr;

        if ( pScope )
        {
            pModule = new AstModule(*$3, pScope);
            if( AstDeclaration* pExists = pScope->lookupForAdd(pModule) )
            {
                pExists->setInMainfile(idlc()->isInMainFile());
                pExists->setFileName(pModule->getFileName());
                if (pExists->isPredefined())
                {
                    pExists->setPredefined(false);
                    if (pExists->getDocumentation().getLength() == 0 &&
                        pModule->getDocumentation().getLength() > 0)
                    {
                        pExists->setDocumentation(pModule->getDocumentation());
                    }
                }
                delete(pModule);
                pModule = static_cast<AstModule*>(pExists);
            } else
            {
                pScope->addDeclaration(pModule);
            }
            idlc()->scopes()->push(pModule);
        }
        delete $3;
    }
    '{'
    {
        idlc()->setParseState(PS_ModuleSqSeen);
    }
    definitions
    {
        idlc()->setParseState(PS_ModuleBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_ModuleQsSeen);
        /*
         * Finished with this module - pop it from the scope stack
         */
        idlc()->scopes()->pop();
    }
    ;

interface :
    interface_dcl
    | forward_dcl
    ;

interface_decl :
    IDL_INTERFACE
    {
        idlc()->setParseState(PS_InterfaceSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_InterfaceIDSeen);
        checkIdentifier($3);
        $$ = $3;
    }
    ;

forward_dcl :
    interface_decl
    {
        idlc()->setParseState(PS_ForwardDeclSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstInterface*   pForward = nullptr;
        AstDeclaration* pDecl = nullptr;

        /*
         * Make a new forward interface node and add it to its enclosing scope
         */
        if ( pScope && $1 )
        {
            pForward = new AstInterface(*$1, nullptr, pScope);

            pDecl = pScope->lookupByName(pForward->getScopedName());
            if ( pDecl )
            {
                if ( (pDecl != pForward) &&
                     (pDecl->getNodeType() == NT_interface) )
                {
                    delete pForward;
                } else
                {
                    ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(pScope), pDecl);
                }
            } else
            {
                /*
                 * Add the interface to its definition scope
                 */
                pScope->addDeclaration(pForward);
            }
        }
        delete $1;
    }
    ;

interface_dcl :
    interfaceheader
    {
        idlc()->setParseState(PS_InterfaceHeadSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstInterface*   pInterface = nullptr;
        AstInterface*   pForward = nullptr;

        /*
         * Make a new interface node and add it to its enclosing scope
         */
        if ( pScope && $1 )
        {
            pInterface = new AstInterface(
                *$1->getName(),
                static_cast< AstInterface const * >(resolveTypedefs($1->getInherits())), pScope);
            if ( AstDeclaration* pDecl = pScope->lookupByName(pInterface->getScopedName()) )
            {
                /*
                 * See if we're defining a forward declared interface.
                 */
                if (pDecl->getNodeType() == NT_interface)
                {
                    pForward = static_cast<AstInterface*>(pDecl);
                    if ( !pForward->isDefined() )
                    {
                        /*
                         * Check if redefining in same scope
                         */
                        if ( pForward->getScope() != pScope )
                        {
                            if ( pForward->getScopedName() != pInterface->getScopedName() )
                            {
                                ErrorHandler::error3(ErrorCode::ScopeConflict,
                                         pInterface, pForward, scopeAsDecl(pScope));
                            }
                        }
                        else if ( !pInterface->isPublished()
                                  && pForward->isPublished() )
                        {
                            ErrorHandler::error0(ErrorCode::PublishedForward);
                        }
                        /*
                         * All OK, set full definition
                         */
                        else
                        {
                            pForward->forwardDefined(*pInterface);
                            delete pInterface;
                            pInterface = pForward;
                        }
                    } else {
                        // special handling for XInterface because it is predefined
                        if ( pForward->isPredefined() &&
                             pForward->getScopedName() == "com::sun::star::uno::XInterface")
                        {
                            /* replace the predefined XInterface */
                            *pForward = *pInterface;
                            delete pInterface;
                            pInterface = pForward;
                        }

                    }
                }
            } else
            {
                /*
                 * Add the interface to its definition scope
                 */
                pScope->addDeclaration(pInterface);
            }
        }
        /*
         * Push it on the scope stack
         */
        idlc()->scopes()->push(pInterface);
        delete $1;
    }
    '{'
    {
        idlc()->setParseState(PS_InterfaceSqSeen);
    }
    exports
    {
        AstInterface * ifc = static_cast< AstInterface * >(
            idlc()->scopes()->topNonNull());
        if (!ifc->hasMandatoryInheritedInterfaces()
            && ifc->getScopedName() != "com::sun::star::uno::XInterface")
        {
            addInheritedInterface(
                ifc, "::com::sun::star::uno::XInterface", false,
                OUString());
        }
        ifc->setDefined();
        idlc()->setParseState(PS_InterfaceBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_InterfaceQsSeen);
        /*
         * Done with this interface - pop it off the scopes stack
         */
        idlc()->scopes()->pop();
    }
    | error '}'
    {
        yyerror("interface definition");
        yyerrok;
    }
    ;

interfaceheader :
    interface_decl inheritance_spec
    {
        idlc()->setParseState(PS_InheritSpecSeen);

        $$ = new FeInheritanceHeader(NT_interface, $1, $2, nullptr);
        delete $2;
    }
    ;

inheritance_spec :
    ':'
    {
        idlc()->setParseState(PS_InheritColonSeen);
    }
    scoped_name
    {
        $$ = $3;
    }
    | /* EMPTY */
    {
        $$ = nullptr;
    }
    ;

exports :
    exports export
    | /* EMPTY */
    ;

export :
    attribute
    {
        idlc()->setParseState(PS_AttributeDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | operation
    {
        idlc()->setParseState(PS_OperationDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    | interface_inheritance_decl
    {
        idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_NoState);
    }
    ;

attribute :
    flag_header
    simple_type_spec
    {
        idlc()->setParseState(PS_AttrTypeSeen);
    }
    declarator
    {
        idlc()->setParseState(PS_AttrCompleted);
        if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
            ErrorHandler::flagError(ErrorCode::BadAttributeFlags, $1);
        }
        AstInterface * scope = static_cast< AstInterface * >(
            idlc()->scopes()->top());
        AstAttribute * attr = new AstAttribute(
            $1, FeDeclarator::compose($2), $4->getName(), scope);
        delete $4;
        AstInterface::DoubleMemberDeclarations doubleMembers(
            scope->checkMemberClashes(attr));
        if (doubleMembers.empty()) {
            scope->addMember(attr);
        } else {
            reportDoubleMemberDeclarations(doubleMembers);
        }
        idlc()->scopes()->push(attr);
    }
    opt_attribute_block
    {
        static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
            $6.get.documentation, $6.get.exceptions, $6.set.documentation,
            $6.set.exceptions);
        delete $6.get.documentation;
        delete $6.get.exceptions;
        delete $6.set.documentation;
        delete $6.set.exceptions;
        idlc()->scopes()->pop();
    }
    ;

flag_header :
    '[' opt_attrflags ']'
    {
        idlc()->setParseState(PS_FlagHeaderSeen);
        $$ = $2;
    }
    ;

opt_attrflags :
    opt_attrflags ',' opt_attrflag
    {
        if ( ($1 & $3) == $3 )
            ErrorHandler::flagError(ErrorCode::DefinedAttributeFlag, $3);

        $$ = $1 | $3;
    }
    | opt_attrflag
    {
        $$ = $1;
    }
    ;

opt_attrflag :
    IDL_ATTRIBUTE
    {
        idlc()->setParseState(PS_AttrSeen);
        $$ = AF_ATTRIBUTE;
    }
    | IDL_PROPERTY
    {
        idlc()->setParseState(PS_PropertySeen);
        $$ = AF_PROPERTY;
    }
    | IDL_READONLY
    {
        idlc()->setParseState(PS_ReadOnlySeen);
        $$ = AF_READONLY;
    }
    | IDL_OPTIONAL
    {
        idlc()->setParseState(PS_OptionalSeen);
        $$ = AF_OPTIONAL;
    }
    | IDL_MAYBEVOID
    {
        idlc()->setParseState(PS_MayBeVoidSeen);
        $$ = AF_MAYBEVOID;
    }
    | IDL_BOUND
    {
        idlc()->setParseState(PS_BoundSeen);
        $$ = AF_BOUND;
    }
    | IDL_CONSTRAINED
    {
        idlc()->setParseState(PS_ConstrainedSeen);
        $$ = AF_CONSTRAINED;
    }
    | IDL_TRANSIENT
    {
        idlc()->setParseState(PS_TransientSeen);
        $$ = AF_TRANSIENT;
    }
    | IDL_MAYBEAMBIGUOUS
    {
        idlc()->setParseState(PS_MayBeAmbiguousSeen);
        $$ = AF_MAYBEAMBIGUOUS;
    }
    | IDL_MAYBEDEFAULT
    {
        idlc()->setParseState(PS_MayBeDefaultSeen);
        $$ = AF_MAYBEDEFAULT;
    }
    | IDL_REMOVABLE
    {
        idlc()->setParseState(PS_RemoveableSeen);
        $$ = AF_REMOVABLE;
    }
    | error ']'
    {
        yyerror("unknown property|attribute flag");
        yyerrok;
    }
    ;

opt_attribute_block:
    '{' attribute_block_rest { $$ = $2; }
    | /* empty */
    {
        $$.get.documentation = nullptr;
        $$.get.exceptions = nullptr;
        $$.set.documentation = nullptr;
        $$.set.exceptions = nullptr;
    }
    ;

attribute_block_rest:
    opt_attribute_raises '}'
    | error '}'
    {
        yyerror("bad attribute raises block");
        yyerrok;
        $$.get.documentation = nullptr;
        $$.get.exceptions = nullptr;
        $$.set.documentation = nullptr;
        $$.set.exceptions = nullptr;
    }
    ;

opt_attribute_raises:
    attribute_get_raises
    opt_attribute_set_raises
    {
        $$.get = $1;
        $$.set = $2;
    }
    | attribute_set_raises
    opt_attribute_get_raises
    {
        $$.get = $2;
        $$.set = $1;
    }
    | /* empty */
    {
        $$.get.documentation = nullptr;
        $$.get.exceptions = nullptr;
        $$.set.documentation = nullptr;
        $$.set.exceptions = nullptr;
    }
    ;

opt_attribute_get_raises:
    attribute_get_raises
    | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
    ;

attribute_get_raises:
    IDL_GET raises ';'
    {
        $$.documentation = new OUString(
            OStringToOUString(
                idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
        $$.exceptions = $2;
    }
    ;

opt_attribute_set_raises:
    attribute_set_raises
    | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
    ;

attribute_set_raises:
    IDL_SET
    {
        if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
            isReadonly())
        {
            ErrorHandler::error0(ErrorCode::ReadOnlyAttributeSetExceptions);
        }
    }
    raises ';'
    {
        $$.documentation = new OUString(
            OStringToOUString(
                idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
        $$.exceptions = $3;
    }
    ;

operation :
    op_type_spec
    {
        idlc()->setParseState(PS_OpTypeSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_OpIDSeen);
        checkIdentifier($3);

        AstInterface * pScope = static_cast< AstInterface * >(
            idlc()->scopes()->top());
        AstOperation*   pOp = nullptr;

        /*
         * Create a node representing an operation on an interface
         * and add it to its enclosing scope
         */
        if ( pScope && $1 )
        {
            AstType const *pType = static_cast<AstType const *>($1);
            if ( !pType || (pType->getNodeType() == NT_exception) )
            {
                // type ERROR
            } else
            {
                pOp = new AstOperation(pType, *$3, pScope);

                AstInterface::DoubleMemberDeclarations doubleMembers(
                    pScope->checkMemberClashes(pOp));
                if (doubleMembers.empty()) {
                    pScope->addMember(pOp);
                } else {
                    reportDoubleMemberDeclarations(doubleMembers);
                }
            }
        }
        delete $3;
        /*
         * Push the operation scope onto the scopes stack
         */
        idlc()->scopes()->push(pOp);
    }
    '('
    {
        idlc()->setParseState(PS_OpSqSeen);
    }
    parameters
    {
        idlc()->setParseState(PS_OpParsCompleted);
    }
    ')'
    {
        idlc()->setParseState(PS_OpQsSeen);
    }
    opt_raises
    {
        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstOperation*   pOp = nullptr;
        /*
         * Add exceptions and context to the operation
         */
        if ( pScope && pScope->getScopeNodeType() == NT_operation)
        {
            pOp = static_cast<AstOperation*>(pScope);

            if ( pOp )
                pOp->setExceptions($11);
        }
        delete $11;
        /*
         * Done with this operation. Pop its scope from the scopes stack
         */
        idlc()->scopes()->pop();
    }
    ;

op_type_spec :
    simple_type_spec
    | IDL_VOID
    {
        $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
    }
    ;

parameters :
    parameter
    | parameters
    ','
    {
        idlc()->setParseState(PS_OpParCommaSeen);
    }
    parameter
    | /* EMPTY */
    | error ','
    {
        yyerror("parameter definition");
        yyerrok;
    }
    ;

parameter :
    '['
    direction
    ']'
    {
        idlc()->setParseState(PS_OpParDirSeen);
    }
    simple_type_spec
    {
        idlc()->setParseState(PS_OpParTypeSeen);
    }
    opt_rest
    declarator
    {
        idlc()->setParseState(PS_OpParDeclSeen);

        AstOperation * pScope = static_cast< AstOperation * >(
            idlc()->scopes()->top());
        AstParameter*   pParam = nullptr;

        /*
         * Create a node representing an argument to an operation
         * Add it to the enclosing scope (the operation scope)
         */
        if ( pScope && $5 && $8 )
        {
            AstType const * pType = FeDeclarator::compose($5);
            if ( pType )
            {
                if (pScope->isConstructor() && $2 != DIR_IN) {
                    ErrorHandler::error0(ErrorCode::ConstructorParameterNotIn);
                }
                if (pScope->isVariadic()) {
                    ErrorHandler::error0(ErrorCode::RestParameterNotLast);
                }
                if ($7) {
                    AstDeclaration const * type = resolveTypedefs(pType);
                    if (type->getNodeType() != NT_predefined
                        || (static_cast< AstBaseType const * >(type)->
                            getExprType() != ET_any))
                    {
                        ErrorHandler::error0(ErrorCode::RestParameterNotAny);
                    }
                    if (pScope->isConstructor()) {
                        if (pScope->getIteratorBegin()
                            != pScope->getIteratorEnd())
                        {
                            ErrorHandler::error0(
                                ErrorCode::ConstructorRestParameterNotFirst);
                        }
                    } else {
                        ErrorHandler::error0(ErrorCode::MethodHasRestParameter);
                    }
                }

                pParam = new AstParameter(
                    static_cast< Direction >($2), $7, pType, $8->getName(),
                    pScope);

                if ( !$8->checkType($5) )
                {
                    // WARNING
                }

                pScope->addDeclaration(pParam);
            }
        }
    }
    | error
    simple_type_spec
    {
        idlc()->setParseState(PS_NoState);
        yyerrok;
    }
    ;

direction :
    IDL_IN
    {
        $$ = DIR_IN;
    }
    | IDL_OUT
    {
        $$ = DIR_OUT;
    }
    | IDL_INOUT
    {
        $$ = DIR_INOUT;
    }
    ;

opt_rest:
    IDL_ELLIPSIS
    {
        $$ = true;
    }
    | /* empty */
    {
        $$ = false;
    }
    ;

opt_raises:
    raises
    | /* empty */
    {
        $$ = nullptr;
    }
    ;

raises:
    IDL_RAISES
    {
        idlc()->setParseState(PS_RaiseSeen);
    }
    '('
    {
        idlc()->setParseState(PS_RaiseSqSeen);
    }
    exception_list
    ')'
    {
        idlc()->setParseState(PS_RaiseQsSeen);
        $$ = $5;
    }
    ;

exception_list:
    exception_name
    {
        $$ = new DeclList;
        $$->push_back($1);
    }
    | exception_list ',' exception_name
    {
        $1->push_back($3);
        $$ = $1;
    }
    ;

exception_name:
    scoped_name
    {
        // The topmost scope is either an AstOperation (for interface methods
        // and service constructors) or an AstAttribute (for interface
        // attributes), so look up exception names in the next-to-topmost scope:
        AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
            *$1);
        if (decl == nullptr) {
            ErrorHandler::lookupError(*$1);
        } else if (!ErrorHandler::checkPublished(decl)) {
            decl = nullptr;
        } else if (decl->getNodeType() != NT_exception) {
            ErrorHandler::error1(ErrorCode::IllegalRaises, decl);
            decl = nullptr;
        }
        delete $1;
        $$ = decl;
    }
    ;

interface_inheritance_decl:
    optional_inherited_interface
    IDL_INTERFACE
    {
        idlc()->setParseState(PS_ServiceIFHeadSeen);
    }
    scoped_name
    {
        AstInterface * ifc = static_cast< AstInterface * >(
            idlc()->scopes()->top());
        if (ifc->usesSingleInheritance()) {
            ErrorHandler::error0(ErrorCode::MixedInheritance);
        } else {
            addInheritedInterface(
                ifc, *$4, $1,
                OStringToOUString(
                    idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
        }
        delete $4;
    }
    ;

optional_inherited_interface:
    '[' IDL_OPTIONAL ']' { $$ = true; }
    | /* EMPTY */ { $$ = false; }
    ;

constants_exports :
    constants_export constants_exports
    | /* EMPTY */
    ;

constants_export :
    IDL_CONST
    {
        idlc()->setParseState(PS_ConstSeen);
    }
    const_type
    {
        idlc()->setParseState(PS_ConstTypeSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_ConstIDSeen);
        checkIdentifier($5);
    }
    '='
    {
        idlc()->setParseState(PS_ConstAssignSeen);
    }
    expression
    {
        idlc()->setParseState(PS_ConstExprSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstConstant*    pConstant = nullptr;

        if ( $9 && pScope )
        {
            if ( !$9->coerce($3) )
            {
                ErrorHandler::coercionError($9, $3);
            } else
            {
                pConstant = new AstConstant($3, $9, *$5, pScope);
                pScope->addDeclaration(pConstant);
            }
        }
        delete $5;

        idlc()->setParseState(PS_ConstantDeclSeen);
    }
    ';' {};
    ;

constants_dcl :
    IDL_CONSTANTS
    {
        idlc()->setParseState(PS_ConstantsSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_ConstantsIDSeen);
        checkIdentifier($3);
    }
    '{'
    {
        idlc()->setParseState(PS_ConstantsSqSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstConstants*   pConstants = nullptr;

        if ( pScope )
        {
            pConstants = new AstConstants(*$3, pScope);
            if( AstDeclaration* pExists = pScope->lookupForAdd(pConstants) )
            {
                pExists->setInMainfile(idlc()->isInMainFile());
                delete(pConstants);
                pConstants = static_cast<AstConstants*>(pExists);
            } else
            {
                pScope->addDeclaration(pConstants);
            }
            idlc()->scopes()->push(pConstants);
        }
        delete $3;
    }
    constants_exports
    {
        idlc()->setParseState(PS_ConstantsBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_ConstantsQsSeen);
        /*
         * Finished with this constants - pop it from the scope stack
         */
        idlc()->scopes()->pop();
    }
    ;

expression : const_expr ;

const_expr : or_expr ;

or_expr :
    xor_expr
    | or_expr '|' xor_expr
    {
        $$ = new AstExpression(ExprComb::Or, $1, $3);
    }
    ;

xor_expr :
    and_expr
    | xor_expr '^' and_expr
    {
        $$ = new AstExpression(ExprComb::Xor, $1, $3);
    }
    ;

and_expr :
    shift_expr
    | and_expr '&' shift_expr
    {
        $$ = new AstExpression(ExprComb::And, $1, $3);
    }
    ;

shift_expr :
    add_expr
    | shift_expr IDL_LEFTSHIFT add_expr
    {
        $$ = new AstExpression(ExprComb::Left, $1, $3);
    }
    | shift_expr IDL_RIGHTSHIFT add_expr
    {
        $$ = new AstExpression(ExprComb::Right, $1, $3);
    }
    ;

add_expr :
    mult_expr
    | add_expr '+' mult_expr
    {
        $$ = new AstExpression(ExprComb::Add, $1, $3);
    }
    | add_expr '-' mult_expr
    {
        $$ = new AstExpression(ExprComb::Minus, $1, $3);
    }
    ;

mult_expr :
    unary_expr
    | mult_expr '*' unary_expr
    {
        $$ = new AstExpression(ExprComb::Mul, $1, $3);
    }
    | mult_expr '/' unary_expr
    {
        $$ = new AstExpression(ExprComb::Div, $1, $3);
    }
    | mult_expr '%' unary_expr
    {
        $$ = new AstExpression(ExprComb::Mod, $1, $3);
    }
    ;

unary_expr :
    primary_expr
    | '+' primary_expr
    {
        $$ = new AstExpression(ExprComb::UPlus, $2, nullptr);
    }
    | '-' primary_expr
    {
        $$ = new AstExpression(ExprComb::UMinus, $2, nullptr);
    }
    | '~' primary_expr
    {
    }
    ;

primary_expr :
    scoped_name
    {
        /*
         * An expression which is a scoped name is not resolved now,
         * but only when it is evaluated (such as when it is assigned
         * as a constant value)
         */
        $$ = new AstExpression($1);
    }
    | literal
    | '(' const_expr ')'
    {
        $$ = $2;
    }
    ;

literal :
    IDL_INTEGER_LITERAL
    {
        $$ = new AstExpression($1);
    }
    | IDL_INTEGER_ULITERAL
    {
        $$ = new AstExpression($1);
    }
    | IDL_FLOATING_PT_LITERAL
    {
        $$ = new AstExpression($1);
    }
    | IDL_TRUE
    {
        $$ = new AstExpression(sal_Int32(1), ET_boolean);
    }
    | IDL_FALSE
    {
        $$ = new AstExpression(sal_Int32(0), ET_boolean);
    }
    ;

const_type :
    integer_type
    | byte_type
    | boolean_type
    | floating_pt_type
    | scoped_name
    {
        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstDeclaration const * type = nullptr;

        /*
         * If the constant's type is a scoped name, it must resolve
         * to a scalar constant type
         */
        if ( pScope ) {
            type = pScope->lookupByName(*$1);
            if (type) {
                if (!ErrorHandler::checkPublished(type))
                {
                    type = nullptr;
                    $$ = ET_none;
                }
                else
                {
                    type = resolveTypedefs(type);
                    if (type->getNodeType() == NT_predefined)
                    {
                        $$ = static_cast< AstBaseType const * >(type)->
                            getExprType();
                    } else
                        $$ = ET_any;
                }
            } else
                $$ = ET_any;
        } else
            $$ = ET_any;
    }
    ;

exception_header :
    IDL_EXCEPTION
    {
        idlc()->setParseState(PS_ExceptSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_ExceptIDSeen);
        checkIdentifier($3);
    }
    inheritance_spec
    {
        idlc()->setParseState(PS_InheritSpecSeen);

        $$ = new FeInheritanceHeader(NT_exception, $3, $5, nullptr);
        delete $5;
    }
    ;

exception_dcl :
    exception_header
    {
        idlc()->setParseState(PS_ExceptHeaderSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstException*   pExcept = nullptr;

        if ( pScope )
        {
            AstException* pBase = static_cast< AstException* >(
                $1->getInherits());
            pExcept = new AstException(*$1->getName(), pBase, pScope);
            pScope->addDeclaration(pExcept);
        }
        /*
         * Push the scope of the exception on the scopes stack
         */
        idlc()->scopes()->push(pExcept);
        delete $1;
    }
    '{'
    {
        idlc()->setParseState(PS_ExceptSqSeen);
    }
    members
    {
        idlc()->setParseState(PS_ExceptBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_ExceptQsSeen);
        /* this exception is finished, pop its scope from the stack */
        idlc()->scopes()->pop();
    }
    ;

property :
    flag_header
    simple_type_spec
    {
        idlc()->setParseState(PS_PropertyTypeSeen);
    }
    at_least_one_declarator
    {
        idlc()->setParseState(PS_PropertyCompleted);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstAttribute*   pAttr = nullptr;
        FeDeclList*     pList = $4;
        FeDeclarator*   pDecl = nullptr;
        AstType const * pType = nullptr;

        if ( pScope->getScopeNodeType() == NT_singleton )
        {
            ErrorHandler::error0(ErrorCode::IllegalAdd);
        } else
        {
            if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
                ErrorHandler::flagError(ErrorCode::WrongAttributeKeyword, AF_ATTRIBUTE);

            if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
                ErrorHandler::flagError(ErrorCode::MissingAttributeKeyword, AF_PROPERTY);

            /*
             * Create nodes representing attributes and add them to the
             * enclosing scope
             */
            if ( pScope && $2 && pList )
            {
                FeDeclList::iterator iter = pList->begin();
                FeDeclList::iterator end = pList->end();

                while (iter != end)
                {
                    pDecl = (*iter);
                    if ( !pDecl )
                    {
                        ++iter;
                        continue;
                    }

                    pType = FeDeclarator::compose($2);

                    if ( !pType )
                    {
                        ++iter;
                        continue;
                    }

                    pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);

                    pScope->addDeclaration(pAttr);
                    ++iter;
                    delete pDecl;
                }
            }
        }

        if ( pList )
            delete pList;
    }
    | error ';'
    {
        yyerror("property");
        yyerrok;
    }
    ;

service_exports :
    service_exports service_export
    | /* EMPTY */
    ;

service_export :
    service_interface_header
    at_least_one_scoped_name
    ';'
    {
        idlc()->setParseState(PS_ServiceMemberSeen);

        AstScope*           pScope = idlc()->scopes()->topNonNull();
        AstDeclaration*     pDecl = nullptr;
        AstInterfaceMember* pIMember = nullptr;

        if ( pScope->getScopeNodeType() == NT_singleton )
        {
            ErrorHandler::error0(ErrorCode::IllegalAdd);
        } else
        {
            /*
             * Create a node representing a class member.
             * Store it in the enclosing scope
             */
            if ( pScope && $2 )
            {
                for (auto const& elem : *($2))
                {
                    pDecl = pScope->lookupByName(elem);
                    if ( pDecl && (pDecl->getNodeType() == NT_interface) )
                    {
                        /* we relax the strict published check and allow to add new
                         * interfaces if they are optional
                         */
                        bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
                        if ( ErrorHandler::checkPublished(pDecl, bOptional) )
                        {
                            pIMember = new AstInterfaceMember(
                                $1, static_cast<AstInterface*>(pDecl), elem, pScope);
                            pScope->addDeclaration(pIMember);
                        }
                    } else
                    {
                        ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
                    }
                }
            }
        }
        delete $2;
    }
    | service_service_header
    at_least_one_scoped_name
    ';'
    {
        idlc()->setParseState(PS_ServiceMemberSeen);

        AstScope*         pScope = idlc()->scopes()->topNonNull();
        AstDeclaration*   pDecl = nullptr;
        AstServiceMember* pSMember = nullptr;

        /*
         * Create a node representing a class member.
         * Store it in the enclosing scope
         */
        if ( pScope && $2 )
        {
            for (auto const& elem : *($2))
            {
                pDecl = pScope->lookupByName(elem);
                if ( pDecl && (pDecl->getNodeType() == NT_service) )
                {
                    if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
                        ErrorHandler::error0(ErrorCode::IllegalAdd);
                    else if ( ErrorHandler::checkPublished(pDecl) )
                    {
                        pSMember = new AstServiceMember(
                            $1, static_cast<AstService*>(pDecl), elem, pScope);
                        pScope->addDeclaration(pSMember);
                    }
                } else
                {
                    ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
                }
            }
        }
        delete $2;
    }
    | IDL_OBSERVES
    at_least_one_scoped_name
    ';'
    {
        idlc()->setParseState(PS_ServiceMemberSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstDeclaration* pDecl = nullptr;
        AstObserves*    pObserves = nullptr;

        if ( pScope->getScopeNodeType() == NT_singleton )
        {
            ErrorHandler::error0(ErrorCode::IllegalAdd);
        } else
        {
            /*
             * Create a node representing a class member.
             * Store it in the enclosing scope
             */
            if ( pScope && $2 )
            {
                for (auto const& elem : *($2))
                {
                    pDecl = pScope->lookupByName(elem);
                    if ( pDecl && (pDecl->getNodeType() == NT_interface) )
                    {
                        pObserves = new AstObserves(static_cast<AstInterface*>(pDecl), elem, pScope);
                        pScope->addDeclaration(pObserves);
                    } else
                    {
                        ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
                    }
                }
            }
        }
        delete $2;
    }
    | IDL_NEEDS
    at_least_one_scoped_name
    ';'
    {
        idlc()->setParseState(PS_ServiceMemberSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstDeclaration* pDecl = nullptr;
        AstNeeds*       pNeeds = nullptr;

        if ( pScope->getScopeNodeType() == NT_singleton )
        {
            ErrorHandler::error0(ErrorCode::IllegalAdd);
        } else
        {
            /*
             * Create a node representing a class member.
             * Store it in the enclosing scope
             */
            if ( pScope && $2 )
            {
                for (auto const& elem : *($2))
                {
                    pDecl = pScope->lookupByName(elem);
                    if ( pDecl && (pDecl->getNodeType() == NT_service) )
                    {
                        pNeeds = new AstNeeds(static_cast<AstService*>(pDecl), elem, pScope);
                        pScope->addDeclaration(pNeeds);
                    } else
                    {
                        ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
                    }
                }
            }
        }
        delete $2;
    }
    | property
    ';'
    {
        idlc()->setParseState(PS_PropertyDeclSeen);
    }
    ;

service_interface_header :
    IDL_INTERFACE
    {
        idlc()->setParseState(PS_ServiceIFHeadSeen);
        $$ = AF_INVALID;
    }
    | flag_header
    IDL_INTERFACE
    {
        idlc()->setParseState(PS_ServiceIFHeadSeen);
        if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
            ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
        $$ = $1;
    }
    ;

service_service_header :
    IDL_SERVICE
    {
        idlc()->setParseState(PS_ServiceSHeadSeen);
        $$ = AF_INVALID;
    }
    | flag_header
    IDL_SERVICE
    {
        idlc()->setParseState(PS_ServiceSHeadSeen);
        if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
            ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
        $$ = $1;
    }
    ;

service_dcl :
    IDL_SERVICE
    {
        idlc()->setParseState(PS_ServiceSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_ServiceIDSeen);
        checkIdentifier($3);

        AstScope*   pScope = idlc()->scopes()->topNonNull();
        AstService* pService = nullptr;

        /*
         * Make a new service and add it to the enclosing scope
         */
        if (pScope != nullptr)
        {
            pService = new AstService(*$3, pScope);
            pScope->addDeclaration(pService);
        }
        delete $3;
        /*
         * Push it on the stack
         */
        idlc()->scopes()->push(pService);
    }
    service_dfn
    {
        /* this service is finished, pop its scope from the stack */
        idlc()->scopes()->pop();
    }
    ;

service_dfn:
    service_interface_dfn
    | service_obsolete_dfn
    ;

service_interface_dfn:
    ':' scoped_name
    {
        AstScope * scope = idlc()->scopes()->nextToTop();
            // skip the scope pushed by service_dcl
        AstDeclaration * decl = scope->lookupByName(*$2);
        if (decl != nullptr
            && resolveTypedefs(decl)->getNodeType() == NT_interface)
        {
            if (ErrorHandler::checkPublished(decl)) {
                idlc()->scopes()->top()->addDeclaration(decl);
            }
        } else {
            ErrorHandler::lookupError(
                ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
        }
        delete $2;
    }
    opt_service_body
    {
        AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
        if (s != nullptr) {
            s->setSingleInterfaceBasedService();
            s->setDefaultConstructor(!$4);
        }
    }
    ;

opt_service_body:
    service_body { $$ = true; }
    | /* empty */ { $$ = false; }
    ;

service_body:
    '{'
    constructors
    '}'
    ;

constructors:
    constructors constructor
    | /* empty */
    ;

constructor:
    identifier
    {
        checkIdentifier($1);
        AstScope * scope = idlc()->scopes()->top();
        AstOperation * ctor = new AstOperation(nullptr, *$1, scope);
        delete $1;
        scope->addDeclaration(ctor);
        idlc()->scopes()->push(ctor);
    }
    '('
    parameters
    ')'
    opt_raises
    {
        static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
            $6);
        delete $6;
        idlc()->scopes()->pop();
        if (static_cast< AstService * >(idlc()->scopes()->top())->
            checkLastConstructor())
        {
            ErrorHandler::error0(ErrorCode::SimilarConstructors);
        }
    }
    ';'
    ;

singleton_dcl :
    IDL_SINGLETON
    {
        idlc()->setParseState(PS_SingletonSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_SingletonIDSeen);
        checkIdentifier($3);

        AstScope*   pScope = idlc()->scopes()->topNonNull();
        AstService* pService = nullptr;

        /*
         * Make a new service and add it to the enclosing scope
         */
        if (pScope != nullptr)
        {
            pService = new AstService(NT_singleton, *$3, pScope);
            pScope->addDeclaration(pService);
        }
        delete $3;
        /*
         * Push it on the stack
         */
        idlc()->scopes()->push(pService);
    }
    singleton_dfn
    {
        /* this singleton is finished, pop its scope from the stack */
        idlc()->scopes()->pop();
    }
    ;

singleton_dfn:
    singleton_interface_dfn
    | service_obsolete_dfn
    ;

singleton_interface_dfn:
    ':' scoped_name
    {
        AstScope * scope = idlc()->scopes()->nextToTop();
            // skip the scope (needlessly) pushed by singleton_dcl
        AstDeclaration * decl = scope->lookupByName(*$2);
        if (decl != nullptr
            && resolveTypedefs(decl)->getNodeType() == NT_interface)
        {
            if (ErrorHandler::checkPublished(decl)) {
                idlc()->scopes()->top()->addDeclaration(decl);
            }
        } else {
            ErrorHandler::lookupError(
                ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
        }
        delete $2;
    }
    ;

service_obsolete_dfn:
    '{'
    {
        idlc()->setParseState(
            idlc()->scopes()->top()->getScopeNodeType() == NT_service
            ? PS_ServiceSqSeen : PS_SingletonSqSeen);
    }
    service_exports
    {
        idlc()->setParseState(
            idlc()->scopes()->top()->getScopeNodeType() == NT_service
            ? PS_ServiceBodySeen : PS_SingletonBodySeen);
    }
    '}'
    {
        idlc()->setParseState(
            idlc()->scopes()->top()->getScopeNodeType() == NT_service
            ? PS_ServiceQsSeen : PS_SingletonQsSeen);
    }
    ;

type_dcl :
    IDL_TYPEDEF
    {
        idlc()->setParseState(PS_TypedefSeen);
    }
    type_declarator {}
    | struct_type {}
    | enum_type {}
    ;

type_declarator :
    type_spec
    {
        idlc()->setParseState(PS_TypeSpecSeen);
        if ($1 != nullptr && $1->getNodeType() == NT_instantiated_struct) {
            ErrorHandler::error0(ErrorCode::InstantiatedStructTypeTypedef);
        }
    }
    at_least_one_declarator
    {
        idlc()->setParseState(PS_DeclaratorsSeen);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstTypeDef*     pTypeDef = nullptr;
        FeDeclList*     pList = $3;
        FeDeclarator*   pDecl = nullptr;
        AstType const * pType = nullptr;

        /*
         * Create nodes representing typedefs and add them to the
         * enclosing scope
         */
        if ( pScope && $1 && pList )
        {
            FeDeclList::iterator iter = pList->begin();
            FeDeclList::iterator end = pList->end();

            while (iter != end)
            {
                pDecl = (*iter);
                if ( !pDecl )
                {
                    ++iter;
                    continue;
                }

                pType = FeDeclarator::compose($1);

                if ( !pType )
                {
                    ++iter;
                    continue;
                }

                pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);

                pScope->addDeclaration(pTypeDef);
                ++iter;
                delete pDecl;
            }
            delete pList;
        }
    }
    ;

at_least_one_declarator :
    declarator declarators
    {
        if ( $2 )
        {
            $2->push_back($1);
            $$ = $2;
        } else
        {
            FeDeclList* pList = new FeDeclList;
            pList->push_back($1);
            $$ = pList;
        }
    }
    ;

declarators :
    declarators
    ','
    {
        idlc()->setParseState(PS_DeclsCommaSeen);
    }
    declarator
    {
        idlc()->setParseState(PS_DeclsDeclSeen);
        if ( $1 )
        {
            $1->push_back($4);
            $$ = $1;
        } else
        {
            FeDeclList* pList = new FeDeclList;
            pList->push_back($4);
            $$ = pList;
        }
    }
    | /* EMPTY */
    {
        $$ = nullptr;
    }
    ;

declarator :
    identifier
    {
        // For historic reasons, the struct com.sun.star.uno.Uik contains
        // members with illegal names (of the form "m_DataN"); avoid useless
        // warnings about them:
        AstScope * scope = idlc()->scopes()->top();
        if (scope == nullptr || scope->getScopeNodeType() != NT_struct
            || (scopeAsDecl(scope)->getScopedName()
                != "com::sun::star::uno::Uik"))
        {
            checkIdentifier($1);
        }

        $$ = new FeDeclarator(*$1);
        delete $1;
    }
    ;

at_least_one_scoped_name :
    scoped_name scoped_names
    {
        if ($2)
        {
            $2->push_front(*$1);
            $$ = $2;
        } else
        {
            std::list< OString >* pScopedNames = new std::list< OString >;
            // coverity[copy_paste_error : FALSE] - this is not a cut and paste
            pScopedNames->push_back(*$1);
            $$ = pScopedNames;
        }
        delete $1;
    }
    ;

scoped_names :
    scoped_names
    ','
    {
        idlc()->setParseState(PS_SNListCommaSeen);
    }
    scoped_name
    {
        idlc()->setParseState(PS_ScopedNameSeen);
        if ($1)
        {
            $1->push_back(*$4);
            $$ = $1;
        } else
        {
            std::list< OString >* pNames = new std::list< OString >;
            pNames->push_back(*$4);
            $$ = pNames;
        }
        delete $4;
    }
    | /* EMPTY */
    {
        $$ = nullptr;
    }
    ;

scoped_name :
    identifier
    {
        idlc()->setParseState(PS_SN_IDSeen);
        checkIdentifier($1);
        $$ = $1;
    }
    | IDL_SCOPESEPARATOR
    {
        idlc()->setParseState(PS_ScopeDelimSeen);
    }
    identifier
    {
        checkIdentifier($3);
        OString* pName = new OString("::");
        *pName += *$3;
        delete $3;
        $$ = pName;
    }
    | scoped_name
    IDL_SCOPESEPARATOR
    {
    }
    identifier
    {
        checkIdentifier($4);
        *$1 += "::";
        *$1 += *$4;
        delete $4;
        $$ = $1;
    }
    ;

type_spec :
    simple_type_spec
    | constructed_type_spec
    ;

simple_type_spec :
    fundamental_type
    | scoped_name opt_type_args
    {
        $$ = createNamedType($1, $2);
    }
    ;

fundamental_type:
    base_type_spec
    {
        $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
    }
    | sequence_type_spec
    ;

opt_type_args:
    '<' type_args '>' { $$ = $2; }
    | /* empty */ { $$ = nullptr; }
    ;

type_args:
    type_arg
    {
        $$ = new DeclList;
        $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
    }
    | type_args ',' type_arg
    {
        $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
        $$ = $1;
    }
    ;

type_arg:
    simple_type_spec
    {
        if ($1 != nullptr && static_cast< AstType const * >($1)->isUnsigned()) {
            ErrorHandler::error0(ErrorCode::UnsignedTypeArgument);
        }
        $$ = $1;
    }
    ;

base_type_spec :
    integer_type
    | floating_pt_type
    | char_type
    | boolean_type
    | byte_type
    | any_type
    | type_type
    | string_type
    ;

integer_type :
    signed_int
    | unsigned_int
    ;

signed_int :
    IDL_LONG
    {
        $$ = ET_long;
    }
    | IDL_HYPER
    {
        $$ = ET_hyper;
    }
    | IDL_SHORT
    {
        $$ = ET_short;
    }
    ;

unsigned_int :
    IDL_UNSIGNED IDL_LONG
    {
        $$ = ET_ulong;
    }
    | IDL_UNSIGNED IDL_HYPER
    {
        $$ = ET_uhyper;
    }
    | IDL_UNSIGNED IDL_SHORT
    {
        $$ = ET_ushort;
    }
    ;

floating_pt_type :
    IDL_DOUBLE
    {
        $$ = ET_double;
    }
    | IDL_FLOAT
    {
        $$ = ET_float;
    }
    ;

char_type :
    IDL_CHAR
    {
        $$ = ET_char;
    }
    ;

byte_type :
    IDL_BYTE
    {
        $$ = ET_byte;
    }
    ;

boolean_type :
    IDL_BOOLEAN
    {
        $$ = ET_boolean;
    }
    ;

any_type :
    IDL_ANY
    {
        $$ = ET_any;
    }
    ;

type_type :
    IDL_TYPE
    {
        $$ = ET_type;
    }
    ;

string_type :
    IDL_STRING
    {
        $$ = ET_string;
    }
    ;

constructed_type_spec :
    struct_type
    | enum_type
    ;

sequence_type_spec :
    IDL_SEQUENCE
    {
        idlc()->setParseState(PS_SequenceSeen);
        /*
         * Push a sequence marker on scopes stack
         */
        idlc()->scopes()->push(nullptr);
    }
    '<'
    {
        idlc()->setParseState(PS_SequenceSqSeen);
    }
    simple_type_spec
    {
        idlc()->setParseState(PS_SequenceTypeSeen);
    }
    '>'
    {
        idlc()->setParseState(PS_SequenceQsSeen);
        /*
         * Remove sequence marker from scopes stack
         */
        if (idlc()->scopes()->top() == nullptr)
            idlc()->scopes()->pop();
        /*
         * Create a node representing a sequence
         */
        AstScope* pScope = idlc()->scopes()->bottom();
        AstDeclaration* pDecl = nullptr;
        AstDeclaration* pSeq = nullptr;

        if ( $5 )
        {
            AstType const *pType = static_cast<AstType const *>($5);
            if ( pType )
            {
                pSeq = new AstSequence(pType, pScope);
                /*
                 * Add this AstSequence to the types defined in the global scope
                 */
                pDecl = pScope->addDeclaration(pSeq);
                if ( pSeq != pDecl )
                {
                    // if sequence type already defined then use it
                    delete pSeq;
                    pSeq = pDecl;
                }
            }
        }
        $$ = pSeq;
    }
    | error '>'
    {
        yyerror("sequence declaration");
        yyerrok;
        $$ = nullptr;
    }
    ;

struct_type :
    structure_header
    {
        idlc()->setParseState(PS_StructHeaderSeen);

        AstScope*   pScope = idlc()->scopes()->topNonNull();
        AstStruct*  pStruct = nullptr;

        if ( pScope )
        {
            AstStruct const* pBase= static_cast< AstStruct const* >(resolveTypedefs($1->getInherits()));
            pStruct = new AstStruct(
                *$1->getName(), $1->getTypeParameters(), pBase, pScope);
            pScope->addDeclaration(pStruct);
        }
        /*
         * Push the scope of the struct on the scopes stack
         */
        idlc()->scopes()->push(pStruct);
        delete $1;
    }
    '{'
    {
        idlc()->setParseState(PS_StructSqSeen);
    }
    at_least_one_member
    {
        idlc()->setParseState(PS_StructBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_StructQsSeen);
        /* this exception is finished, pop its scope from the stack */
        idlc()->scopes()->pop();
    }
    ;

structure_header :
    IDL_STRUCT
    {
        idlc()->setParseState(PS_StructSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_StructIDSeen);
        checkIdentifier($3);
    }
    opt_type_params
    inheritance_spec
    {
        idlc()->setParseState(PS_InheritSpecSeen);

        // Polymorphic struct type templates with base types would cause various
        // problems in language bindings, so forbid them here.  For example,
        // GCC prior to version 3.4 fails with code like
        //
        //  struct Base { ... };
        //  template< typename typeparam_T > struct Derived: public Base {
        //      int member1 CPPU_GCC3_ALIGN(Base);
        //      ... };
        //
        // (Note that plain struct types with instantiated polymorphic struct
        // type bases, which might also cause problems in language bindings, are
        // already rejected on a syntactic level.)
        if ($5 != nullptr && $6 != nullptr) {
            ErrorHandler::error0(ErrorCode::StructTypeTemplateWithBase);
        }

        $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
        delete $5;
        delete $6;
    }
    ;

opt_type_params:
    '<' type_params '>' { $$ = $2; }
    | /* empty */ { $$ = nullptr; }
    ;

type_params:
    identifier
    {
        $$ = new std::vector< OString >;
        $$->push_back(*$1);
        delete $1;
    }
    | type_params ',' identifier
    {
        if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
            ErrorHandler::error0(ErrorCode::IdenticalTypeParameters);
        }
        $1->push_back(*$3);
        delete $3;
        $$ = $1;
    }
    ;

at_least_one_member : member members ;

members :
    members member
    | /* EMPTY */
    ;

member :
    type_or_parameter
    {
        idlc()->setParseState(PS_MemberTypeSeen);
    }
    at_least_one_declarator
    {
        idlc()->setParseState(PS_MemberDeclsSeen);
    }
    ';'
    {
        idlc()->setParseState(PS_MemberDeclsCompleted);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstMember*      pMember = nullptr;
        FeDeclList*     pList = $3;
        FeDeclarator*   pDecl = nullptr;
        AstType const * pType = nullptr;

        // !!! check recursive type

        if ( pScope && pList && $1 )
        {
            FeDeclList::iterator iter = pList->begin();
            FeDeclList::iterator end = pList->end();
            while (iter != end)
            {
                pDecl = (*iter);
                if ( !pDecl )
                {
                    ++iter;
                    continue;
                }

                pType = FeDeclarator::compose($1);

                if ( !pType )
                {
                    ++iter;
                    continue;
                }

                pMember = new AstMember(pType, pDecl->getName(), pScope);

                if ( !pDecl->checkType($1) )
                {
                    // WARNING
                }

                pScope->addDeclaration(pMember);
                ++iter;
                delete pDecl;
            }
            delete pList;
        }
    }
    | error ';'
    {
        yyerror("member definition");
        yyerrok;
    }
    ;

type_or_parameter:
    fundamental_type
    | scoped_name opt_type_args
    {
        AstDeclaration const * decl = nullptr;
        AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
        if (scope != nullptr && $2 == nullptr) {
            decl = scope->findTypeParameter(*$1);
        }
        if (decl != nullptr) {
            delete $1;
            delete $2;
        } else {
            decl = createNamedType($1, $2);
            if (scope != nullptr && includes(decl, scopeAsDecl(scope))) {
                ErrorHandler::error1(
                    ErrorCode::RecursiveType, scopeAsDecl(scope));
                decl = nullptr;
            }
        }
        $$ = decl;
    }
    ;

enum_type :
    IDL_ENUM
    {
        idlc()->setParseState(PS_EnumSeen);
    }
    identifier
    {
        idlc()->setParseState(PS_EnumIDSeen);
        checkIdentifier($3);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstEnum*        pEnum = nullptr;

        /*
         * Create a node representing an enum and add it to its
         * enclosing scope
         */
        if (pScope != nullptr)
        {
            pEnum = new AstEnum(*$3, pScope);
            /*
             * Add it to its defining scope
             */
            pScope->addDeclaration(pEnum);
        }
        delete $3;
        /*
         * Push the enum scope on the scopes stack
         */
        idlc()->scopes()->push(pEnum);

    }
    '{'
    {
        idlc()->setParseState(PS_EnumSqSeen);
    }
    at_least_one_enumerator
    {
        idlc()->setParseState(PS_EnumBodySeen);
    }
    '}'
    {
        idlc()->setParseState(PS_EnumQsSeen);
        /*
         * Done with this enum. Pop its scope from the scopes stack
         */
        if (idlc()->scopes()->top() == nullptr)
            $$ = nullptr;
        else
        {
            $$ = static_cast<AstEnum*>(idlc()->scopes()->topNonNull());
            idlc()->scopes()->pop();
        }
    }
    ;

at_least_one_enumerator : enumerator enumerators ;

enumerators :
    enumerators
    ','
    {
        idlc()->setParseState(PS_EnumCommaSeen);
    }
    enumerator
    | /* EMPTY */
    | error ','
    {
        yyerror("enumerator definition");
        yyerrok;
    }
    ;

enumerator :
    identifier
    {
        checkIdentifier($1);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstEnum*        pEnum = nullptr;
        AstConstant*    pEnumVal = nullptr;

        if ( pScope && pScope->getScopeNodeType() == NT_enum)
        {
            pEnum = static_cast<AstEnum*>(pScope);
            if (pEnum && $1)
            {
                AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
                pEnumVal = new AstConstant(ET_long , NT_enum_val,
                                           pExpr, *$1, pScope);
            }
            if ( pEnum->checkValue(pEnumVal->getConstValue()) )
                ErrorHandler::error1(ErrorCode::Eval, pEnum);

            pScope->addDeclaration(pEnumVal);
        }
        delete $1;
    }
    | identifier
    '='
    const_expr
    {
        checkIdentifier($1);

        AstScope*       pScope = idlc()->scopes()->topNonNull();
        AstEnum*        pEnum = nullptr;
        AstConstant*    pEnumVal = nullptr;

        if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
        {
            $3->evaluate();
            if ( $3->coerce(ET_long) )
            {
                pEnum = static_cast<AstEnum*>(pScope);
                if (pEnum)
                {
                    pEnumVal = new AstConstant(ET_long , NT_enum_val,
                                               $3, *$1, pScope);
                }
                if ( pEnum->checkValue(pEnumVal->getConstValue()) )
                    ErrorHandler::error1(ErrorCode::Eval, pEnum);

                pScope->addDeclaration(pEnumVal);
            } else
            {
                ErrorHandler::coercionError($3, ET_long);
                delete $3;
            }
        }
        delete $1;
    }
    ;

identifier:
    IDL_IDENTIFIER
    | IDL_GET { $$ = new OString("get"); }
    | IDL_SET { $$ = new OString("set"); }
    | IDL_PUBLISHED { $$ = new OString("published"); }
    ;

%%

/*
 * Report an error situation discovered in a production
 */
void yyerror(char const *errmsg)
{
    ErrorHandler::syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
    idlc()->setParseState(PS_NoState);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/source/scanner.l b/idlc/source/scanner.l
deleted file mode 100644
index aaf74a5..0000000
--- a/idlc/source/scanner.l
+++ /dev/null
@@ -1,526 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

%option yylineno

%{
/*
 * scanner.ll - Lexical scanner for IDLC 1.0
 */

#include <sal/config.h>

#include <stdlib.h>
#include <string.h>

#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
#include <rtl/character.hxx>

#if defined _MSC_VER
#pragma warning ( push )
// Silence warnings about redefinition of INT8_MIN etc in stdint.h
// The flex-generated workdir/LexTarget/idlc/source/scanner.cxx defines them prior to these includes
#pragma warning ( disable : 4005 )
#endif
#include <idlc.hxx>
#if defined _MSC_VER
#pragma warning ( pop )
#endif
#include <errorhandler.hxx>
#include <fehelper.hxx>

#include "attributeexceptions.hxx"


class AstExpression;
class AstMember;

#include <parser.hxx>

/* handle locations */
static int yycolumn = 1;

#define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
    yycolumn += yyleng;

static sal_Int32       beginLine = 0;
static OString docu;

static int asciiToInteger(char const * s, sal_Int64  * sval, sal_uInt64 * uval) {
    bool neg = false;
    if (*s == '-') {
        neg = true;
        ++s;
    }
    unsigned int base = 10;
    if (*s == '0') {
        base = 8;
        ++s;
        if (*s == 'X' || *s == 'x') {
            base = 16;
            ++s;
        }
    }
    sal_uInt64 val = 0;
    for (; *s != 0; ++s) {
        unsigned int n;
        if (*s >= '0' && *s <= '9') {
            n = *s - '0';
        } else {
            switch (*s) {
            case 'A':
            case 'a':
                n = 10;
                break;
            case 'B':
            case 'b':
                n = 11;
                break;
            case 'C':
            case 'c':
                n = 12;
                break;
            case 'D':
            case 'd':
                n = 13;
                break;
            case 'E':
            case 'e':
                n = 14;
                break;
            case 'F':
            case 'f':
                n = 15;
                break;
            default:
                goto done;
            }
        }
        // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
        // base and n are sufficiently small), *if*
        // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
        sal_uInt64 nval = val * base + n;
        if (nval < val) {
            ErrorHandler::syntaxError(
                PS_NoState, idlc()->getLineNumber(),
                "integral constant too large");
            val = 0;
            break;
        }
        val = nval;
    }
 done:
    if (neg) {
        if (val < SAL_CONST_UINT64(0x8000000000000000)) {
            *sval = -static_cast< sal_Int64 >(val);
        } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
            *sval = SAL_MIN_INT64;
        } else {
            ErrorHandler::syntaxError(
                PS_NoState, idlc()->getLineNumber(),
                "negative integral constant too large");
            *sval = 0;
        }
        return IDL_INTEGER_LITERAL;
    } else if (val <= o3tl::make_unsigned(SAL_MAX_INT64)) {
        *sval = static_cast< sal_Int64 >(val);
        return IDL_INTEGER_LITERAL;
    } else {
        *uval = val;
        return IDL_INTEGER_ULITERAL;
    }
}

static double asciiToFloat(const char *s)
{
    double      d = 0.0;
    double      e, k;
    sal_Int32   neg = 0;

    if (*s == '-')
    {
        neg = 1;
        s++;
    }
    while (*s >= '0' && *s <= '9')
    {
        d = (d * 10) + *s - '0';
        s++;
    }
    if (*s == '.')
    {
        s++;
        e = 10;
        while (*s >= '0' && *s <= '9')
        {
            d += (*s - '0') / (e * 1.0);
            e *= 10;
            s++;
        }
    }
    if (*s == 'e' || *s == 'E')
    {
        s++;
        if (*s == '-')
        {
            s++;
        } else
        {
            if (*s == '+')
                s++;
            e = 0;
            while (*s >= '0' && *s <= '9')
            {
                e = (e * 10) + *s - '0';
                s++;
            }
            if (e > 0)
            {
                for (k = 1; e > 0; k *= 10, e--)
                    ;
                d /= k;
            }
        }
    }
    if (neg) d *= -1.0;
    return d;
}

static void idlParsePragma(char* pPragma)
{
    OString pragma(pPragma);
    sal_Int32 index = pragma.indexOf("include");
    char* begin = pPragma + index + 8;
    char* offset = begin;
    while (*offset != ',') offset++;
    //OString include = pragma.copy(index + 8, offset - begin);
    //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
}   

static void parseLineAndFile(char* pBuf)
{
    char    *r = pBuf;
    char    *h;
    bool    bIsInMain = false;

    /* Skip initial '#' */
    if (*r != '#')
        return;

    /* Find line number */
    for (r++; *r == ' ' || *r == '\t' || rtl::isAsciiAlpha(static_cast<unsigned char>(*r)); r++) ;
    h = r;
    for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
    *r++ = 0;
    idlc()->setLineNumber(sal_uInt32(atol(h)));
    yylineno = atol(h);

    /* Find file name, if present */
    for (; *r != '"'; r++)
    {
        if (*r == '\n' || *r == '\0')
            return;
    }
    h = ++r;
    for (; *r != '"'; r++) ;
    *r = 0;
    if (*h == '\0')
        idlc()->setFileName("standard input");
    else
        idlc()->setFileName(OString(h));

    bIsInMain = idlc()->getFileName() == idlc()->getRealFileName();
    idlc()->setInMainfile(bIsInMain);       
}   

// Suppress any warnings from generated code:
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-label"
#elif defined _MSC_VER
/**/
#ifdef yywrap
#undef  yywrap
#define yywrap() 1
#endif
/**/
#endif
#define YY_NO_UNISTD_H
%}

%option noyywrap
%option never-interactive

%x DOCU
%x COMMENT

DIGIT           [0-9]
OCT_DIGIT       [0-7]
HEX_DIGIT       [a-fA-F0-9]
CAPITAL         [A-Z]
ALPHA           [a-zA-Z]
INT_LITERAL     [1-9][0-9]*
OCT_LITERAL     0{OCT_DIGIT}*
HEX_LITERAL     (0x|0X){HEX_DIGIT}*

IDENTIFIER_NEW  ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
IDENTIFIER      ("_"?({ALPHA}|{DIGIT})+)*

%%

[ \t\r]+    ; /* eat up whitespace */
[\n]           {
       idlc()->incLineNumber();
       yycolumn = 1;
       yylineno++;
}

attribute       return IDL_ATTRIBUTE;
bound           return IDL_BOUND;
const           return IDL_CONST;
constants       return IDL_CONSTANTS;
constrained     return IDL_CONSTRAINED;
enum            return IDL_ENUM;
exception       return IDL_EXCEPTION;
interface       return IDL_INTERFACE;
maybeambiguous  return IDL_MAYBEAMBIGUOUS;
maybedefault    return IDL_MAYBEDEFAULT;
maybevoid       return IDL_MAYBEVOID;
module          return IDL_MODULE;
needs           return IDL_NEEDS;
observes        return IDL_OBSERVES;
optional        return IDL_OPTIONAL;
property        return IDL_PROPERTY;
raises          return IDL_RAISES;
readonly        return IDL_READONLY;
removable       return IDL_REMOVABLE;
service         return IDL_SERVICE;
sequence        return IDL_SEQUENCE;
singleton       return IDL_SINGLETON;
struct          return IDL_STRUCT;
transient       return IDL_TRANSIENT;
typedef         return IDL_TYPEDEF;

any             return IDL_ANY;             
boolean         return IDL_BOOLEAN;
byte            return IDL_BYTE;
char            return IDL_CHAR;
double          return IDL_DOUBLE;
float           return IDL_FLOAT;
hyper           return IDL_HYPER;
long            return IDL_LONG;
short           return IDL_SHORT;
string          return IDL_STRING;
type            return IDL_TYPE;
unsigned        return IDL_UNSIGNED;
void            return IDL_VOID;

TRUE            return IDL_TRUE;
True            return IDL_TRUE;
FALSE           return IDL_FALSE;
False           return IDL_FALSE;

in              return IDL_IN;
out             return IDL_OUT;
inout           return IDL_INOUT;

get             return IDL_GET;
set             return IDL_SET;

published       return IDL_PUBLISHED;

"..."           return IDL_ELLIPSIS;

("-")?{INT_LITERAL}+(l|L|u|U)?    {
                return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
            }

("-")?{OCT_LITERAL}+(l|L|u|U)?    {
                return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
            }

("-")?{HEX_LITERAL}+(l|L|u|U)?    {
                return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
            }

("-")?{DIGIT}+(e|E)(("+"|"-")?{DIGIT}+)?(f|F)?  |
("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)?        {
                yylval.dval = asciiToFloat( yytext );
                return IDL_FLOATING_PT_LITERAL;
            }

{IDENTIFIER}    {
                yylval.sval = new OString(yytext);
                return IDL_IDENTIFIER;
            }

\<\<    {
        yylval.strval = yytext;
        return IDL_LEFTSHIFT;
    }
\>\>    {
        yylval.strval = yytext;
        return IDL_RIGHTSHIFT;
    }
\:\:    {
        yylval.strval = yytext;
        return IDL_SCOPESEPARATOR;
    }

"/*"    { 
            BEGIN( COMMENT );
            docu = OString();
            beginLine = idlc()->getLineNumber();
        }

"/***"  { 
            BEGIN( COMMENT );
            docu = OString();
            beginLine = idlc()->getLineNumber();
        }

<COMMENT>[^*]+  {
                docu += yytext;
            } 

<COMMENT>"*"[^*/]+  {
                docu += yytext;
            }

<COMMENT>"**"   {
                docu += yytext;
            }

<COMMENT>[*]+"/"  {
                docu = docu.trim();
                sal_Int32 nIndex = 0;
                int count = 0;
                do { o3tl::getToken(docu, 0, '\n', nIndex ); count++; } while( nIndex != -1 );
                idlc()->setLineNumber( beginLine + count - 1);
                BEGIN( INITIAL );
            }

"/**"   {
            BEGIN( DOCU );
            docu = OString();
            beginLine = idlc()->getLineNumber();
        }

<DOCU>[^*\n]+   {
                docu += yytext;
            }

<DOCU>"\n"[ \t]*"*"{1}  {
                idlc()->setLineNumber( idlc()->getLineNumber()  + 1);
                docu += "\n";
            }

<DOCU>"\n"  {
                idlc()->setLineNumber( idlc()->getLineNumber()  + 1);
                docu += yytext;
            }

<DOCU>"*"[^*^/\n]*  {
                docu += yytext;
            }

<DOCU>"\n"[ \t]*"*/"    {
                docu = docu.trim();
                sal_Int32 nIndex = 0;
                int count = 0;
                do { o3tl::getToken(docu, 0, '\n', nIndex ); count++; } while( nIndex != -1 );
                idlc()->setLineNumber( beginLine + count - 1);                
                if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
                {
                    if ( 0 != nIndex &&
                         (docu[nIndex - 1] != '"' && docu[nIndex - 1] != ':') )
                        ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
                                                     "nested documentation strings are not allowed!");
                }
                idlc()->setDocumentation(docu);
                BEGIN( INITIAL );
            }

<DOCU>"*/"  {
                docu = docu.trim();
                sal_Int32 nIndex = 0;
                int count = 0;
                do { o3tl::getToken(docu, 0, '\n', nIndex ); count++; } while( nIndex != -1 );
                idlc()->setLineNumber( beginLine + count - 1);
                if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
                {
                    if ( 0 != nIndex &&
                         (docu[nIndex - 1] != '"' && docu[nIndex - 1] != ':') )
                        ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
                                                     "nested documentation strings are not allowed!");
                }
                idlc()->setDocumentation(docu);
                BEGIN( INITIAL );
            }

"//"[^/]{1}.*"\n" {
                /* only a comment */
                OString docStr(yytext);
                docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
                docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
                docStr = docStr.trim();
                idlc()->incLineNumber();
            }

"///".*"\n"  {
                OString docStr(yytext);
                docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
                docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
                docStr = docStr.trim();
                idlc()->incLineNumber();
                idlc()->setDocumentation(docStr);
            }

.   return yytext[0];

^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n    {
    parseLineAndFile(yytext);
}

^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
    parseLineAndFile(yytext);
}

^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
    parseLineAndFile(yytext);
}

^#[ \t]*[0-9]*\n {
    parseLineAndFile(yytext);
}

^#[ \t]*ident.*\n {
    /* ignore cpp ident */
    idlc()->incLineNumber();
}

^#[ \t]*pragma[ \t].*\n        {       /* remember pragma */
    idlParsePragma(yytext);
    idlc()->incLineNumber();
}

%%

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/idlc/test/const.idl b/idlc/test/const.idl
deleted file mode 100644
index aeb638e..0000000
--- a/idlc/test/const.idl
+++ /dev/null
@@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

module idlc
{
module test
{
    const long l = 1;
    const long add = 1 + 2;
    const long sub = 3 - 2;
    const hyper h = 123456789;
    const float f7 = 3.4123;
    const float f2 = 3.4123 + 10e-12;
    const boolean bt = True;
    const boolean bf = False;
    const boolean and = bt & bf;

    /// SHORT_MAX + 1;
    const short shortMax = -0x8000;
    /// LONG_MAX + 1;
    const unsigned long longMax = 0x80000000;


constants USER
{
    /// = 1
    const long FLAG1 = 0x00000001;
    /// = 2
    const long FLAG2 = 0x00000002;
    /// = 4
    const long FLAG3 = 0x00000004;
    /// = 8
    const long FLAG4 = 0x00000008;
    /// = 16
    const long FLAG5 = 0x00000010;
    /// = 0
    const long FLAG6 = FLAG1 & FLAG2;
    /// = 3
    const long FLAG7 = FLAG1 | FLAG2;
    /// = 2
    const long FLAG8 = (FLAG1 | FLAG2) & FLAG2;
    /// = 4
    const long FLAG9 = FLAG1 << 2;
    /// = 32
    const long FLAG10 = (FLAG5 >> 1) << 2;
    /// = 1
    const long FLAG11 = 33 % 4;
    /// = 4
    const long FLAG12 = FLAG10 / 8;
};

};
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/enum.idl b/idlc/test/enum.idl
deleted file mode 100644
index 9ddbd6e..0000000
--- a/idlc/test/enum.idl
+++ /dev/null
@@ -1,45 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

module idlc
{
module test
{

enum Error
{
    NONE,
    FATAL,
    SYSTEM,
    RUNTIME
};

enum Warning
{
    NO,
    USER = 2,
    WRONGPASSWORD = 4,
    IDFAILURE
};


};
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/exception.idl b/idlc/test/exception.idl
deleted file mode 100644
index cc15069..0000000
--- a/idlc/test/exception.idl
+++ /dev/null
@@ -1,40 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

module idlc
{
module test
{

exception BaseException
{
    string  Description;
};

exception RuntimeException : BaseException
{
    long    Id;
    type    Context;
};


};
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/identifiers.idl b/idlc/test/identifiers.idl
deleted file mode 100644
index d845b372..0000000
--- a/idlc/test/identifiers.idl
+++ /dev/null
@@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

struct Identifiers
{
    long onlysmallalphas;
    long smallMixedAlphas;
    long CapMixedAlphas;
    long ONLYCAPS;
    long CAPS_WITH_UNDERSCORE;
    long CAPS_WITH_UNDERSCORE_11;
    long CAPS_WITH_UNDERSCORE11_11TEST;
    long CapMixed_Alphas_11;
    long m_CapMixedAlphas_11; // should be not allowed with -cid
    long small_get; //should be not allowed with -cid
    long small_11; //should be not allowed with -cid
    long small_11small; //should be not allowed with -cid
    long mixedAlphas_11CAPS; // should be not allowed with -cid
    long mixedAlphas_11mixedAlphas; // should be not allowed with -cid
    long _mixedAlphas; // should be not allowed with -cid
//     long _mixedAlphas_; // should be not allowed
//     long CapsMixedAlphas_; // should be not allowed
//     long _CapsMixedAlphas_; // should be not allowed

};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/interface.idl b/idlc/test/interface.idl
deleted file mode 100644
index 5de90a0..0000000
--- a/idlc/test/interface.idl
+++ /dev/null
@@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <enum.idl>
#include <struct.idl>

module idlc
{

module test
{

interface XBase
{
    [readonly, attribute] string description;

    string getDescription();
};

interface XTestBaseTypes : XBase
{
    void voidFunc();

    short shortFunc( [in] short inparam, [out] short outparam, [inout] short inoutparam);
    unsigned short uShortFunc( [in] unsigned short inparam, [out] unsigned short outparam, [inout] unsigned short inoutparam);

    long longFunc( [in] long inparam, [out] long outparam, [inout] long inoutparam);
    unsigned long ulongFunc( [in] unsigned long inparam, [out] unsigned long outparam, [inout] unsigned long inoutparam);

    hyper hyperFunc( [in] hyper inparam, [out] hyper outparam, [inout] hyper inoutparam);
    unsigned hyper uHyperFunc( [in] unsigned hyper inparam, [out] unsigned hyper outparam, [inout] unsigned hyper inoutparam);

    float floatFunc( [in] float inparam, [out] float outparam, [inout] float inoutparam);
    double doubleFunc( [in] double inparam, [out] double outparam, [inout] double inoutparam);
    char charFunc( [in] char inparam, [out] char outparam, [inout] char inoutparam);
    string stringFunc( [in] string inparam, [out] string outparam, [inout] string inoutparam);
    byte byteFunc( [in] byte inparam, [out] byte outparam, [inout] byte inoutparam);

    type typeFunc( [in] type inparam, [out] type outparam, [inout] type inoutparam);
    any anyFunc( [in] any inparam, [out] any outparam, [inout] any inoutparam);
};


interface XTestComplexTypes : XBase
{
    Error enumFunc( [in] Error inparam, [out] Error outparam, [inout] Error inoutparam);

    BaseStruct structFunc( [in] ::idlc::test::BaseStruct inparam, [out] idlc::test::BaseStruct outparam, [inout] BaseStruct inoutparam);
};

};

};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/service.idl b/idlc/test/service.idl
deleted file mode 100644
index 79107f93..0000000
--- a/idlc/test/service.idl
+++ /dev/null
@@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <interface.idl>

module idlc
{
module test
{

exception bla
{
};

service IdlTest
{
//  [property] bla p0;
    [property] short p1;
    [optional, property] unsigned short p2;

    [maybevoid, property] long p3;
    [bound, property] unsigned long p4;

    [constrained, property] hyper p5;
    [transient, property] unsigned hyper p6;

    [maybeambiguous, property] string p7;
    [maybedefault, property] type p8;
    [removable, property] any p9;

    [readonly, optional, removable, property] ::idlc::test::BaseStruct p10;

    interface XTestBaseTypes;
    [optional] interface ::idlc::test::XTestComplexTypes;
};

service BetterIdlTest
{
    service IdlTest;

    interface XTestBaseTypes;
    [optional] interface ::idlc::test::XTestComplexTypes;
};

};
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/singleton.idl b/idlc/test/singleton.idl
deleted file mode 100644
index e69e290..0000000
--- a/idlc/test/singleton.idl
+++ /dev/null
@@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <interface.idl>

module idlc
{
module test
{

exception bla
{
};

service IdlTest
{
//  [property] bla p0;
    [property] short p1;
    [optional, property] unsigned short p2;

    [maybevoid, property] long p3;
    [bound, property] unsigned long p4;

    [constrained, property] hyper p5;
    [transient, property] unsigned hyper p6;

    [maybeambiguous, property] string p7;
    [maybedefault, property] type p8;
    [removable, property] any p9;

    [readonly, optional, removable, property] ::idlc::test::BaseStruct p10;

    interface XTestBaseTypes;
    [optional] interface ::idlc::test::XTestComplexTypes;
};

singleton SingletonTest
{
    service IdlTest;
};

};
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/struct.idl b/idlc/test/struct.idl
deleted file mode 100644
index 133471d..0000000
--- a/idlc/test/struct.idl
+++ /dev/null
@@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

/* In this file the idl struct will be tested.
  bla
 */

/// idlc defines a test module
module idlc
{

/// test defines a test module
module test
{

typedef sequence< long > Id;
//struct Bla
//{
//  long bla;
//};

/** bla
   BaseStruct defines an * initial struct
 */
struct BaseStruct
{
    Id Id;

    /// a short  member
    short   m1;

    /// an unsigned short  member
    unsigned short  m2;

    /// a long member
    long    m3;

    /// an unsigned long  member
    unsigned long   m4;

    /// a hyper member
    hyper   m5;

    /// an unsigned hyper  member
    unsigned hyper  m6;

    /// a string member
    string  m7;

    /// a byte member
    byte    m8;

    /// a type member
    type    m9;

    /// a float member
    float   m10;

    /// a double member
    double  m11;

    /// a char member
    char    m12;

    /// a boolean member
    boolean m13;

    /// an any member
    any     m14;
};

interface XTestBaseTypes;

typedef sequence< long > LongSeq;

typedef sequence< LongSeq > LongSeqSeq;

/** TestStruct deinfes a struct which inherits
    from the base strcut type BaseStruct.
*/
struct TestStruct : BaseStruct
{
    /// a sequence< long > member
    sequence< long >    ms1;

    /// a sequence< sequence< long > > member
    sequence< sequence< long > >    ms2;

    /// an interface member
    XTestBaseTypes ms5;

    /// a typedef  member
    LongSeq ms6;

    /// a further typedef  member
    LongSeqSeq ms7;

    /// a sequence typedef  member
    sequence<LongSeq> ms8;

};

}; };

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/idlc/test/typelookup.idl b/idlc/test/typelookup.idl
deleted file mode 100644
index a9b5612..0000000
--- a/idlc/test/typelookup.idl
+++ /dev/null
@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

/* In this file the idl struct will be tested.
  bla
 */

#include <enum.idl>

typedef short Error;

/// idlc defines a test module
module idlc
{

typedef long Error;

/// test defines a test module
module test
{

/** bla
   BaseStruct defines an * initial struct
 */
struct BaseStruct
{
    /// a long member
    long    m1;
    /// a string member
    string  m2;
    /// a byte member
    byte    m3;
    /// a type member
    type    m4;
    /// an enum member, Error in module idlc::test
    Error   m5;
    /// a typedef member, global Error (typedef short)
    ::Error m6;
    /// a typedef member, Error in module idlc (typedef long)
    ::idlc::Error   m7;
    /// a typedef member, Error in module idlc (typedef long)
    idlc::Error m8;
    /// an enum member, Error in module idlc::test
    test::Error m9;
};

/** TestStruct deinfes a struct which inherits
    from the base strcut type BaseStruct.
*/
struct TestStruct : BaseStruct
{
    /// a short member
    short           ms1;
    /// a hyper member
    hyper           ms2;
    /// a sequence<long> member
    sequence< long >    ms3;
};

}; // test

}; // idlc

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/odk/CustomTarget_check.mk b/odk/CustomTarget_check.mk
index 0286cc6..e77b1fb 100644
--- a/odk/CustomTarget_check.mk
+++ b/odk/CustomTarget_check.mk
@@ -29,7 +29,7 @@ $(call gb_CustomTarget_get_workdir,odk/check)/checkbin : \
		$(SRCDIR)/odk/util/check.pl \
		$(if $(DOXYGEN),$(call gb_GeneratedPackage_get_target,odk_doxygen)) \
		$(foreach exe,$(if $(filter WNT,$(OS)),$(if $(filter-out AARCH64,$(CPUNAME)),climaker)) cppumaker \
				idlc javamaker $(if $(SYSTEM_UCPP),,ucpp) uno-skeletonmaker unoapploader unoidl-read unoidl-write,\
				javamaker uno-skeletonmaker unoapploader unoidl-read unoidl-write,\
			$(call gb_Executable_get_target,$(exe))) \
		$(if $(filter WNT,$(OS)),$(call gb_Package_get_target,odk_cli)) \
		$(call gb_Package_get_target,odk_config) \
diff --git a/odk/config/cfgWin.js b/odk/config/cfgWin.js
index 128f3e2..f112e23 100644
--- a/odk/config/cfgWin.js
+++ b/odk/config/cfgWin.js
@@ -127,12 +127,12 @@ function getSdkHome()
                continue;
            }
        }
        //Check if this is an sdk folder by looking for the idl sub - dir
        var idlDir = sHome + "\\idl";
        if (! aFileSystemObject.FolderExists(idlDir))
        //Check if this is an sdk folder by looking for the examples sub - dir
        var examplesDir = sHome + "\\examples";
        if (! aFileSystemObject.FolderExists(examplesDir))
        {
            stdout.WriteLine("\n Error: Could not find directory \"" +
                             idlDir + "\". An SDK is required, please specify " +
                             examplesDir + "\". An SDK is required, please specify " +
                             "the path to a valid SDK installation.");
            continue;
        }
diff --git a/odk/docs/tools.html b/odk/docs/tools.html
index adbe0f1..092f4b1 100644
--- a/odk/docs/tools.html
+++ b/odk/docs/tools.html
@@ -70,15 +70,8 @@
            </tr>
            <tr valign="top">
              <td class="content3"><img src="images/arrow-1.gif"/></td>
              <td><a href="#idlc" title="link to the idlc tool description">idlc</a></td>
              <td class="content87">The deprecated UNOIDL compiler, generates a common
			  legacy binary type library format as base for all codemaker tools and
			  the UNO runtime type library.</td>
            </tr>
            <tr valign="top">
              <td class="content3"><img src="images/arrow-1.gif"/></td>
              <td><a href="#unoidl-write" title="link to the unoidl-write tool description">unoidl-write</a></td>
              <td class="content87">The new UNOIDL compiler, generates a common
              <td class="content87">The UNOIDL compiler, generates a common
			  binary type library format as base for all codemaker tools and
			  the UNO runtime type library.</td>
            </tr>
@@ -113,12 +106,6 @@
            </tr>
            <tr valign="top">
              <td class="content3"><img src="images/arrow-1.gif"/></td>
              <td><a href="#regmerge"  title="link to the regmerge tool description">regmerge</a></td>
              <td class="content87">Deprecated tool to merge several legacy registry (e.g. type
			  libraries) files into one file. <b>Note:</b> Since OpenOffice.org 3 it is no longer part of the SDK but it comes directly with the office as part of the <b>ure</b>.</td>
            </tr>
            <tr valign="top">
              <td class="content3"><img src="images/arrow-1.gif"/></td>
              <td><a href="#regview"  title="link to the regview tool description">regview</a></td>
              <td class="content87">Tool to view the content of a legacy registry file
			  in a human readable manner. Special support for type library
@@ -334,80 +321,6 @@
    <td>
      <table class="table2">
        <tr>
		  <td colspan="2" class="head1"><a name="idlc"/>idlc</td>
		  <td align="right">
		    <a href="#tools" title="link to the tools overview"><img class="navigate" src="images/nav_up.png"/></a>
		    <a href="../index.html" title="link to the SDK start page"><img class="navigate" src="images/nav_home.png"/></a>
		  </td>
        </tr>
		<tr>
		  <td colspan="3">
		  <p>'idlc' is the deprecated UNOIDL compiler.  It is a full featured compiler used
		  to check UNODL type definitions and transform valid type definitions
		  into a binary type library format, which is later used by all codemaker
		  tools. It is also used as a dynamic type library for UNO at runtime.<br/>
		  You can find a syntax description for UNOIDL <a href="http://wiki.openoffice.org/wiki/Documentation/DevGuide/AppendixD/UNOIDL_Syntax_Specification" title="link to the &quot;UNOIDL Syntax Specification&quot; chapter in the Developer's Guide">here</a>.</p>
		  <p><b>Note:</b> idlc and regmerge are deprecated and produce a legacy binary type
		  library format that is different from the new format that is produced by
		  unoidl-write.</p>
		  <p class="head2">Usage:</p>
		  <blockquote>
		  <b><code>idlc [-options] file_1 ... file_n | @&lt;filename&gt;</code></b>
		  </blockquote>
		  <table class="table4">
		  <tr>
            <td class="cell15"><code>file_1 ... file_n</code></td>
			<td class="cell85">specifies one or more idl files. Only files with
			the extension '.idl' are valid.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>@&lt;filename&gt;</code></td>
			<td class="cell85">filename specifies the name of a command
			file.</td>
          </tr>
		  </table>
		  <p class="head2">Options:</p>
		  <table class="table4">
		  <tr>
            <td class="cell15"><code>-O&lt;path&gt;</code></td>
			<td class="cell85">path describes the output directory. The
			generated output is a legacy registry file with the same name as the idl
			input file.</td>
          </tr>
          <tr>
		    <td class="cell15"><code>-I&lt;path&gt;</code></td>
			<td class="cell85">path specifies a directory where included files
			that will be searched by the preprocessor are located. Multiple
			directories can be combined with ';'.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>-D&lt;name&gt;</code></td>
			<td class="cell85">name defines a macro for the preprocessor.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>-C</code></td>
			<td class="cell85">generates complete type information, including
			additional service information and documentation.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>-h|?</code></td>
			<td class="cell85">print this help message and exit.</td>
          </tr>
		  </table>
		  </td>
		</tr>
      </table>
    </td>
    <td class="content1"><img class="nothing8" src="images/nada.gif"/></td>
  </tr>
  <tr>
    <td colspan="3"><img class="line" src="images/sdk_line-1.gif"/></td>
  </tr>
  <tr>
    <td class="content1"><img class="nothing8" src="images/nada.gif"/></td>
    <td>
      <table class="table2">
        <tr>
		  <td colspan="2" class="head1"><a name="unoidl-write"/>unoidl-write</td>
		  <td align="right">
		    <a href="#tools" title="link to the tools overview"><img class="navigate" src="images/nav_up.png"/></a>
@@ -897,61 +810,6 @@ types the specified types depend on.</p>
    <td>
      <table class="table2">
        <tr>
		  <td colspan="2" class="head1"><a name="regmerge"/>regmerge</td>
		  <td align="right">
		    <a href="#tools" title="link to the tools overview"><img class="navigate" src="images/nav_up.png"/></a>
		    <a href="../index.html" title="link to the SDK start page"><img class="navigate" src="images/nav_home.png"/></a>
		  </td>
        </tr>
		<tr>
		  <td colspan="3">
		  <p>The deprecated 'regmerge' is a small tool to merge different legacy registry files under a
		  specified key into another legacy registry file. If a value already exists in
		  the target file the value is overwritten by the value of the source
		  file.</p>
		  <p><b>Note:</b> idlc and regmerge are deprecated and produce a legacy binary type
		  library format that is different from the new format that is produced by
		  unoidl-write.</p>
		  <p class="head2">Usage:</p>
		  <blockquote>
		  <b><code>regmerge [-v|--verbose] &lt;mergefile&gt; &lt;mergeKeyName&gt; &lt;regfile_1&gt; ... &lt;regfile_n&gt;</code></b>
		  </blockquote>
		  <p class="head2">Options:</p>
		  <table class="table4">
		  <tr>
            <td class="cell15"><code>-v|--verbose</code></td>
			<td class="cell85">verbose output on stdout.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>&lt;mergefile&gt;</code></td>
			<td class="cell85">specifies the merged registry file. If this file
			doesn't exist, it is created.</td>
		  </tr>
		  <tr>
            <td class="cell15"><code>&lt;mergeKeyName&gt;</code></td>
			<td class="cell85">specifies the merge key, everything is merged
			under this key. If this key doesn't exist, it is created.</td>
          </tr>
		  <tr>
            <td class="cell15"><code>&lt;regfile_1&gt; ... &lt;regfile_n&gt;</code></td>
			<td class="cell85">specifies one or more registry files that are
			merged.</td>
		  </tr>
		  </table>
		  </td>
		</tr>
      </table>
    </td>
    <td class="content1"><img class="nothing8" src="images/nada.gif"/></td>
  </tr>
  <tr>
    <td colspan="3"><img class="line" src="images/sdk_line-1.gif"/></td>
  </tr>
  <tr>
    <td class="content1"><img class="nothing8" src="images/nada.gif"/></td>
    <td>
      <table class="table2">
        <tr>
		  <td colspan="2" class="head1"><a name="regview"/>regview</td>
		  <td align="right">
		    <a href="#tools" title="link to the tools overview"><img class="navigate" src="images/nav_up.png"/></a>
diff --git a/odk/settings/std.mk b/odk/settings/std.mk
index e457e84..2a07632 100644
--- a/odk/settings/std.mk
+++ b/odk/settings/std.mk
@@ -88,11 +88,9 @@ SDK_SED="$(OO_SDK_SED_HOME)/sed"
else
SDK_SED=sed
endif
IDLC="$(OO_SDK_HOME)/bin/idlc"
UNOIDLWRITE="$(OO_SDK_HOME)/bin/unoidl-write"
CPPUMAKER="$(OO_SDK_HOME)/bin/cppumaker"
JAVAMAKER="$(OO_SDK_HOME)/bin/javamaker"
REGMERGE="$(OO_SDK_URE_BIN_DIR)/regmerge"

SDK_JAVA_UNO_BOOTSTRAP_FILES=\
    -C $(CLASSES_DIR) $(SQM)com/sun/star/lib/loader/$(SQM)
diff --git a/odk/util/check.pl b/odk/util/check.pl
index 377c8be..8c17286 100644
--- a/odk/util/check.pl
+++ b/odk/util/check.pl
@@ -45,12 +45,9 @@ if (-d "$SdkDir") {
    # check binaries
    print "check binaries: ";
    if (check_dir("bin")) {
        my @binarylist = ( "idlc","cppumaker","javamaker",
        my @binarylist = ( "cppumaker","javamaker",
               "unoidl-read", "unoidl-write",
               "unoapploader", "uno-skeletonmaker" );
    if ($ENV{SYSTEM_UCPP} eq "") {
        push @binarylist,"ucpp";
    }

    foreach $i (@binarylist)
    {
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 5f0ae2e..4ed97c8 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -19,7 +19,6 @@

$(eval $(call gb_UnoApi_UnoApi,offapi))

$(eval $(call gb_UnoApi_package_idlfiles,offapi))

$(eval $(call gb_UnoApi_use_api,offapi,\
    udkapi \
diff --git a/registry/Executable_regmerge.mk b/registry/Executable_regmerge.mk
deleted file mode 100644
index a55acf8..0000000
--- a/registry/Executable_regmerge.mk
+++ /dev/null
@@ -1,29 +0,0 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

$(eval $(call gb_Executable_Executable,regmerge))

$(eval $(call gb_Executable_use_libraries,regmerge,\
    reg \
    $(if $(filter TRUE,$(DISABLE_DYNLOADING)),store) \
    $(if $(filter TRUE,$(DISABLE_DYNLOADING)),salhelper) \
    sal \
))

$(eval $(call gb_Executable_use_static_libraries,regmerge,\
    registry_helper \
))

$(eval $(call gb_Executable_add_exception_objects,regmerge,\
    registry/tools/regmerge \
))

$(eval $(call gb_Executable_add_default_nativeres,regmerge))

# vim:set noet sw=4 ts=4:
diff --git a/registry/Module_registry.mk b/registry/Module_registry.mk
index 40f7230..45c23bd 100644
--- a/registry/Module_registry.mk
+++ b/registry/Module_registry.mk
@@ -12,7 +12,6 @@ $(eval $(call gb_Module_Module,registry))
$(eval $(call gb_Module_add_targets,registry,\
	Library_reg \
    $(call gb_CondExeRegistryTools, \
        Executable_regmerge \
        Executable_regview \
        StaticLibrary_registry_helper \
    ) \
diff --git a/registry/StaticLibrary_registry_helper.mk b/registry/StaticLibrary_registry_helper.mk
index a0c1142..cffd7a2 100644
--- a/registry/StaticLibrary_registry_helper.mk
+++ b/registry/StaticLibrary_registry_helper.mk
@@ -12,7 +12,6 @@ $(eval $(call gb_StaticLibrary_StaticLibrary,registry_helper))

$(eval $(call gb_StaticLibrary_add_exception_objects,registry_helper,\
    registry/tools/fileurl \
    registry/tools/options \
))

# vim: set noet sw=4 ts=4:
diff --git a/registry/tools/options.cxx b/registry/tools/options.cxx
deleted file mode 100644
index 0212c94e..0000000
--- a/registry/tools/options.cxx
+++ /dev/null
@@ -1,144 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "options.hxx"

#include <osl/diagnose.h>

#include <stdio.h>

namespace registry::tools
{

Options::Options (char const * program)
    : m_program (program)
{}

Options::~Options()
{}

// static
bool Options::checkArgument(std::vector< std::string> & rArgs, char const * arg, size_t len)
{
    bool result = ((arg != nullptr) && (len > 0));
    OSL_PRECOND(result, "registry::tools::Options::checkArgument(): invalid arguments");
    if (!result)
        return false;

    switch (arg[0])
    {
    case '@':
        result = len > 1;
        if (result)
        {
            // "@<cmdfile>"
            result = Options::checkCommandFile(rArgs, &(arg[1]));
        }
        break;
    case '-':
        result = len > 1;
        if (result)
        {
            // "-<option>"
            std::string option (&(arg[0]), 2);
            rArgs.push_back(option);
            if (len > 2)
            {
                // "-<option><param>"
                std::string param(&(arg[2]), len - 2);
                rArgs.push_back(param);
            }
        }
        break;
    default:
        rArgs.push_back(std::string(arg, len));
        break;
    }
    return result;
}

// static
bool Options::checkCommandFile(std::vector< std::string > & rArgs, char const * filename)
{
    FILE * fp = fopen(filename, "r");
    if (fp == nullptr)
    {
        fprintf(stderr, "ERROR: Can't open command file \"%s\"\n", filename);
        return false;
    }

    std::string buffer;
    buffer.reserve(256);

    bool quoted = false;
    int  c = EOF;
    while ((c = fgetc(fp)) != EOF)
    {
        switch(c)
        {
        case '\"':
            quoted = !quoted;
            break;
        case ' ':
        case '\t':
        case '\r':
        case '\n':
            if (!quoted)
            {
                if (!buffer.empty())
                {
                    if (!checkArgument(rArgs, buffer.c_str(), buffer.size()))
                    {
                        // failure.
                        (void) fclose(fp);
                        return false;
                    }
                    buffer.clear();
                }
                break;
            }
            [[fallthrough]];
        default:
            buffer.push_back(sal::static_int_cast<char>(c));
            break;
        }
    }
    return fclose(fp) == 0;
}

bool Options::initOptions (std::vector< std::string > & rArgs)
{
    return initOptions_Impl (rArgs);
}

bool Options::badOption (char const * reason, char const * option) const
{
    (void) fprintf(stderr, "%s: %s option '%s'\n", m_program.c_str(), reason, option);
    return printUsage();
}

bool Options::printUsage() const
{
    printUsage_Impl();
    return false;
}

} // namespace registry::tools

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/registry/tools/options.hxx b/registry/tools/options.hxx
deleted file mode 100644
index 6813d21..0000000
--- a/registry/tools/options.hxx
+++ /dev/null
@@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_REGISTRY_TOOLS_OPTIONS_HXX
#define INCLUDED_REGISTRY_TOOLS_OPTIONS_HXX

#include <string>
#include <vector>

namespace registry::tools
{
class Options
{
    std::string m_program;

    Options (Options const &) = delete;
    Options & operator= (Options const &) = delete;

public:
    explicit Options (char const * program);
    virtual ~Options();

    static bool checkArgument (std::vector< std::string > & rArgs, char const * arg, size_t len);

    bool initOptions (std::vector< std::string > & rArgs);
    bool badOption (char const * reason, char const * option) const;

    bool printUsage() const;

protected:
    static  bool checkCommandFile(std::vector< std::string > & rArgs, char const * filename);

    virtual bool initOptions_Impl(std::vector< std::string > & rArgs) = 0;
    virtual void printUsage_Impl() const = 0;
};

} // namespace registry::tools

#endif /* INCLUDED_REGISTRY_TOOLS_OPTIONS_HXX */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/registry/tools/regmerge.cxx b/registry/tools/regmerge.cxx
deleted file mode 100644
index 409773a..0000000
--- a/registry/tools/regmerge.cxx
+++ /dev/null
@@ -1,183 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <registry/registry.hxx>
#include "fileurl.hxx"
#include "options.hxx"

#include <rtl/ustring.hxx>
#include <sal/log.hxx>

#include <stdio.h>
#include <string.h>

using namespace registry::tools;

namespace {

class Options_Impl : public Options
{
    bool m_bVerbose;

public:
    explicit Options_Impl (char const * program)
        : Options(program), m_bVerbose(false)
    {}
    bool isVerbose() const { return m_bVerbose; }

protected:
    virtual void printUsage_Impl() const override;
    virtual bool initOptions_Impl(std::vector< std::string > & rArgs) override;
};

}

void Options_Impl::printUsage_Impl() const
{
    fprintf(stderr, "using: regmerge [-v|--verbose] mergefile mergeKeyName regfile_1 ... regfile_n\n");
    fprintf(stderr, "       regmerge @regcmds\nOptions:\n");
    fprintf(stderr, "  -v, --verbose : verbose output on stdout.\n");
    fprintf(stderr, "  mergefile     : specifies the merged registry file. If this file doesn't exists,\n");
    fprintf(stderr, "                  it is created.\n");
    fprintf(stderr, "  mergeKeyName  : specifies the merge key, everything is merged under this key.\n");
    fprintf(stderr, "                  If this key doesn't exists, it is created.\n");
    fprintf(stderr, "  regfile_1..n  : specifies one or more registry files which are merged.\n");
}

bool Options_Impl::initOptions_Impl (std::vector< std::string > & rArgs)
{
    std::vector< std::string >::iterator first = rArgs.begin(), last = rArgs.end();
    if ((first != last) && ((*first)[0] == '-'))
    {
        std::string option(*first);
        if ((option.compare("-v") == 0) || (option.compare("--verbose") == 0))
        {
            m_bVerbose = true;
        }
        else if ((option.compare("-h") == 0) || (option.compare("-?") == 0))
        {
            return printUsage();
        }
        else
        {
            return badOption("unknown", option.c_str());
        }
        (void) rArgs.erase(first);
    }
    return true;
}

#if (defined UNX)
int main( int argc, char * argv[] )
#else
int __cdecl main( int argc, char * argv[] )
#endif
{
    try
    {
        Options_Impl options(argv[0]);

        std::vector< std::string > args;
        for (int i = 1; i < argc; i++)
        {
            if (!Options::checkArgument(args, argv[i], strlen(argv[i])))
            {
                options.printUsage();
                return 1;
            }
        }
        if (!options.initOptions(args))
        {
            return 1;
        }
        if (args.size() < 3)
        {
            options.printUsage();
            return 1;
        }

        Registry reg;
        OUString regName( convertToFileUrl(args[0].c_str(), args[0].size()) );
        if (reg.open(regName, RegAccessMode::READWRITE) != RegError::NO_ERROR)
        {
            if (reg.create(regName) != RegError::NO_ERROR)
            {
                if (options.isVerbose())
                    fprintf(stderr, "open registry \"%s\" failed\n", args[0].c_str());
                return -1;
            }
        }

        RegistryKey rootKey;
        if (reg.openRootKey(rootKey) != RegError::NO_ERROR)
        {
            if (options.isVerbose())
                fprintf(stderr, "open root key of registry \"%s\" failed\n", args[0].c_str());
            return -4;
        }

        OUString mergeKeyName( OUString::createFromAscii(args[1].c_str()) );
        for (size_t i = 2; i < args.size(); i++)
        {
            OUString targetRegName( convertToFileUrl(args[i].c_str(), args[i].size()) );
            RegError _ret = reg.mergeKey(rootKey, mergeKeyName, targetRegName, options.isVerbose());
            if (_ret != RegError::NO_ERROR)
            {
                if (_ret == RegError::MERGE_CONFLICT)
                {
                    if (options.isVerbose())
                        fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                                args[i].c_str(), args[1].c_str(), args[0].c_str());
                }
                else
                {
                    if (options.isVerbose())
                        fprintf(stderr, "ERROR: merging registry \"%s\" under key \"%s\" in registry \"%s\" failed.\n",
                                args[i].c_str(), args[1].c_str(), args[0].c_str());
                    return -2;
                }
            }
            else
            {
                if (options.isVerbose())
                    fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                            args[i].c_str(), args[1].c_str(), args[0].c_str());
            }
        }

        rootKey.releaseKey();
        if (reg.close() != RegError::NO_ERROR)
        {
            if (options.isVerbose())
                fprintf(stderr, "closing registry \"%s\" failed\n", args[0].c_str());
            return -5;
        }
    }
    catch (const std::exception &e)
    {
        SAL_WARN("registry", "Fatal exception: " << e.what());
        return -5;
    }


    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index a0bb88b..5fc99e2 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -4767,44 +4767,6 @@ idl/source/prj/database.cxx
idl/source/prj/globals.cxx
idl/source/prj/parser.cxx
idl/source/prj/svidl.cxx
idlc/inc/astattribute.hxx
idlc/inc/astbasetype.hxx
idlc/inc/astconstant.hxx
idlc/inc/astdeclaration.hxx
idlc/inc/astexpression.hxx
idlc/inc/astinterface.hxx
idlc/inc/astinterfacemember.hxx
idlc/inc/astmember.hxx
idlc/inc/astoperation.hxx
idlc/inc/astparameter.hxx
idlc/inc/astservice.hxx
idlc/inc/astservicemember.hxx
idlc/inc/aststruct.hxx
idlc/inc/aststructinstance.hxx
idlc/inc/asttypedef.hxx
idlc/inc/errorhandler.hxx
idlc/inc/fehelper.hxx
idlc/inc/idlc.hxx
idlc/inc/idlctypes.hxx
idlc/inc/inheritedinterface.hxx
idlc/inc/options.hxx
idlc/source/astconstant.cxx
idlc/source/astdeclaration.cxx
idlc/source/astdump.cxx
idlc/source/astenum.cxx
idlc/source/astinterface.cxx
idlc/source/astoperation.cxx
idlc/source/astscope.cxx
idlc/source/astservice.cxx
idlc/source/aststruct.cxx
idlc/source/aststructinstance.cxx
idlc/source/errorhandler.cxx
idlc/source/fehelper.cxx
idlc/source/idlc.cxx
idlc/source/idlccompile.cxx
idlc/source/idlcmain.cxx
idlc/source/idlcproduce.cxx
idlc/source/options.cxx
include/LibreOfficeKit/LibreOfficeKit.h
include/LibreOfficeKit/LibreOfficeKit.hxx
include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -7435,9 +7397,6 @@ registry/source/regkey.hxx
registry/test/regdiagnose.h
registry/test/testmerge.cxx
registry/test/testregcpp.cxx
registry/tools/options.cxx
registry/tools/options.hxx
registry/tools/regmerge.cxx
registry/tools/regview.cxx
remotebridges/source/unourl_resolver/unourl_resolver.cxx
reportdesign/inc/PropertyForward.hxx
diff --git a/solenv/flatpak-manifest.in b/solenv/flatpak-manifest.in
index 55358b0..a8b788f 100644
--- a/solenv/flatpak-manifest.in
+++ b/solenv/flatpak-manifest.in
@@ -82,13 +82,6 @@
                    "dest-filename": "@PDFIUM_TARBALL@"
                },
                {
                    "url": "https://dev-www.libreoffice.org/src/@UCPP_TARBALL@",
                    "sha256": "@UCPP_SHA256SUM@",
                    "type": "file",
                    "dest": "external/tarballs",
                    "dest-filename": "@UCPP_TARBALL@"
                },
                {
                    "url": "https://dev-www.libreoffice.org/src/@XMLSEC_TARBALL@",
                    "sha256": "@XMLSEC_SHA256SUM@",
                    "type": "file",
diff --git a/solenv/gbuild/UnoApi.mk b/solenv/gbuild/UnoApi.mk
index d99195d..f396642 100644
--- a/solenv/gbuild/UnoApi.mk
+++ b/solenv/gbuild/UnoApi.mk
@@ -7,8 +7,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

gb_UnoApi_ENABLE_INSTALL := $(and $(filter host,$(gb_Side)),$(filter ODK,$(BUILD_TYPE)))

.PHONY : $(call gb_UnoApi_get_clean_target,%)
$(call gb_UnoApi_get_clean_target,%) :
	$(call gb_Helper_abbreviate_dirs,\
@@ -18,10 +16,6 @@ $(call gb_UnoApi_get_clean_target,%) :
define gb_UnoApi_UnoApi
$(call gb_UnoApiTarget_UnoApiTarget,$(1),$(1))
$(call gb_UnoApiHeadersTarget_UnoApiHeadersTarget,$(1))
ifneq ($(gb_UnoApi_ENABLE_INSTALL),)
$(call gb_Package_Package_internal,$(1)_idl,$(SRCDIR))
$(call gb_Package_set_outdir,$(1)_idl,$(INSTDIR))
endif

$(call gb_UnoApi_get_target,$(1)) :| $(dir $(call gb_UnoApi_get_target,$(1))).dir
$(call gb_UnoApi_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
@@ -36,36 +30,12 @@ $(call gb_Helper_make_userfriendly_targets,$(1),UnoApi)

endef

ifneq ($(gb_UnoApi_ENABLE_INSTALL),)

# Create a package of IDL files for putting into SDK.
#
# gb_UnoApi_package_idlfiles api
define gb_UnoApi_package_idlfiles
$(call gb_UnoApi_get_target,$(1)) :| $(call gb_Package_get_target,$(1)_idl)
$(call gb_UnoApi_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(1)_idl)

endef

define gb_UnoApi__add_idlfile
$(call gb_Package_add_file,$(1)_idl,$(patsubst $(1)/%,$(SDKDIRNAME)/idl/%,$(2).idl),$(2).idl)

endef

else # !gb_UnoApi_ENABLE_INSTALL

gb_UnoApi_package_idlfiles :=
gb_UnoApi__add_idlfile :=

endif

# For enum types, plain struct types, polymorphic struct type templates,
# exception types, interface types, typedefs, and constant groups:
define gb_UnoApi_add_idlfiles
$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hpp,$(3)))
$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hdl,$(3)))
$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))

endef

@@ -73,14 +43,12 @@ endef
define gb_UnoApi_add_idlfiles_nohdl
$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hpp,$(3)))
$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))

endef

# For accumulation-based services and service-based singletons:
define gb_UnoApi_add_idlfiles_noheader
$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))

endef

diff --git a/solenv/qa/python/gbuildtojson.py b/solenv/qa/python/gbuildtojson.py
index b54c901..8f08668 100644
--- a/solenv/qa/python/gbuildtojson.py
+++ b/solenv/qa/python/gbuildtojson.py
@@ -124,7 +124,7 @@ class CheckGbuildToJsonModules(unittest.TestCase):
        shutil.rmtree(self.tempwork)

    def test_gbuildtojson(self):
        modules = ['accessibility', 'android', 'animations', 'apple_remote', 'avmedia', 'basctl', 'basegfx', 'basic', 'bean', 'canvas', 'chart2', 'codemaker', 'comphelper', 'cppcanvas', 'cui', 'dbaccess', 'desktop', 'drawinglayer', 'editeng', 'embeddedobj', 'embedserv', 'eventattacher', 'extras', 'filter', 'forms', 'formula', 'fpicker', 'framework', 'hwpfilter', 'i18nlangtag', 'i18nutil', 'idl', 'idlc', 'instsetoo_native', 'io', 'ios', 'jvmaccess', 'jvmfwk', 'l10ntools', 'librelogo', 'libreofficekit', 'linguistic', 'lotuswordpro', 'nlpsolver', 'o3tl', 'offapi', 'officecfg', 'onlineupdate', 'oovbaapi', 'oox', 'opencl', 'package', 'postprocess', 'pyuno', 'registry', 'remotebridges', 'reportbuilder', 'reportdesign', 'ridljar', 'salhelper', 'sax', 'sc', 'sccomp', 'scp2', 'scripting', 'sd', 'sdext', 'setup_native', 'sfx2', 'slideshow', 'smoketest', 'soltools', 'sot', 'starmath', 'store', 'svgio', 'emfio', 'svl', 'svtools', 'svx', 'sw', 'swext', 'sysui', 'test', 'testtools', 'toolkit', 'ucb', 'ucbhelper', 'udkapi', 'uitest', 'UnoControls', 'unodevtools', 'unoidl', 'unoil', 'unotest', 'unotools', 'unoxml', 'ure', 'uui', 'vbahelper', 'vcl', 'winaccessibility', 'wizards', 'writerperfect', 'xmerge', 'xmlhelp', 'xmloff', 'xmlreader', 'xmlscript', 'xmlsecurity']
        modules = ['accessibility', 'android', 'animations', 'apple_remote', 'avmedia', 'basctl', 'basegfx', 'basic', 'bean', 'canvas', 'chart2', 'codemaker', 'comphelper', 'cppcanvas', 'cui', 'dbaccess', 'desktop', 'drawinglayer', 'editeng', 'embeddedobj', 'embedserv', 'eventattacher', 'extras', 'filter', 'forms', 'formula', 'fpicker', 'framework', 'hwpfilter', 'i18nlangtag', 'i18nutil', 'idl', 'instsetoo_native', 'io', 'ios', 'jvmaccess', 'jvmfwk', 'l10ntools', 'librelogo', 'libreofficekit', 'linguistic', 'lotuswordpro', 'nlpsolver', 'o3tl', 'offapi', 'officecfg', 'onlineupdate', 'oovbaapi', 'oox', 'opencl', 'package', 'postprocess', 'pyuno', 'registry', 'remotebridges', 'reportbuilder', 'reportdesign', 'ridljar', 'salhelper', 'sax', 'sc', 'sccomp', 'scp2', 'scripting', 'sd', 'sdext', 'setup_native', 'sfx2', 'slideshow', 'smoketest', 'soltools', 'sot', 'starmath', 'store', 'svgio', 'emfio', 'svl', 'svtools', 'svx', 'sw', 'swext', 'sysui', 'test', 'testtools', 'toolkit', 'ucb', 'ucbhelper', 'udkapi', 'uitest', 'UnoControls', 'unodevtools', 'unoidl', 'unoil', 'unotest', 'unotools', 'unoxml', 'ure', 'uui', 'vbahelper', 'vcl', 'winaccessibility', 'wizards', 'writerperfect', 'xmerge', 'xmlhelp', 'xmloff', 'xmlreader', 'xmlscript', 'xmlsecurity']
        if os.environ['OS'] == 'WNT':
            # for now, use a limited subset for testing on windows as it is so annoyingly slow on this
            modules = ['chart2', 'cui', 'dbaccess', 'framework', 'oox', 'sfx2', 'svl', 'svtools', 'svx', 'toolkit', 'vcl', 'xmloff']
diff --git a/udkapi/UnoApi_udkapi.mk b/udkapi/UnoApi_udkapi.mk
index 7e54736..03a3acc 100644
--- a/udkapi/UnoApi_udkapi.mk
+++ b/udkapi/UnoApi_udkapi.mk
@@ -19,8 +19,6 @@

$(eval $(call gb_UnoApi_UnoApi,udkapi))

$(eval $(call gb_UnoApi_package_idlfiles,udkapi))


$(eval $(call gb_UnoApi_add_idlfiles_noheader,udkapi,com/sun/star/beans,\
	PropertySet \
diff --git a/unoidl/README.md b/unoidl/README.md
index ed2ec7b..d6421f8 100644
--- a/unoidl/README.md
+++ b/unoidl/README.md
@@ -22,8 +22,7 @@ formats to the `UNOIDL` format.  It is used at build-time to compile `UNOIDL` fo
`.rdb` files (that are used at build-time only, or included in installation sets
in `URE` or `program/types/` or as part of bundled extensions that are created
during the build and not merely included as pre-built `.oxt` files) from source
`.idl` files.  (The SDK still supports deprecated idlc generating legacy format `.rdb` files for
now.)
`.idl` files.

`Executable_unoidl-read` is a helper tool to convert from any of the registry
formats to the source-file format.  It can be used manually after a LibreOffice
diff --git a/ure/source/README b/ure/source/README
index afd642b..d66b700 100644
--- a/ure/source/README
+++ b/ure/source/README
@@ -25,7 +25,6 @@ ELF platforms (Linux, Solaris, *BSD):
/opt/libreoffice/ure/THIRDPARTYLICENSEREADME.html
/opt/libreoffice/ure/README
/opt/libreoffice/ure/bin/uno
/opt/libreoffice/ure/bin/regmerge
/opt/libreoffice/ure/bin/regview
/opt/libreoffice/ure/bin/javaldx
/opt/libreoffice/ure/lib/libuno_cppu.so.3
@@ -83,7 +82,6 @@ Program Files\URE\LICENSE
Program Files\URE\THIRDPARTYLICENSEREADME.html
Program Files\URE\README
Program Files\URE\bin\uno.exe
Program Files\URE\bin\regmerge.exe
Program Files\URE\bin\regview.exe
Program Files\URE\bin\cppu3.dll
Program Files\URE\bin\cppuhelper3MSC.dll
@@ -168,7 +166,7 @@ A URE installation contains the following public files:
- uno is the executable file that runs UNO components.  For more details, see
the SDK Developer's Guide.

- regmerge and regview are tools that work with binary registries that contain
- regview is a tool that works with old-format binary registries that contain
UNO type or UNO service information.  For more details, see the SDK Developer's
Guide.