tbb-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 18520 discussions

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_30468'
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit f16f8734b4834eaccd4d2c9dc018084f766b60f9
Merge: b1ce9a7 7b1c46d
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 20:01:53 2019 +0000
Merge remote-tracking branch 'boklm/bug_30468'
projects/firefox-locale-bundle/build | 2 ++
projects/firefox/build | 6 ++++--
rbm.conf | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
1
0

04 Jul '19
commit 86b5513abc35287d635855de7e2f1321358f9faf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 19:59:27 2019 +0000
Pick up Torbutton 2.2.1
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index fc5f85c225f7..cbf7172b5daa 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit fc5f85c225f7518b078ca20457468e38a78430ad
+Subproject commit cbf7172b5daa49ab53542c7757a64ddbabb29dce
1
0
commit 123e2eb78f9b8922cd50a8fc68f0c15cb8354e0b
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:49:16 2019 +0000
Translations update
---
src/chrome/locale/da/network-settings.dtd | 6 +++---
src/chrome/locale/da/torlauncher.properties | 8 ++++----
src/chrome/locale/fr/network-settings.dtd | 2 +-
src/chrome/locale/th/torlauncher.properties | 10 +++++-----
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/chrome/locale/da/network-settings.dtd b/src/chrome/locale/da/network-settings.dtd
index cdc10bd..52f89be 100644
--- a/src/chrome/locale/da/network-settings.dtd
+++ b/src/chrome/locale/da/network-settings.dtd
@@ -29,7 +29,7 @@
<!ENTITY torsettings.useProxy.type "Proxytype:">
<!ENTITY torsettings.useProxy.type.placeholder "vælg en proxytype">
<!ENTITY torsettings.useProxy.address "Adresse:">
-<!ENTITY torsettings.useProxy.address.placeholder "IP adresse eller værtsnavn">
+<!ENTITY torsettings.useProxy.address.placeholder "IP-adresse eller værtsnavn">
<!ENTITY torsettings.useProxy.port "Port:">
<!ENTITY torsettings.useProxy.username "Brugernavn:">
<!ENTITY torsettings.useProxy.password "Adgangskode:">
@@ -37,7 +37,7 @@
<!ENTITY torsettings.useProxy.type.socks5 "SOCKS 5">
<!ENTITY torsettings.useProxy.type.http "HTTP/HTTPS">
<!ENTITY torsettings.firewall.checkbox "Computeren går gennem en firewall som kun tillader forbindelse til bestemte porte">
-<!ENTITY torsettings.firewall.allowedPorts "Tilladte Porte:">
+<!ENTITY torsettings.firewall.allowedPorts "Tilladte porte:">
<!ENTITY torsettings.useBridges.checkbox "Tor er censureret i mit land">
<!ENTITY torsettings.useBridges.default "Vælg en indbygget bro">
<!ENTITY torsettings.useBridges.default.placeholder "vælg en bro">
@@ -54,7 +54,7 @@
<!ENTITY torsettings.proxyHelpTitle "Hjælp til proxy">
<!ENTITY torsettings.proxyHelp1 "Der kan være brug for en lokal proxy når der oprettes forbindelse gennem et netværk i virksomhed, skole eller universitet. Hvis du er i tvivl om der er brug for en proxy, så kig i internetindstillingerne i en anden browser eller tjek dit systems netværksindstillinger.">
-<!ENTITY torsettings.bridgeHelpTitle "Bro-relæ hjælp">
+<!ENTITY torsettings.bridgeHelpTitle "Hjælp til bro-relæ">
<!ENTITY torsettings.bridgeHelp1 "Broer er ulistede relæer som gør det sværrer at blokere forbindelser til Tor-netværket.  Hver type bro bruger en anderledes metode for at undgå censur.  Dem med obfs får din netværkstrafik til at ligne tilfældig støj og dem med meek får din netværkstrafik til at se ud som om den er forbundet til tjenesten i stedet for Tor.">
<!ENTITY torsettings.bridgeHelp2 "Pga. den måde bestemte lande prøver at blokere Tor, vil bestemte broer virke i nogle lande men ikke andre.  Besøg torproject.org/about/contact.html#support hvis du er i tvivl om hvilke broer der virker i dit land.">
diff --git a/src/chrome/locale/da/torlauncher.properties b/src/chrome/locale/da/torlauncher.properties
index 3046997..fd93c6d 100644
--- a/src/chrome/locale/da/torlauncher.properties
+++ b/src/chrome/locale/da/torlauncher.properties
@@ -22,7 +22,7 @@ torlauncher.failed_to_get_settings=Kan ikke hente Tor-indstillingerne..\n\n%S
torlauncher.failed_to_save_settings=Kan ikke gemme Tor-indstillingerne.\n\n%S
torlauncher.ensure_tor_is_running=Kontroller venligst at Tor kører.
-torlauncher.error_proxy_addr_missing=Du skal angive både IP adresse eller værts navn og en port, for at konfigurere Tor til at bruge en proxy som forbindelse til internettet.
+torlauncher.error_proxy_addr_missing=Du skal angive både IP-adresse eller værtsnavn og en port, for at konfigurere Tor til at bruge en proxy som forbindelse til internettet.
torlauncher.error_proxy_type_missing=Du skal vælge proxytypen:
torlauncher.error_bridges_missing=Du skal angive en eller flere broer.
torlauncher.error_default_bridges_type_missing=Du skal vælge en transporttype for de tildelte broer.
@@ -47,10 +47,10 @@ torlauncher.quit=Afslut
torlauncher.quit_win=Afslut
torlauncher.done=Færdig
-torlauncher.forAssistance=For hjælp, kontakt %S
-torlauncher.forAssistance2=For hjælp, besøg %S
+torlauncher.forAssistance=For at få hjælp, kontakt %S
+torlauncher.forAssistance2=For at få hjælp, besøg %S
-torlauncher.copiedNLogMessages=Kopieringen er gennemført. %S logbeskeder fra Tor er klar til at blive sat ind i et tekstdokument eller en e-mail.
+torlauncher.copiedNLogMessages=Kopieringen er gennemført. %S logbeskeder er klar til at blive indsæt i en tekstredigering eller en e-mail.
torlauncher.bootstrapStatus.starting=Starter
torlauncher.bootstrapStatus.conn_pt=Opretter forbindelse til bro
diff --git a/src/chrome/locale/fr/network-settings.dtd b/src/chrome/locale/fr/network-settings.dtd
index abbc13d..fd80e04 100644
--- a/src/chrome/locale/fr/network-settings.dtd
+++ b/src/chrome/locale/fr/network-settings.dtd
@@ -46,7 +46,7 @@
<!ENTITY torsettings.useBridges.reloadCaptcha.tooltip "Obtenir un nouveau test">
<!ENTITY torsettings.useBridges.captchaSubmit "Envoyer">
<!ENTITY torsettings.useBridges.custom "Utiliser un pont que je connais">
-<!ENTITY torsettings.useBridges.label "Saisir des informations de pont provenant d’une source fiable">
+<!ENTITY torsettings.useBridges.label "Saisir des renseignements de pont provenant d’une source fiable">
<!ENTITY torsettings.useBridges.placeholder "type adresse:port (un par ligne)">
<!ENTITY torsettings.copyLog "Copier le journal Tor dans le presse-papiers">
diff --git a/src/chrome/locale/th/torlauncher.properties b/src/chrome/locale/th/torlauncher.properties
index 3d587f1..5c97813 100644
--- a/src/chrome/locale/th/torlauncher.properties
+++ b/src/chrome/locale/th/torlauncher.properties
@@ -67,7 +67,7 @@ torlauncher.bootstrapStatus.loading_status=กำลังดึงข้อม
torlauncher.bootstrapStatus.loading_keys=กำลังดึง ใบรับรองสิทธิ
torlauncher.bootstrapStatus.requesting_descriptors=กำลังร้องขอข้อมูล relay
torlauncher.bootstrapStatus.loading_descriptors=กำลังดึงข้อมูล relay
-torlauncher.bootstrapStatus.enough_dirinfo=การโหลดข้อมูลrelay เสร็จสิ้น
+torlauncher.bootstrapStatus.enough_dirinfo=การโหลดข้อมูลรีเลย์ เสร็จสิ้น
torlauncher.bootstrapStatus.ap_conn_pt=กำลังสร้างวงจร: กำลังเชื่อมต่อกับสะพาน
torlauncher.bootstrapStatus.ap_conn_done_pt=กำลังสร้างวงจร: เชื่อมต่อกับสะพานแล้ว
torlauncher.bootstrapStatus.ap_conn_proxy=กำลังสร้างวงจร: กำลังเชื่อมต่อกับพร็อกซี
@@ -84,11 +84,11 @@ torlauncher.bootstrapWarning.connectrefused=ถูกปฏิเสธการ
torlauncher.bootstrapWarning.misc=เบ็ดเตล็ด
torlauncher.bootstrapWarning.resourcelimit=ทรัพยากรไม่เพียงพอ
torlauncher.bootstrapWarning.identity=ข้อมูลประจำตัวไม่ตรงกัน
-torlauncher.bootstrapWarning.timeout=นานเกินไปในการเชื่อมต่อ
-torlauncher.bootstrapWarning.noroute=หาเส้นทางไปหา host ไม่พบ
+torlauncher.bootstrapWarning.timeout=หมดเวลาสำหรับการเชื่อมต่อ
+torlauncher.bootstrapWarning.noroute=ไม่พบเส้นทางไปยัง host
torlauncher.bootstrapWarning.ioerror=อ่าน/เขียน ผิดพลาด
-torlauncher.bootstrapWarning.pt_missing=ที่เสียบสำหรับการขนส่งหายไป
+torlauncher.bootstrapWarning.pt_missing=ที่เสียบสำหรับการโอนถ่ายข้อมูลหายไป
torlauncher.nsresult.NS_ERROR_NET_RESET=การเชื่อมต่อกับเซิร์ฟเวอร์หายไป
-torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้.
+torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้
torlauncher.nsresult.NS_ERROR_PROXY_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับพร็อกซี
1
0
commit a5ea1aced958a6c566c5f643ae015aebdafcb32a
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:49:57 2019 +0000
Release preparations for 0.2.19.2
Version bump
---
src/install.rdf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/install.rdf b/src/install.rdf
index d78b9a8..9df9f31 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -7,7 +7,7 @@
<em:creator>The Tor Project, Inc.</em:creator>
<em:contributor>Pearl Crescent, LLC</em:contributor>
<em:id>tor-launcher(a)torproject.org</em:id>
- <em:version>0.2.19.1</em:version>
+ <em:version>0.2.19.2</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html</em:homepageURL>
<em:updateURL>data:text/plain,</em:updateURL>
1
0
commit 397253580d87f74447fe150f7336edcf4d816c79
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 2 10:38:24 2019 +0000
Bug 30468: Add mk locale
---
src/chrome/content/network-settings.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index 7bcd52e..b39a194 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -321,6 +321,7 @@ function populateLocaleList(aLangPackAddons)
"ja" : "\u65e5\u672c\u8a9e",
"ka" : "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8",
"ko" : "\ud55c\uad6d\uc5b4",
+ "mk" : "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438",
"nl" : "Nederlands",
"nb" : "Norsk bokmå\u0345l",
"pl" : "Polski",
1
0
commit cbf7172b5daa49ab53542c7757a64ddbabb29dce
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:11:16 2019 +0000
Release preparations for 2.2.1
CHANGELOG update and version bump
---
src/CHANGELOG | 6 ++++++
src/install.rdf | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index e1b56304..ce95f237 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,3 +1,9 @@
+2.2.1
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Bug 30468: Add mk locale
+ * Translations update
+
2.2
* Bug 30469: Add ro translation
* Translations update
diff --git a/src/install.rdf b/src/install.rdf
index 2d855202..79a4a6db 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>2.2</em:version>
+ <em:version>2.2.1</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0

[tor-browser-build/master] Bug 31058: Pick up correct tor-android-service commit
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit b1ce9a7e79a9d75b1a6388a23bcff3afd64c06bf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:44:21 2019 +0000
Bug 31058: Pick up correct tor-android-service commit
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index e98f745..e269704 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %]'
-git_hash: 074285582eb6415431759738fcccc712d1e4bee3
+git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0
commit 016a6e44a67b5054c9d05b70d604ef4a62e56610
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:07:52 2019 +0000
Translations update
---
src/chrome/locale/ka/aboutTor.dtd | 4 ++--
src/chrome/locale/mk/aboutTor.dtd | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/chrome/locale/ka/aboutTor.dtd b/src/chrome/locale/ka/aboutTor.dtd
index 3cdf164e..c7b5bbff 100644
--- a/src/chrome/locale/ka/aboutTor.dtd
+++ b/src/chrome/locale/ka/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "შეინარჩუნეთ Tor ძლიერი.">
<!ENTITY aboutTor.donationBanner.buttonA "გაიღეთ თანხა">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "ყოველთვიური შემოწირულობები მეტად აძლიერებს Tor-ს.">
+<!ENTITY aboutTor.donationBanner3.line2 "გახდით პირადულობის გუშაგი დღესვე!">
diff --git a/src/chrome/locale/mk/aboutTor.dtd b/src/chrome/locale/mk/aboutTor.dtd
index 551ad217..bb87e67c 100644
--- a/src/chrome/locale/mk/aboutTor.dtd
+++ b/src/chrome/locale/mk/aboutTor.dtd
@@ -30,3 +30,6 @@
<!ENTITY aboutTor.newsletter.link_text "Пријавете се за Tor Вести.">
<!ENTITY aboutTor.donationBanner.line2e "Чувај го Tor силен.">
<!ENTITY aboutTor.donationBanner.buttonA "Донирај сега">
+
+<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
+<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
1
0
commit 3ec6d04c3eeefb766fa1ad4d7e8de8da212863ce
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 2 13:17:41 2019 +0000
Update mk localization
---
src/chrome/locale/mk/aboutDialog.dtd | 19 ++++++
src/chrome/locale/mk/aboutTBUpdate.dtd | 8 +++
src/chrome/locale/mk/aboutTor.dtd | 57 ++++++----------
src/chrome/locale/mk/brand.dtd | 11 +++-
src/chrome/locale/mk/brand.properties | 13 ++--
src/chrome/locale/mk/browserOnboarding.properties | 71 ++++++++++++++++++++
src/chrome/locale/mk/securityLevel.properties | 23 ++++++-
src/chrome/locale/mk/torbutton.dtd | 56 +++++++++++-----
src/chrome/locale/mk/torbutton.properties | 79 ++++++++++++++++-------
9 files changed, 252 insertions(+), 85 deletions(-)
diff --git a/src/chrome/locale/mk/aboutDialog.dtd b/src/chrome/locale/mk/aboutDialog.dtd
new file mode 100644
index 00000000..6fb30ffe
--- /dev/null
+++ b/src/chrome/locale/mk/aboutDialog.dtd
@@ -0,0 +1,19 @@
+<!ENTITY project.start "&brandShortName; е создаден од">
+<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
+<!ENTITY project.tpoLink "the &vendorShortName;">
+<!ENTITY project.end ", кој е непрофитен и кој работи за вашата онлајн приватност и слобода.">
+
+<!ENTITY help.start "Сакате да помогнете?">
+<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
+<!ENTITY help.donateLink "Донирај">
+<!ENTITY help.or "или">
+<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
+<!ENTITY help.getInvolvedLink "приклучи се">
+<!ENTITY help.end "!">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
+<!ENTITY bottomLinks.questions "Прашања?">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
+<!ENTITY bottomLinks.grow "Помогнете Тор мрежата да расте!">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
+<!ENTITY bottomLinks.license "Лиценца">
+<!ENTITY tor.TrademarkStatement "'Tor' и 'Onion Logo' се регистрирани трговски марки на Tor Project, Inc.">
diff --git a/src/chrome/locale/mk/aboutTBUpdate.dtd b/src/chrome/locale/mk/aboutTBUpdate.dtd
new file mode 100644
index 00000000..eb627510
--- /dev/null
+++ b/src/chrome/locale/mk/aboutTBUpdate.dtd
@@ -0,0 +1,8 @@
+<!ENTITY aboutTBUpdate.changelogTitle "Tor Browser Листа на промени">
+<!ENTITY aboutTBUpdate.updated "Tor Browser е ажуриран.">
+<!ENTITY aboutTBUpdate.linkPrefix "За најнови информации за оваа верзија,">
+<!ENTITY aboutTBUpdate.linkLabel "посетете ја нашата веб страна">
+<!ENTITY aboutTBUpdate.linkSuffix ".">
+<!ENTITY aboutTBUpdate.version "Верзија">
+<!ENTITY aboutTBUpdate.releaseDate "Датум на издавање">
+<!ENTITY aboutTBUpdate.releaseNotes "Забелешки за изданието">
diff --git a/src/chrome/locale/mk/aboutTor.dtd b/src/chrome/locale/mk/aboutTor.dtd
index 9f14022b..551ad217 100644
--- a/src/chrome/locale/mk/aboutTor.dtd
+++ b/src/chrome/locale/mk/aboutTor.dtd
@@ -1,47 +1,32 @@
<!--
- - Copyright (c) 2014, The Tor Project, Inc.
+ - Copyright (c) 2018, The Tor Project, Inc.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
-<!ENTITY aboutTor.title "About Tor">
+<!ENTITY aboutTor.title "За Tor">
-<!ENTITY aboutTor.outOfDateTorOn.label "HOWEVER, this browser is out of date.">
-<!ENTITY aboutTor.outOfDateTorOff.label "ALSO, this browser is out of date.">
-<!ENTITY aboutTor.outOfDate2.label "Click on the onion and then choose Download Tor Browser Bundle Update.">
+<!ENTITY aboutTor.viewChangelog.label "Види Листа на промени">
-<!ENTITY aboutTor.check.label "Test Tor Network Settings">
+<!ENTITY aboutTor.ready.label "Истражувај. Приватно.">
+<!ENTITY aboutTor.ready2.label "Подготвени сте за најприватното прелистувачко искуство во светот.">
+<!ENTITY aboutTor.failure.label "Настана грешка!">
+<!ENTITY aboutTor.failure2.label "Tor не работи во овој прелистувач.">
-<!ENTITY aboutTor.success.label "Congratulations!">
-<!ENTITY aboutTor.success2.label "This browser is configured to use Tor.">
-<!ENTITY aboutTor.success3.label "You are now free to browse the Internet anonymously.">
-<!ENTITY aboutTor.failure.label "Something Went Wrong!">
-<!ENTITY aboutTor.failure2.label "Tor is not working in this browser.">
-<!ENTITY aboutTor.failure3prefix.label "For assistance, please contact ">
-<!ENTITY aboutTor.failure3Link "help(a)rt.torproject.org">
-<!ENTITY aboutTor.failure3suffix.label ".">
+<!ENTITY aboutTor.search.label "Пребарај со DuckDuckGo">
+<!ENTITY aboutTor.searchDDGPost.link "https://duckduckgo.com">
-<!ENTITY aboutTor.search.label "Search">
-<!ENTITY aboutTor.searchSPPost.link "https://startpage.com/do/search">
-<!ENTITY aboutTor.searchDDGPost.link "https://duckduckgo.com/html/">
+<!ENTITY aboutTor.torbrowser_user_manual_questions.label "Прашања?">
+<!ENTITY aboutTor.torbrowser_user_manual_link.label "Провери го Tor Browser Упатството »">
+<!-- The next two entities are used within the browser's Help menu. -->
+<!ENTITY aboutTor.torbrowser_user_manual.accesskey "М">
+<!ENTITY aboutTor.torbrowser_user_manual.label "Tor Browser Упатство">
-<!ENTITY aboutTor.torInfo1.label "Additional Info:">
-<!ENTITY aboutTor.torInfo2.label "Country & IP Address:">
-<!ENTITY aboutTor.torInfo3.label "Exit Node:">
-<!ENTITY aboutTor.torInfo4.label "This server does not log any information about visitors.">
-<!ENTITY aboutTor.whatnextQuestion.label "What Next?">
-<!ENTITY aboutTor.whatnextAnswer.label "Tor is NOT all you need to browse anonymously! You may need to change some of your browsing habits to ensure your identity stays safe.">
-<!ENTITY aboutTor.whatnext.label "Tips On Staying Anonymous »">
-<!ENTITY aboutTor.whatnext.link "https://www.torproject.org/download/download.html.en#warning">
-<!ENTITY aboutTor.helpInfo1.label "You Can Help!">
-<!ENTITY aboutTor.helpInfo2.label "There are many ways you can help make the Tor Network faster and stronger:">
-<!ENTITY aboutTor.helpInfo3.label "Run a Tor Relay Node »">
-<!ENTITY aboutTor.helpInfo3.link "https://www.torproject.org/docs/tor-doc-relay.html.en">
-<!ENTITY aboutTor.helpInfo4.label "Volunteer Your Services »">
-<!ENTITY aboutTor.helpInfo4.link "https://www.torproject.org/getinvolved/volunteer.html.en">
-<!ENTITY aboutTor.helpInfo5.label "Make a Donation »">
-<!ENTITY aboutTor.helpInfo5.link "https://www.torproject.org/donate/donate.html.en">
+<!ENTITY aboutTor.tor_mission.label "Tor Project е US 501(c)(3) не-профитна организација која ги унапредува човековите права и слободи со креирање и имплементирање на слободни и отворен-код технологии за анонимност и приватност, поддржувајќи ги нивната неограничена достапност и употреба, како и нивното понатамошно научно и популарно разбирање.">
+<!ENTITY aboutTor.getInvolved.label "Приклучете се »">
+<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
-<!ENTITY aboutTor.footer.label "The Tor Project is a US 501(c)(3) non-profit dedicated to the research, development, and education of online anonymity and privacy.">
-<!ENTITY aboutTor.learnMore.label "Learn more about The Tor Project »">
-<!ENTITY aboutTor.learnMore.link "https://www.torproject.org/about/overview.html.en">
+<!ENTITY aboutTor.newsletter.tagline "Добијте ги најновите вести од Tor директно во вашето сандаче.">
+<!ENTITY aboutTor.newsletter.link_text "Пријавете се за Tor Вести.">
+<!ENTITY aboutTor.donationBanner.line2e "Чувај го Tor силен.">
+<!ENTITY aboutTor.donationBanner.buttonA "Донирај сега">
diff --git a/src/chrome/locale/mk/brand.dtd b/src/chrome/locale/mk/brand.dtd
index 59f665e8..e5e6dca5 100644
--- a/src/chrome/locale/mk/brand.dtd
+++ b/src/chrome/locale/mk/brand.dtd
@@ -2,7 +2,14 @@
- 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/. -->
+<!ENTITY brandShorterName "Tor Browser">
<!ENTITY brandShortName "Tor Browser">
<!ENTITY brandFullName "Tor Browser">
-<!ENTITY vendorShortName "Tor Project">
-<!ENTITY trademarkInfo.part1 "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
+<!ENTITY vendorShortName "Tor Browser">
+<!ENTITY trademarkInfo.part1 "Firefox и Firefox логоата се трговски марки на Mozilla Фондацијата.">
+
+<!-- The following strings are for bug #10280's UI. We place them here for our translators -->
+<!ENTITY plugins.installed.find "Кликни за вчитување на инсталираните системски приклучоци">
+<!ENTITY plugins.installed.enable "Овозможи приклучоци">
+<!ENTITY plugins.installed.disable "Оневозможи приклучоци">
+<!ENTITY plugins.installed.disable.tip "Кликни за запирање на вчитувањето на системските приклучоци">
diff --git a/src/chrome/locale/mk/brand.properties b/src/chrome/locale/mk/brand.properties
index f63def38..8ffcbdf0 100644
--- a/src/chrome/locale/mk/brand.properties
+++ b/src/chrome/locale/mk/brand.properties
@@ -2,14 +2,15 @@
# 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/.
+brandShorterName=Tor Browser
brandShortName=Tor Browser
brandFullName=Tor Browser
-vendorShortName=Tor Project
+vendorShortName=Tor Browser
-homePageSingleStartMain=Firefox Start, a fast home page with built-in search
-homePageImport=Import your home page from %S
+homePageSingleStartMain=Firefox Старт, брза домашна страница со вграден пребарувач
+homePageImport=Внесете ваша домаша страница од %S
-homePageMigrationPageTitle=Home Page Selection
-homePageMigrationDescription=Please select the home page you wish to use:
+homePageMigrationPageTitle=Избор на Домашна странција
+homePageMigrationDescription=Одберете домашна страница која сакате да ја користите:
-syncBrandShortName=Sync
+syncBrandShortName=Синхронизирај
diff --git a/src/chrome/locale/mk/browserOnboarding.properties b/src/chrome/locale/mk/browserOnboarding.properties
new file mode 100644
index 00000000..f7e732cc
--- /dev/null
+++ b/src/chrome/locale/mk/browserOnboarding.properties
@@ -0,0 +1,71 @@
+# Copyright (c) 2019, The Tor Project, Inc.
+# See LICENSE for licensing information.
+# vim: set sw=2 sts=2 ts=8 et:
+
+onboarding.tour-tor-welcome=Добредојдовте
+onboarding.tour-tor-welcome.title=Вие сте подготвени.
+onboarding.tour-tor-welcome.description=Tor Browser ви нуди највисок стандард на приватност и безбедност додека прелистувате на Интернет. Сега сте заштитени од следење, надзор и цензура. Ова брзо ќе ви покаже како.
+onboarding.tour-tor-welcome.next-button=Оди во Приватност
+
+onboarding.tour-tor-privacy=Приватност
+onboarding.tour-tor-privacy.title=Прескокнете ги следачите и водачите.
+onboarding.tour-tor-privacy.description=Tor Browser ги изолира колачињата и ја брише историјата на вашиот прелистувач после вашата сесија. Овие промени кои ја осигуруваат вашата приватност и безбедност се заштитени во прелистувачот. Кликнете на 'Tor Мрежа' за да научите како да се заштитите на мрежно ниво.
+onboarding.tour-tor-privacy.button=Одете на Tor Мрежа
+
+onboarding.tour-tor-network=Tor Мрежа
+onboarding.tour-tor-network.title=Патувајте низ децентрализираната мрежа.
+onboarding.tour-tor-network.description=Tor Browser ве поврзува на Tor мрежата одржувана од илјадници волонтери низ целиот свет. За разлика од VPN, овде нема место за неуспех или централизиран ентитет на кого треба да му верувате со цел да уживате приватност на Интернет.
+onboarding.tour-tor-network.button=Одете на Круг екранот
+
+onboarding.tour-tor-circuit-display=Круг екран
+onboarding.tour-tor-circuit-display.title=Видете ја вашата патека.
+onboarding.tour-tor-circuit-display.description=За секој домеин кој го посетувате, вашиот сообраќај е пренесуван и енкриптиран во круг преку три Tor релеа низ светот. Ниту една веб страна не знае од каде сте поврзани. Можете да побарате нов круг со кликање на 'Нов круг за оваа веб страна' на Круг екранот.
+onboarding.tour-tor-circuit-display.button=Види ја мојата патека
+onboarding.tour-tor-circuit-display.next-button=Оди во Безбедност
+
+onboarding.tour-tor-security=Безбедност
+onboarding.tour-tor-security.title=Изберете го вашето искуство.
+onboarding.tour-tor-security.description=Ние исто така ви овозможуваме дополнителни поставки за зголемување на безбедноста на вашиот прелистувач. Нашите безбедносни поставки ви овозможуваат да блокирате елементи кои можат да бидат користени да го нападнат вашиот компјутер. Кликнете подолу за да ги видите намените на различните опции.
+onboarding.tour-tor-security.description-suffix=Забелешка: Стандардно, NoScript и HTTPS Насекаде не се вклучени во лентата со алатки, но можете да ја прилагодувате вашата лента со алатки за истите да ги додадете.
+onboarding.tour-tor-security-level.button=Погледнете го вашето ниво на безбедност
+onboarding.tour-tor-security-level.next-button=Оди во Препораки од искуство
+
+onboarding.tour-tor-expect-differences=Препораки од искуство
+onboarding.tour-tor-expect-differences.title=Очекувајте некои разлики.
+onboarding.tour-tor-expect-differences.description=Со сите карактеристики за безбедност и приватност кои ви ги овозможува Tor, вашето искуство додека прелистувате на Интернет може да биде малку различно. Некои нешта можат да бидат побавни, и во зависност од вашето поставено ниво на безбедност, некои елементи можат да не работат или да не бидат вчитани воопшто. Исто така можете да бидете прашани да докажете дека сте човек, а не машина.
+onboarding.tour-tor-expect-differences.button=Види ЧПП
+onboarding.tour-tor-expect-differences.next-button=Оди во Onion услуги
+
+onboarding.tour-tor-onion-services=Onion Услуги
+onboarding.tour-tor-onion-services.title=Бидете екстра заштитени.
+onboarding.tour-tor-onion-services.description=Onion услугите се веб страни кои завршуваат со домеин .onion кој овозможува екстра заштити на издавачите и посетителите, вклучувајќи и додадени заштити против цензурата. Onion услугите му овозможуваат на секого да овозможи содржина и услуги анонимно. Кликнете подолу за да ја посетите onion веб страната DuckDuckGo.
+onboarding.tour-tor-onion-services.button=Посетете Onion
+onboarding.tour-tor-onion-services.next-button=Завршено
+
+onboarding.overlay-icon-tooltip-updated2=Видете што има ново\nво %S
+onboarding.tour-tor-update.prefix-new=Ново
+onboarding.tour-tor-update.prefix-updated=Ажурирано
+
+onboarding.tour-tor-toolbar=Лента со алатки
+onboarding.tour-tor-toolbar-update-8.5.title=Распоред на лентата со алатки
+onboarding.tour-tor-toolbar-update-8.5.description=Го подобривме распоредот на лентата со алатки на прелистувачот. Ја поместивме иконата Torbutton после URL барот, и додадовме икона за безбеносно ниво до неа.
+onboarding.tour-tor-toolbar-update-8.5.next-button=Оди во Безбедност
+
+onboarding.tour-tor-security-update-8.5.title=Искуство од безбедносно ниво
+onboarding.tour-tor-security-update-8.5.description=Го подобривме начинот на кој го гледате и поставувате вашето ниво на безбедност. Го заменивме лизгачот за безбедност со икона за лента со алатки која го прави моменталното ниво видливо цело време. Кликнете ја за да видете детали за вашето моментално ниво или да ги промените вашите поставки за безбедност.
+
+# Circuit Display onboarding.
+onboarding.tor-circuit-display.next=Следно
+onboarding.tor-circuit-display.done=Завршено
+onboarding.tor-circuit-display.one-of-three=1 од 3
+onboarding.tor-circuit-display.two-of-three=2 од 3
+onboarding.tor-circuit-display.three-of-three=3 од 3
+
+onboarding.tor-circuit-display.intro.title=Како работат заобиколувањата?
+onboarding.tor-circuit-display.intro.msg=Заобиколувањата се направени од релеа задолжени по случаен избор, кои се всушност компјутери низ целиот свет кои се конфигурирани да го препраќаат Tor сообраќајот. Заобиколувањата ви овозможуваат да прелистувате приватно и да се поврзувате на onion услуги.
+
+onboarding.tor-circuit-display.diagram.title=Круг екран
+onboarding.tor-circuit-display.diagram.msg=Овој дијаграм покажува релеа кои прават круг за оваа веб страна. За да превенирате поврзување на активност низ различни веб страни, секоја веб страна добива различен круг.
+
+onboarding.tor-circuit-display.new-circuit.title=Дали ви треба нов круг?
+onboarding.tor-circuit-display.new-circuit.msg=Ако не можете да се поврзете на веб страната која се обидувате да ја посетите или истата не се вчитува правилно, тогаш можете да го користите ова копче да ја вчитате отпочеток преку нов круг.
diff --git a/src/chrome/locale/mk/securityLevel.properties b/src/chrome/locale/mk/securityLevel.properties
index b6ceb35c..ad7824bc 100644
--- a/src/chrome/locale/mk/securityLevel.properties
+++ b/src/chrome/locale/mk/securityLevel.properties
@@ -1 +1,22 @@
-securityLevel.restoreDefaults = Стандардни подесувања
+securityLevel.securityLevel = Безбедносно ниво
+securityLevel.customWarning = Прилагодено
+securityLevel.overview = Оневозможи одредени веб можности кои можат да бидат користени за напад врз вашата безбедност и анонимност.
+securityLevel.standard.level = Стандардно
+securityLevel.standard.tooltip = Безбедносно ниво: Стандардно
+securityLevel.standard.summary = Сите можности на Tor Browser и веб страните се овозможени.
+securityLevel.safer.level = Побезбедно
+securityLevel.safer.tooltip = Безбедносно ниво: Побезбедно
+securityLevel.safer.summary = Оневозможува можности на веб страните кои често се опасни, сепак воедно предизвикувајќи некои веб страни да ја изгубат функционалноста.
+securityLevel.safer.description1 = JavaScript е оневозможен на не-HTTPS веб страните.
+securityLevel.safer.description2 = Некои фонтови и математички симболи се оневозможени.
+securityLevel.safer.description3 = Аудио и видео (HTML5 медиа), и WebGL се кликни-да-пуштиш.
+securityLevel.safest.level = Најбезбедно
+securityLevel.safest.tooltip = Безбедносно ниво: Најбезбедно
+securityLevel.safest.summary = Дозволува само можности на веб страните потребни за статичните страни и основните услужни сервиси. Овие измени влијаат на сликите, разни мултимедијални датотеки, и скрипти.
+securityLevel.safest.description1 = JavaScript е стандардно оневозможен на сите веб страни.
+securityLevel.safest.description2 = Некои фонтови, икони, математички симболи, и слики се оневозможени.
+securityLevel.safest.description3 = Аудиото и видеото (HTML5 мултимедијата) се кликни-да-почне.
+securityLevel.custom.summary = Вашите прилагодени својства на прелистувачот резултираа со невообичаени безбедносни поставки. Од причини поврзани со безбедноста и приватноста, ви препорачуваме да ги изберете почетните безбедносни нивоа.
+securityLevel.learnMore = Научи повеќе
+securityLevel.restoreDefaults = Врати на стандардно
+securityLevel.advancedSecuritySettings = Напредни Безбедносни Поставки
diff --git a/src/chrome/locale/mk/torbutton.dtd b/src/chrome/locale/mk/torbutton.dtd
index cc240827..1d7224aa 100644
--- a/src/chrome/locale/mk/torbutton.dtd
+++ b/src/chrome/locale/mk/torbutton.dtd
@@ -1,19 +1,41 @@
-<!ENTITY torbutton.context_menu.new_identity "New Identity">
+<!ENTITY torbutton.context_menu.new_identity "Нов идентитет">
<!ENTITY torbutton.context_menu.new_identity_key "I">
-<!ENTITY torbutton.context_menu.networksettings "Open Network Settings…">
-<!ENTITY torbutton.context_menu.downloadUpdate "Download Tor Browser Bundle Update...">
-<!ENTITY torbutton.context_menu.downloadUpdate.key "Z">
-<!ENTITY torbutton.context_menu.cookieProtections "Cookie Protections">
+<!ENTITY torbutton.context_menu.new_circuit "Нов Tor круг за оваа страна">
+<!ENTITY torbutton.context_menu.new_circuit_key "C">
+<!ENTITY torbutton.context_menu.networksettings "Тор мрежни поставки...">
+<!ENTITY torbutton.context_menu.networksettings.key "N">
+<!ENTITY torbutton.context_menu.downloadUpdate "Провери за нова верзија на Tor Browser...">
+<!ENTITY torbutton.context_menu.downloadUpdate.key "U">
+<!ENTITY torbutton.context_menu.cookieProtections "Заштита за колаче...">
<!ENTITY torbutton.context_menu.cookieProtections.key "C">
-<!ENTITY torbutton.button.tooltip "Кликнете за иницирање на Torbutton">
-<!ENTITY torbutton.cookiedialog.title "Manage Cookie Protections">
-<!ENTITY torbutton.cookiedialog.lockCol "Protected">
-<!ENTITY torbutton.cookiedialog.domainCol "Host">
-<!ENTITY torbutton.cookiedialog.nameCol "Name">
-<!ENTITY torbutton.cookiedialog.pathCol "Path">
-<!ENTITY torbutton.cookiedialog.protectCookie "Protect Cookie">
-<!ENTITY torbutton.cookiedialog.removeCookie "Remove Cookie">
-<!ENTITY torbutton.cookiedialog.unprotectCookie "Unprotect Cookie">
-<!ENTITY torbutton.cookiedialog.removeAllBut "Remove All But Protected">
-<!ENTITY torbutton.cookiedialog.saveAllCookies "Protect New Cookies">
-<!ENTITY torbutton.cookiedialog.doNotSaveAllCookies "Do Not Protect New Cookies">
+<!ENTITY torbutton.button.tooltip "Кликнете за иницијализирање на Torbutton">
+<!ENTITY torbutton.prefs.security_settings "Tor Browser безбедносни поставки">
+<!ENTITY torbutton.cookiedialog.title "Уреди ги заштитите за колаче">
+<!ENTITY torbutton.cookiedialog.lockCol "Заштитено">
+<!ENTITY torbutton.cookiedialog.domainCol "Хост">
+<!ENTITY torbutton.cookiedialog.nameCol "Име">
+<!ENTITY torbutton.cookiedialog.pathCol "Патека">
+<!ENTITY torbutton.cookiedialog.protectCookie "Заштити колаче">
+<!ENTITY torbutton.cookiedialog.removeCookie "Избриши колаче">
+<!ENTITY torbutton.cookiedialog.unprotectCookie "Отстрани заштита на колаче">
+<!ENTITY torbutton.cookiedialog.removeAllBut "Избриши ги сите освен заштитените">
+<!ENTITY torbutton.cookiedialog.saveAllCookies "Заштити ги новите колачиња">
+<!ENTITY torbutton.cookiedialog.doNotSaveAllCookies "Не ги штити новите колачиња">
+<!ENTITY torbutton.prefs.sec_caption "Безбедносно ниво">
+<!ENTITY torbutton.prefs.sec_caption_tooltip "Безбедносниот лизгач ви овозможува да исклучите дадени прелистувачки можности кои можат да го направат вашиот прелистувач поранлив на хакерски напади.">
+<!ENTITY torbutton.prefs.sec_standard_label "Стандардно">
+<!ENTITY torbutton.prefs.sec_standard_description "Сите можности на Tor Browser и веб страните се овозможени.">
+<!ENTITY torbutton.prefs.sec_safer_label "Побезбедно">
+<!ENTITY torbutton.prefs.sec_safer_description "Оневозможува можности на веб страните кои често се опасни, предизвикувајќи некои страни да ја изгубат функционалноста.">
+<!ENTITY torbutton.prefs.sec_safer_list_label "На побезбедна поставка:">
+<!ENTITY torbutton.prefs.sec_safest_label "Најбезбедно">
+<!ENTITY torbutton.prefs.sec_safest_description "Дозволува само можности на веб страните потребни за статичните страни и основните услужни сервиси. Овие измени влијаат на сликите, разни мултимедијални датотеки, и на скрптите.">
+<!ENTITY torbutton.prefs.sec_safest_list_label "На најбезбедна поставка:">
+<!ENTITY torbutton.prefs.sec_learn_more_label "Научи повеќе">
+<!ENTITY torbutton.prefs.sec_js_on_https_sites_only "JavaScript е оневозможен на не-HTTPS веб страните.">
+<!ENTITY torbutton.prefs.sec_js_disabled "JavaScript е стандардно оневозможен на сите веб страни.">
+<!ENTITY torbutton.prefs.sec_limit_typography "Некои фонтови и математички симболи се оневозможени.">
+<!ENTITY torbutton.prefs.sec_limit_graphics_and_typography "Некои фонтови, икони, математички симболи, и слики се оневозможени.">
+<!ENTITY torbutton.prefs.sec_click_to_play_media "Аудио и видео (HTML5 медиа), и WebGL се кликни-да-пуштиш.">
+<!ENTITY torbutton.circuit_display.title "Tor круг">
+<!ENTITY torbutton.circuit_display.new_circuit "Нов круг за оваа веб страна">
diff --git a/src/chrome/locale/mk/torbutton.properties b/src/chrome/locale/mk/torbutton.properties
index 7936dde4..898662af 100644
--- a/src/chrome/locale/mk/torbutton.properties
+++ b/src/chrome/locale/mk/torbutton.properties
@@ -1,27 +1,60 @@
-torbutton.panel.tooltip.disabled = Кликнете за да го вклучите Тор
-torbutton.panel.tooltip.enabled = Кликнете за да го исклучите Тор
-torbutton.panel.label.disabled = Тор е исклучен
-torbutton.panel.label.enabled = Тор е вклучен
-extensions.torbutton(a)torproject.org.description = Torbutton provides a button to configure Tor settings and quickly and easily clear private browsing data.
-torbutton.popup.external.title = Вчитување на екстерна содржина?
-torbutton.popup.external.app = Потребна е екстерна апликација за справување со:\n\n
-torbutton.popup.external.note = \n\nЗАБЕЛЕШКА: Екстерните апликации обично НЕ се свесни за Тор и можат да ве откријат!\n
-torbutton.popup.external.suggest = \nIf this file is untrusted, you should either save it to view while offline or in a VM,\nor consider using a transparent Tor proxy like Tails LiveCD or torsocks.\n
-torbutton.popup.launch = Лансирај ја апликацијата
-torbutton.popup.cancel = Откажи се
-torbutton.popup.dontask = Отсега натаму, секогаш лансирај ги апликациите
-torbutton.popup.prompted_language = To give you more privacy, Torbutton can request the English language version of web pages. This may cause web pages that you prefer to read in your native language to display in English instead.\n\nWould you like to request English language web pages for better privacy?
-torbutton.popup.no_newnym = Torbutton cannot safely give you a new identity. It does not have access to the Tor Control Port.\n\nAre you running Tor Browser Bundle?
-torbutton.title.prompt_torbrowser = Important Torbutton Information
-torbutton.popup.prompt_torbrowser = Torbutton works differently now: you can't turn it off any more.\n\nWe made this change because it isn't safe to use Torbutton in a browser that's also used for non-Tor browsing. There were too many bugs there that we couldn't fix any other way.\n\nIf you want to keep using Firefox normally, you should uninstall Torbutton and download Tor Browser Bundle. The privacy properties of Tor Browser are also superior to those of normal Firefox, even when Firefox is used with Torbutton.\n\nTo remove Torbutton, go to Tools->Addons->Extensions and then click the Remove button next to Torbutton.
-torbutton.popup.short_torbrowser = Important Torbutton Information!\n\nTorbutton is now always enabled.\n\nClick on the Torbutton for more information.
+torbutton.circuit_display.internet = Интернет
+torbutton.circuit_display.ip_unknown = IP непозната
+torbutton.circuit_display.onion_site = Onion веб страна
+torbutton.circuit_display.this_browser = Овој прелистувач
+torbutton.circuit_display.relay = Реле
+torbutton.circuit_display.tor_bridge = Мост
+torbutton.circuit_display.unknown_country = Непозната држава
+torbutton.circuit_display.guard = Чувар
+torbutton.circuit_display.guard_note = Твојот [Чувар] јазол може да не се промени.
+torbutton.circuit_display.learn_more = Научи повеќе
+torbutton.content_sizer.margin_tooltip = Tor Browser ја додава ова маргина за ширината и висината на вашиот прозорец да биде постандарден, со што се намалува можноста луѓето да ве следат онлајн.
+torbutton.panel.tooltip.disabled = Кликнете за да го овозможите Tor
+torbutton.panel.tooltip.enabled = Кликнете за да го оневозможите Tor
+torbutton.panel.label.disabled = Tor е оневозможен
+torbutton.panel.label.enabled = Tor е овозможен
+extensions.torbutton(a)torproject.org.description = Torbutton пружа копче за конфигурирање на Tor поставките и брзо и олеснето чисто приватно прелистување на податоци.
+torbutton.popup.external.title = Преземање на надворешна датотека?
+torbutton.popup.external.app = Tor прелистувачот не може да ја прикаже оваа датотека. Треба да ја отворите со друга апликација.\n\n
+torbutton.popup.external.note = Некои типови на датотеки можат да направат апликациите / програмите да се поврзат на Интернет без да користат Тор.\n\n
+torbutton.popup.external.suggest = Да би биле безбедни, единствено треба преземените датотеки да ги отворате додека сте исклучени од Интернет, или користејќи Tor бутирачкото ЦД како Tails.\n
+torbutton.popup.launch = Преземи датотека
+torbutton.popup.cancel = Откажи
+torbutton.popup.dontask = Автоматски преземај датотеки отсега па натаму
+torbutton.popup.no_newnym = Torbutton не може безбедно да ви даде нов идентитет. Нема пристап до Тор контролната порта.\n\nДали го користите Тор прелистувач-киот пакет?
+torbutton.security_settings.menu.title = Безбедносни подесувања
+torbutton.title.prompt_torbrowser = Важна Torbutton информација
+torbutton.popup.prompt_torbrowser = Torbutton работи поинаку сега: не може повеќе да биде исклучен.\n\nЈа направивме оваа промена, заота што не е безбедно да се користи Torbutton во прелистувач кој исто така се користи за не-Tor прелистување. Имаше премногу грешки и проблеми кои не можеа да бидат поправени на поинаков начин.\n\nАко сакате да продолжите да го користите Firefox стандардно, треба да го деинсталирате Torbutton и да го преземете Tor Browser пакетот. Приватните поставки на Tor Browser се помоќни од оние на стандардниот Firefox дури и кога Firefox се користи со Torbutton.\n\nЗа да го отрстранит
е Torbutton, одете во Алатки->Додатоци->Проширувања и кликнете на 'Отстрани' копчето до Torbutton.
+torbutton.popup.short_torbrowser = Важна Torbutton информација!\n\nTorbutton сега е секогаш вклучен.\n\nКликни на Torbutton за повеќе информации.
-torbutton.popup.confirm_plugins = Plugins such as Flash can harm your privacy and anonymity.\n\nThey can also bypass Tor to reveal your current location and IP address.\n\nAre you sure you want to enable plugins?\n\n
-torbutton.popup.never_ask_again = Never ask me again
+torbutton.popup.confirm_plugins = Приклучоците како Flash можат да ја повредат вашата приватност и анонимност.\n\nТие можат исто така да го заобиколат Tor и да ја откријат важата локација и IP адресата.\n\nДали сте сигурни дека сакате да ги овозможите приклучоците?\n\n
+torbutton.popup.never_ask_again = Не ме прашувај никогаш повеќе
+torbutton.popup.confirm_newnym = Tor Browser ќе ги затвори сите прозорци и табови. Сите веб сесии ќе бидат изгубени.\n\nРестартирајте го Tor Browser сега да го промените вашиот идентитет.\n\n
+
+torbutton.maximize_warning = Максимизирањето на Tor Browser дозволува на веб страните да ја утврдат големината на вашиот монитор, што пак може да се користи за ваше следење. Ви препорачуваме да ги оставите прозорците на Tor Browser во нивната оригинална големина.
# Canvas permission prompt. Strings are kept here for ease of translation.
-canvas.siteprompt=This website (%S) attempted to access image data on a canvas. Since canvas image data can be used to discover information about your computer, blank image data was returned this time.
-canvas.allow=Allow in the Future
-canvas.allowAccessKey=Z
-canvas.never=Never for This Site
+canvas.siteprompt=Оваа веб страна (%S) пробува да извлече HTML5 податоци, преку кои може уникатно да се идентифукува вашиот компјутер.\n\nТреба ли Tor Browser да и дозволи на оваа веб страна да ги извлече HTML5 податоците?
+canvas.notNow=Не сега
+canvas.notNowAccessKey=N
+canvas.allow=Дозволи во иднина
+canvas.allowAccessKey=A
+canvas.never=Никогаш за оваа веб страна (препорачано)
canvas.neverAccessKey=e
+
+# Profile/startup error messages. Strings are kept here for ease of translation.
+# LOCALIZATION NOTE: %S is the application name.
+profileProblemTitle=%S Профил проблем
+profileReadOnly=Не можете да го стартувате %S од систем без запишувачки привилегии. Копирајте %S на друга локација пред обид за користење.
+profileReadOnlyMac=Не можете да го стартувате %S од систем без запишувачки привилегии. Копирајте го %S на Работната површина или во Апликативната папка / Program Files.
+profileAccessDenied=%S нема дозвола да пристапи на профилот. Прилагодете ги системските привилегии на датотеката и обидете се повторно.
+profileMigrationFailed=Миграцијата на вашиот постоечки %S профил не успеа.\nНови поставки ќе бидат користени.
+
+# "Downloading update" string for the hamburger menu (see #28885).
+# This string is kept here for ease of translation.
+# LOCALIZATION NOTE: %S is the application name.
+updateDownloadingPanelUILabel=Преземање %S ажурирање
+
+# .Onion Page Info prompt. Strings are kept here for ease of translation.
+pageInfo_OnionEncryptionWithBitsAndProtocol=Енкриптирано поврзување (Onion Услуга, %1$S, %2$S битни клучеви, %3$S)
+pageInfo_OnionEncryption=Енкриптирано поврзување (Onion Услуга)
1
0
commit a6e66dfd822ca437c1ffeeb48ae6338f776d7681
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue May 14 08:57:16 2019 +0000
Bug 30468: Add mk translation
---
trans_tools/import-translations.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/trans_tools/import-translations.sh b/trans_tools/import-translations.sh
index e52db02a..66c37ac7 100755
--- a/trans_tools/import-translations.sh
+++ b/trans_tools/import-translations.sh
@@ -2,7 +2,7 @@
# This var comes from the TBB locale list.
# XXX: Find some way to keep this, tor-launcher, and Tor Browser in sync
-BUNDLE_LOCALES="ar ca cs da de el es-AR es-ES fa fr ga-IE he hu id is it ja ka ko nb-NO nl pl pt-BR ro ru sv-SE tr vi zh-CN zh-TW"
+BUNDLE_LOCALES="ar ca cs da de el es-AR es-ES fa fr ga-IE he hu id is it ja ka ko nb-NO mk nl pl pt-BR ro ru sv-SE tr vi zh-CN zh-TW"
# XXX: Basque (eu) by request in #10687.
# This is not used for official builds, but should remain so Basque XPIs can be
1
0
commit 171b482609c7b8dc644150f4e83900bac715f071
Merge: 208b1131 3ec6d04c
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:06:49 2019 +0000
Merge branch 'bug_30468_v4'
src/chrome/locale/mk/aboutDialog.dtd | 19 ++++++
src/chrome/locale/mk/aboutTBUpdate.dtd | 8 +++
src/chrome/locale/mk/aboutTor.dtd | 57 ++++++----------
src/chrome/locale/mk/brand.dtd | 11 +++-
src/chrome/locale/mk/brand.properties | 13 ++--
src/chrome/locale/mk/browserOnboarding.properties | 71 ++++++++++++++++++++
src/chrome/locale/mk/securityLevel.properties | 23 ++++++-
src/chrome/locale/mk/torbutton.dtd | 56 +++++++++++-----
src/chrome/locale/mk/torbutton.properties | 79 ++++++++++++++++-------
trans_tools/import-translations.sh | 2 +-
10 files changed, 253 insertions(+), 86 deletions(-)
1
0

[tor-browser-build/master] Merge remote-tracking branch 'richard/bug_27503'
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit b9696546f5416c79449a2f20044ae3ec9ee36e1b
Merge: 702bb68 25aa6ad
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 15:51:11 2019 +0000
Merge remote-tracking branch 'richard/bug_27503'
projects/mingw-w64/27503.patch | 10660 +++++++++++++++++++++++++++++++++++++++
projects/mingw-w64/build | 3 +
projects/mingw-w64/config | 1 +
3 files changed, 10664 insertions(+)
1
0

[tor-browser-build/master] Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit 25aa6ad4eb02c98d17e9f8f714aab22b5ce3b31e
Author: Richard Pospesel <richard(a)torproject.org>
Date: Thu Jun 6 18:08:48 2019 -0700
Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
---
projects/mingw-w64/27503.patch | 10660 +++++++++++++++++++++++++++++++++++++++
projects/mingw-w64/build | 3 +
projects/mingw-w64/config | 1 +
3 files changed, 10664 insertions(+)
diff --git a/projects/mingw-w64/27503.patch b/projects/mingw-w64/27503.patch
new file mode 100644
index 0000000..f6bd197
--- /dev/null
+++ b/projects/mingw-w64/27503.patch
@@ -0,0 +1,10660 @@
+diff --git a/mingw-w64-tools/widl/src/client.c b/mingw-w64-tools/widl/src/client.c
+index a3b2bbb6..d27c6cad 100644
+--- a/mingw-w64-tools/widl/src/client.c
++++ b/mingw-w64-tools/widl/src/client.c
+@@ -20,7 +20,7 @@
+
+ #include "config.h"
+ #include "wine/port.h"
+-
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #ifdef HAVE_UNISTD_H
+@@ -34,7 +34,7 @@
+ #include "parser.h"
+ #include "header.h"
+
+-#include "widltypes.h"
++#include "typetree.h"
+ #include "typegen.h"
+ #include "expr.h"
+
+@@ -52,12 +52,13 @@ static void print_client( const char *format, ... )
+
+ static void write_client_func_decl( const type_t *iface, const var_t *func )
+ {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
+- type_t *rettype = type_function_get_rettype(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
+
+ if (!callconv) callconv = "__cdecl";
+- write_type_decl_left(client, rettype);
++ write_declspec_decl_left(client, retdeclspec);
++ if (func->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(client, " inline");
+ fprintf(client, " %s ", callconv);
+ fprintf(client, "%s%s(\n", prefix_client, get_name(func));
+ indent++;
+@@ -74,9 +75,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ {
+ unsigned char explicit_fc, implicit_fc;
+ int has_full_pointer = is_full_pointer_function(func);
+- var_t *retval = type_function_get_retval(func->type);
++ var_t *retval = type_function_get_retval(func->declspec.type);
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
+- int has_ret = !is_void(retval->type);
++ int has_ret = !is_void(retval->declspec.type);
+
+ if (is_interpreted_func( iface, func ))
+ {
+@@ -97,7 +98,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ print_client("RPC_BINDING_HANDLE _Handle;\n");
+ }
+
+- if (has_ret && decl_indirect(retval->type))
++ if (has_ret && decl_indirect(retval->declspec.type))
+ {
+ print_client("void *_p_%s;\n", retval->name);
+ }
+@@ -136,7 +137,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ if (has_ret)
+ {
+ print_client("%s", "");
+- write_type_decl(client, retval->type, retval->name);
++ write_declspec_decl(client, &retval->declspec, retval->name);
+ fprintf(client, ";\n");
+ }
+ print_client("RPC_MESSAGE _RpcMessage;\n");
+@@ -147,7 +148,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ if (explicit_fc == FC_BIND_GENERIC)
+ print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
+ }
+- if (has_ret && decl_indirect(retval->type))
++ if (has_ret && decl_indirect(retval->declspec.type))
+ {
+ print_client("__frame->_p_%s = &%s;\n", retval->name, retval->name);
+ }
+@@ -194,7 +195,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ /* if the context_handle attribute appears in the chain of types
+ * without pointers being followed, then the context handle must
+ * be direct, otherwise it is a pointer */
+- int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE);
++ int is_ch_ptr = !is_aliaschain_attr(handle_var->declspec.type, ATTR_CONTEXTHANDLE);
+ print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name);
+ indent++;
+ print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n",
+@@ -257,9 +258,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ /* unmarshal return value */
+ if (has_ret)
+ {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
+- else if (is_ptr(retval->type) || is_array(retval->type))
++ else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
+ print_client("%s = 0;\n", retval->name);
+ write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
+ }
+@@ -291,7 +292,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ const char *func_name, const char *ret_type)
+ {
+ enum stub_mode mode = get_stub_mode();
+- static int emited_pickling_info;
++ static int emitted_pickling_info;
+
+ if (iface && !type->typestring_offset)
+ {
+@@ -301,7 +302,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ return;
+ }
+
+- if (!emited_pickling_info && iface && mode != MODE_Os)
++ if (!emitted_pickling_info && iface && mode != MODE_Os)
+ {
+ fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
+ fprintf(file, "{\n");
+@@ -312,7 +313,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ fprintf(file, " 0\n");
+ fprintf(file, "};\n");
+ fprintf(file, "\n");
+- emited_pickling_info = 1;
++ emitted_pickling_info = 1;
+ }
+
+ /* FIXME: Assuming explicit handle */
+@@ -365,8 +366,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
+ case STMT_DECLARATION:
+ {
+ const var_t *func = stmt->u.var;
+- if (stmt->u.var->stgclass != STG_NONE
+- || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
++ if (stmt->u.var->declspec.stgclass != STG_NONE
++ || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
+ continue;
+ write_function_stub( iface, func, method_count++, *proc_offset );
+ *proc_offset += get_size_procformatstring_func( iface, func );
+@@ -425,7 +426,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_client("1, /* -error bounds_check flag */\n");
+ print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_client("0,\n");
+- print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_client("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_client("0,\n");
+ print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_client("0, /* notify & notify_flag routine table */\n");
+@@ -488,7 +489,7 @@ static void write_implicithandledecl(type_t *iface)
+
+ if (implicit_handle)
+ {
+- write_type_decl( client, implicit_handle->type, implicit_handle->name );
++ write_declspec_decl( client, &implicit_handle->declspec, implicit_handle->name );
+ fprintf(client, ";\n\n");
+ }
+ }
+@@ -532,8 +533,8 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
+
+ LIST_FOR_EACH_ENTRY(stmt2, type_iface_get_stmts(iface), const statement_t, entry)
+ {
+- if (stmt2->type == STMT_DECLARATION && stmt2->u.var->stgclass == STG_NONE &&
+- type_get_type_detect_alias(stmt2->u.var->type) == TYPE_FUNCTION)
++ if (stmt2->type == STMT_DECLARATION && stmt2->u.var->declspec.stgclass == STG_NONE &&
++ type_get_type_detect_alias(stmt2->u.var->declspec.type) == TYPE_FUNCTION)
+ {
+ needs_stub = 1;
+ break;
+@@ -627,26 +628,6 @@ void write_client(const statement_list_t *stmts)
+ if (!client)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(client, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_client_routines( stmts );
+- fprintf(client, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_client_routines( stmts );
+- fprintf(client, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_client_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_client_routines( stmts );
+- }
+-
++ write_client_routines( stmts );
+ fclose(client);
+ }
+diff --git a/mingw-w64-tools/widl/src/expr.c b/mingw-w64-tools/widl/src/expr.c
+index 2ed4aff6..2f075816 100644
+--- a/mingw-w64-tools/widl/src/expr.c
++++ b/mingw-w64-tools/widl/src/expr.c
+@@ -194,10 +194,10 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
+ expr_t *e;
+ type_t *tref;
+
+- if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
++ if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
+ error_loc("invalid storage class for type expression\n");
+
+- tref = var->type;
++ tref = var->declspec.type;
+
+ e = xmalloc(sizeof(expr_t));
+ e->type = type;
+@@ -474,7 +474,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ if (field->name && !strcmp(identifier, field->name))
+ {
+- type = field->type;
++ type = field->declspec.type;
+ *found_in_cont_type = 1;
+ break;
+ }
+@@ -482,7 +482,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
+ if (!type)
+ {
+ var_t *const_var = find_const(identifier, 0);
+- if (const_var) type = const_var->type;
++ if (const_var) type = const_var->declspec.type;
+ }
+
+ return type;
+@@ -521,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ break;
+ case EXPR_STRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0));
+ break;
+ case EXPR_WSTRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0));
+ break;
+ case EXPR_CHARCONST:
+ result.is_temporary = TRUE;
+@@ -575,15 +575,15 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ expr_loc->attr ? expr_loc->attr : "");
+ result.is_variable = FALSE;
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, result.type, NULL);
++ result.type = type_new_pointer(FC_UP, result.type);
+ break;
+ case EXPR_PPTR:
+ result = resolve_expression(expr_loc, cont_type, e->ref);
+ if (result.type && is_ptr(result.type))
+- result.type = type_pointer_get_ref(result.type);
++ result.type = type_pointer_get_ref_type(result.type);
+ else if(result.type && is_array(result.type)
+ && type_array_is_decl_as_ptr(result.type))
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ else
+ error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
+ expr_loc->attr ? " for attribute " : "",
+@@ -665,7 +665,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ if (result.type && is_array(result.type))
+ {
+ struct expression_type index_result;
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
+ if (!index_result.type || !is_integer_type(index_result.type))
+ error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
+diff --git a/mingw-w64-tools/widl/src/header.c b/mingw-w64-tools/widl/src/header.c
+index defc7f85..d0d0dc4b 100644
+--- a/mingw-w64-tools/widl/src/header.c
++++ b/mingw-w64-tools/widl/src/header.c
+@@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list);
+ context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
+ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name);
+
+ static void indent(FILE *h, int delta)
+ {
+@@ -69,15 +69,15 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t)
+ return 1;
+ else
+ {
+- type_t *type = var->type;
++ type_t *type = var->declspec.type;
+ for (;;)
+ {
+ if (is_attr(type->attrs, t))
+ return 1;
+ else if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
++ type = type_alias_get_aliasee_type(type);
+ else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ else return 0;
+ }
+ }
+@@ -91,7 +91,7 @@ int is_aliaschain_attr(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return 1;
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return 0;
+ }
+ }
+@@ -204,9 +204,9 @@ static void write_fields(FILE *h, var_list_t *fields)
+ if (!fields) return;
+
+ LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+- if (!v || !v->type) continue;
++ if (!v || !v->declspec.type) continue;
+
+- switch(type_get_type_detect_alias(v->type)) {
++ switch(type_get_type_detect_alias(v->declspec.type)) {
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+ nameless_struct_cnt++;
+@@ -220,12 +220,12 @@ static void write_fields(FILE *h, var_list_t *fields)
+ }
+
+ LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+- if (!v || !v->type) continue;
++ if (!v || !v->declspec.type) continue;
+
+ indent(h, 0);
+ name = v->name;
+
+- switch(type_get_type_detect_alias(v->type)) {
++ switch(type_get_type_detect_alias(v->declspec.type)) {
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+ if(!v->name) {
+@@ -252,7 +252,7 @@ static void write_fields(FILE *h, var_list_t *fields)
+ default:
+ ;
+ }
+- write_type_def_or_decl(h, v->type, TRUE, name);
++ write_type_v(h, &v->declspec, TRUE, v->declonly, name);
+ fprintf(h, ";\n");
+ }
+ }
+@@ -295,14 +295,21 @@ static void write_pointer_left(FILE *h, type_t *ref)
+ }
+
+ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
++{
++ decl_spec_t ds;
++ write_declspec_left(h, init_declspec(&ds, t), name_type, declonly);
++}
++
++void write_declspec_left(FILE* h, const decl_spec_t *ds, enum name_type name_type, int declonly)
+ {
+ const char *name;
++ type_t *t = ds->type;
+
+ if (!h) return;
+
+ name = type_get_name(t, name_type);
+
+- if (is_attr(t->attrs, ATTR_CONST) &&
++ if ((ds->typequalifier == TYPE_QUALIFIER_CONST) &&
+ (type_is_alias(t) || !is_ptr(t)))
+ fprintf(h, "const ");
+
+@@ -310,7 +317,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else {
+ switch (type_get_type_detect_alias(t)) {
+ case TYPE_ENUM:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "enum %s {\n", name);
+ else fprintf(h, "enum {\n");
+ t->written = TRUE;
+@@ -323,7 +330,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "struct %s {\n", name);
+ else fprintf(h, "struct {\n");
+ t->written = TRUE;
+@@ -338,7 +345,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else fprintf(h, "struct %s", name ? name : "");
+ break;
+ case TYPE_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (t->name) fprintf(h, "union %s {\n", t->name);
+ else fprintf(h, "union {\n");
+ t->written = TRUE;
+@@ -351,9 +358,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_POINTER:
+ {
+- write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
+- write_pointer_left(h, type_pointer_get_ref(t));
+- if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
++ write_declspec_left(h, type_pointer_get_ref(t), name_type, declonly);
++ write_pointer_left(h, type_pointer_get_ref_type(t));
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST) fprintf(h, "const ");
+ break;
+ }
+ case TYPE_ARRAY:
+@@ -361,9 +368,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ fprintf(h, "%s", t->name);
+ else
+ {
+- write_type_left(h, type_array_get_element(t), name_type, declonly);
++ write_declspec_left(h, type_array_get_element(t), name_type, declonly);
+ if (type_array_is_decl_as_ptr(t))
+- write_pointer_left(h, type_array_get_element(t));
++ write_pointer_left(h, type_array_get_element_type(t));
+ }
+ break;
+ case TYPE_BASIC:
+@@ -443,7 +450,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ {
+ case TYPE_ARRAY:
+ {
+- type_t *elem = type_array_get_element(t);
++ type_t *elem = type_array_get_element_type(t);
+ if (type_array_is_decl_as_ptr(t))
+ {
+ if (!type_is_alias(elem) && is_array(elem) && !type_array_is_decl_as_ptr(elem))
+@@ -461,7 +468,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ case TYPE_POINTER:
+ {
+- type_t *ref = type_pointer_get_ref(t);
++ type_t *ref = type_pointer_get_ref_type(t);
+ if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
+ fprintf(h, ")");
+ write_type_right(h, ref, FALSE);
+@@ -485,30 +492,33 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ }
+
+-static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name)
+ {
++ type_t *t = ds->type;
+ type_t *pt = NULL;
+ int ptr_level = 0;
+
+ if (!h) return;
+
+ if (t) {
+- for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
++ const decl_spec_t *dpt = NULL;
++ for (dpt = ds; is_ptr(dpt->type); dpt = type_pointer_get_ref(dpt->type), ptr_level++)
+ ;
++ pt = dpt->type;
+
+ if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
+ int i;
+ const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
+ if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
+- if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
+- write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
++ if (!is_ptr(ds->type) && dpt->funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline ");
++ write_declspec_left(h, type_function_get_retdeclspec(pt), NAME_DEFAULT, declonly);
+ fputc(' ', h);
+ if (ptr_level) fputc('(', h);
+ if (callconv) fprintf(h, "%s ", callconv);
+ for (i = 0; i < ptr_level; i++)
+ fputc('*', h);
+ } else
+- write_type_left(h, t, NAME_DEFAULT, declonly);
++ write_declspec_left(h, ds, NAME_DEFAULT, declonly);
+ }
+
+ if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
+@@ -529,12 +539,7 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
+ }
+ }
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
+-{
+- write_type_v(f, t, field, FALSE, name);
+-}
+-
+-static void write_type_definition(FILE *f, type_t *t)
++static void write_type_definition(FILE *f, type_t *t, int declonly)
+ {
+ int in_namespace = t->namespace && !is_global_namespace(t->namespace);
+ int save_written = t->written;
+@@ -545,14 +550,14 @@ static void write_type_definition(FILE *f, type_t *t)
+ write_namespace_start(f, t->namespace);
+ }
+ indent(f, 0);
+- write_type_left(f, t, NAME_DEFAULT, FALSE);
++ write_type_left(f, t, NAME_DEFAULT, declonly);
+ fprintf(f, ";\n");
+ if(in_namespace) {
+ t->written = save_written;
+ write_namespace_end(f, t->namespace);
+ fprintf(f, "extern \"C\" {\n");
+ fprintf(f, "#else\n");
+- write_type_left(f, t, NAME_C, FALSE);
++ write_type_left(f, t, NAME_C, declonly);
+ fprintf(f, ";\n");
+ fprintf(f, "#endif\n\n");
+ }
+@@ -560,12 +565,18 @@ static void write_type_definition(FILE *f, type_t *t)
+
+ void write_type_decl(FILE *f, type_t *t, const char *name)
+ {
+- write_type_v(f, t, FALSE, TRUE, name);
++ decl_spec_t ds;
++ write_declspec_decl(f, init_declspec(&ds, t), name);
++}
++
++void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name)
++{
++ write_type_v(f, ds, FALSE, TRUE, name);
+ }
+
+-void write_type_decl_left(FILE *f, type_t *t)
++void write_declspec_decl_left(FILE *f, const decl_spec_t *ds)
+ {
+- write_type_left(f, t, NAME_DEFAULT, TRUE);
++ write_declspec_left(f, ds, NAME_DEFAULT, TRUE);
+ }
+
+ static int user_type_registered(const char *name)
+@@ -602,8 +613,8 @@ unsigned int get_context_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a context handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
+@@ -622,8 +633,8 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_HANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a generic handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
+@@ -637,82 +648,77 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ /* check for types which require additional prototypes to be generated in the
+ * header */
+-void check_for_additional_prototype_types(const var_list_t *list)
+-{
+- const var_t *v;
+-
+- if (!list) return;
+- LIST_FOR_EACH_ENTRY( v, list, const var_t, entry )
+- {
+- type_t *type = v->type;
+- if (!type) continue;
+- for (;;) {
+- const char *name = type->name;
+- if (type->user_types_registered) break;
+- type->user_types_registered = 1;
+- if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
+- if (!context_handle_registered(name))
+- {
+- context_handle_t *ch = xmalloc(sizeof(*ch));
+- ch->name = xstrdup(name);
+- list_add_tail(&context_handle_list, &ch->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
+- }
+- if ((type_get_type(type) != TYPE_BASIC ||
+- type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
+- is_attr(type->attrs, ATTR_HANDLE)) {
+- if (!generic_handle_registered(name))
+- {
+- generic_handle_t *gh = xmalloc(sizeof(*gh));
+- gh->name = xstrdup(name);
+- list_add_tail(&generic_handle_list, &gh->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
++void check_for_additional_prototype_types(type_t *type)
++{
++ if (!type) return;
++ for (;;) {
++ const char *name = type->name;
++ if (type->user_types_registered) break;
++ type->user_types_registered = 1;
++ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
++ if (!context_handle_registered(name))
++ {
++ context_handle_t *ch = xmalloc(sizeof(*ch));
++ ch->name = xstrdup(name);
++ list_add_tail(&context_handle_list, &ch->entry);
+ }
+- if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
+- if (!user_type_registered(name))
+- {
+- user_type_t *ut = xmalloc(sizeof *ut);
+- ut->name = xstrdup(name);
+- list_add_tail(&user_type_list, &ut->entry);
+- }
+- /* don't carry on parsing fields within this type as we are already
+- * using a wire marshaled type */
+- break;
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if ((type_get_type(type) != TYPE_BASIC ||
++ type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
++ is_attr(type->attrs, ATTR_HANDLE)) {
++ if (!generic_handle_registered(name))
++ {
++ generic_handle_t *gh = xmalloc(sizeof(*gh));
++ gh->name = xstrdup(name);
++ list_add_tail(&generic_handle_list, &gh->entry);
+ }
+- else if (type_is_complete(type))
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
++ if (!user_type_registered(name))
+ {
+- var_list_t *vars;
+- switch (type_get_type_detect_alias(type))
+- {
+- case TYPE_ENUM:
+- vars = type_enum_get_values(type);
+- break;
+- case TYPE_STRUCT:
+- vars = type_struct_get_fields(type);
+- break;
+- case TYPE_UNION:
+- vars = type_union_get_cases(type);
+- break;
+- default:
+- vars = NULL;
+- break;
+- }
+- check_for_additional_prototype_types(vars);
++ user_type_t *ut = xmalloc(sizeof *ut);
++ ut->name = xstrdup(name);
++ list_add_tail(&user_type_list, &ut->entry);
+ }
+-
+- if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
+- else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
+- else if (is_array(type))
+- type = type_array_get_element(type);
+- else
++ /* don't carry on parsing fields within this type as we are already
++ * using a wire marshaled type */
++ break;
++ }
++ else if (type_is_complete(type))
++ {
++ var_list_t *vars;
++ const var_t *v;
++ switch (type_get_type_detect_alias(type))
++ {
++ case TYPE_ENUM:
++ vars = type_enum_get_values(type);
++ break;
++ case TYPE_STRUCT:
++ vars = type_struct_get_fields(type);
+ break;
++ case TYPE_UNION:
++ vars = type_union_get_cases(type);
++ break;
++ default:
++ vars = NULL;
++ break;
++ }
++ if (vars) LIST_FOR_EACH_ENTRY( v, vars, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
+ }
++
++ if (type_is_alias(type))
++ type = type_alias_get_aliasee_type(type);
++ else if (is_ptr(type))
++ type = type_pointer_get_ref_type(type);
++ else if (is_array(type))
++ type = type_array_get_element_type(type);
++ else
++ break;
+ }
+ }
+
+@@ -791,26 +797,26 @@ static void write_generic_handle_routines(FILE *header)
+ }
+ }
+
+-static void write_typedef(FILE *header, type_t *type)
++static void write_typedef(FILE *header, type_t *type, int declonly)
+ {
+ fprintf(header, "typedef ");
+- write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
++ write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name);
+ fprintf(header, ";\n");
+ }
+
+ int is_const_decl(const var_t *var)
+ {
+- const type_t *t;
++ const decl_spec_t *ds;
+ /* strangely, MIDL accepts a const attribute on any pointer in the
+ * declaration to mean that data isn't being instantiated. this appears
+ * to be a bug, but there is no benefit to being incompatible with MIDL,
+ * so we'll do the same thing */
+- for (t = var->type; ; )
++ for (ds = &var->declspec; ;)
+ {
+- if (is_attr(t->attrs, ATTR_CONST))
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST)
+ return TRUE;
+- else if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ else if (is_ptr(ds->type))
++ ds = type_pointer_get_ref(ds->type);
+ else break;
+ }
+ return FALSE;
+@@ -826,7 +832,7 @@ static void write_declaration(FILE *header, const var_t *v)
+ }
+ else
+ {
+- switch (v->stgclass)
++ switch (v->declspec.stgclass)
+ {
+ case STG_NONE:
+ case STG_REGISTER: /* ignored */
+@@ -838,7 +844,7 @@ static void write_declaration(FILE *header, const var_t *v)
+ fprintf(header, "extern ");
+ break;
+ }
+- write_type_def_or_decl(header, v->type, FALSE, v->name);
++ write_type_v(header, &v->declspec, FALSE, FALSE, v->name);
+ fprintf(header, ";\n\n");
+ }
+ }
+@@ -855,9 +861,9 @@ static void write_library(FILE *header, const typelib_t *typelib)
+ const type_t* get_explicit_generic_handle_type(const var_t* var)
+ {
+ const type_t *t;
+- for (t = var->type;
++ for (t = var->declspec.type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
+ is_attr(t->attrs, ATTR_HANDLE))
+ return t;
+@@ -868,13 +874,13 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+ unsigned char *explicit_fc, unsigned char *implicit_fc )
+ {
+ const var_t *var;
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+
+ *explicit_fc = *implicit_fc = 0;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+ {
+ if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue;
+- if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC && type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ {
+ *explicit_fc = FC_BIND_PRIMITIVE;
+ return var;
+@@ -884,7 +890,7 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+ *explicit_fc = FC_BIND_GENERIC;
+ return var;
+ }
+- if (is_context_handle( var->type ))
++ if (is_context_handle( var->declspec.type ))
+ {
+ *explicit_fc = FC_BIND_CONTEXT;
+ return var;
+@@ -893,8 +899,8 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+
+ if ((var = get_attrp( iface->attrs, ATTR_IMPLICIT_HANDLE )))
+ {
+- if (type_get_type( var->type ) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ *implicit_fc = FC_BIND_PRIMITIVE;
+ else
+ *implicit_fc = FC_BIND_GENERIC;
+@@ -909,13 +915,13 @@ int has_out_arg_or_return(const var_t *func)
+ {
+ const var_t *var;
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ return 1;
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return 0;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ if (is_attr(var->attrs, ATTR_OUT))
+ return 1;
+
+@@ -995,7 +1001,7 @@ static int is_override_method(const type_t *iface, const type_t *child, const va
+
+ static int is_aggregate_return(const var_t *func)
+ {
+- enum type_type type = type_get_type(type_function_get_rettype(func->type));
++ enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
+ return type == TYPE_STRUCT || type == TYPE_UNION ||
+ type == TYPE_COCLASS || type == TYPE_INTERFACE;
+ }
+@@ -1035,8 +1041,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
+ const var_t *arg;
+
+ fprintf(header, "#define %s_%s(This", name, get_name(func));
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ") ");
+
+@@ -1047,8 +1053,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
+ }
+
+ fprintf(header, "(This)->lpVtbl->%s(This", get_vtbl_entry_name(iface, func));
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ")\n");
+ }
+@@ -1078,7 +1084,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
+ }
+ else fprintf(h, ",");
+ }
+- write_type_decl(h, arg->type, arg->name);
++ write_declspec_decl(h, &arg->declspec, arg->name);
+ if (method == 2) {
+ const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
+ if (expr) {
+@@ -1090,7 +1096,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
+ expr_t bstr;
+
+ /* Fixup the expression type for a BSTR like midl does. */
+- if (get_type_vt(arg->type) == VT_BSTR && expr->type == EXPR_STRLIT)
++ if (get_type_vt(arg->declspec.type) == VT_BSTR && expr->type == EXPR_STRLIT)
+ {
+ bstr = *expr;
+ bstr.type = EXPR_WSTRLIT;
+@@ -1119,8 +1125,8 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ {
+ const var_t *func = stmt->u.var;
+ if (!is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
+ const var_t *arg;
+
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+@@ -1130,11 +1136,11 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+
+ indent(header, 0);
+ fprintf(header, "virtual ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, "* %s %s(\n", callconv, get_name(func));
+ ++indentation;
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ --indentation;
+ if (args) {
+@@ -1144,7 +1150,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ fprintf(header, ") = 0;\n");
+
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ")\n");
+@@ -1152,7 +1158,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ fprintf(header, "{\n");
+ ++indentation;
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *%s(&__ret", get_name(func));
+@@ -1169,7 +1175,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+
+ indent(header, 0);
+ fprintf(header, "virtual ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ") = 0;\n");
+@@ -1206,25 +1212,25 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
+ const var_t *arg;
+
+ fprintf(header, "static FORCEINLINE ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s_%s(", name, get_name(func));
+- write_args(header, type_get_function_args(func->type), name, 1, FALSE);
++ write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE);
+ fprintf(header, ") {\n");
+ ++indentation;
+ if (!is_aggregate_return(func)) {
+ indent(header, 0);
+ fprintf(header, "%sThis->lpVtbl->%s(This",
+- is_void(type_function_get_rettype(func->type)) ? "" : "return ",
++ is_void(type_function_get_rettype(func->declspec.type)) ? "" : "return ",
+ get_vtbl_entry_name(iface, func));
+ } else {
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
+ }
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ");\n");
+ --indentation;
+@@ -1250,10 +1256,10 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
+ first_iface = 0;
+ }
+ if (!is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ if (is_aggregate_return(func))
+ fprintf(header, " *");
+ if (is_inherited_method(iface, func))
+@@ -1266,13 +1272,13 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
+ if (is_aggregate_return(func)) {
+ fprintf(header, ",\n");
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ }
+ --indentation;
+- if (type_get_function_args(func->type)) {
++ if (type_function_get_args(func->declspec.type)) {
+ fprintf(header, ",\n");
+- write_args(header, type_get_function_args(func->type), name, 0, TRUE);
++ write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE);
+ }
+ fprintf(header, ");\n");
+ fprintf(header, "\n");
+@@ -1299,12 +1305,12 @@ static void write_method_proto(FILE *header, const type_t *iface)
+ const var_t *func = stmt->u.var;
+
+ if (is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+ /* proxy prototype */
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+- write_args(header, type_get_function_args(func->type), iface->name, 1, TRUE);
++ write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(header, ");\n");
+ /* stub prototype */
+ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
+@@ -1337,12 +1343,12 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
+ if (&stmt2->entry != type_iface_get_stmts(iface)) {
+ const var_t *m = stmt2->u.var;
+ /* proxy prototype - use local prototype */
+- write_type_decl_left(fp, type_function_get_rettype(m->type));
++ write_declspec_decl_left(fp, type_function_get_retdeclspec(m->declspec.type));
+ fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m));
+- write_args(fp, type_get_function_args(m->type), iface->name, 1, TRUE);
++ write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE);
+ fprintf(fp, ")");
+ if (body) {
+- type_t *rt = type_function_get_rettype(m->type);
++ type_t *rt = type_function_get_rettype(m->declspec.type);
+ fprintf(fp, "\n{\n");
+ fprintf(fp, " %s\n", comment);
+ if (rt->name && strcmp(rt->name, "HRESULT") == 0)
+@@ -1359,9 +1365,9 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
+ else
+ fprintf(fp, ";\n");
+ /* stub prototype - use remotable prototype */
+- write_type_decl_left(fp, type_function_get_rettype(func->type));
++ write_declspec_decl_left(fp, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m));
+- write_args(fp, type_get_function_args(func->type), iface->name, 1, TRUE);
++ write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(fp, ")");
+ if (body)
+ /* Remotable methods must all return HRESULTs. */
+@@ -1407,15 +1413,16 @@ void write_local_stubs(const statement_list_t *stmts)
+
+ static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
+ {
+- const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(fun->declspec.type->attrs, ATTR_CALLCONV);
+
+ if (!callconv) callconv = "__cdecl";
+ /* FIXME: do we need to handle call_as? */
+- write_type_decl_left(header, type_function_get_rettype(fun->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(fun->declspec.type));
++ if (fun->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(header, " inline");
+ fprintf(header, " %s ", callconv);
+ fprintf(header, "%s%s(\n", prefix, get_name(fun));
+- if (type_get_function_args(fun->type))
+- write_args(header, type_get_function_args(fun->type), iface->name, 0, TRUE);
++ if (type_function_get_args(fun->declspec.type))
++ write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE);
+ else
+ fprintf(header, " void");
+ fprintf(header, ");\n\n");
+@@ -1541,7 +1548,7 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
+ if (var)
+ {
+ fprintf(header, "extern ");
+- write_type_decl( header, var->type, var->name );
++ write_declspec_decl( header, &var->declspec, var->name );
+ fprintf(header, ";\n");
+ }
+ if (old_names)
+@@ -1653,6 +1660,7 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
+ {
+ type_t *iface = stmt->u.type;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
+ {
+ write_forward(header, iface);
+@@ -1694,6 +1702,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ type_t *iface = stmt->u.type;
+ type_t *async_iface = iface->details.iface->async_iface;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface)) is_object_interface++;
+ if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
+ {
+@@ -1718,7 +1727,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ write_coclass(header, stmt->u.type);
+ else
+ {
+- write_type_definition(header, stmt->u.type);
++ write_type_definition(header, stmt->u.type, stmt->declonly);
+ }
+ break;
+ case STMT_TYPEREF:
+@@ -1739,7 +1748,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ const type_list_t *type_entry = stmt->u.type_list;
+ for (; type_entry; type_entry = type_entry->next)
+- write_typedef(header, type_entry->type);
++ write_typedef(header, type_entry->type, stmt->declonly);
+ break;
+ }
+ case STMT_LIBRARY:
+@@ -1750,7 +1759,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ fprintf(header, "%s\n", stmt->u.str);
+ break;
+ case STMT_DECLARATION:
+- if (iface && type_get_type(stmt->u.var->type) == TYPE_FUNCTION)
++ if (iface && type_get_type(stmt->u.var->declspec.type) == TYPE_FUNCTION)
+ {
+ if (!ignore_funcs)
+ {
+@@ -1784,15 +1793,15 @@ void write_header(const statement_list_t *stmts)
+ }
+ fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
+
++ fprintf(header, "#ifdef _WIN32\n");
+ fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
+ fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
+- fprintf(header, "#endif\n\n");
+-
++ fprintf(header, "#endif\n");
+ fprintf(header, "#include <rpc.h>\n" );
+ fprintf(header, "#include <rpcndr.h>\n" );
+ if (!for_each_serializable(stmts, NULL, serializable_exists))
+ fprintf(header, "#include <midles.h>\n" );
+- fprintf(header, "\n" );
++ fprintf(header, "#endif\n\n");
+
+ fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
+ fprintf(header, "#include <windows.h>\n");
+diff --git a/mingw-w64-tools/widl/src/header.h b/mingw-w64-tools/widl/src/header.h
+index 0d44b403..0e62f77c 100644
+--- a/mingw-w64-tools/widl/src/header.h
++++ b/mingw-w64-tools/widl/src/header.h
+@@ -29,10 +29,12 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
+ extern void *get_attrp(const attr_list_t *list, enum attr_type t);
+ extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
+ extern const char* get_name(const var_t *v);
++extern void write_declspec_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly);
+ extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
+ extern void write_type_right(FILE *h, type_t *t, int is_field);
+ extern void write_type_decl(FILE *f, type_t *t, const char *name);
+-extern void write_type_decl_left(FILE *f, type_t *t);
++extern void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name);
++extern void write_declspec_decl_left(FILE *f, const decl_spec_t *ds);
+ extern unsigned int get_context_handle_offset( const type_t *type );
+ extern unsigned int get_generic_handle_offset( const type_t *type );
+ extern int needs_space_after(type_t *t);
+@@ -83,12 +85,12 @@ static inline int is_conformant_array(const type_t *t)
+
+ static inline int last_ptr(const type_t *type)
+ {
+- return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
++ return is_ptr(type) && !is_declptr(type_pointer_get_ref_type(type));
+ }
+
+ static inline int last_array(const type_t *type)
+ {
+- return is_array(type) && !is_array(type_array_get_element(type));
++ return is_array(type) && !is_array(type_array_get_element_type(type));
+ }
+
+ static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
+@@ -102,7 +104,7 @@ static inline int is_context_handle(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return 1;
+ return 0;
+diff --git a/mingw-w64-tools/widl/src/parser.tab.c b/mingw-w64-tools/widl/src/parser.tab.c
+index 6266e054..d7053e79 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.c
++++ b/mingw-w64-tools/widl/src/parser.tab.c
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison implementation for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -44,7 +44,7 @@
+ #define YYBISON 1
+
+ /* Bison version. */
+-#define YYBISON_VERSION "3.0.5"
++#define YYBISON_VERSION "3.0.4"
+
+ /* Skeleton name. */
+ #define YYSKELETON_NAME "yacc.c"
+@@ -125,13 +125,6 @@ struct _import_t
+ int import_performed;
+ };
+
+-typedef struct _decl_spec_t
+-{
+- type_t *type;
+- attr_list_t *attrs;
+- enum storage_class stgclass;
+-} decl_spec_t;
+-
+ typelist_t incomplete_types = LIST_INIT(incomplete_types);
+
+ static void fix_incomplete(void);
+@@ -140,7 +133,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -156,6 +149,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -212,7 +206,7 @@ static struct namespace *current_namespace = &global_namespace;
+ static typelib_t *current_typelib;
+
+
+-#line 216 "parser.tab.c" /* yacc.c:339 */
++#line 210 "parser.tab.c" /* yacc.c:339 */
+
+ # ifndef YY_NULLPTR
+ # if defined __cplusplus && 201103L <= __cplusplus
+@@ -438,7 +432,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:355 */
++#line 136 "parser.y" /* yacc.c:355 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -465,8 +459,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 470 "parser.tab.c" /* yacc.c:355 */
++#line 466 "parser.tab.c" /* yacc.c:355 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+@@ -483,7 +479,7 @@ int parser_parse (void);
+
+ /* Copy the second part of user declarations. */
+
+-#line 487 "parser.tab.c" /* yacc.c:358 */
++#line 483 "parser.tab.c" /* yacc.c:358 */
+
+ #ifdef short
+ # undef short
+@@ -799,48 +795,48 @@ static const yytype_uint8 yytranslate[] =
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+ static const yytype_uint16 yyrline[] =
+ {
+- 0, 325, 325, 340, 340, 342, 343, 343, 345, 346,
+- 347, 350, 353, 354, 355, 358, 359, 360, 360, 362,
+- 363, 364, 367, 368, 369, 370, 373, 374, 377, 378,
+- 382, 383, 384, 385, 386, 387, 388, 391, 402, 403,
+- 407, 408, 409, 410, 411, 412, 413, 414, 415, 418,
+- 420, 428, 434, 438, 439, 441, 445, 449, 450, 453,
+- 454, 457, 458, 462, 467, 474, 478, 479, 482, 483,
+- 487, 490, 491, 492, 495, 496, 499, 500, 501, 502,
+- 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
+- 513, 514, 515, 516, 517, 518, 519, 520, 521, 522,
+- 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+- 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
+- 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
+- 553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
+- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
+- 573, 574, 578, 579, 580, 581, 582, 583, 584, 585,
+- 586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+- 596, 597, 598, 599, 600, 601, 605, 606, 611, 612,
+- 613, 614, 617, 618, 621, 625, 631, 632, 633, 636,
+- 640, 652, 656, 661, 664, 665, 668, 669, 672, 673,
+- 674, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+- 684, 685, 686, 687, 688, 689, 690, 691, 692, 693,
+- 694, 695, 696, 697, 698, 699, 700, 701, 702, 703,
+- 704, 705, 706, 707, 708, 709, 711, 713, 714, 717,
+- 718, 721, 727, 733, 734, 737, 742, 749, 750, 753,
+- 754, 758, 759, 762, 766, 772, 780, 784, 789, 790,
+- 793, 794, 795, 798, 800, 803, 804, 805, 806, 807,
+- 808, 809, 810, 811, 812, 813, 816, 817, 820, 821,
+- 822, 823, 824, 825, 826, 827, 828, 831, 832, 840,
+- 846, 850, 853, 854, 858, 861, 862, 865, 874, 875,
+- 878, 879, 882, 888, 894, 895, 898, 899, 902, 912,
+- 922, 928, 932, 933, 936, 937, 940, 945, 952, 953,
+- 954, 958, 962, 965, 966, 969, 970, 974, 975, 979,
+- 980, 981, 985, 987, 989, 993, 994, 995, 996, 1004,
+- 1006, 1008, 1013, 1015, 1020, 1021, 1026, 1027, 1028, 1029,
+- 1034, 1043, 1045, 1046, 1051, 1053, 1057, 1058, 1065, 1066,
+- 1067, 1068, 1069, 1074, 1082, 1083, 1086, 1087, 1090, 1097,
+- 1098, 1103, 1104, 1108, 1109, 1110, 1111, 1112, 1116, 1117,
+- 1118, 1121, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131,
+- 1132, 1133, 1136, 1143, 1145, 1151, 1152, 1153, 1156, 1158,
+- 1160, 1162, 1165, 1170, 1178, 1179, 1182, 1183, 1186, 1187,
+- 1188
++ 0, 323, 323, 338, 338, 340, 341, 341, 343, 344,
++ 345, 348, 351, 352, 353, 356, 357, 358, 358, 360,
++ 361, 362, 365, 366, 367, 368, 371, 372, 375, 376,
++ 380, 381, 382, 383, 384, 385, 386, 389, 400, 401,
++ 405, 406, 407, 408, 409, 410, 411, 412, 413, 416,
++ 418, 426, 432, 436, 437, 439, 443, 447, 448, 451,
++ 452, 455, 456, 460, 465, 472, 476, 477, 480, 481,
++ 485, 488, 489, 490, 493, 494, 497, 498, 499, 500,
++ 501, 502, 503, 504, 505, 506, 507, 508, 509, 510,
++ 511, 512, 513, 514, 515, 516, 517, 518, 519, 520,
++ 521, 522, 523, 524, 525, 526, 527, 528, 529, 530,
++ 531, 532, 533, 534, 535, 536, 537, 538, 539, 540,
++ 541, 542, 543, 544, 545, 546, 547, 548, 549, 550,
++ 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
++ 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
++ 571, 572, 576, 577, 578, 579, 580, 581, 582, 583,
++ 584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
++ 594, 595, 596, 597, 598, 599, 603, 604, 609, 610,
++ 611, 612, 615, 616, 619, 623, 629, 630, 631, 634,
++ 638, 650, 654, 659, 662, 663, 666, 667, 670, 671,
++ 672, 673, 674, 675, 676, 677, 678, 679, 680, 681,
++ 682, 683, 684, 685, 686, 687, 688, 689, 690, 691,
++ 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
++ 702, 703, 704, 705, 706, 707, 709, 711, 712, 715,
++ 716, 719, 725, 731, 732, 735, 740, 747, 748, 751,
++ 752, 756, 757, 760, 764, 770, 778, 782, 787, 788,
++ 791, 792, 793, 796, 798, 801, 802, 803, 804, 805,
++ 806, 807, 808, 809, 810, 811, 814, 815, 818, 819,
++ 820, 821, 822, 823, 824, 825, 826, 829, 830, 838,
++ 844, 848, 851, 852, 856, 859, 860, 863, 872, 873,
++ 876, 877, 880, 886, 892, 893, 896, 897, 900, 910,
++ 920, 926, 930, 931, 934, 935, 938, 943, 950, 951,
++ 952, 956, 960, 963, 964, 967, 968, 972, 973, 977,
++ 978, 979, 983, 985, 987, 991, 992, 993, 994, 1002,
++ 1004, 1006, 1011, 1013, 1018, 1019, 1024, 1025, 1026, 1027,
++ 1032, 1041, 1043, 1044, 1049, 1051, 1055, 1056, 1063, 1064,
++ 1065, 1066, 1067, 1072, 1080, 1081, 1084, 1085, 1088, 1095,
++ 1096, 1101, 1102, 1106, 1107, 1108, 1109, 1110, 1114, 1115,
++ 1116, 1119, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129,
++ 1130, 1131, 1134, 1141, 1143, 1149, 1150, 1151, 1154, 1156,
++ 1158, 1160, 1163, 1168, 1176, 1177, 1180, 1181, 1184, 1185,
++ 1186
+ };
+ #endif
+
+@@ -903,7 +899,7 @@ static const char *const yytname[] =
+ "dispinterfacedef", "inherit", "interface", "interfacehdr",
+ "interfacedef", "interfacedec", "module", "modulehdr", "moduledef",
+ "storage_cls_spec", "function_specifier", "type_qualifier",
+- "m_type_qual_list", "decl_spec", "m_decl_spec_no_type",
++ "m_type_qual_bits", "decl_spec", "m_decl_spec_no_type",
+ "decl_spec_no_type", "declarator", "direct_declarator",
+ "abstract_declarator", "abstract_declarator_no_direct",
+ "m_abstract_declarator", "abstract_direct_declarator", "any_declarator",
+@@ -2298,7 +2294,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ case N: \
+ yyformat = S; \
+ break
+- default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+@@ -2615,7 +2610,7 @@ yyreduce:
+ switch (yyn)
+ {
+ case 2:
+-#line 325 "parser.y" /* yacc.c:1648 */
++#line 323 "parser.y" /* yacc.c:1646 */
+ { fix_incomplete();
+ check_statements((yyvsp[-1].stmt_list), FALSE);
+ check_all_user_types((yyvsp[-1].stmt_list));
+@@ -2629,197 +2624,197 @@ yyreduce:
+ write_dlldata((yyvsp[-1].stmt_list));
+ write_local_stubs((yyvsp[-1].stmt_list));
+ }
+-#line 2633 "parser.tab.c" /* yacc.c:1648 */
++#line 2628 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 5:
+-#line 342 "parser.y" /* yacc.c:1648 */
++#line 340 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2639 "parser.tab.c" /* yacc.c:1648 */
++#line 2634 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 6:
+-#line 343 "parser.y" /* yacc.c:1648 */
++#line 341 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2645 "parser.tab.c" /* yacc.c:1648 */
++#line 2640 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 7:
+-#line 344 "parser.y" /* yacc.c:1648 */
++#line 342 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2651 "parser.tab.c" /* yacc.c:1648 */
++#line 2646 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 8:
+-#line 345 "parser.y" /* yacc.c:1648 */
++#line 343 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2657 "parser.tab.c" /* yacc.c:1648 */
++#line 2652 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 9:
+-#line 346 "parser.y" /* yacc.c:1648 */
++#line 344 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2663 "parser.tab.c" /* yacc.c:1648 */
++#line 2658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+-#line 347 "parser.y" /* yacc.c:1648 */
++#line 345 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list);
+ reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0);
+ }
+-#line 2671 "parser.tab.c" /* yacc.c:1648 */
++#line 2666 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+-#line 350 "parser.y" /* yacc.c:1648 */
++#line 348 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2679 "parser.tab.c" /* yacc.c:1648 */
++#line 2674 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+-#line 353 "parser.y" /* yacc.c:1648 */
++#line 351 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2685 "parser.tab.c" /* yacc.c:1648 */
++#line 2680 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+-#line 354 "parser.y" /* yacc.c:1648 */
++#line 352 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2691 "parser.tab.c" /* yacc.c:1648 */
++#line 2686 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+-#line 355 "parser.y" /* yacc.c:1648 */
++#line 353 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2697 "parser.tab.c" /* yacc.c:1648 */
++#line 2692 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+-#line 358 "parser.y" /* yacc.c:1648 */
++#line 356 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2703 "parser.tab.c" /* yacc.c:1648 */
++#line 2698 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+-#line 359 "parser.y" /* yacc.c:1648 */
++#line 357 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2709 "parser.tab.c" /* yacc.c:1648 */
++#line 2704 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+-#line 360 "parser.y" /* yacc.c:1648 */
++#line 358 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2715 "parser.tab.c" /* yacc.c:1648 */
++#line 2710 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+-#line 361 "parser.y" /* yacc.c:1648 */
++#line 359 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2721 "parser.tab.c" /* yacc.c:1648 */
++#line 2716 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+-#line 362 "parser.y" /* yacc.c:1648 */
++#line 360 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2727 "parser.tab.c" /* yacc.c:1648 */
++#line 2722 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+-#line 363 "parser.y" /* yacc.c:1648 */
++#line 361 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list); reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0); }
+-#line 2733 "parser.tab.c" /* yacc.c:1648 */
++#line 2728 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+-#line 364 "parser.y" /* yacc.c:1648 */
++#line 362 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2741 "parser.tab.c" /* yacc.c:1648 */
++#line 2736 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+-#line 367 "parser.y" /* yacc.c:1648 */
++#line 365 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2747 "parser.tab.c" /* yacc.c:1648 */
++#line 2742 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+-#line 368 "parser.y" /* yacc.c:1648 */
++#line 366 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2753 "parser.tab.c" /* yacc.c:1648 */
++#line 2748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+-#line 369 "parser.y" /* yacc.c:1648 */
++#line 367 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_importlib((yyvsp[0].str))); }
+-#line 2759 "parser.tab.c" /* yacc.c:1648 */
++#line 2754 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 25:
+-#line 370 "parser.y" /* yacc.c:1648 */
++#line 368 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2765 "parser.tab.c" /* yacc.c:1648 */
++#line 2760 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 26:
+-#line 373 "parser.y" /* yacc.c:1648 */
++#line 371 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2771 "parser.tab.c" /* yacc.c:1648 */
++#line 2766 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+-#line 374 "parser.y" /* yacc.c:1648 */
++#line 372 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2777 "parser.tab.c" /* yacc.c:1648 */
++#line 2772 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+-#line 382 "parser.y" /* yacc.c:1648 */
++#line 380 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_cppquote((yyvsp[0].str)); }
+-#line 2783 "parser.tab.c" /* yacc.c:1648 */
++#line 2778 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+-#line 383 "parser.y" /* yacc.c:1648 */
++#line 381 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type)); }
+-#line 2789 "parser.tab.c" /* yacc.c:1648 */
++#line 2784 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+-#line 384 "parser.y" /* yacc.c:1648 */
++#line 382 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_declaration((yyvsp[-1].var)); }
+-#line 2795 "parser.tab.c" /* yacc.c:1648 */
++#line 2790 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 33:
+-#line 385 "parser.y" /* yacc.c:1648 */
++#line 383 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_import((yyvsp[0].str)); }
+-#line 2801 "parser.tab.c" /* yacc.c:1648 */
++#line 2796 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 34:
+-#line 386 "parser.y" /* yacc.c:1648 */
++#line 384 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = (yyvsp[-1].statement); }
+-#line 2807 "parser.tab.c" /* yacc.c:1648 */
++#line 2802 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+-#line 387 "parser.y" /* yacc.c:1648 */
++#line 385 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_pragma((yyvsp[0].str)); }
+-#line 2813 "parser.tab.c" /* yacc.c:1648 */
++#line 2808 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+-#line 388 "parser.y" /* yacc.c:1648 */
++#line 386 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = NULL; }
+-#line 2819 "parser.tab.c" /* yacc.c:1648 */
++#line 2814 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 37:
+-#line 392 "parser.y" /* yacc.c:1648 */
++#line 390 "parser.y" /* yacc.c:1646 */
+ {
+ int result;
+ (yyval.statement) = NULL;
+@@ -2827,909 +2822,909 @@ yyreduce:
+ if(!result)
+ error_loc("expected \"disable\" or \"enable\"\n");
+ }
+-#line 2831 "parser.tab.c" /* yacc.c:1648 */
++#line 2826 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 38:
+-#line 402 "parser.y" /* yacc.c:1648 */
++#line 400 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning(NULL, (yyvsp[0].num)); }
+-#line 2837 "parser.tab.c" /* yacc.c:1648 */
++#line 2832 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 39:
+-#line 403 "parser.y" /* yacc.c:1648 */
++#line 401 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning((yyvsp[-1].warning_list), (yyvsp[0].num)); }
+-#line 2843 "parser.tab.c" /* yacc.c:1648 */
++#line 2838 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 41:
+-#line 408 "parser.y" /* yacc.c:1648 */
++#line 406 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2849 "parser.tab.c" /* yacc.c:1648 */
++#line 2844 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 43:
+-#line 410 "parser.y" /* yacc.c:1648 */
++#line 408 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2855 "parser.tab.c" /* yacc.c:1648 */
++#line 2850 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+-#line 412 "parser.y" /* yacc.c:1648 */
++#line 410 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 2861 "parser.tab.c" /* yacc.c:1648 */
++#line 2856 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+-#line 413 "parser.y" /* yacc.c:1648 */
++#line 411 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_enum_attrs((yyvsp[-1].attr_list)); }
+-#line 2867 "parser.tab.c" /* yacc.c:1648 */
++#line 2862 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+-#line 414 "parser.y" /* yacc.c:1648 */
++#line 412 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_struct_attrs((yyvsp[-1].attr_list)); }
+-#line 2873 "parser.tab.c" /* yacc.c:1648 */
++#line 2868 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 48:
+-#line 415 "parser.y" /* yacc.c:1648 */
++#line 413 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_union_attrs((yyvsp[-1].attr_list)); }
+-#line 2879 "parser.tab.c" /* yacc.c:1648 */
++#line 2874 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+-#line 418 "parser.y" /* yacc.c:1648 */
++#line 416 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-1].str); }
+-#line 2885 "parser.tab.c" /* yacc.c:1648 */
++#line 2880 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 50:
+-#line 420 "parser.y" /* yacc.c:1648 */
++#line 418 "parser.y" /* yacc.c:1646 */
+ { assert(yychar == YYEMPTY);
+ (yyval.import) = xmalloc(sizeof(struct _import_t));
+ (yyval.import)->name = (yyvsp[-1].str);
+ (yyval.import)->import_performed = do_import((yyvsp[-1].str));
+ if (!(yyval.import)->import_performed) yychar = aEOF;
+ }
+-#line 2896 "parser.tab.c" /* yacc.c:1648 */
++#line 2891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 51:
+-#line 428 "parser.y" /* yacc.c:1648 */
++#line 426 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].import)->name;
+ if ((yyvsp[-2].import)->import_performed) pop_import();
+ free((yyvsp[-2].import));
+ }
+-#line 2905 "parser.tab.c" /* yacc.c:1648 */
++#line 2900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 52:
+-#line 435 "parser.y" /* yacc.c:1648 */
++#line 433 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].str); if(!parse_only) add_importlib((yyvsp[-2].str), current_typelib); }
+-#line 2911 "parser.tab.c" /* yacc.c:1648 */
++#line 2906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+-#line 438 "parser.y" /* yacc.c:1648 */
++#line 436 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2917 "parser.tab.c" /* yacc.c:1648 */
++#line 2912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 54:
+-#line 439 "parser.y" /* yacc.c:1648 */
++#line 437 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2923 "parser.tab.c" /* yacc.c:1648 */
++#line 2918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+-#line 441 "parser.y" /* yacc.c:1648 */
++#line 439 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = make_library((yyvsp[-1].str), check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list)));
+ if (!parse_only && do_typelib) current_typelib = (yyval.typelib);
+ }
+-#line 2931 "parser.tab.c" /* yacc.c:1648 */
++#line 2926 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 56:
+-#line 446 "parser.y" /* yacc.c:1648 */
++#line 444 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = (yyvsp[-3].typelib); (yyval.typelib)->stmts = (yyvsp[-2].stmt_list); }
+-#line 2937 "parser.tab.c" /* yacc.c:1648 */
++#line 2932 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 57:
+-#line 449 "parser.y" /* yacc.c:1648 */
++#line 447 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 2943 "parser.tab.c" /* yacc.c:1648 */
++#line 2938 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+-#line 453 "parser.y" /* yacc.c:1648 */
++#line 451 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); }
+-#line 2949 "parser.tab.c" /* yacc.c:1648 */
++#line 2944 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+-#line 454 "parser.y" /* yacc.c:1648 */
++#line 452 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); }
+-#line 2955 "parser.tab.c" /* yacc.c:1648 */
++#line 2950 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+-#line 458 "parser.y" /* yacc.c:1648 */
++#line 456 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), make_var(strdup("...")) ); }
+-#line 2961 "parser.tab.c" /* yacc.c:1648 */
++#line 2956 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+-#line 462 "parser.y" /* yacc.c:1648 */
++#line 460 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2971 "parser.tab.c" /* yacc.c:1648 */
++#line 2966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+-#line 467 "parser.y" /* yacc.c:1648 */
++#line 465 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2981 "parser.tab.c" /* yacc.c:1648 */
++#line 2976 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+-#line 474 "parser.y" /* yacc.c:1648 */
++#line 472 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr);
+ if (!(yyval.expr)->is_const || (yyval.expr)->cval <= 0)
+ error_loc("array dimension is not a positive integer constant\n");
+ }
+-#line 2990 "parser.tab.c" /* yacc.c:1648 */
++#line 2985 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+-#line 478 "parser.y" /* yacc.c:1648 */
++#line 476 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 2996 "parser.tab.c" /* yacc.c:1648 */
++#line 2991 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 67:
+-#line 479 "parser.y" /* yacc.c:1648 */
++#line 477 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3002 "parser.tab.c" /* yacc.c:1648 */
++#line 2997 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+-#line 482 "parser.y" /* yacc.c:1648 */
++#line 480 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 3008 "parser.tab.c" /* yacc.c:1648 */
++#line 3003 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+-#line 487 "parser.y" /* yacc.c:1648 */
++#line 485 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 3014 "parser.tab.c" /* yacc.c:1648 */
++#line 3009 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+-#line 490 "parser.y" /* yacc.c:1648 */
++#line 488 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); }
+-#line 3020 "parser.tab.c" /* yacc.c:1648 */
++#line 3015 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 72:
+-#line 491 "parser.y" /* yacc.c:1648 */
++#line 489 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); }
+-#line 3026 "parser.tab.c" /* yacc.c:1648 */
++#line 3021 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+-#line 492 "parser.y" /* yacc.c:1648 */
++#line 490 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); }
+-#line 3032 "parser.tab.c" /* yacc.c:1648 */
++#line 3027 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+-#line 495 "parser.y" /* yacc.c:1648 */
++#line 493 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); }
+-#line 3038 "parser.tab.c" /* yacc.c:1648 */
++#line 3033 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 75:
+-#line 496 "parser.y" /* yacc.c:1648 */
++#line 494 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); }
+-#line 3044 "parser.tab.c" /* yacc.c:1648 */
++#line 3039 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 76:
+-#line 499 "parser.y" /* yacc.c:1648 */
++#line 497 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = NULL; }
+-#line 3050 "parser.tab.c" /* yacc.c:1648 */
++#line 3045 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 77:
+-#line 500 "parser.y" /* yacc.c:1648 */
++#line 498 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); }
+-#line 3056 "parser.tab.c" /* yacc.c:1648 */
++#line 3051 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 78:
+-#line 501 "parser.y" /* yacc.c:1648 */
++#line 499 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ANNOTATION, (yyvsp[-1].str)); }
+-#line 3062 "parser.tab.c" /* yacc.c:1648 */
++#line 3057 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 79:
+-#line 502 "parser.y" /* yacc.c:1648 */
++#line 500 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_APPOBJECT); }
+-#line 3068 "parser.tab.c" /* yacc.c:1648 */
++#line 3063 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 80:
+-#line 503 "parser.y" /* yacc.c:1648 */
++#line 501 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ASYNC); }
+-#line 3074 "parser.tab.c" /* yacc.c:1648 */
++#line 3069 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+-#line 504 "parser.y" /* yacc.c:1648 */
++#line 502 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); }
+-#line 3080 "parser.tab.c" /* yacc.c:1648 */
++#line 3075 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+-#line 505 "parser.y" /* yacc.c:1648 */
++#line 503 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BINDABLE); }
+-#line 3086 "parser.tab.c" /* yacc.c:1648 */
++#line 3081 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+-#line 506 "parser.y" /* yacc.c:1648 */
++#line 504 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BROADCAST); }
+-#line 3092 "parser.tab.c" /* yacc.c:1648 */
++#line 3087 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+-#line 507 "parser.y" /* yacc.c:1648 */
++#line 505 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); }
+-#line 3098 "parser.tab.c" /* yacc.c:1648 */
++#line 3093 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 85:
+-#line 508 "parser.y" /* yacc.c:1648 */
++#line 506 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); }
+-#line 3104 "parser.tab.c" /* yacc.c:1648 */
++#line 3099 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 86:
+-#line 509 "parser.y" /* yacc.c:1648 */
++#line 507 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CODE); }
+-#line 3110 "parser.tab.c" /* yacc.c:1648 */
++#line 3105 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 87:
+-#line 510 "parser.y" /* yacc.c:1648 */
++#line 508 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_COMMSTATUS); }
+-#line 3116 "parser.tab.c" /* yacc.c:1648 */
++#line 3111 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 88:
+-#line 511 "parser.y" /* yacc.c:1648 */
++#line 509 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); }
+-#line 3122 "parser.tab.c" /* yacc.c:1648 */
++#line 3117 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 89:
+-#line 512 "parser.y" /* yacc.c:1648 */
++#line 510 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
+-#line 3128 "parser.tab.c" /* yacc.c:1648 */
++#line 3123 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 90:
+-#line 513 "parser.y" /* yacc.c:1648 */
++#line 511 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+-#line 3134 "parser.tab.c" /* yacc.c:1648 */
++#line 3129 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 91:
+-#line 514 "parser.y" /* yacc.c:1648 */
++#line 512 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CONTROL); }
+-#line 3140 "parser.tab.c" /* yacc.c:1648 */
++#line 3135 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 92:
+-#line 515 "parser.y" /* yacc.c:1648 */
++#line 513 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 3146 "parser.tab.c" /* yacc.c:1648 */
++#line 3141 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 93:
+-#line 516 "parser.y" /* yacc.c:1648 */
++#line 514 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULT); }
+-#line 3152 "parser.tab.c" /* yacc.c:1648 */
++#line 3147 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 94:
+-#line 517 "parser.y" /* yacc.c:1648 */
++#line 515 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTBIND); }
+-#line 3158 "parser.tab.c" /* yacc.c:1648 */
++#line 3153 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 95:
+-#line 518 "parser.y" /* yacc.c:1648 */
++#line 516 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); }
+-#line 3164 "parser.tab.c" /* yacc.c:1648 */
++#line 3159 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 96:
+-#line 519 "parser.y" /* yacc.c:1648 */
++#line 517 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[-1].expr)); }
+-#line 3170 "parser.tab.c" /* yacc.c:1648 */
++#line 3165 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 97:
+-#line 520 "parser.y" /* yacc.c:1648 */
++#line 518 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); }
+-#line 3176 "parser.tab.c" /* yacc.c:1648 */
++#line 3171 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 98:
+-#line 521 "parser.y" /* yacc.c:1648 */
++#line 519 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
+-#line 3182 "parser.tab.c" /* yacc.c:1648 */
++#line 3177 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+-#line 522 "parser.y" /* yacc.c:1648 */
++#line 520 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); }
+-#line 3188 "parser.tab.c" /* yacc.c:1648 */
++#line 3183 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+-#line 523 "parser.y" /* yacc.c:1648 */
++#line 521 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); }
+-#line 3194 "parser.tab.c" /* yacc.c:1648 */
++#line 3189 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+-#line 524 "parser.y" /* yacc.c:1648 */
++#line 522 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DUAL); }
+-#line 3200 "parser.tab.c" /* yacc.c:1648 */
++#line 3195 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+-#line 525 "parser.y" /* yacc.c:1648 */
++#line 523 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENABLEALLOCATE); }
+-#line 3206 "parser.tab.c" /* yacc.c:1648 */
++#line 3201 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 103:
+-#line 526 "parser.y" /* yacc.c:1648 */
++#line 524 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 3212 "parser.tab.c" /* yacc.c:1648 */
++#line 3207 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 104:
+-#line 527 "parser.y" /* yacc.c:1648 */
++#line 525 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); }
+-#line 3218 "parser.tab.c" /* yacc.c:1648 */
++#line 3213 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 105:
+-#line 528 "parser.y" /* yacc.c:1648 */
++#line 526 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[-1].expr)); }
+-#line 3224 "parser.tab.c" /* yacc.c:1648 */
++#line 3219 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 106:
+-#line 529 "parser.y" /* yacc.c:1648 */
++#line 527 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 3230 "parser.tab.c" /* yacc.c:1648 */
++#line 3225 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 107:
+-#line 530 "parser.y" /* yacc.c:1648 */
++#line 528 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FAULTSTATUS); }
+-#line 3236 "parser.tab.c" /* yacc.c:1648 */
++#line 3231 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 108:
+-#line 531 "parser.y" /* yacc.c:1648 */
++#line 529 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FORCEALLOCATE); }
+-#line 3242 "parser.tab.c" /* yacc.c:1648 */
++#line 3237 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 109:
+-#line 532 "parser.y" /* yacc.c:1648 */
++#line 530 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HANDLE); }
+-#line 3248 "parser.tab.c" /* yacc.c:1648 */
++#line 3243 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 110:
+-#line 533 "parser.y" /* yacc.c:1648 */
++#line 531 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); }
+-#line 3254 "parser.tab.c" /* yacc.c:1648 */
++#line 3249 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 111:
+-#line 534 "parser.y" /* yacc.c:1648 */
++#line 532 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); }
+-#line 3260 "parser.tab.c" /* yacc.c:1648 */
++#line 3255 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 112:
+-#line 535 "parser.y" /* yacc.c:1648 */
++#line 533 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); }
+-#line 3266 "parser.tab.c" /* yacc.c:1648 */
++#line 3261 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 113:
+-#line 536 "parser.y" /* yacc.c:1648 */
++#line 534 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); }
+-#line 3272 "parser.tab.c" /* yacc.c:1648 */
++#line 3267 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 114:
+-#line 537 "parser.y" /* yacc.c:1648 */
++#line 535 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); }
+-#line 3278 "parser.tab.c" /* yacc.c:1648 */
++#line 3273 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 115:
+-#line 538 "parser.y" /* yacc.c:1648 */
++#line 536 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HIDDEN); }
+-#line 3284 "parser.tab.c" /* yacc.c:1648 */
++#line 3279 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 116:
+-#line 539 "parser.y" /* yacc.c:1648 */
++#line 537 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); }
+-#line 3290 "parser.tab.c" /* yacc.c:1648 */
++#line 3285 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 117:
+-#line 540 "parser.y" /* yacc.c:1648 */
++#line 538 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); }
+-#line 3296 "parser.tab.c" /* yacc.c:1648 */
++#line 3291 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 118:
+-#line 541 "parser.y" /* yacc.c:1648 */
++#line 539 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IGNORE); }
+-#line 3302 "parser.tab.c" /* yacc.c:1648 */
++#line 3297 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 119:
+-#line 542 "parser.y" /* yacc.c:1648 */
++#line 540 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); }
+-#line 3308 "parser.tab.c" /* yacc.c:1648 */
++#line 3303 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 120:
+-#line 543 "parser.y" /* yacc.c:1648 */
++#line 541 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); }
+-#line 3314 "parser.tab.c" /* yacc.c:1648 */
++#line 3309 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 121:
+-#line 544 "parser.y" /* yacc.c:1648 */
++#line 542 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].var)); }
+-#line 3320 "parser.tab.c" /* yacc.c:1648 */
++#line 3315 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 122:
+-#line 545 "parser.y" /* yacc.c:1648 */
++#line 543 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IN); }
+-#line 3326 "parser.tab.c" /* yacc.c:1648 */
++#line 3321 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 123:
+-#line 546 "parser.y" /* yacc.c:1648 */
++#line 544 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_INPUTSYNC); }
+-#line 3332 "parser.tab.c" /* yacc.c:1648 */
++#line 3327 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 124:
+-#line 547 "parser.y" /* yacc.c:1648 */
++#line 545 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); }
+-#line 3338 "parser.tab.c" /* yacc.c:1648 */
++#line 3333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 125:
+-#line 548 "parser.y" /* yacc.c:1648 */
++#line 546 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[-1].expr)); }
+-#line 3344 "parser.tab.c" /* yacc.c:1648 */
++#line 3339 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 126:
+-#line 549 "parser.y" /* yacc.c:1648 */
++#line 547 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARAMLCID); }
+-#line 3350 "parser.tab.c" /* yacc.c:1648 */
++#line 3345 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 127:
+-#line 550 "parser.y" /* yacc.c:1648 */
++#line 548 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LICENSED); }
+-#line 3356 "parser.tab.c" /* yacc.c:1648 */
++#line 3351 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 128:
+-#line 551 "parser.y" /* yacc.c:1648 */
++#line 549 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LOCAL); }
+-#line 3362 "parser.tab.c" /* yacc.c:1648 */
++#line 3357 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 129:
+-#line 552 "parser.y" /* yacc.c:1648 */
++#line 550 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MAYBE); }
+-#line 3368 "parser.tab.c" /* yacc.c:1648 */
++#line 3363 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 130:
+-#line 553 "parser.y" /* yacc.c:1648 */
++#line 551 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MESSAGE); }
+-#line 3374 "parser.tab.c" /* yacc.c:1648 */
++#line 3369 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 131:
+-#line 554 "parser.y" /* yacc.c:1648 */
++#line 552 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOCODE); }
+-#line 3380 "parser.tab.c" /* yacc.c:1648 */
++#line 3375 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 132:
+-#line 555 "parser.y" /* yacc.c:1648 */
++#line 553 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); }
+-#line 3386 "parser.tab.c" /* yacc.c:1648 */
++#line 3381 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 133:
+-#line 556 "parser.y" /* yacc.c:1648 */
++#line 554 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONCREATABLE); }
+-#line 3392 "parser.tab.c" /* yacc.c:1648 */
++#line 3387 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 134:
+-#line 557 "parser.y" /* yacc.c:1648 */
++#line 555 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); }
+-#line 3398 "parser.tab.c" /* yacc.c:1648 */
++#line 3393 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 135:
+-#line 558 "parser.y" /* yacc.c:1648 */
++#line 556 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFY); }
+-#line 3404 "parser.tab.c" /* yacc.c:1648 */
++#line 3399 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 136:
+-#line 559 "parser.y" /* yacc.c:1648 */
++#line 557 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFYFLAG); }
+-#line 3410 "parser.tab.c" /* yacc.c:1648 */
++#line 3405 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 137:
+-#line 560 "parser.y" /* yacc.c:1648 */
++#line 558 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OBJECT); }
+-#line 3416 "parser.tab.c" /* yacc.c:1648 */
++#line 3411 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 138:
+-#line 561 "parser.y" /* yacc.c:1648 */
++#line 559 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ODL); }
+-#line 3422 "parser.tab.c" /* yacc.c:1648 */
++#line 3417 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 139:
+-#line 562 "parser.y" /* yacc.c:1648 */
++#line 560 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); }
+-#line 3428 "parser.tab.c" /* yacc.c:1648 */
++#line 3423 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 140:
+-#line 563 "parser.y" /* yacc.c:1648 */
++#line 561 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_OPTIMIZE, (yyvsp[-1].str)); }
+-#line 3434 "parser.tab.c" /* yacc.c:1648 */
++#line 3429 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 141:
+-#line 564 "parser.y" /* yacc.c:1648 */
++#line 562 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OPTIONAL); }
+-#line 3440 "parser.tab.c" /* yacc.c:1648 */
++#line 3435 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 142:
+-#line 565 "parser.y" /* yacc.c:1648 */
++#line 563 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OUT); }
+-#line 3446 "parser.tab.c" /* yacc.c:1648 */
++#line 3441 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 143:
+-#line 566 "parser.y" /* yacc.c:1648 */
++#line 564 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARTIALIGNORE); }
+-#line 3452 "parser.tab.c" /* yacc.c:1648 */
++#line 3447 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 144:
+-#line 567 "parser.y" /* yacc.c:1648 */
++#line 565 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); }
+-#line 3458 "parser.tab.c" /* yacc.c:1648 */
++#line 3453 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 145:
+-#line 568 "parser.y" /* yacc.c:1648 */
++#line 566 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_PROGID, (yyvsp[-1].str)); }
+-#line 3464 "parser.tab.c" /* yacc.c:1648 */
++#line 3459 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 146:
+-#line 569 "parser.y" /* yacc.c:1648 */
++#line 567 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPGET); }
+-#line 3470 "parser.tab.c" /* yacc.c:1648 */
++#line 3465 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 147:
+-#line 570 "parser.y" /* yacc.c:1648 */
++#line 568 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUT); }
+-#line 3476 "parser.tab.c" /* yacc.c:1648 */
++#line 3471 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 148:
+-#line 571 "parser.y" /* yacc.c:1648 */
++#line 569 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUTREF); }
+-#line 3482 "parser.tab.c" /* yacc.c:1648 */
++#line 3477 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 149:
+-#line 572 "parser.y" /* yacc.c:1648 */
++#line 570 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROXY); }
+-#line 3488 "parser.tab.c" /* yacc.c:1648 */
++#line 3483 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 150:
+-#line 573 "parser.y" /* yacc.c:1648 */
++#line 571 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PUBLIC); }
+-#line 3494 "parser.tab.c" /* yacc.c:1648 */
++#line 3489 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 151:
+-#line 575 "parser.y" /* yacc.c:1648 */
++#line 573 "parser.y" /* yacc.c:1646 */
+ { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
+ list = append_expr( list, (yyvsp[-1].expr) );
+ (yyval.attr) = make_attrp(ATTR_RANGE, list); }
+-#line 3502 "parser.tab.c" /* yacc.c:1648 */
++#line 3497 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 152:
+-#line 578 "parser.y" /* yacc.c:1648 */
++#line 576 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_READONLY); }
+-#line 3508 "parser.tab.c" /* yacc.c:1648 */
++#line 3503 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 153:
+-#line 579 "parser.y" /* yacc.c:1648 */
++#line 577 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_REPRESENTAS, (yyvsp[-1].type)); }
+-#line 3514 "parser.tab.c" /* yacc.c:1648 */
++#line 3509 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 154:
+-#line 580 "parser.y" /* yacc.c:1648 */
++#line 578 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); }
+-#line 3520 "parser.tab.c" /* yacc.c:1648 */
++#line 3515 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 155:
+-#line 581 "parser.y" /* yacc.c:1648 */
++#line 579 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RESTRICTED); }
+-#line 3526 "parser.tab.c" /* yacc.c:1648 */
++#line 3521 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 156:
+-#line 582 "parser.y" /* yacc.c:1648 */
++#line 580 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RETVAL); }
+-#line 3532 "parser.tab.c" /* yacc.c:1648 */
++#line 3527 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 157:
+-#line 583 "parser.y" /* yacc.c:1648 */
++#line 581 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); }
+-#line 3538 "parser.tab.c" /* yacc.c:1648 */
++#line 3533 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 158:
+-#line 584 "parser.y" /* yacc.c:1648 */
++#line 582 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_SOURCE); }
+-#line 3544 "parser.tab.c" /* yacc.c:1648 */
++#line 3539 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 159:
+-#line 585 "parser.y" /* yacc.c:1648 */
++#line 583 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); }
+-#line 3550 "parser.tab.c" /* yacc.c:1648 */
++#line 3545 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 160:
+-#line 586 "parser.y" /* yacc.c:1648 */
++#line 584 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRING); }
+-#line 3556 "parser.tab.c" /* yacc.c:1648 */
++#line 3551 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 161:
+-#line 587 "parser.y" /* yacc.c:1648 */
++#line 585 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); }
+-#line 3562 "parser.tab.c" /* yacc.c:1648 */
++#line 3557 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 162:
+-#line 588 "parser.y" /* yacc.c:1648 */
++#line 586 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); }
+-#line 3568 "parser.tab.c" /* yacc.c:1648 */
++#line 3563 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 163:
+-#line 589 "parser.y" /* yacc.c:1648 */
++#line 587 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); }
+-#line 3574 "parser.tab.c" /* yacc.c:1648 */
++#line 3569 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 164:
+-#line 590 "parser.y" /* yacc.c:1648 */
++#line 588 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_THREADING, (yyvsp[-1].num)); }
+-#line 3580 "parser.tab.c" /* yacc.c:1648 */
++#line 3575 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 165:
+-#line 591 "parser.y" /* yacc.c:1648 */
++#line 589 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_UIDEFAULT); }
+-#line 3586 "parser.tab.c" /* yacc.c:1648 */
++#line 3581 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 166:
+-#line 592 "parser.y" /* yacc.c:1648 */
++#line 590 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_USESGETLASTERROR); }
+-#line 3592 "parser.tab.c" /* yacc.c:1648 */
++#line 3587 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 167:
+-#line 593 "parser.y" /* yacc.c:1648 */
++#line 591 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_USERMARSHAL, (yyvsp[-1].type)); }
+-#line 3598 "parser.tab.c" /* yacc.c:1648 */
++#line 3593 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 168:
+-#line 594 "parser.y" /* yacc.c:1648 */
++#line 592 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); }
+-#line 3604 "parser.tab.c" /* yacc.c:1648 */
++#line 3599 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 169:
+-#line 595 "parser.y" /* yacc.c:1648 */
++#line 593 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ASYNCUUID, (yyvsp[-1].uuid)); }
+-#line 3610 "parser.tab.c" /* yacc.c:1648 */
++#line 3605 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 170:
+-#line 596 "parser.y" /* yacc.c:1648 */
++#line 594 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_V1ENUM); }
+-#line 3616 "parser.tab.c" /* yacc.c:1648 */
++#line 3611 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 171:
+-#line 597 "parser.y" /* yacc.c:1648 */
++#line 595 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_VARARG); }
+-#line 3622 "parser.tab.c" /* yacc.c:1648 */
++#line 3617 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 172:
+-#line 598 "parser.y" /* yacc.c:1648 */
++#line 596 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); }
+-#line 3628 "parser.tab.c" /* yacc.c:1648 */
++#line 3623 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 173:
+-#line 599 "parser.y" /* yacc.c:1648 */
++#line 597 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_VIPROGID, (yyvsp[-1].str)); }
+-#line 3634 "parser.tab.c" /* yacc.c:1648 */
++#line 3629 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 174:
+-#line 600 "parser.y" /* yacc.c:1648 */
++#line 598 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); }
+-#line 3640 "parser.tab.c" /* yacc.c:1648 */
++#line 3635 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 175:
+-#line 601 "parser.y" /* yacc.c:1648 */
++#line 599 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); }
+-#line 3646 "parser.tab.c" /* yacc.c:1648 */
++#line 3641 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 177:
+-#line 606 "parser.y" /* yacc.c:1648 */
++#line 604 "parser.y" /* yacc.c:1646 */
+ { if (!is_valid_uuid((yyvsp[0].str)))
+ error_loc("invalid UUID: %s\n", (yyvsp[0].str));
+ (yyval.uuid) = parse_uuid((yyvsp[0].str)); }
+-#line 3654 "parser.tab.c" /* yacc.c:1648 */
++#line 3649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 178:
+-#line 611 "parser.y" /* yacc.c:1648 */
++#line 609 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__cdecl"); }
+-#line 3660 "parser.tab.c" /* yacc.c:1648 */
++#line 3655 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 179:
+-#line 612 "parser.y" /* yacc.c:1648 */
++#line 610 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__fastcall"); }
+-#line 3666 "parser.tab.c" /* yacc.c:1648 */
++#line 3661 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 180:
+-#line 613 "parser.y" /* yacc.c:1648 */
++#line 611 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__pascal"); }
+-#line 3672 "parser.tab.c" /* yacc.c:1648 */
++#line 3667 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 181:
+-#line 614 "parser.y" /* yacc.c:1648 */
++#line 612 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__stdcall"); }
+-#line 3678 "parser.tab.c" /* yacc.c:1648 */
++#line 3673 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 182:
+-#line 617 "parser.y" /* yacc.c:1648 */
++#line 615 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3684 "parser.tab.c" /* yacc.c:1648 */
++#line 3679 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 183:
+-#line 618 "parser.y" /* yacc.c:1648 */
++#line 616 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 3690 "parser.tab.c" /* yacc.c:1648 */
++#line 3685 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 184:
+-#line 621 "parser.y" /* yacc.c:1648 */
++#line 619 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3699 "parser.tab.c" /* yacc.c:1648 */
++#line 3694 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 185:
+-#line 625 "parser.y" /* yacc.c:1648 */
++#line 623 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attr(ATTR_DEFAULT);
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3708 "parser.tab.c" /* yacc.c:1648 */
++#line 3703 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 186:
+-#line 631 "parser.y" /* yacc.c:1648 */
++#line 629 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3714 "parser.tab.c" /* yacc.c:1648 */
++#line 3709 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 187:
+-#line 632 "parser.y" /* yacc.c:1648 */
++#line 630 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = (yyvsp[-1].var_list); }
+-#line 3720 "parser.tab.c" /* yacc.c:1648 */
++#line 3715 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 189:
+-#line 636 "parser.y" /* yacc.c:1648 */
++#line 634 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
+ (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
+ }
+-#line 3729 "parser.tab.c" /* yacc.c:1648 */
++#line 3724 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 190:
+-#line 640 "parser.y" /* yacc.c:1648 */
++#line 638 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ {
+ var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
+@@ -3740,656 +3735,656 @@ yyreduce:
+ }
+ (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) );
+ }
+-#line 3744 "parser.tab.c" /* yacc.c:1648 */
++#line 3739 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 191:
+-#line 652 "parser.y" /* yacc.c:1648 */
++#line 650 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[-2].var));
+ (yyval.var)->eval = (yyvsp[0].expr);
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3753 "parser.tab.c" /* yacc.c:1648 */
++#line 3748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 192:
+-#line 656 "parser.y" /* yacc.c:1648 */
++#line 654 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[0].var));
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3761 "parser.tab.c" /* yacc.c:1648 */
++#line 3756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 193:
+-#line 661 "parser.y" /* yacc.c:1648 */
++#line 659 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 3767 "parser.tab.c" /* yacc.c:1648 */
++#line 3762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 194:
+-#line 664 "parser.y" /* yacc.c:1648 */
++#line 662 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 3773 "parser.tab.c" /* yacc.c:1648 */
++#line 3768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 195:
+-#line 665 "parser.y" /* yacc.c:1648 */
++#line 663 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 3779 "parser.tab.c" /* yacc.c:1648 */
++#line 3774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 196:
+-#line 668 "parser.y" /* yacc.c:1648 */
++#line 666 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3785 "parser.tab.c" /* yacc.c:1648 */
++#line 3780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 198:
+-#line 672 "parser.y" /* yacc.c:1648 */
++#line 670 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); }
+-#line 3791 "parser.tab.c" /* yacc.c:1648 */
++#line 3786 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 199:
+-#line 673 "parser.y" /* yacc.c:1648 */
++#line 671 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); }
+-#line 3797 "parser.tab.c" /* yacc.c:1648 */
++#line 3792 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 200:
+-#line 674 "parser.y" /* yacc.c:1648 */
++#line 672 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); }
+-#line 3803 "parser.tab.c" /* yacc.c:1648 */
++#line 3798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 201:
+-#line 675 "parser.y" /* yacc.c:1648 */
++#line 673 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); }
+-#line 3809 "parser.tab.c" /* yacc.c:1648 */
++#line 3804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 202:
+-#line 676 "parser.y" /* yacc.c:1648 */
++#line 674 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, 0); }
+-#line 3815 "parser.tab.c" /* yacc.c:1648 */
++#line 3810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 203:
+-#line 677 "parser.y" /* yacc.c:1648 */
++#line 675 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); }
+-#line 3821 "parser.tab.c" /* yacc.c:1648 */
++#line 3816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 204:
+-#line 678 "parser.y" /* yacc.c:1648 */
++#line 676 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[0].str)); }
+-#line 3827 "parser.tab.c" /* yacc.c:1648 */
++#line 3822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 205:
+-#line 679 "parser.y" /* yacc.c:1648 */
++#line 677 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[0].str)); }
+-#line 3833 "parser.tab.c" /* yacc.c:1648 */
++#line 3828 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 206:
+-#line 680 "parser.y" /* yacc.c:1648 */
++#line 678 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_CHARCONST, (yyvsp[0].str)); }
+-#line 3839 "parser.tab.c" /* yacc.c:1648 */
++#line 3834 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 207:
+-#line 681 "parser.y" /* yacc.c:1648 */
++#line 679 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); }
+-#line 3845 "parser.tab.c" /* yacc.c:1648 */
++#line 3840 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 208:
+-#line 682 "parser.y" /* yacc.c:1648 */
++#line 680 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3851 "parser.tab.c" /* yacc.c:1648 */
++#line 3846 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 209:
+-#line 683 "parser.y" /* yacc.c:1648 */
++#line 681 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3857 "parser.tab.c" /* yacc.c:1648 */
++#line 3852 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 210:
+-#line 684 "parser.y" /* yacc.c:1648 */
++#line 682 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3863 "parser.tab.c" /* yacc.c:1648 */
++#line 3858 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 211:
+-#line 685 "parser.y" /* yacc.c:1648 */
++#line 683 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3869 "parser.tab.c" /* yacc.c:1648 */
++#line 3864 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 212:
+-#line 686 "parser.y" /* yacc.c:1648 */
++#line 684 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3875 "parser.tab.c" /* yacc.c:1648 */
++#line 3870 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 213:
+-#line 687 "parser.y" /* yacc.c:1648 */
++#line 685 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3881 "parser.tab.c" /* yacc.c:1648 */
++#line 3876 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 214:
+-#line 688 "parser.y" /* yacc.c:1648 */
++#line 686 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3887 "parser.tab.c" /* yacc.c:1648 */
++#line 3882 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 215:
+-#line 689 "parser.y" /* yacc.c:1648 */
++#line 687 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3893 "parser.tab.c" /* yacc.c:1648 */
++#line 3888 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 216:
+-#line 690 "parser.y" /* yacc.c:1648 */
++#line 688 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3899 "parser.tab.c" /* yacc.c:1648 */
++#line 3894 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 217:
+-#line 691 "parser.y" /* yacc.c:1648 */
++#line 689 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3905 "parser.tab.c" /* yacc.c:1648 */
++#line 3900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 218:
+-#line 692 "parser.y" /* yacc.c:1648 */
++#line 690 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3911 "parser.tab.c" /* yacc.c:1648 */
++#line 3906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 219:
+-#line 693 "parser.y" /* yacc.c:1648 */
++#line 691 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3917 "parser.tab.c" /* yacc.c:1648 */
++#line 3912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 220:
+-#line 694 "parser.y" /* yacc.c:1648 */
++#line 692 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3923 "parser.tab.c" /* yacc.c:1648 */
++#line 3918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 221:
+-#line 695 "parser.y" /* yacc.c:1648 */
++#line 693 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3929 "parser.tab.c" /* yacc.c:1648 */
++#line 3924 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 222:
+-#line 696 "parser.y" /* yacc.c:1648 */
++#line 694 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3935 "parser.tab.c" /* yacc.c:1648 */
++#line 3930 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 223:
+-#line 697 "parser.y" /* yacc.c:1648 */
++#line 695 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3941 "parser.tab.c" /* yacc.c:1648 */
++#line 3936 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 224:
+-#line 698 "parser.y" /* yacc.c:1648 */
++#line 696 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3947 "parser.tab.c" /* yacc.c:1648 */
++#line 3942 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 225:
+-#line 699 "parser.y" /* yacc.c:1648 */
++#line 697 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3953 "parser.tab.c" /* yacc.c:1648 */
++#line 3948 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 226:
+-#line 700 "parser.y" /* yacc.c:1648 */
++#line 698 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3959 "parser.tab.c" /* yacc.c:1648 */
++#line 3954 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 227:
+-#line 701 "parser.y" /* yacc.c:1648 */
++#line 699 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[0].expr)); }
+-#line 3965 "parser.tab.c" /* yacc.c:1648 */
++#line 3960 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 228:
+-#line 702 "parser.y" /* yacc.c:1648 */
++#line 700 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); }
+-#line 3971 "parser.tab.c" /* yacc.c:1648 */
++#line 3966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 229:
+-#line 703 "parser.y" /* yacc.c:1648 */
++#line 701 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[0].expr)); }
+-#line 3977 "parser.tab.c" /* yacc.c:1648 */
++#line 3972 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 230:
+-#line 704 "parser.y" /* yacc.c:1648 */
++#line 702 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); }
+-#line 3983 "parser.tab.c" /* yacc.c:1648 */
++#line 3978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 231:
+-#line 705 "parser.y" /* yacc.c:1648 */
++#line 703 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); }
+-#line 3989 "parser.tab.c" /* yacc.c:1648 */
++#line 3984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 232:
+-#line 706 "parser.y" /* yacc.c:1648 */
++#line 704 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); }
+-#line 3995 "parser.tab.c" /* yacc.c:1648 */
++#line 3990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 233:
+-#line 707 "parser.y" /* yacc.c:1648 */
++#line 705 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[-2].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4001 "parser.tab.c" /* yacc.c:1648 */
++#line 3996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 234:
+-#line 708 "parser.y" /* yacc.c:1648 */
++#line 706 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[-2].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4007 "parser.tab.c" /* yacc.c:1648 */
++#line 4002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 235:
+-#line 710 "parser.y" /* yacc.c:1648 */
++#line 708 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_CAST, declare_var(NULL, (yyvsp[-3].declspec), (yyvsp[-2].declarator), 0), (yyvsp[0].expr)); free((yyvsp[-3].declspec)); free((yyvsp[-2].declarator)); }
+-#line 4013 "parser.tab.c" /* yacc.c:1648 */
++#line 4008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 236:
+-#line 712 "parser.y" /* yacc.c:1648 */
++#line 710 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_SIZEOF, declare_var(NULL, (yyvsp[-2].declspec), (yyvsp[-1].declarator), 0), NULL); free((yyvsp[-2].declspec)); free((yyvsp[-1].declarator)); }
+-#line 4019 "parser.tab.c" /* yacc.c:1648 */
++#line 4014 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 237:
+-#line 713 "parser.y" /* yacc.c:1648 */
++#line 711 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[-3].expr), (yyvsp[-1].expr)); }
+-#line 4025 "parser.tab.c" /* yacc.c:1648 */
++#line 4020 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 238:
+-#line 714 "parser.y" /* yacc.c:1648 */
++#line 712 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr); }
+-#line 4031 "parser.tab.c" /* yacc.c:1648 */
++#line 4026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 239:
+-#line 717 "parser.y" /* yacc.c:1648 */
++#line 715 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 4037 "parser.tab.c" /* yacc.c:1648 */
++#line 4032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 240:
+-#line 718 "parser.y" /* yacc.c:1648 */
++#line 716 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 4043 "parser.tab.c" /* yacc.c:1648 */
++#line 4038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 241:
+-#line 721 "parser.y" /* yacc.c:1648 */
++#line 719 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const)
+ error_loc("expression is not an integer constant\n");
+ }
+-#line 4052 "parser.tab.c" /* yacc.c:1648 */
++#line 4047 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 242:
+-#line 727 "parser.y" /* yacc.c:1648 */
++#line 725 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT)
+ error_loc("expression is not constant\n");
+ }
+-#line 4061 "parser.tab.c" /* yacc.c:1648 */
++#line 4056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 243:
+-#line 733 "parser.y" /* yacc.c:1648 */
++#line 731 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4067 "parser.tab.c" /* yacc.c:1648 */
++#line 4062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 244:
+-#line 734 "parser.y" /* yacc.c:1648 */
++#line 732 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var_list((yyvsp[-1].var_list), (yyvsp[0].var_list)); }
+-#line 4073 "parser.tab.c" /* yacc.c:1648 */
++#line 4068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 245:
+-#line 738 "parser.y" /* yacc.c:1648 */
++#line 736 "parser.y" /* yacc.c:1646 */
+ { const char *first = LIST_ENTRY(list_head((yyvsp[-1].declarator_list)), declarator_t, entry)->var->name;
+ check_field_attrs(first, (yyvsp[-3].attr_list));
+ (yyval.var_list) = set_var_types((yyvsp[-3].attr_list), (yyvsp[-2].declspec), (yyvsp[-1].declarator_list));
+ }
+-#line 4082 "parser.tab.c" /* yacc.c:1648 */
++#line 4077 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 246:
+-#line 742 "parser.y" /* yacc.c:1648 */
++#line 740 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
++ v->declspec.type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
+ (yyval.var_list) = append_var(NULL, v);
+ }
+-#line 4091 "parser.tab.c" /* yacc.c:1648 */
++#line 4086 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 247:
+-#line 749 "parser.y" /* yacc.c:1648 */
++#line 747 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4097 "parser.tab.c" /* yacc.c:1648 */
++#line 4092 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 248:
+-#line 750 "parser.y" /* yacc.c:1648 */
++#line 748 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); }
+-#line 4103 "parser.tab.c" /* yacc.c:1648 */
++#line 4098 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 249:
+-#line 753 "parser.y" /* yacc.c:1648 */
++#line 751 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4109 "parser.tab.c" /* yacc.c:1648 */
++#line 4104 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 250:
+-#line 754 "parser.y" /* yacc.c:1648 */
++#line 752 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 4115 "parser.tab.c" /* yacc.c:1648 */
++#line 4110 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 251:
+-#line 758 "parser.y" /* yacc.c:1648 */
++#line 756 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4121 "parser.tab.c" /* yacc.c:1648 */
++#line 4116 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 252:
+-#line 759 "parser.y" /* yacc.c:1648 */
++#line 757 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4127 "parser.tab.c" /* yacc.c:1648 */
++#line 4122 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 253:
+-#line 762 "parser.y" /* yacc.c:1648 */
++#line 760 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(check_field_attrs((yyvsp[0].declarator)->var->name, (yyvsp[-2].attr_list)),
+ (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4136 "parser.tab.c" /* yacc.c:1648 */
++#line 4131 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 254:
+-#line 766 "parser.y" /* yacc.c:1648 */
++#line 764 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
++ v->declspec.type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
+ (yyval.var) = v;
+ }
+-#line 4145 "parser.tab.c" /* yacc.c:1648 */
++#line 4140 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 255:
+-#line 772 "parser.y" /* yacc.c:1648 */
++#line 770 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[0].var);
+- if (type_get_type((yyval.var)->type) != TYPE_FUNCTION)
++ if (type_get_type((yyval.var)->declspec.type) != TYPE_FUNCTION)
+ error_loc("only methods may be declared inside the methods section of a dispinterface\n");
+ check_function_attrs((yyval.var)->name, (yyval.var)->attrs);
+ }
+-#line 4155 "parser.tab.c" /* yacc.c:1648 */
++#line 4150 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 256:
+-#line 781 "parser.y" /* yacc.c:1648 */
++#line 779 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4163 "parser.tab.c" /* yacc.c:1648 */
++#line 4158 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 257:
+-#line 784 "parser.y" /* yacc.c:1648 */
++#line 782 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4171 "parser.tab.c" /* yacc.c:1648 */
++#line 4166 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 258:
+-#line 789 "parser.y" /* yacc.c:1648 */
++#line 787 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4177 "parser.tab.c" /* yacc.c:1648 */
++#line 4172 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 260:
+-#line 793 "parser.y" /* yacc.c:1648 */
++#line 791 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = NULL; }
+-#line 4183 "parser.tab.c" /* yacc.c:1648 */
++#line 4178 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 261:
+-#line 794 "parser.y" /* yacc.c:1648 */
++#line 792 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4189 "parser.tab.c" /* yacc.c:1648 */
++#line 4184 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 262:
+-#line 795 "parser.y" /* yacc.c:1648 */
++#line 793 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4195 "parser.tab.c" /* yacc.c:1648 */
++#line 4190 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 263:
+-#line 798 "parser.y" /* yacc.c:1648 */
++#line 796 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4201 "parser.tab.c" /* yacc.c:1648 */
++#line 4196 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 264:
+-#line 800 "parser.y" /* yacc.c:1648 */
++#line 798 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4207 "parser.tab.c" /* yacc.c:1648 */
++#line 4202 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 265:
+-#line 803 "parser.y" /* yacc.c:1648 */
++#line 801 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4213 "parser.tab.c" /* yacc.c:1648 */
++#line 4208 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 266:
+-#line 804 "parser.y" /* yacc.c:1648 */
++#line 802 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4219 "parser.tab.c" /* yacc.c:1648 */
++#line 4214 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 268:
+-#line 806 "parser.y" /* yacc.c:1648 */
++#line 804 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), -1); }
+-#line 4225 "parser.tab.c" /* yacc.c:1648 */
++#line 4220 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 269:
+-#line 807 "parser.y" /* yacc.c:1648 */
++#line 805 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), 1); }
+-#line 4231 "parser.tab.c" /* yacc.c:1648 */
++#line 4226 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 270:
+-#line 808 "parser.y" /* yacc.c:1648 */
++#line 806 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 1); }
+-#line 4237 "parser.tab.c" /* yacc.c:1648 */
++#line 4232 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 271:
+-#line 809 "parser.y" /* yacc.c:1648 */
++#line 807 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4243 "parser.tab.c" /* yacc.c:1648 */
++#line 4238 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 272:
+-#line 810 "parser.y" /* yacc.c:1648 */
++#line 808 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4249 "parser.tab.c" /* yacc.c:1648 */
++#line 4244 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 273:
+-#line 811 "parser.y" /* yacc.c:1648 */
++#line 809 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4255 "parser.tab.c" /* yacc.c:1648 */
++#line 4250 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 274:
+-#line 812 "parser.y" /* yacc.c:1648 */
++#line 810 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4261 "parser.tab.c" /* yacc.c:1648 */
++#line 4256 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 275:
+-#line 813 "parser.y" /* yacc.c:1648 */
++#line 811 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4267 "parser.tab.c" /* yacc.c:1648 */
++#line 4262 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 278:
+-#line 820 "parser.y" /* yacc.c:1648 */
++#line 818 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 0); }
+-#line 4273 "parser.tab.c" /* yacc.c:1648 */
++#line 4268 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 279:
+-#line 821 "parser.y" /* yacc.c:1648 */
++#line 819 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT16, 0); }
+-#line 4279 "parser.tab.c" /* yacc.c:1648 */
++#line 4274 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 280:
+-#line 822 "parser.y" /* yacc.c:1648 */
++#line 820 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT8, 0); }
+-#line 4285 "parser.tab.c" /* yacc.c:1648 */
++#line 4280 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 281:
+-#line 823 "parser.y" /* yacc.c:1648 */
++#line 821 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_LONG, 0); }
+-#line 4291 "parser.tab.c" /* yacc.c:1648 */
++#line 4286 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 282:
+-#line 824 "parser.y" /* yacc.c:1648 */
++#line 822 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_HYPER, 0); }
+-#line 4297 "parser.tab.c" /* yacc.c:1648 */
++#line 4292 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 283:
+-#line 825 "parser.y" /* yacc.c:1648 */
++#line 823 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT64, 0); }
+-#line 4303 "parser.tab.c" /* yacc.c:1648 */
++#line 4298 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 284:
+-#line 826 "parser.y" /* yacc.c:1648 */
++#line 824 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_CHAR, 0); }
+-#line 4309 "parser.tab.c" /* yacc.c:1648 */
++#line 4304 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 285:
+-#line 827 "parser.y" /* yacc.c:1648 */
++#line 825 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT32, 0); }
+-#line 4315 "parser.tab.c" /* yacc.c:1648 */
++#line 4310 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 286:
+-#line 828 "parser.y" /* yacc.c:1648 */
++#line 826 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT3264, 0); }
+-#line 4321 "parser.tab.c" /* yacc.c:1648 */
++#line 4316 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 287:
+-#line 831 "parser.y" /* yacc.c:1648 */
++#line 829 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_coclass((yyvsp[0].str)); }
+-#line 4327 "parser.tab.c" /* yacc.c:1648 */
++#line 4322 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 288:
+-#line 832 "parser.y" /* yacc.c:1648 */
++#line 830 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type((yyvsp[0].str), NULL, 0);
+ if (type_get_type_detect_alias((yyval.type)) != TYPE_COCLASS)
+ error_loc("%s was not declared a coclass at %s:%d\n",
+ (yyvsp[0].str), (yyval.type)->loc_info.input_name,
+ (yyval.type)->loc_info.line_number);
+ }
+-#line 4338 "parser.tab.c" /* yacc.c:1648 */
++#line 4333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 289:
+-#line 840 "parser.y" /* yacc.c:1648 */
++#line 838 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+ (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4347 "parser.tab.c" /* yacc.c:1648 */
++#line 4342 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 290:
+-#line 847 "parser.y" /* yacc.c:1648 */
++#line 845 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_coclass_define((yyvsp[-4].type), (yyvsp[-2].ifref_list)); }
+-#line 4353 "parser.tab.c" /* yacc.c:1648 */
++#line 4348 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 291:
+-#line 850 "parser.y" /* yacc.c:1648 */
++#line 848 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4359 "parser.tab.c" /* yacc.c:1648 */
++#line 4354 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 292:
+-#line 853 "parser.y" /* yacc.c:1648 */
++#line 851 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = NULL; }
+-#line 4365 "parser.tab.c" /* yacc.c:1648 */
++#line 4360 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 293:
+-#line 854 "parser.y" /* yacc.c:1648 */
++#line 852 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); }
+-#line 4371 "parser.tab.c" /* yacc.c:1648 */
++#line 4366 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 294:
+-#line 858 "parser.y" /* yacc.c:1648 */
++#line 856 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); }
+-#line 4377 "parser.tab.c" /* yacc.c:1648 */
++#line 4372 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 295:
+-#line 861 "parser.y" /* yacc.c:1648 */
++#line 859 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4383 "parser.tab.c" /* yacc.c:1648 */
++#line 4378 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 296:
+-#line 862 "parser.y" /* yacc.c:1648 */
++#line 860 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4389 "parser.tab.c" /* yacc.c:1648 */
++#line 4384 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 297:
+-#line 865 "parser.y" /* yacc.c:1648 */
++#line 863 "parser.y" /* yacc.c:1646 */
+ { attr_t *attrs;
+ (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+@@ -4397,75 +4392,75 @@ yyreduce:
+ (yyval.type)->attrs = append_attr( check_dispiface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list)), attrs );
+ (yyval.type)->defined = TRUE;
+ }
+-#line 4401 "parser.tab.c" /* yacc.c:1648 */
++#line 4396 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 298:
+-#line 874 "parser.y" /* yacc.c:1648 */
++#line 872 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4407 "parser.tab.c" /* yacc.c:1648 */
++#line 4402 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 299:
+-#line 875 "parser.y" /* yacc.c:1648 */
++#line 873 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4413 "parser.tab.c" /* yacc.c:1648 */
++#line 4408 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 300:
+-#line 878 "parser.y" /* yacc.c:1648 */
++#line 876 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4419 "parser.tab.c" /* yacc.c:1648 */
++#line 4414 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 301:
+-#line 879 "parser.y" /* yacc.c:1648 */
++#line 877 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4425 "parser.tab.c" /* yacc.c:1648 */
++#line 4420 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 302:
+-#line 885 "parser.y" /* yacc.c:1648 */
++#line 883 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define((yyval.type), (yyvsp[-2].var_list), (yyvsp[-1].var_list));
+ }
+-#line 4433 "parser.tab.c" /* yacc.c:1648 */
++#line 4428 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 303:
+-#line 889 "parser.y" /* yacc.c:1648 */
++#line 887 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define_from_iface((yyval.type), (yyvsp[-2].type));
+ }
+-#line 4441 "parser.tab.c" /* yacc.c:1648 */
++#line 4436 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 304:
+-#line 894 "parser.y" /* yacc.c:1648 */
++#line 892 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = NULL; }
+-#line 4447 "parser.tab.c" /* yacc.c:1648 */
++#line 4442 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 305:
+-#line 895 "parser.y" /* yacc.c:1648 */
++#line 893 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error2((yyvsp[0].str), 0); }
+-#line 4453 "parser.tab.c" /* yacc.c:1648 */
++#line 4448 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 306:
+-#line 898 "parser.y" /* yacc.c:1648 */
++#line 896 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4459 "parser.tab.c" /* yacc.c:1648 */
++#line 4454 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 307:
+-#line 899 "parser.y" /* yacc.c:1648 */
++#line 897 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4465 "parser.tab.c" /* yacc.c:1648 */
++#line 4460 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 308:
+-#line 902 "parser.y" /* yacc.c:1648 */
++#line 900 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifinfo).interface = (yyvsp[0].type);
+ (yyval.ifinfo).old_pointer_default = pointer_default;
+ if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
+@@ -4474,11 +4469,11 @@ yyreduce:
+ (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ (yyvsp[0].type)->defined = TRUE;
+ }
+-#line 4478 "parser.tab.c" /* yacc.c:1648 */
++#line 4473 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 309:
+-#line 913 "parser.y" /* yacc.c:1648 */
++#line 911 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-5].ifinfo).interface;
+ if((yyval.type) == (yyvsp[-4].type))
+ error_loc("Interface can't inherit from itself\n");
+@@ -4486,594 +4481,594 @@ yyreduce:
+ check_async_uuid((yyval.type));
+ pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
+ }
+-#line 4490 "parser.tab.c" /* yacc.c:1648 */
++#line 4485 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 310:
+-#line 924 "parser.y" /* yacc.c:1648 */
++#line 922 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-7].ifinfo).interface;
+ type_interface_define((yyval.type), find_type_or_error2((yyvsp[-5].str), 0), (yyvsp[-2].stmt_list));
+ pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
+ }
+-#line 4499 "parser.tab.c" /* yacc.c:1648 */
++#line 4494 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 311:
+-#line 928 "parser.y" /* yacc.c:1648 */
++#line 926 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4505 "parser.tab.c" /* yacc.c:1648 */
++#line 4500 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 312:
+-#line 932 "parser.y" /* yacc.c:1648 */
++#line 930 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4511 "parser.tab.c" /* yacc.c:1648 */
++#line 4506 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 313:
+-#line 933 "parser.y" /* yacc.c:1648 */
++#line 931 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4517 "parser.tab.c" /* yacc.c:1648 */
++#line 4512 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 314:
+-#line 936 "parser.y" /* yacc.c:1648 */
++#line 934 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4523 "parser.tab.c" /* yacc.c:1648 */
++#line 4518 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 315:
+-#line 937 "parser.y" /* yacc.c:1648 */
++#line 935 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4529 "parser.tab.c" /* yacc.c:1648 */
++#line 4524 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 316:
+-#line 940 "parser.y" /* yacc.c:1648 */
++#line 938 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4537 "parser.tab.c" /* yacc.c:1648 */
++#line 4532 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 317:
+-#line 946 "parser.y" /* yacc.c:1648 */
++#line 944 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_module_define((yyval.type), (yyvsp[-2].stmt_list));
+ }
+-#line 4545 "parser.tab.c" /* yacc.c:1648 */
++#line 4540 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 318:
+-#line 952 "parser.y" /* yacc.c:1648 */
++#line 950 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_EXTERN; }
+-#line 4551 "parser.tab.c" /* yacc.c:1648 */
++#line 4546 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 319:
+-#line 953 "parser.y" /* yacc.c:1648 */
++#line 951 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_STATIC; }
+-#line 4557 "parser.tab.c" /* yacc.c:1648 */
++#line 4552 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 320:
+-#line 954 "parser.y" /* yacc.c:1648 */
++#line 952 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_REGISTER; }
+-#line 4563 "parser.tab.c" /* yacc.c:1648 */
++#line 4558 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 321:
+-#line 958 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_INLINE); }
+-#line 4569 "parser.tab.c" /* yacc.c:1648 */
++#line 956 "parser.y" /* yacc.c:1646 */
++ { (yyval.funcspecifier) = FUNCTION_SPECIFIER_INLINE; }
++#line 4564 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 322:
+-#line 962 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_CONST); }
+-#line 4575 "parser.tab.c" /* yacc.c:1648 */
++#line 960 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_CONST; }
++#line 4570 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 323:
+-#line 965 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = NULL; }
+-#line 4581 "parser.tab.c" /* yacc.c:1648 */
++#line 963 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_NONE; }
++#line 4576 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 324:
+-#line 966 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = append_attr((yyvsp[-1].attr_list), (yyvsp[0].attr)); }
+-#line 4587 "parser.tab.c" /* yacc.c:1648 */
++#line 964 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = (yyvsp[-1].typequalifier) | (yyvsp[0].typequalifier); }
++#line 4582 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 325:
+-#line 969 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, NULL, STG_NONE); }
+-#line 4593 "parser.tab.c" /* yacc.c:1648 */
++#line 967 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4588 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 326:
+-#line 971 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), NULL, STG_NONE); }
+-#line 4599 "parser.tab.c" /* yacc.c:1648 */
++#line 969 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4594 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 327:
+-#line 974 "parser.y" /* yacc.c:1648 */
++#line 972 "parser.y" /* yacc.c:1646 */
+ { (yyval.declspec) = NULL; }
+-#line 4605 "parser.tab.c" /* yacc.c:1648 */
++#line 4600 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 329:
+-#line 979 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4611 "parser.tab.c" /* yacc.c:1648 */
++#line 977 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, (yyvsp[-1].typequalifier), FUNCTION_SPECIFIER_NONE); }
++#line 4606 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 330:
+-#line 980 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4617 "parser.tab.c" /* yacc.c:1648 */
++#line 978 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, (yyvsp[-1].funcspecifier)); }
++#line 4612 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 331:
+-#line 981 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, NULL, (yyvsp[-1].stgclass)); }
+-#line 4623 "parser.tab.c" /* yacc.c:1648 */
++#line 979 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].stgclass), TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4618 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 332:
+-#line 986 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4629 "parser.tab.c" /* yacc.c:1648 */
++#line 984 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4624 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 333:
+-#line 987 "parser.y" /* yacc.c:1648 */
++#line 985 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4636 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4631 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 335:
+-#line 993 "parser.y" /* yacc.c:1648 */
++#line 991 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4642 "parser.tab.c" /* yacc.c:1648 */
++#line 4637 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 336:
+-#line 994 "parser.y" /* yacc.c:1648 */
++#line 992 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4648 "parser.tab.c" /* yacc.c:1648 */
++#line 4643 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 337:
+-#line 995 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4654 "parser.tab.c" /* yacc.c:1648 */
++#line 993 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 338:
+-#line 996 "parser.y" /* yacc.c:1648 */
++#line 994 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4663 "parser.tab.c" /* yacc.c:1648 */
++#line 4658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 339:
+-#line 1005 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4669 "parser.tab.c" /* yacc.c:1648 */
++#line 1003 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4664 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 340:
+-#line 1006 "parser.y" /* yacc.c:1648 */
++#line 1004 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4676 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4671 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 342:
+-#line 1014 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4682 "parser.tab.c" /* yacc.c:1648 */
++#line 1012 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4677 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 343:
+-#line 1015 "parser.y" /* yacc.c:1648 */
++#line 1013 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4689 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4684 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 344:
+-#line 1020 "parser.y" /* yacc.c:1648 */
++#line 1018 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4695 "parser.tab.c" /* yacc.c:1648 */
++#line 4690 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 346:
+-#line 1026 "parser.y" /* yacc.c:1648 */
++#line 1024 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4701 "parser.tab.c" /* yacc.c:1648 */
++#line 4696 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 347:
+-#line 1027 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4707 "parser.tab.c" /* yacc.c:1648 */
++#line 1025 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4702 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 348:
+-#line 1028 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4713 "parser.tab.c" /* yacc.c:1648 */
++#line 1026 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4708 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 349:
+-#line 1030 "parser.y" /* yacc.c:1648 */
++#line 1028 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4722 "parser.tab.c" /* yacc.c:1648 */
++#line 4717 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 350:
+-#line 1035 "parser.y" /* yacc.c:1648 */
++#line 1033 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4731 "parser.tab.c" /* yacc.c:1648 */
++#line 4726 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 351:
+-#line 1044 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4737 "parser.tab.c" /* yacc.c:1648 */
++#line 1042 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4732 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 352:
+-#line 1045 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4743 "parser.tab.c" /* yacc.c:1648 */
++#line 1043 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4738 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 354:
+-#line 1052 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4749 "parser.tab.c" /* yacc.c:1648 */
++#line 1050 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4744 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 355:
+-#line 1053 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4755 "parser.tab.c" /* yacc.c:1648 */
++#line 1051 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4750 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 356:
+-#line 1057 "parser.y" /* yacc.c:1648 */
++#line 1055 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4761 "parser.tab.c" /* yacc.c:1648 */
++#line 4756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 358:
+-#line 1065 "parser.y" /* yacc.c:1648 */
++#line 1063 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4767 "parser.tab.c" /* yacc.c:1648 */
++#line 4762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 359:
+-#line 1066 "parser.y" /* yacc.c:1648 */
++#line 1064 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4773 "parser.tab.c" /* yacc.c:1648 */
++#line 4768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 360:
+-#line 1067 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4779 "parser.tab.c" /* yacc.c:1648 */
++#line 1065 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 361:
+-#line 1068 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4785 "parser.tab.c" /* yacc.c:1648 */
++#line 1066 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 362:
+-#line 1070 "parser.y" /* yacc.c:1648 */
++#line 1068 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4794 "parser.tab.c" /* yacc.c:1648 */
++#line 4789 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 363:
+-#line 1075 "parser.y" /* yacc.c:1648 */
++#line 1073 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4803 "parser.tab.c" /* yacc.c:1648 */
++#line 4798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 364:
+-#line 1082 "parser.y" /* yacc.c:1648 */
++#line 1080 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4809 "parser.tab.c" /* yacc.c:1648 */
++#line 4804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 365:
+-#line 1083 "parser.y" /* yacc.c:1648 */
++#line 1081 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4815 "parser.tab.c" /* yacc.c:1648 */
++#line 4810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 366:
+-#line 1086 "parser.y" /* yacc.c:1648 */
++#line 1084 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = NULL; }
+-#line 4821 "parser.tab.c" /* yacc.c:1648 */
++#line 4816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 367:
+-#line 1087 "parser.y" /* yacc.c:1648 */
++#line 1085 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr); }
+-#line 4827 "parser.tab.c" /* yacc.c:1648 */
++#line 4822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 368:
+-#line 1090 "parser.y" /* yacc.c:1648 */
++#line 1088 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->bits = (yyvsp[0].expr);
+ if (!(yyval.declarator)->bits && !(yyval.declarator)->var->name)
+ error_loc("unnamed fields are not allowed\n");
+ }
+-#line 4836 "parser.tab.c" /* yacc.c:1648 */
++#line 4831 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 369:
+-#line 1097 "parser.y" /* yacc.c:1648 */
++#line 1095 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4842 "parser.tab.c" /* yacc.c:1648 */
++#line 4837 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 370:
+-#line 1099 "parser.y" /* yacc.c:1648 */
++#line 1097 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4848 "parser.tab.c" /* yacc.c:1648 */
++#line 4843 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 371:
+-#line 1103 "parser.y" /* yacc.c:1648 */
++#line 1101 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); }
+-#line 4854 "parser.tab.c" /* yacc.c:1648 */
++#line 4849 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 372:
+-#line 1104 "parser.y" /* yacc.c:1648 */
++#line 1102 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-2].declarator); (yyvsp[-2].declarator)->var->eval = (yyvsp[0].expr); }
+-#line 4860 "parser.tab.c" /* yacc.c:1648 */
++#line 4855 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 373:
+-#line 1108 "parser.y" /* yacc.c:1648 */
++#line 1106 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_APARTMENT; }
+-#line 4866 "parser.tab.c" /* yacc.c:1648 */
++#line 4861 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 374:
+-#line 1109 "parser.y" /* yacc.c:1648 */
++#line 1107 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_NEUTRAL; }
+-#line 4872 "parser.tab.c" /* yacc.c:1648 */
++#line 4867 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 375:
+-#line 1110 "parser.y" /* yacc.c:1648 */
++#line 1108 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_SINGLE; }
+-#line 4878 "parser.tab.c" /* yacc.c:1648 */
++#line 4873 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 376:
+-#line 1111 "parser.y" /* yacc.c:1648 */
++#line 1109 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_FREE; }
+-#line 4884 "parser.tab.c" /* yacc.c:1648 */
++#line 4879 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 377:
+-#line 1112 "parser.y" /* yacc.c:1648 */
++#line 1110 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_BOTH; }
+-#line 4890 "parser.tab.c" /* yacc.c:1648 */
++#line 4885 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 378:
+-#line 1116 "parser.y" /* yacc.c:1648 */
++#line 1114 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_RP; }
+-#line 4896 "parser.tab.c" /* yacc.c:1648 */
++#line 4891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 379:
+-#line 1117 "parser.y" /* yacc.c:1648 */
++#line 1115 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_UP; }
+-#line 4902 "parser.tab.c" /* yacc.c:1648 */
++#line 4897 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 380:
+-#line 1118 "parser.y" /* yacc.c:1648 */
++#line 1116 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_FP; }
+-#line 4908 "parser.tab.c" /* yacc.c:1648 */
++#line 4903 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 381:
+-#line 1121 "parser.y" /* yacc.c:1648 */
++#line 1119 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 4914 "parser.tab.c" /* yacc.c:1648 */
++#line 4909 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 382:
+-#line 1124 "parser.y" /* yacc.c:1648 */
++#line 1122 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_void(); }
+-#line 4920 "parser.tab.c" /* yacc.c:1648 */
++#line 4915 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 383:
+-#line 1125 "parser.y" /* yacc.c:1648 */
++#line 1123 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4926 "parser.tab.c" /* yacc.c:1648 */
++#line 4921 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 384:
+-#line 1126 "parser.y" /* yacc.c:1648 */
++#line 1124 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4932 "parser.tab.c" /* yacc.c:1648 */
++#line 4927 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 385:
+-#line 1127 "parser.y" /* yacc.c:1648 */
++#line 1125 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4938 "parser.tab.c" /* yacc.c:1648 */
++#line 4933 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 386:
+-#line 1128 "parser.y" /* yacc.c:1648 */
++#line 1126 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4944 "parser.tab.c" /* yacc.c:1648 */
++#line 4939 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 387:
+-#line 1129 "parser.y" /* yacc.c:1648 */
++#line 1127 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4950 "parser.tab.c" /* yacc.c:1648 */
++#line 4945 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 388:
+-#line 1130 "parser.y" /* yacc.c:1648 */
++#line 1128 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4956 "parser.tab.c" /* yacc.c:1648 */
++#line 4951 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 389:
+-#line 1131 "parser.y" /* yacc.c:1648 */
++#line 1129 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4962 "parser.tab.c" /* yacc.c:1648 */
++#line 4957 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 390:
+-#line 1132 "parser.y" /* yacc.c:1648 */
++#line 1130 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 4968 "parser.tab.c" /* yacc.c:1648 */
++#line 4963 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 391:
+-#line 1133 "parser.y" /* yacc.c:1648 */
++#line 1131 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = make_safearray((yyvsp[-1].type)); }
+-#line 4974 "parser.tab.c" /* yacc.c:1648 */
++#line 4969 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 392:
+-#line 1137 "parser.y" /* yacc.c:1648 */
++#line 1135 "parser.y" /* yacc.c:1646 */
+ { (yyvsp[-4].attr_list) = append_attribs((yyvsp[-4].attr_list), (yyvsp[-2].attr_list));
+ reg_typedefs((yyvsp[-1].declspec), (yyvsp[0].declarator_list), check_typedef_attrs((yyvsp[-4].attr_list)));
+ (yyval.statement) = make_statement_typedef((yyvsp[0].declarator_list));
+ }
+-#line 4983 "parser.tab.c" /* yacc.c:1648 */
++#line 4978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 393:
+-#line 1144 "parser.y" /* yacc.c:1648 */
++#line 1142 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[-3].str), TRUE, (yyvsp[-1].var_list)); }
+-#line 4989 "parser.tab.c" /* yacc.c:1648 */
++#line 4984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 394:
+-#line 1147 "parser.y" /* yacc.c:1648 */
++#line 1145 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_encapsulated_union((yyvsp[-8].str), (yyvsp[-5].var), (yyvsp[-3].var), (yyvsp[-1].var_list)); }
+-#line 4995 "parser.tab.c" /* yacc.c:1648 */
++#line 4990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 395:
+-#line 1151 "parser.y" /* yacc.c:1648 */
++#line 1149 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); }
+-#line 5001 "parser.tab.c" /* yacc.c:1648 */
++#line 4996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 396:
+-#line 1152 "parser.y" /* yacc.c:1648 */
++#line 1150 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); }
+-#line 5007 "parser.tab.c" /* yacc.c:1648 */
++#line 5002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 397:
+-#line 1153 "parser.y" /* yacc.c:1648 */
++#line 1151 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = (yyvsp[0].num); }
+-#line 5013 "parser.tab.c" /* yacc.c:1648 */
++#line 5008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 402:
+-#line 1166 "parser.y" /* yacc.c:1648 */
++#line 1164 "parser.y" /* yacc.c:1646 */
+ { type_t *type = find_type_or_error((yyvsp[-1].str), 0);
+ type->attrs = append_attr_list(type->attrs, (yyvsp[-2].attr_list));
+ }
+-#line 5021 "parser.tab.c" /* yacc.c:1648 */
++#line 5016 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 403:
+-#line 1171 "parser.y" /* yacc.c:1648 */
++#line 1169 "parser.y" /* yacc.c:1646 */
+ { type_t *iface = find_type_or_error2((yyvsp[-3].str), 0);
+ if (type_get_type(iface) != TYPE_INTERFACE)
+ error_loc("%s is not an interface\n", iface->name);
+ iface->attrs = append_attr_list(iface->attrs, (yyvsp[-5].attr_list));
+ }
+-#line 5031 "parser.tab.c" /* yacc.c:1648 */
++#line 5026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 404:
+-#line 1178 "parser.y" /* yacc.c:1648 */
++#line 1176 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 5037 "parser.tab.c" /* yacc.c:1648 */
++#line 5032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 405:
+-#line 1179 "parser.y" /* yacc.c:1648 */
++#line 1177 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 5043 "parser.tab.c" /* yacc.c:1648 */
++#line 5038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 406:
+-#line 1182 "parser.y" /* yacc.c:1648 */
++#line 1180 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr(NULL, (yyvsp[0].attr)); }
+-#line 5049 "parser.tab.c" /* yacc.c:1648 */
++#line 5044 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 407:
+-#line 1183 "parser.y" /* yacc.c:1648 */
++#line 1181 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr((yyvsp[-2].attr_list), (yyvsp[0].attr)); }
+-#line 5055 "parser.tab.c" /* yacc.c:1648 */
++#line 5050 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 408:
+-#line 1186 "parser.y" /* yacc.c:1648 */
++#line 1184 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 5061 "parser.tab.c" /* yacc.c:1648 */
++#line 5056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 409:
+-#line 1187 "parser.y" /* yacc.c:1648 */
++#line 1185 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 5067 "parser.tab.c" /* yacc.c:1648 */
++#line 5062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 410:
+-#line 1188 "parser.y" /* yacc.c:1648 */
++#line 1186 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 5073 "parser.tab.c" /* yacc.c:1648 */
++#line 5068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+
+-#line 5077 "parser.tab.c" /* yacc.c:1648 */
++#line 5072 "parser.tab.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+@@ -5301,7 +5296,7 @@ yyreturn:
+ #endif
+ return yyresult;
+ }
+-#line 1190 "parser.y" /* yacc.c:1907 */
++#line 1188 "parser.y" /* yacc.c:1906 */
+
+
+ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+@@ -5312,7 +5307,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -5323,7 +5319,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -5354,6 +5350,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -5413,53 +5410,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -5545,6 +5562,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -5589,31 +5607,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -5629,7 +5676,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -5638,58 +5685,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* add type onto the end of the pointers in pident->type */
+- v->type = append_chain_type(decl ? decl->type : NULL, type);
+- v->stgclass = decl_spec->stgclass;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->stgclass;
+ v->attrs = attrs;
+
+ /* check for pointer attribute being applied to non-pointer, non-array
+ * type */
+- if (!is_array(v->type))
++ if (!is_array(v->declspec.type))
+ {
+ int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
+ const type_t *ptr = NULL;
+ /* pointer attributes on the left side of the type belong to the function
+ * pointer, if one is being declared */
+- type_t **pt = func_type ? &func_type : &v->type;
++ type_t **pt = func_type ? &func_type : &v->declspec.type;
+ for (ptr = *pt; ptr && !ptr_attr; )
+ {
+ ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -5700,16 +5769,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ {
+ type_t *t = type;
+
+- if (!is_ptr(v->type) && !is_array(v->type))
++ if (!is_ptr(v->declspec.type) && !is_array(v->declspec.type))
+ error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+ v->name);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -5726,15 +5795,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+
+ if (is_attr(v->attrs, ATTR_V1ENUM))
+ {
+- if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
++ if (type_get_type_detect_alias(v->declspec.type) != TYPE_ENUM)
+ error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+ }
+
+- if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
++ if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->declspec.type))
+ error_loc("'%s': [range] attribute applied to non-integer type\n",
+ v->name);
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -5747,7 +5816,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -5756,15 +5825,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in size_is attribute\n", v->name);
+ }
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -5782,10 +5852,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -5796,29 +5867,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ if (func_type)
+ {
+ type_t *ft, *t;
+- type_t *return_type = v->type;
+- v->type = func_type;
+- for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
++ type_t *return_type = v->declspec.type;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(ft))
+ ;
+ assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
+ ft->details.function->retval = make_var(xstrdup("_RetVal"));
+- ft->details.function->retval->type = return_type;
++ ft->details.function->retval->declspec.type = return_type;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* move calling convention attribute, if present, from pointer nodes to
+ * function node */
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+ }
+ else
+ {
+ type_t *t;
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CALLCONV))
+ error_loc("calling convention applied to non-function-pointer type\n");
+ }
+
+- if (decl->bits)
+- v->type = type_new_bitfield(v->type, decl->bits);
+-
+ return v;
+ }
+
+@@ -5866,6 +5939,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -5885,11 +5962,11 @@ var_t *make_var(char *name)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = NULL;
++ init_declspec(&v->declspec, NULL);
+ v->attrs = NULL;
+ v->eval = NULL;
+- v->stgclass = STG_NONE;
+ init_loc_info(&v->loc_info);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -5897,10 +5974,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = src->type;
++ v->declspec = src->declspec;
+ v->attrs = map_attrs(src->attrs, attr_filter);
+ v->eval = src->eval;
+- v->stgclass = src->stgclass;
+ v->loc_info = src->loc_info;
+ return v;
+ }
+@@ -5920,7 +5996,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -5928,7 +6004,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -6007,6 +6091,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -6018,15 +6104,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -6034,19 +6121,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -6070,7 +6154,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -6094,7 +6178,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -6120,12 +6210,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ cur->loc_info.line_number);
+
+ name = declare_var(attrs, decl_spec, decl, 0);
+- cur = type_new_alias(name->type, name->name);
++ cur = type_new_alias(&name->declspec, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -6140,6 +6230,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -6293,7 +6385,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -6328,7 +6419,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -6400,10 +6490,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+ if (attr->type == ATTR_IMPLICIT_HANDLE)
+ {
+ const var_t *var = attr->u.pval;
+- if (type_get_type( var->type) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ continue;
+- if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
++ if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
+ continue;
+ error_loc("attribute %s requires a handle type in interface %s\n",
+ allowed_attr[attr->type].display_name, name);
+@@ -6608,7 +6698,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -6635,7 +6725,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+ static void check_field_common(const type_t *container_type,
+ const char *container_name, const var_t *arg)
+ {
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+ int more_to_do;
+ const char *container_type_name;
+ const char *var_type;
+@@ -6665,7 +6755,7 @@ static void check_field_common(const type_t *container_type,
+ }
+
+ if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+- (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
++ (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->declspec.type, ATTR_STRING)))
+ error_loc_info(&arg->loc_info,
+ "string and length_is specified for argument %s are mutually exclusive attributes\n",
+ arg->name);
+@@ -6762,23 +6852,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -6803,13 +6898,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->type) check_field_common(type, type->name, field);
++ if (field->declspec.type) check_field_common(type, type->name, field);
+ }
+
+ /* checks that arguments for a function make sense for marshalling and unmarshalling */
+@@ -6818,9 +6918,10 @@ static void check_remoting_args(const var_t *func)
+ const char *funcname = func->name;
+ const var_t *arg;
+
+- if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->type;
++ const type_t *type = arg->declspec.type;
+
+ /* check that [out] parameters have enough pointer levels */
+ if (is_attr(arg->attrs, ATTR_OUT))
+@@ -6860,16 +6961,16 @@ static void check_remoting_args(const var_t *func)
+ }
+ }
+
+- check_field_common(func->type, funcname, arg);
++ check_field_common(func->declspec.type, funcname, arg);
+ }
+
+- if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
++ if (type_get_type(type_function_get_rettype(func->declspec.type)) != TYPE_VOID)
+ {
+ var_t var;
+ var = *func;
+- var.type = type_function_get_rettype(func->type);
++ var.declspec.type = type_function_get_rettype(func->declspec.type);
+ var.name = xstrdup("return value");
+- check_field_common(func->type, funcname, &var);
++ check_field_common(func->declspec.type, funcname, &var);
+ free(var.name);
+ }
+ }
+@@ -6886,8 +6987,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+ * function */
+ var_t *idl_handle = make_var(xstrdup("IDL_handle"));
+ idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
+- idl_handle->type = find_type_or_error("handle_t", 0);
+- type_function_add_head_arg(func->type, idl_handle);
++ idl_handle->declspec.type = find_type_or_error("handle_t", 0);
++ type_function_add_head_arg(func->declspec.type, idl_handle);
+ }
+ }
+
+@@ -6952,6 +7053,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -6968,7 +7070,8 @@ static void check_async_uuid(type_t *iface)
+ var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
+ var_list_t *begin_args = NULL, *finish_args = NULL, *args;
+
+- args = func->type->details.function->args;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -6978,15 +7081,15 @@ static void check_async_uuid(type_t *iface)
+ }
+
+ begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
+- begin_func->type = type_new_function(begin_args);
+- begin_func->type->attrs = func->attrs;
+- begin_func->type->details.function->retval = func->type->details.function->retval;
++ begin_func->declspec.type = type_new_function(begin_args);
++ begin_func->declspec.type->attrs = func->attrs;
++ begin_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(begin_func));
+
+ finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
+- finish_func->type = type_new_function(finish_args);
+- finish_func->type->attrs = func->attrs;
+- finish_func->type->details.function->retval = func->type->details.function->retval;
++ finish_func->declspec.type = type_new_function(finish_args);
++ finish_func->declspec.type->attrs = func->attrs;
++ finish_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(finish_func));
+ }
+
+@@ -7026,6 +7129,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -7037,7 +7141,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+ const statement_t *stmt_func;
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
+ const var_t *func = stmt_func->u.var;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -7071,6 +7179,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -7085,16 +7197,16 @@ static statement_t *make_statement_declaration(var_t *var)
+ {
+ statement_t *stmt = make_statement(STMT_DECLARATION);
+ stmt->u.var = var;
+- if (var->stgclass == STG_EXTERN && var->eval)
++ if (var->declspec.stgclass == STG_EXTERN && var->eval)
+ warning("'%s' initialised and declared extern\n", var->name);
+ if (is_const_decl(var))
+ {
+ if (var->eval)
+ reg_const(var);
+ }
+- else if (type_get_type(var->type) == TYPE_FUNCTION)
++ else if (type_get_type(var->declspec.type) == TYPE_FUNCTION)
+ check_function_attrs(var->name, var->attrs);
+- else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
++ else if (var->declspec.stgclass == STG_NONE || var->declspec.stgclass == STG_REGISTER)
+ error_loc("instantiation of data is illegal\n");
+ return stmt;
+ }
+@@ -7146,6 +7258,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -7157,6 +7270,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -7166,6 +7291,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -7206,7 +7332,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.tab.h b/mingw-w64-tools/widl/src/parser.tab.h
+index 09874726..fc7a8f4d 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.h
++++ b/mingw-w64-tools/widl/src/parser.tab.h
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison interface for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -239,7 +239,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:1910 */
++#line 136 "parser.y" /* yacc.c:1909 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -266,8 +266,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 271 "parser.tab.h" /* yacc.c:1910 */
++#line 273 "parser.tab.h" /* yacc.c:1909 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+diff --git a/mingw-w64-tools/widl/src/parser.y b/mingw-w64-tools/widl/src/parser.y
+index d9793941..bb14bf76 100644
+--- a/mingw-w64-tools/widl/src/parser.y
++++ b/mingw-w64-tools/widl/src/parser.y
+@@ -52,13 +52,6 @@ struct _import_t
+ int import_performed;
+ };
+
+-typedef struct _decl_spec_t
+-{
+- type_t *type;
+- attr_list_t *attrs;
+- enum storage_class stgclass;
+-} decl_spec_t;
+-
+ typelist_t incomplete_types = LIST_INIT(incomplete_types);
+
+ static void fix_incomplete(void);
+@@ -67,7 +60,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -83,6 +76,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -165,6 +159,8 @@ static typelib_t *current_typelib;
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+ }
+
+ %token <str> aIDENTIFIER aPRAGMA
+@@ -266,14 +262,16 @@ static typelib_t *current_typelib;
+ %token tWCHAR tWIREMARSHAL
+ %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
+
+-%type <attr> attribute type_qualifier function_specifier acf_attribute
+-%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
++%type <attr> attribute acf_attribute
++%type <attr_list> m_attributes attributes attrib_list
+ %type <attr_list> acf_attributes acf_attribute_list
+ %type <str_list> str_list
+ %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
+ %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
+ %type <ifinfo> interfacehdr
+ %type <stgclass> storage_cls_spec
++%type <typequalifier> type_qualifier m_type_qual_bits
++%type <funcspecifier> function_specifier
+ %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
+ %type <type> inherit interface interfacedef interfacedec
+ %type <type> dispinterface dispinterfacehdr dispinterfacedef
+@@ -318,7 +316,7 @@ static typelib_t *current_typelib;
+ %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
+ %left '.' MEMBERPTR '[' ']'
+
+-%error-verbose
++%define parse.error verbose
+
+ %%
+
+@@ -651,10 +649,10 @@ enum_list: enum { if (!$1->eval)
+
+ enum: ident '=' expr_int_const { $$ = reg_const($1);
+ $$->eval = $3;
+- $$->type = type_new_int(TYPE_BASIC_INT, 0);
++ $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+ | ident { $$ = reg_const($1);
+- $$->type = type_new_int(TYPE_BASIC_INT, 0);
++ $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+ ;
+
+@@ -740,7 +738,7 @@ field: m_attributes decl_spec struct_declarator_list ';'
+ $$ = set_var_types($1, $2, $3);
+ }
+ | m_attributes uniondef ';' { var_t *v = make_var(NULL);
+- v->type = $2; v->attrs = $1;
++ v->declspec.type = $2; v->attrs = $1;
+ $$ = append_var(NULL, v);
+ }
+ ;
+@@ -764,13 +762,13 @@ s_field: m_attributes decl_spec declarator { $$ = declare_var(check_field_attrs
+ free($3);
+ }
+ | m_attributes structdef { var_t *v = make_var(NULL);
+- v->type = $2; v->attrs = $1;
++ v->declspec.type = $2; v->attrs = $1;
+ $$ = v;
+ }
+ ;
+
+ funcdef: declaration { $$ = $1;
+- if (type_get_type($$->type) != TYPE_FUNCTION)
++ if (type_get_type($$->declspec.type) != TYPE_FUNCTION)
+ error_loc("only methods may be declared inside the methods section of a dispinterface\n");
+ check_function_attrs($$->name, $$->attrs);
+ }
+@@ -955,20 +953,20 @@ storage_cls_spec:
+ ;
+
+ function_specifier:
+- tINLINE { $$ = make_attr(ATTR_INLINE); }
++ tINLINE { $$ = FUNCTION_SPECIFIER_INLINE; }
+ ;
+
+ type_qualifier:
+- tCONST { $$ = make_attr(ATTR_CONST); }
++ tCONST { $$ = TYPE_QUALIFIER_CONST; }
+ ;
+
+-m_type_qual_list: { $$ = NULL; }
+- | m_type_qual_list type_qualifier { $$ = append_attr($1, $2); }
++m_type_qual_bits: { $$ = TYPE_QUALIFIER_NONE; }
++ | m_type_qual_bits type_qualifier { $$ = $1 | $2; }
+ ;
+
+-decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
++decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ | decl_spec_no_type type m_decl_spec_no_type
+- { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
++ { $$ = make_decl_spec($2, $1, $3, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ m_decl_spec_no_type: { $$ = NULL; }
+@@ -976,44 +974,44 @@ m_decl_spec_no_type: { $$ = NULL; }
+ ;
+
+ decl_spec_no_type:
+- type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
++ type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, $1, FUNCTION_SPECIFIER_NONE); }
++ | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, $1); }
++ | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ declarator:
+- '*' m_type_qual_list declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | direct_declarator
+ ;
+
+ direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' declarator ')' { $$ = $2; }
+- | direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
++ | direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
+ | direct_declarator '(' m_args ')' { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract declarator */
+ abstract_declarator:
+- '*' m_type_qual_list m_abstract_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_abstract_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | abstract_direct_declarator
+ ;
+
+ /* abstract declarator without accepting direct declarator */
+ abstract_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract declarator or empty */
+@@ -1024,33 +1022,33 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
+ /* abstract direct declarator */
+ abstract_direct_declarator:
+ '(' abstract_declarator_no_direct ')' { $$ = $2; }
+- | abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | abstract_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | abstract_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract or non-abstract declarator */
+ any_declarator:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | any_direct_declarator
+ ;
+
+ /* abstract or non-abstract declarator without accepting direct declarator */
+ any_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract or non-abstract declarator or empty */
+@@ -1064,17 +1062,17 @@ m_any_declarator: { $$ = make_declarator(NULL); }
+ any_direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' any_declarator_no_direct ')' { $$ = $2; }
+- | any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | any_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | any_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+@@ -1197,7 +1195,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -1208,7 +1207,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -1239,6 +1238,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -1298,53 +1298,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -1430,6 +1450,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -1474,31 +1495,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -1514,7 +1564,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -1523,58 +1573,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* add type onto the end of the pointers in pident->type */
+- v->type = append_chain_type(decl ? decl->type : NULL, type);
+- v->stgclass = decl_spec->stgclass;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->stgclass;
+ v->attrs = attrs;
+
+ /* check for pointer attribute being applied to non-pointer, non-array
+ * type */
+- if (!is_array(v->type))
++ if (!is_array(v->declspec.type))
+ {
+ int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
+ const type_t *ptr = NULL;
+ /* pointer attributes on the left side of the type belong to the function
+ * pointer, if one is being declared */
+- type_t **pt = func_type ? &func_type : &v->type;
++ type_t **pt = func_type ? &func_type : &v->declspec.type;
+ for (ptr = *pt; ptr && !ptr_attr; )
+ {
+ ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -1585,16 +1657,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ {
+ type_t *t = type;
+
+- if (!is_ptr(v->type) && !is_array(v->type))
++ if (!is_ptr(v->declspec.type) && !is_array(v->declspec.type))
+ error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+ v->name);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -1611,15 +1683,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+
+ if (is_attr(v->attrs, ATTR_V1ENUM))
+ {
+- if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
++ if (type_get_type_detect_alias(v->declspec.type) != TYPE_ENUM)
+ error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+ }
+
+- if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
++ if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->declspec.type))
+ error_loc("'%s': [range] attribute applied to non-integer type\n",
+ v->name);
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -1632,7 +1704,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -1641,15 +1713,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in size_is attribute\n", v->name);
+ }
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -1667,10 +1740,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -1681,29 +1755,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ if (func_type)
+ {
+ type_t *ft, *t;
+- type_t *return_type = v->type;
+- v->type = func_type;
+- for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
++ type_t *return_type = v->declspec.type;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(ft))
+ ;
+ assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
+ ft->details.function->retval = make_var(xstrdup("_RetVal"));
+- ft->details.function->retval->type = return_type;
++ ft->details.function->retval->declspec.type = return_type;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* move calling convention attribute, if present, from pointer nodes to
+ * function node */
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+ }
+ else
+ {
+ type_t *t;
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CALLCONV))
+ error_loc("calling convention applied to non-function-pointer type\n");
+ }
+
+- if (decl->bits)
+- v->type = type_new_bitfield(v->type, decl->bits);
+-
+ return v;
+ }
+
+@@ -1751,6 +1827,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -1770,11 +1850,11 @@ var_t *make_var(char *name)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = NULL;
++ init_declspec(&v->declspec, NULL);
+ v->attrs = NULL;
+ v->eval = NULL;
+- v->stgclass = STG_NONE;
+ init_loc_info(&v->loc_info);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -1782,10 +1862,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = src->type;
++ v->declspec = src->declspec;
+ v->attrs = map_attrs(src->attrs, attr_filter);
+ v->eval = src->eval;
+- v->stgclass = src->stgclass;
+ v->loc_info = src->loc_info;
+ return v;
+ }
+@@ -1805,7 +1884,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -1813,7 +1892,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -1892,6 +1979,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -1903,15 +1992,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -1919,19 +2009,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -1955,7 +2042,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -1979,7 +2066,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -2005,12 +2098,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ cur->loc_info.line_number);
+
+ name = declare_var(attrs, decl_spec, decl, 0);
+- cur = type_new_alias(name->type, name->name);
++ cur = type_new_alias(&name->declspec, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -2025,6 +2118,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -2178,7 +2273,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -2213,7 +2307,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -2285,10 +2378,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+ if (attr->type == ATTR_IMPLICIT_HANDLE)
+ {
+ const var_t *var = attr->u.pval;
+- if (type_get_type( var->type) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ continue;
+- if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
++ if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
+ continue;
+ error_loc("attribute %s requires a handle type in interface %s\n",
+ allowed_attr[attr->type].display_name, name);
+@@ -2493,7 +2586,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -2520,7 +2613,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+ static void check_field_common(const type_t *container_type,
+ const char *container_name, const var_t *arg)
+ {
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+ int more_to_do;
+ const char *container_type_name;
+ const char *var_type;
+@@ -2550,7 +2643,7 @@ static void check_field_common(const type_t *container_type,
+ }
+
+ if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+- (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
++ (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->declspec.type, ATTR_STRING)))
+ error_loc_info(&arg->loc_info,
+ "string and length_is specified for argument %s are mutually exclusive attributes\n",
+ arg->name);
+@@ -2647,23 +2740,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -2688,13 +2786,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->type) check_field_common(type, type->name, field);
++ if (field->declspec.type) check_field_common(type, type->name, field);
+ }
+
+ /* checks that arguments for a function make sense for marshalling and unmarshalling */
+@@ -2703,9 +2806,10 @@ static void check_remoting_args(const var_t *func)
+ const char *funcname = func->name;
+ const var_t *arg;
+
+- if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->type;
++ const type_t *type = arg->declspec.type;
+
+ /* check that [out] parameters have enough pointer levels */
+ if (is_attr(arg->attrs, ATTR_OUT))
+@@ -2745,16 +2849,16 @@ static void check_remoting_args(const var_t *func)
+ }
+ }
+
+- check_field_common(func->type, funcname, arg);
++ check_field_common(func->declspec.type, funcname, arg);
+ }
+
+- if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
++ if (type_get_type(type_function_get_rettype(func->declspec.type)) != TYPE_VOID)
+ {
+ var_t var;
+ var = *func;
+- var.type = type_function_get_rettype(func->type);
++ var.declspec.type = type_function_get_rettype(func->declspec.type);
+ var.name = xstrdup("return value");
+- check_field_common(func->type, funcname, &var);
++ check_field_common(func->declspec.type, funcname, &var);
+ free(var.name);
+ }
+ }
+@@ -2771,8 +2875,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+ * function */
+ var_t *idl_handle = make_var(xstrdup("IDL_handle"));
+ idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
+- idl_handle->type = find_type_or_error("handle_t", 0);
+- type_function_add_head_arg(func->type, idl_handle);
++ idl_handle->declspec.type = find_type_or_error("handle_t", 0);
++ type_function_add_head_arg(func->declspec.type, idl_handle);
+ }
+ }
+
+@@ -2837,6 +2941,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -2853,7 +2958,8 @@ static void check_async_uuid(type_t *iface)
+ var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
+ var_list_t *begin_args = NULL, *finish_args = NULL, *args;
+
+- args = func->type->details.function->args;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -2863,15 +2969,15 @@ static void check_async_uuid(type_t *iface)
+ }
+
+ begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
+- begin_func->type = type_new_function(begin_args);
+- begin_func->type->attrs = func->attrs;
+- begin_func->type->details.function->retval = func->type->details.function->retval;
++ begin_func->declspec.type = type_new_function(begin_args);
++ begin_func->declspec.type->attrs = func->attrs;
++ begin_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(begin_func));
+
+ finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
+- finish_func->type = type_new_function(finish_args);
+- finish_func->type->attrs = func->attrs;
+- finish_func->type->details.function->retval = func->type->details.function->retval;
++ finish_func->declspec.type = type_new_function(finish_args);
++ finish_func->declspec.type->attrs = func->attrs;
++ finish_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(finish_func));
+ }
+
+@@ -2911,6 +3017,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -2922,7 +3029,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+ const statement_t *stmt_func;
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
+ const var_t *func = stmt_func->u.var;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -2956,6 +3067,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -2970,16 +3085,16 @@ static statement_t *make_statement_declaration(var_t *var)
+ {
+ statement_t *stmt = make_statement(STMT_DECLARATION);
+ stmt->u.var = var;
+- if (var->stgclass == STG_EXTERN && var->eval)
++ if (var->declspec.stgclass == STG_EXTERN && var->eval)
+ warning("'%s' initialised and declared extern\n", var->name);
+ if (is_const_decl(var))
+ {
+ if (var->eval)
+ reg_const(var);
+ }
+- else if (type_get_type(var->type) == TYPE_FUNCTION)
++ else if (type_get_type(var->declspec.type) == TYPE_FUNCTION)
+ check_function_attrs(var->name, var->attrs);
+- else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
++ else if (var->declspec.stgclass == STG_NONE || var->declspec.stgclass == STG_REGISTER)
+ error_loc("instantiation of data is illegal\n");
+ return stmt;
+ }
+@@ -3031,6 +3146,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -3042,6 +3158,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -3051,6 +3179,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -3091,7 +3220,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.yy.c b/mingw-w64-tools/widl/src/parser.yy.c
+index 2aaf3c27..0482aa7e 100644
+--- a/mingw-w64-tools/widl/src/parser.yy.c
++++ b/mingw-w64-tools/widl/src/parser.yy.c
+@@ -1,6 +1,6 @@
+-#line 1 "parser.yy.c"
++#line 2 "parser.yy.c"
+
+-#line 3 "parser.yy.c"
++#line 4 "parser.yy.c"
+
+ #define YY_INT_ALIGNED short int
+
+@@ -1041,13 +1041,13 @@ UUID *parse_uuid(const char *u)
+ return uuid;
+ }
+
+-#line 1044 "parser.yy.c"
++#line 1045 "parser.yy.c"
+ /*
+ **************************************************************************
+ * The flexer starts here
+ **************************************************************************
+ */
+-#line 1050 "parser.yy.c"
++#line 1051 "parser.yy.c"
+
+ #define INITIAL 0
+ #define QUOTE 1
+@@ -1281,7 +1281,7 @@ YY_DECL
+ {
+ #line 132 "parser.l"
+
+-#line 1284 "parser.yy.c"
++#line 1285 "parser.yy.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+@@ -1616,7 +1616,7 @@ YY_RULE_SETUP
+ #line 239 "parser.l"
+ ECHO;
+ YY_BREAK
+-#line 1619 "parser.yy.c"
++#line 1620 "parser.yy.c"
+
+ case YY_END_OF_BUFFER:
+ {
+diff --git a/mingw-w64-tools/widl/src/proxy.c b/mingw-w64-tools/widl/src/proxy.c
+index 87c27be9..36b552be 100644
+--- a/mingw-w64-tools/widl/src/proxy.c
++++ b/mingw-w64-tools/widl/src/proxy.c
+@@ -67,7 +67,7 @@ static void write_stubdesc(int expr_eval_routines)
+ print_proxy( "1, /* -error bounds_check flag */\n");
+ print_proxy( "0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_proxy( "0,\n");
+- print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_proxy( "0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_proxy( "0,\n");
+ print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_proxy( "0, /* notify & notify_flag routine table */\n");
+@@ -105,15 +105,15 @@ static void clear_output_vars( const var_list_t *args )
+ {
+ if (is_attr(arg->attrs, ATTR_IN)) continue;
+ if (!is_attr(arg->attrs, ATTR_OUT)) continue;
+- if (is_ptr(arg->type))
++ if (is_ptr(arg->declspec.type))
+ {
+- if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue;
+- if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue;
++ if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_BASIC) continue;
++ if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_ENUM) continue;
+ }
+ print_proxy( "if (%s) MIDL_memset( %s, 0, ", arg->name, arg->name );
+- if (is_array(arg->type) && type_array_has_conformance(arg->type))
++ if (is_array(arg->declspec.type) && type_array_has_conformance(arg->declspec.type))
+ {
+- write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" );
++ write_expr( proxy, type_array_get_conformance(arg->declspec.type), 1, 1, NULL, NULL, "" );
+ fprintf( proxy, " * " );
+ }
+ fprintf( proxy, "sizeof( *%s ));\n", arg->name );
+@@ -147,7 +147,7 @@ static int need_delegation_indirect(const type_t *iface)
+ static void free_variable( const var_t *arg, const char *local_var_prefix )
+ {
+ unsigned int type_offset = arg->typestring_offset;
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+
+ write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE);
+
+@@ -191,18 +191,18 @@ static void proxy_free_variables( var_list_t *args, const char *local_var_prefix
+ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ unsigned int proc_offset)
+ {
+- var_t *retval = type_function_get_retval(func->type);
+- int has_ret = !is_void(retval->type);
++ var_t *retval = type_function_get_retval(func->declspec.type);
++ int has_ret = !is_void(retval->declspec.type);
+ int has_full_pointer = is_full_pointer_function(func);
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+
+ indent = 0;
+ if (is_interpreted_func( iface, func ))
+ {
+ if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return;
+- write_type_decl_left(proxy, retval->type);
++ write_declspec_decl_left(proxy, &retval->declspec);
+ print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+ write_args(proxy, args, iface->name, 1, TRUE);
+ print_proxy( ")\n");
+@@ -219,7 +219,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ print_proxy( "}\n");
+ print_proxy( "\n");
+
+- write_type_decl_left(proxy, retval->type);
++ write_declspec_decl_left(proxy, &retval->declspec);
+ print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+ write_args(proxy, args, iface->name, 1, TRUE);
+ print_proxy( ")\n");
+@@ -229,12 +229,12 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ /* local variables */
+ if (has_ret) {
+ print_proxy( "%s", "" );
+- write_type_decl(proxy, retval->type, retval->name);
++ write_declspec_decl(proxy, &retval->declspec, retval->name);
+ fprintf( proxy, ";\n" );
+ }
+ print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
+ if (has_ret) {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name);
+ }
+ print_proxy( "\n");
+@@ -246,7 +246,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ write_full_pointer_init(proxy, indent, func, FALSE);
+
+ /* FIXME: trace */
+- clear_output_vars( type_get_function_args(func->type) );
++ clear_output_vars( type_function_get_args(func->declspec.type) );
+
+ print_proxy( "RpcTryExcept\n" );
+ print_proxy( "{\n" );
+@@ -279,9 +279,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+
+ if (has_ret)
+ {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
+- else if (is_ptr(retval->type) || is_array(retval->type))
++ else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
+ print_proxy("%s = 0;\n", retval->name);
+ write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
+ }
+@@ -301,7 +301,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ print_proxy( "{\n" );
+ if (has_ret) {
+ indent++;
+- proxy_free_variables( type_get_function_args(func->type), "" );
++ proxy_free_variables( type_function_get_args(func->declspec.type), "" );
+ print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
+ indent--;
+ }
+@@ -320,7 +320,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ unsigned int proc_offset)
+ {
+ const var_t *arg;
+- int has_ret = !is_void(type_function_get_rettype(func->type));
++ int has_ret = !is_void(type_function_get_rettype(func->declspec.type));
+ int has_full_pointer = is_full_pointer_function(func);
+
+ if (is_interpreted_func( iface, func )) return;
+@@ -389,10 +389,10 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func));
+ fprintf(proxy, "(__frame->_This");
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
+- fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name);
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
++ fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
+ }
+ fprintf(proxy, ");\n");
+ fprintf(proxy, "\n");
+@@ -401,7 +401,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
+
+ print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &__frame->_StubMsg);\n");
+@@ -410,7 +410,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ fprintf(proxy, "\n");
+
+ /* marshall the return value */
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
+
+ indent--;
+@@ -432,16 +432,16 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+
+ static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_offset )
+ {
+- int has_ret = !is_void( type_function_get_rettype( func->type ));
++ int has_ret = !is_void( type_function_get_rettype( func->declspec.type ));
+ const var_t *arg, *callas = is_callas( func->attrs );
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+
+ indent = 0;
+ print_proxy( "void __RPC_API %s_%s_Thunk( PMIDL_STUB_MESSAGE pStubMsg )\n",
+ iface->name, get_name(func) );
+ print_proxy( "{\n");
+ indent++;
+- write_func_param_struct( proxy, iface, func->type,
++ write_func_param_struct( proxy, iface, func->declspec.type,
+ "*pParamStruct = (struct _PARAM_STRUCT *)pStubMsg->StackTop", has_ret );
+ print_proxy( "%s%s_%s_Stub( pParamStruct->This",
+ has_ret ? "pParamStruct->_RetVal = " : "", iface->name, callas->name );
+@@ -526,6 +526,7 @@ static int write_proxy_methods(type_t *iface, int skip)
+ if (skip || (is_local(func->attrs) && !get_callas_source(iface, func)))
+ print_proxy( "0, /* %s::%s */\n", iface->name, get_name(func));
+ else if (is_interpreted_func( iface, func ) &&
++ get_stub_mode() == MODE_Oif &&
+ !is_local( func->attrs ) &&
+ type_iface_get_inherit(iface))
+ print_proxy( "(void *)-1, /* %s::%s */\n", iface->name, get_name(func));
+@@ -613,14 +614,14 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
+ if (!is_local(func->attrs)) {
+ const var_t *cas = is_callas(func->attrs);
+ const char *cname = cas ? cas->name : NULL;
+- int idx = func->type->details.function->idx;
++ int idx = type_get_details(func->declspec.type)->function->idx;
+ if (cname) {
+ const statement_t *stmt2;
+ STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
+ const var_t *m = stmt2->u.var;
+ if (!strcmp(m->name, cname))
+ {
+- idx = m->type->details.function->idx;
++ idx = type_get_details(m->declspec.type)->function->idx;
+ break;
+ }
+ }
+@@ -738,7 +739,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
+ print_proxy( "{\n");
+ indent++;
+ print_proxy( "%s_%s\n",
+- iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
++ type_get_details(iface)->iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
+ need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
+ indent--;
+ print_proxy( "}\n");
+@@ -839,8 +840,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
+ if (need_proxy(iface))
+ {
+ write_proxy(iface, proc_offset);
+- if (iface->details.iface->async_iface)
+- write_proxy(iface->details.iface->async_iface, proc_offset);
++ if (type_get_details(iface)->iface->async_iface)
++ write_proxy(type_get_details(iface)->iface->async_iface, proc_offset);
+ }
+ }
+ }
+@@ -869,9 +870,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
+ {
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+- if (iface->details.iface->async_iface)
++ if (type_get_details(iface)->iface->async_iface)
+ {
+- iface = iface->details.iface->async_iface;
++ iface = type_get_details(iface)->iface->async_iface;
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+ }
+@@ -942,7 +943,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ write_stubdesc(expr_eval_routines);
+
+ print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
+- print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
++ print_proxy( "#error Invalid build platform for this proxy.\n");
+ print_proxy( "#endif\n");
+ print_proxy( "\n");
+ write_procformatstring(proxy, stmts, need_proxy);
+@@ -1011,7 +1012,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
+ for (i = 0; i < count; i++)
+ {
+- if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
++ if (type_get_details(interfaces[i])->iface->async_iface != interfaces[i]) continue;
+ if (table_version != 6)
+ {
+ fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
+@@ -1053,26 +1054,6 @@ void write_proxies(const statement_list_t *stmts)
+ init_proxy(stmts);
+ if(!proxy) return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(proxy, "\n#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- }
+-
++ write_proxy_routines( stmts );
+ fclose(proxy);
+ }
+diff --git a/mingw-w64-tools/widl/src/register.c b/mingw-w64-tools/widl/src/register.c
+index 210fb747..1c369e7c 100644
+--- a/mingw-w64-tools/widl/src/register.c
++++ b/mingw-w64-tools/widl/src/register.c
+@@ -325,7 +325,7 @@ void output_typelib_regscript( const typelib_t *typelib )
+ sprintf(resname, "%s\\%d", typelib_name, expr->cval);
+ }
+ put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
+- lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part );
++ lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
+ put_str( indent, "FLAGS = s '%u'\n", flags );
+ put_str( --indent, "}\n" );
+ put_str( --indent, "}\n" );
+diff --git a/mingw-w64-tools/widl/src/server.c b/mingw-w64-tools/widl/src/server.c
+index 783ff900..dbed870a 100644
+--- a/mingw-w64-tools/widl/src/server.c
++++ b/mingw-w64-tools/widl/src/server.c
+@@ -55,6 +55,8 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ unsigned char explicit_fc, implicit_fc;
+ int has_full_pointer = is_full_pointer_function(func);
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
++ const decl_spec_t *ret_declspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *ret_type = ret_declspec->type;
+
+ if (is_interpreted_func( iface, func )) return;
+
+@@ -75,7 +77,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ indent++;
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
+
+ if (has_full_pointer)
+@@ -120,7 +122,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ if (has_full_pointer)
+ write_full_pointer_init(server, indent, func, TRUE);
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
+ indent++;
+@@ -154,35 +156,42 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ assign_stub_out_args(server, indent, func, "__frame->");
+
+ /* Call the real server function */
+- print_server("%s%s%s",
+- is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
+- prefix_server, get_name(func));
++ if (is_context_handle(ret_type))
++ {
++ print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
++ print_server("*((");
++ write_declspec_decl(server, ret_declspec, NULL);
++ fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
++ }
++ else
++ print_server("%s", is_void(ret_type) ? "" : "__frame->_RetVal = ");
++ fprintf(server, "%s%s", prefix_server, get_name(func));
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ int first_arg = 1;
+
+ fprintf(server, "(\n");
+ indent++;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ if (first_arg)
+ first_arg = 0;
+ else
+ fprintf(server, ",\n");
+- if (is_context_handle(var->type))
++ if (is_context_handle(var->declspec.type))
+ {
+ /* if the context_handle attribute appears in the chain of types
+ * without pointers being followed, then the context handle must
+ * be direct, otherwise it is a pointer */
+- const char *ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? "*" : "";
++ const char *ch_ptr = is_aliaschain_attr(var->declspec.type, ATTR_CONTEXTHANDLE) ? "*" : "";
+ print_server("(");
+- write_type_decl_left(server, var->type);
++ write_declspec_decl_left(server, &var->declspec);
+ fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name);
+ }
+ else
+ {
+- print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
++ print_server("%s__frame->%s", is_array(var->declspec.type) && !type_array_is_decl_as_ptr(var->declspec.type) ? "*" : "", var->name);
+ }
+ }
+ fprintf(server, ");\n");
+@@ -197,7 +206,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ {
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
+
+ print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
+@@ -216,7 +225,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
+
+ /* marshall the return value */
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
+
+ indent--;
+@@ -378,7 +387,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_server("1, /* -error bounds_check flag */\n");
+ print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_server("0,\n");
+- print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_server("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_server("0,\n");
+ print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_server("0, /* notify & notify_flag routine table */\n");
+@@ -544,26 +553,6 @@ void write_server(const statement_list_t *stmts)
+ if (!server)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(server, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_server_routines( stmts );
+- fprintf(server, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_server_routines( stmts );
+- fprintf(server, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_server_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_server_routines( stmts );
+- }
+-
++ write_server_routines( stmts );
+ fclose(server);
+ }
+diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c
+index 27ba60fc..eebb99f0 100644
+--- a/mingw-w64-tools/widl/src/typegen.c
++++ b/mingw-w64-tools/widl/src/typegen.c
+@@ -67,6 +67,7 @@ enum type_context
+ TYPE_CONTEXT_PARAM,
+ TYPE_CONTEXT_CONTAINER,
+ TYPE_CONTEXT_CONTAINER_NO_POINTERS,
++ TYPE_CONTEXT_RETVAL,
+ };
+
+ /* parameter flags in Oif mode */
+@@ -84,14 +85,14 @@ static const unsigned short IsSimpleRef = 0x0100;
+
+ static unsigned int field_memsize(const type_t *type, unsigned int *offset);
+ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset);
+-static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec, const char *name, unsigned int *tfsoff);
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff);
+ static const var_t *find_array_or_string_in_struct(const type_t *type);
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset);
+ static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
+ const attr_list_t *attrs, int toplevel_param,
+@@ -196,7 +197,7 @@ static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return get_attrp(t->attrs, attr);
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return NULL;
+ }
+ }
+@@ -266,7 +267,7 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t
+ if (pointer_type)
+ return pointer_type;
+
+- for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t))
++ for (t = type; type_is_alias(t); t = type_alias_get_aliasee_type(t))
+ {
+ pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
+ if (pointer_type)
+@@ -287,7 +288,7 @@ static unsigned char get_pointer_fc_context( const type_t *type, const attr_list
+ int pointer_fc = get_pointer_fc(type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM);
+
+ if (pointer_fc == FC_UP && is_attr( attrs, ATTR_OUT ) &&
+- context == TYPE_CONTEXT_PARAM && is_object( current_iface ))
++ (context == TYPE_CONTEXT_PARAM || context == TYPE_CONTEXT_RETVAL) && is_object( current_iface ))
+ pointer_fc = FC_OP;
+
+ return pointer_fc;
+@@ -315,7 +316,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
+ }
+
+ if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else
+ return NULL;
+ }
+@@ -350,10 +351,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
+ return TGT_RANGE;
+ return TGT_ENUM;
+ case TYPE_POINTER:
+- if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE ||
+- (type_get_type(type_pointer_get_ref(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
++ if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
++ (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
+ return TGT_IFACE_POINTER;
+- else if (is_aliaschain_attr(type_pointer_get_ref(type), ATTR_CONTEXTHANDLE))
++ else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
+ return TGT_CTXT_HANDLE_POINTER;
+ else
+ return TGT_POINTER;
+@@ -378,13 +379,13 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
+
+ static int cant_be_null(const var_t *v)
+ {
+- switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
++ switch (typegen_detect_type(v->declspec.type, v->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_ARRAY:
+- if (!type_array_is_decl_as_ptr( v->type )) return 0;
++ if (!type_array_is_decl_as_ptr( v->declspec.type )) return 0;
+ /* fall through */
+ case TGT_POINTER:
+- return (get_pointer_fc(v->type, v->attrs, TRUE) == FC_RP);
++ return (get_pointer_fc(v->declspec.type, v->attrs, TRUE) == FC_RP);
+ case TGT_CTXT_HANDLE_POINTER:
+ return TRUE;
+ default:
+@@ -404,7 +405,7 @@ static int get_padding(const var_list_t *fields)
+
+ LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ unsigned int align = 0;
+ unsigned int size = type_memsize_and_alignment(ft, &align);
+ align = clamp_align(align);
+@@ -421,7 +422,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ unsigned int stack_size;
+ int by_val;
+
+- switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
++ switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
+ {
+ case TGT_BASIC:
+ case TGT_ENUM:
+@@ -429,7 +430,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ case TGT_STRUCT:
+ case TGT_UNION:
+ case TGT_USER_TYPE:
+- stack_size = type_memsize( var->type );
++ stack_size = type_memsize( var->declspec.type );
+ by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */
+ break;
+ default:
+@@ -442,23 +443,27 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ }
+
+ static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
+- const type_t *type )
++ const type_t *type, int is_return )
+ {
+ unsigned char flags = 0;
++ int is_out;
+
+ if (is_attr(iface->attrs, ATTR_STRICTCONTEXTHANDLE)) flags |= NDR_STRICT_CONTEXT_HANDLE;
+
+ if (is_ptr(type) &&
+ !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
+ !is_attr( attrs, ATTR_CONTEXTHANDLE ))
+- flags |= 0x80;
++ flags |= HANDLE_PARAM_IS_VIA_PTR;
+
+- if (is_attr(attrs, ATTR_IN))
++ if (is_return) return flags | HANDLE_PARAM_IS_OUT | HANDLE_PARAM_IS_RETURN;
++
++ is_out = is_attr(attrs, ATTR_OUT);
++ if (is_attr(attrs, ATTR_IN) || !is_out)
+ {
+- flags |= 0x40;
+- if (!is_attr(attrs, ATTR_OUT)) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
++ flags |= HANDLE_PARAM_IS_IN;
++ if (!is_out) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
+ }
+- if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
++ if (is_out) flags |= HANDLE_PARAM_IS_OUT;
+
+ return flags;
+ }
+@@ -490,14 +495,14 @@ unsigned char get_struct_fc(const type_t *type)
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
+ {
+- type_t *t = field->type;
++ type_t *t = field->declspec.type;
+ enum typegen_type typegen_type;
+
+ typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
+
+ if (typegen_type == TGT_ARRAY && !type_array_is_decl_as_ptr(t))
+ {
+- if (is_string_type(field->attrs, field->type))
++ if (is_string_type(field->attrs, field->declspec.type))
+ {
+ if (is_conformant_array(t))
+ has_conformance = 1;
+@@ -505,10 +510,10 @@ unsigned char get_struct_fc(const type_t *type)
+ continue;
+ }
+
+- if (is_array(type_array_get_element(field->type)))
++ if (is_array(type_array_get_element_type(field->declspec.type)))
+ return FC_BOGUS_STRUCT;
+
+- if (type_array_has_conformance(field->type))
++ if (type_array_has_conformance(field->declspec.type))
+ {
+ has_conformance = 1;
+ if (list_next(fields, &field->entry))
+@@ -518,7 +523,7 @@ unsigned char get_struct_fc(const type_t *type)
+ if (type_array_has_variance(t))
+ has_variance = 1;
+
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
+ }
+
+@@ -620,7 +625,7 @@ static unsigned char get_array_fc(const type_t *type)
+ const expr_t *size_is;
+ const type_t *elem_type;
+
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ size_is = type_array_get_conformance(type);
+
+ if (!size_is)
+@@ -709,14 +714,14 @@ static int type_has_pointers(const type_t *type)
+ case TGT_POINTER:
+ return TRUE;
+ case TGT_ARRAY:
+- return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element(type));
++ return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element_type(type));
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(type);
+ const var_t *field;
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (type_has_pointers(field->type))
++ if (type_has_pointers(field->declspec.type))
+ return TRUE;
+ }
+ break;
+@@ -728,7 +733,7 @@ static int type_has_pointers(const type_t *type)
+ fields = type_union_get_cases(type);
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (field->type && type_has_pointers(field->type))
++ if (field->declspec.type && type_has_pointers(field->declspec.type))
+ return TRUE;
+ }
+ break;
+@@ -763,14 +768,14 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
+ if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
+ return TRUE;
+ else
+- return type_has_full_pointer(type_array_get_element(type), NULL, FALSE);
++ return type_has_full_pointer(type_array_get_element_type(type), NULL, FALSE);
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(type);
+ const var_t *field;
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (type_has_full_pointer(field->type, field->attrs, FALSE))
++ if (type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
+ return TRUE;
+ }
+ break;
+@@ -782,7 +787,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
+ fields = type_union_get_cases(type);
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (field->type && type_has_full_pointer(field->type, field->attrs, FALSE))
++ if (field->declspec.type && type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
+ return TRUE;
+ }
+ break;
+@@ -852,7 +857,7 @@ static const char *get_context_handle_type_name(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return t->name;
+ assert(0);
+@@ -902,16 +907,16 @@ static void write_var_init(FILE *file, int indent, const type_t *t, const char *
+
+ void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
+ {
+- const var_t *var = type_function_get_retval(func->type);
++ const var_t *var = type_function_get_retval(func->declspec.type);
+
+- if (!is_void(var->type))
+- write_var_init(file, indent, var->type, var->name, local_var_prefix);
++ if (!is_void(var->declspec.type))
++ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
+- write_var_init(file, indent, var->type, var->name, local_var_prefix);
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
++ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
+
+ fprintf(file, "\n");
+ }
+@@ -975,14 +980,14 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ if (is_out) *flags |= IsOut;
+ if (is_return) *flags |= IsReturn;
+
+- if (!is_string_type( var->attrs, var->type ))
+- buffer_size = get_required_buffer_size_type( var->type, NULL, var->attrs, TRUE, &alignment );
++ if (!is_string_type( var->attrs, var->declspec.type ))
++ buffer_size = get_required_buffer_size_type( var->declspec.type, NULL, var->attrs, TRUE, &alignment );
+
+- switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
++ switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
+ {
+ case TGT_BASIC:
+ *flags |= IsBasetype;
+- fc = get_basic_fc_signed( var->type );
++ fc = get_basic_fc_signed( var->declspec.type );
+ if (fc == FC_BIND_PRIMITIVE)
+ {
+ buffer_size = 4; /* actually 0 but avoids setting MustSize */
+@@ -991,7 +996,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ break;
+ case TGT_ENUM:
+ *flags |= IsBasetype;
+- fc = get_enum_fc( var->type );
++ fc = get_enum_fc( var->declspec.type );
+ break;
+ case TGT_RANGE:
+ *flags |= IsByValue;
+@@ -1006,19 +1011,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ break;
+ case TGT_ARRAY:
+ *flags |= MustFree;
+- if (type_array_is_decl_as_ptr(var->type) && var->type->details.array.ptr_tfsoff &&
+- get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (type_array_is_decl_as_ptr(var->declspec.type) && type_get_details(var->declspec.type)->array.ptr_tfsoff &&
++ get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+- *typestring_offset = var->type->typestring_offset;
++ *typestring_offset = var->declspec.type->typestring_offset;
+ *flags |= IsSimpleRef;
+ }
+ break;
+ case TGT_STRING:
+ *flags |= MustFree;
+- if (is_declptr( var->type ) && get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (is_declptr( var->declspec.type ) && get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+ /* skip over pointer description straight to string description */
+- if (is_conformant_array( var->type )) *typestring_offset += 4;
++ if (is_conformant_array( var->declspec.type )) *typestring_offset += 4;
+ else *typestring_offset += 2;
+ *flags |= IsSimpleRef;
+ }
+@@ -1031,9 +1036,9 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ buffer_size = 20;
+ break;
+ case TGT_POINTER:
+- if (get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+- const type_t *ref = type_pointer_get_ref( var->type );
++ const type_t *ref = type_pointer_get_ref_type( var->declspec.type );
+
+ if (!is_string_type( var->attrs, ref ))
+ buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
+@@ -1059,11 +1064,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ case TGT_UNION:
+ case TGT_USER_TYPE:
+ case TGT_RANGE:
+- case TGT_ARRAY:
+- *flags |= IsSimpleRef | MustFree;
++ *flags |= MustFree | IsSimpleRef;
+ *typestring_offset = ref->typestring_offset;
+ if (!is_in && is_out) server_size = type_memsize( ref );
+ break;
++ case TGT_ARRAY:
++ *flags |= MustFree;
++ if (!type_array_is_decl_as_ptr(ref))
++ {
++ *flags |= IsSimpleRef;
++ *typestring_offset = ref->typestring_offset;
++ }
++ if (!is_in && is_out) server_size = type_memsize( ref );
++ break;
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+@@ -1115,8 +1128,8 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ static unsigned char get_func_oi2_flags( const var_t *func )
+ {
+ const var_t *var;
+- var_list_t *args = type_get_function_args( func->type );
+- var_t *retval = type_function_get_retval( func->type );
++ var_list_t *args = type_function_get_args( func->declspec.type );
++ var_t *retval = type_function_get_retval( func->declspec.type );
+ unsigned char oi2_flags = 0x40; /* HasExtensions */
+ unsigned short flags;
+ unsigned int stack_size, typestring_offset;
+@@ -1131,7 +1144,7 @@ static unsigned char get_func_oi2_flags( const var_t *func )
+ }
+ }
+
+- if (!is_void( retval->type ))
++ if (!is_void( retval->declspec.type ))
+ {
+ oi2_flags |= 0x04; /* HasRet */
+ get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset );
+@@ -1185,8 +1198,8 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+
+ if (!is_in && !is_out) is_in = TRUE;
+
+- if (type_get_type(var->type) == TYPE_BASIC ||
+- type_get_type(var->type) == TYPE_ENUM)
++ if (type_get_type(var->declspec.type) == TYPE_BASIC ||
++ type_get_type(var->declspec.type) == TYPE_ENUM)
+ {
+ unsigned char fc;
+
+@@ -1195,13 +1208,13 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+ else
+ print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+
+- if (type_get_type(var->type) == TYPE_ENUM)
++ if (type_get_type(var->declspec.type) == TYPE_ENUM)
+ {
+- fc = get_enum_fc(var->type);
++ fc = get_enum_fc(var->declspec.type);
+ }
+ else
+ {
+- fc = get_basic_fc_signed(var->type);
++ fc = get_basic_fc_signed(var->declspec.type);
+
+ if (fc == FC_BIND_PRIMITIVE)
+ fc = FC_IGNORE;
+@@ -1215,10 +1228,12 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+ {
+ unsigned short offset = var->typestring_offset;
+
+- if (!is_interpreted && is_array(var->type) &&
+- type_array_is_decl_as_ptr(var->type) &&
+- var->type->details.array.ptr_tfsoff)
+- offset = var->type->typestring_offset;
++ if (!is_interpreted && is_array(var->declspec.type) &&
++ type_array_is_decl_as_ptr(var->declspec.type) &&
++ type_get_details(var->declspec.type)->array.ptr_tfsoff)
++ {
++ offset = var->declspec.type->typestring_offset;
++ }
+
+ if (is_return)
+ print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
+@@ -1241,8 +1256,8 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
+ {
+ const char *str;
+ const var_t *var;
+- const var_list_t *args = type_get_function_args( func->type );
+- const type_t *ret_type = type_function_get_rettype( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
++ const type_t *ret_type = type_function_get_rettype( func->declspec.type );
+
+ if (type_get_type( ret_type ) == TYPE_BASIC)
+ {
+@@ -1264,10 +1279,10 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
+ if (get_stub_mode() != MODE_Oif && args)
+ {
+ LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+- switch (type_get_type( var->type ))
++ switch (type_get_type( var->declspec.type ))
+ {
+ case TYPE_BASIC:
+- switch (type_basic_get_type( var->type ))
++ switch (type_basic_get_type( var->declspec.type ))
+ {
+ /* floating point arguments are not supported in Oi mode */
+ case TYPE_BASIC_FLOAT: return 0;
+@@ -1292,7 +1307,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ unsigned short num_proc )
+ {
+ var_t *var;
+- var_list_t *args = type_get_function_args( func->type );
++ var_list_t *args = type_function_get_args( func->declspec.type );
+ unsigned char explicit_fc, implicit_fc;
+ unsigned char handle_flags;
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
+@@ -1323,7 +1338,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ param_num++;
+ nb_args++;
+ }
+- if (!is_void( type_function_get_rettype( func->type )))
++ if (!is_void( type_function_get_rettype( func->declspec.type )))
+ {
+ stack_size += pointer_size;
+ nb_args++;
+@@ -1351,22 +1366,22 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ *offset += 4;
+ break;
+ case FC_BIND_GENERIC:
+- handle_flags = type_memsize( handle_var->type );
++ handle_flags = type_memsize( handle_var->declspec.type );
+ print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
+ print_file( file, indent, "0x%02x,\n", handle_flags );
+ print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
+ handle_stack_offset, handle_stack_offset );
+- print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->type ) );
++ print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->declspec.type ) );
+ print_file( file, indent, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *offset += 6;
+ break;
+ case FC_BIND_CONTEXT:
+- handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->type );
++ handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->declspec.type, 0 );
+ print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
+ print_file( file, indent, "0x%02x,\n", handle_flags );
+ print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
+ handle_stack_offset, handle_stack_offset );
+- print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->type ) );
++ print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->declspec.type ) );
+ print_file( file, indent, "0x%02x,\t/* param %hu */\n", handle_param_num, handle_param_num );
+ *offset += 6;
+ break;
+@@ -1381,7 +1396,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+
+ if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08; /* HasNotify */
+ if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10; /* HasNotify2 */
+- if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
++ if (iface == type_get_const_details(iface)->iface->async_iface) oi2_flags |= 0x20;
+
+ size = get_function_buffer_size( func, PASS_IN );
+ print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
+@@ -1402,9 +1417,9 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ if (is_object( iface )) pos += 2;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry )
+ {
+- if (type_get_type( var->type ) == TYPE_BASIC)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC)
+ {
+- switch (type_basic_get_type( var->type ))
++ switch (type_basic_get_type( var->declspec.type ))
+ {
+ case TYPE_BASIC_FLOAT: fpu_mask |= 1 << pos; break;
+ case TYPE_BASIC_DOUBLE: fpu_mask |= 2 << pos; break;
+@@ -1427,15 +1442,15 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
+ unsigned int stack_offset = is_object( iface ) ? pointer_size : 0;
+ int is_interpreted = is_interpreted_func( iface, func );
+ int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif);
+- var_t *retval = type_function_get_retval( func->type );
++ var_t *retval = type_function_get_retval( func->declspec.type );
+
+ if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
+
+ /* emit argument data */
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ const var_t *var;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
+ if (is_new_style)
+@@ -1446,7 +1461,7 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
+ }
+
+ /* emit return value data */
+- if (is_void(retval->type))
++ if (is_void(retval->declspec.type))
+ {
+ if (!is_new_style)
+ {
+@@ -1475,13 +1490,13 @@ static void for_each_iface(const statement_list_t *stmts,
+
+ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+ {
+- if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
++ if (stmt->type != STMT_TYPE || type_get_type_detect_alias(stmt->u.type) != TYPE_INTERFACE)
+ continue;
+ iface = stmt->u.type;
+ if (!pred(iface)) continue;
+ proc(iface, file, indent, offset);
+- if (iface->details.iface->async_iface)
+- proc(iface->details.iface->async_iface, file, indent, offset);
++ if (type_get_const_details(iface)->iface->async_iface)
++ proc(type_get_const_details(iface)->iface->async_iface, file, indent, offset);
+ }
+ }
+
+@@ -1593,7 +1608,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+ {
+ conftype = FC_TOP_LEVEL_CONFORMANCE;
+ conftype_string = "parameter";
+- cont_type = current_func->type;
++ cont_type = current_func->declspec.type;
+ name = current_func->name;
+ iface = current_iface;
+ }
+@@ -1656,7 +1671,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+
+ if (type_get_type(cont_type) == TYPE_FUNCTION)
+ {
+- var_list_t *args = type_get_function_args( cont_type );
++ var_list_t *args = type_function_get_args( cont_type );
+
+ if (is_object( iface )) offset += pointer_size;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+@@ -1664,7 +1679,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+ if (var->name && !strcmp(var->name, subexpr->u.sval))
+ {
+ expr_loc.v = var;
+- correlation_variable = var->type;
++ correlation_variable = var->declspec.type;
+ break;
+ }
+ offset += get_stack_size( var, NULL );
+@@ -1676,11 +1691,11 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+
+ if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- unsigned int size = field_memsize( var->type, &offset );
++ unsigned int size = field_memsize( var->declspec.type, &offset );
+ if (var->name && !strcmp(var->name, subexpr->u.sval))
+ {
+ expr_loc.v = var;
+- correlation_variable = var->type;
++ correlation_variable = var->declspec.type;
+ break;
+ }
+ offset += size;
+@@ -1819,7 +1834,7 @@ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align
+ LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
+ {
+ unsigned int falign = 0;
+- unsigned int fsize = type_memsize_and_alignment(v->type, &falign);
++ unsigned int fsize = type_memsize_and_alignment(v->declspec.type, &falign);
+ if (*align < falign) *align = falign;
+ falign = clamp_align(falign);
+ size = ROUND_SIZE(size, falign);
+@@ -1841,9 +1856,9 @@ static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
+ if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
+ {
+ /* we could have an empty default field with NULL type */
+- if (v->type)
++ if (v->declspec.type)
+ {
+- size = type_memsize_and_alignment(v->type, &align);
++ size = type_memsize_and_alignment(v->declspec.type, &align);
+ if (maxs < size) maxs = size;
+ if (*pmaxa < align) *pmaxa = align;
+ }
+@@ -1931,12 +1946,12 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
+ {
+ if (is_conformant_array(t))
+ {
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ size = 0;
+ }
+ else
+ size = type_array_get_dim(t) *
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ }
+ else /* declared as a pointer */
+ {
+@@ -2016,8 +2031,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_struct_get_fields(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+@@ -2025,8 +2040,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_encapsulated_union_get_fields(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+@@ -2034,14 +2049,14 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_union_get_cases(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+ case TYPE_ARRAY:
+ if (!type_array_is_decl_as_ptr(t))
+- return type_buffer_alignment( type_array_get_element(t) );
++ return type_buffer_alignment( type_array_get_element_type(t) );
+ /* else fall through */
+ case TYPE_POINTER:
+ return 4;
+@@ -2064,12 +2079,12 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ int is_full_pointer_function(const var_t *func)
+ {
+ const var_t *var;
+- if (type_has_full_pointer(type_function_get_rettype(func->type), func->attrs, TRUE))
++ if (type_has_full_pointer(type_function_get_rettype(func->declspec.type), func->attrs, TRUE))
+ return TRUE;
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return FALSE;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
+- if (type_has_full_pointer( var->type, var->attrs, TRUE ))
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
++ if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
+ return TRUE;
+ return FALSE;
+ }
+@@ -2114,12 +2129,13 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+ {
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM && is_ptr(type) && pointer_type == FC_RP)
+ {
+- switch (typegen_detect_type(type_pointer_get_ref(type), NULL, TDT_ALL_TYPES))
++ switch (typegen_detect_type(type_pointer_get_ref_type(type), NULL, TDT_ALL_TYPES))
+ {
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
++ case TGT_ARRAY:
+ flags |= FC_ALLOCED_ON_STACK;
+ break;
+ case TGT_IFACE_POINTER:
+@@ -2134,7 +2150,7 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+ if(is_declptr(ref) && !is_user_type(ref))
+ flags |= FC_POINTER_DEREF;
+ }
+@@ -2175,7 +2191,7 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+
+ pointer_fc = get_pointer_fc_context(type, attrs, context);
+
+- ref = type_pointer_get_ref(type);
++ ref = type_pointer_get_ref_type(type);
+ if (type_get_type(ref) == TYPE_ENUM)
+ fc = get_enum_fc(ref);
+ else
+@@ -2200,22 +2216,23 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+ return 4;
+ }
+
+-static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
++static void print_start_tfs_comment(FILE *file, const decl_spec_t *ds, unsigned int tfsoff)
+ {
+ print_file(file, 0, "/* %u (", tfsoff);
+- write_type_decl(file, t, NULL);
++ write_declspec_decl(file, ds, NULL);
+ print_file(file, 0, ") */\n");
+ }
+
+ static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int ref_offset,
++ const decl_spec_t *declspec, unsigned int ref_offset,
+ enum type_context context,
+ unsigned int *typestring_offset)
+ {
+ unsigned int offset = *typestring_offset;
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *type = declspec->type;
++ type_t *ref = type_pointer_get_ref_type(type);
+
+- print_start_tfs_comment(file, type, offset);
++ print_start_tfs_comment(file, declspec, offset);
+ update_tfsoff(type, offset, file);
+
+ switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
+@@ -2258,10 +2275,11 @@ static int user_type_has_variable_size(const type_t *t)
+ return FALSE;
+ }
+
+-static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
++static unsigned int write_user_tfs(FILE *file, const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
+ unsigned int start, absoff, flags;
+ const char *name = NULL;
++ type_t *type = declspec->type;
+ type_t *utype = get_user_type(type, &name);
+ unsigned int usize = type_memsize(utype);
+ unsigned int ualign = type_buffer_alignment(utype);
+@@ -2279,6 +2297,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ type_get_type(utype) == TYPE_ENUM)
+ {
+ unsigned char fc;
++ decl_spec_t ds;
+
+ if (type_get_type(utype) == TYPE_ENUM)
+ fc = get_enum_fc(utype);
+@@ -2286,7 +2305,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ fc = get_basic_fc(utype);
+
+ absoff = *tfsoff;
+- print_start_tfs_comment(file, utype, absoff);
++ print_start_tfs_comment(file, init_declspec(&ds, utype), absoff);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
+ *tfsoff += 2;
+@@ -2294,7 +2313,10 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ else
+ {
+ if (!processed(utype))
+- write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
++ {
++ decl_spec_t ds;
++ write_embedded_types(file, NULL, init_declspec(&ds, utype), utype->name, TRUE, tfsoff);
++ }
+ absoff = utype->typestring_offset;
+ }
+
+@@ -2307,7 +2329,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+
+ start = *tfsoff;
+ update_tfsoff(type, start, file);
+- print_start_tfs_comment(file, type, start);
++ print_start_tfs_comment(file, declspec, start);
+ print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
+ print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
+ flags | (ualign - 1), ualign - 1, flags);
+@@ -2364,11 +2386,12 @@ static void write_member_type(FILE *file, const type_t *cont,
+ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
+ int cont_is_complex, unsigned int *tfsoff)
+ {
+- type_t *elem = type_array_get_element(type);
++ const decl_spec_t *element = type_array_get_element(type);
++ type_t *elem = element->type;
+
+ if (!is_embedded_complex(elem) && is_ptr(elem))
+ {
+- type_t *ref = type_pointer_get_ref(elem);
++ type_t *ref = type_pointer_get_ref_type(elem);
+
+ if (processed(ref))
+ {
+@@ -2378,7 +2401,7 @@ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const
+ }
+ if (cont_is_complex && is_string_type(attrs, elem))
+ {
+- write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
++ write_string_tfs(file, NULL, element, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
+ return;
+ }
+ if (!is_string_type(NULL, elem) &&
+@@ -2410,7 +2433,7 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
+
+ if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ unsigned int size = field_memsize( ft, &offset );
+ if (type_get_type(ft) == TYPE_UNION && is_attr(f->attrs, ATTR_SWITCHIS))
+ {
+@@ -2433,13 +2456,14 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
+ }
+
+ static int write_pointer_description_offsets(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+- if ((is_ptr(type) && type_get_type(type_pointer_get_ref(type)) != TYPE_INTERFACE) ||
++ if ((is_ptr(type) && type_get_type(type_pointer_get_ref_type(type)) != TYPE_INTERFACE) ||
+ (is_array(type) && type_array_is_decl_as_ptr(type)))
+ {
+ if (offset_in_memory && offset_in_buffer)
+@@ -2464,10 +2488,10 @@ static int write_pointer_description_offsets(
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+
+ if (is_string_type(attrs, type))
+- write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
++ write_string_tfs(file, attrs, declspec, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
+ else if (processed(ref))
+ write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER,
+ ref->typestring_offset, typestring_offset);
+@@ -2505,13 +2529,13 @@ static int write_pointer_description_offsets(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ written += write_pointer_description_offsets(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2531,10 +2555,11 @@ static int write_pointer_description_offsets(
+ }
+
+ static int write_no_repeat_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+ if (is_ptr(type) ||
+@@ -2544,7 +2569,7 @@ static int write_no_repeat_pointer_descriptions(
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+
+- return write_pointer_description_offsets(file, attrs, type,
++ return write_pointer_description_offsets(file, attrs, declspec,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+
+@@ -2557,13 +2582,13 @@ static int write_no_repeat_pointer_descriptions(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ written += write_no_repeat_pointer_descriptions(
+- file, v->attrs, v->type,
++ file, v->attrs, &v->declspec,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+ }
+@@ -2582,10 +2607,11 @@ static int write_no_repeat_pointer_descriptions(
+ /* Note: if file is NULL return value is number of pointers to write, else
+ * it is the number of type format characters written */
+ static int write_fixed_array_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int pointer_count = 0;
+
+ if (type_get_type(type) == TYPE_ARRAY &&
+@@ -2602,7 +2628,7 @@ static int write_fixed_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = 0;
+ unsigned int offset_of_array_pointer_buf = 0;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", FC_FIXED_REPEAT);
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+@@ -2613,7 +2639,7 @@ static int write_fixed_array_pointer_descriptions(
+ *typestring_offset += 10;
+
+ pointer_count = write_pointer_description_offsets(
+- file, attrs, type, &offset_of_array_pointer_mem,
++ file, attrs, declspec, &offset_of_array_pointer_mem,
+ &offset_of_array_pointer_buf, typestring_offset);
+ }
+ }
+@@ -2626,13 +2652,13 @@ static int write_fixed_array_pointer_descriptions(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ pointer_count += write_fixed_array_pointer_descriptions(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2673,7 +2699,7 @@ static int write_conformant_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = offset_in_memory;
+ unsigned int offset_of_array_pointer_buf = offset_in_memory;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2715,7 +2741,7 @@ static int write_varying_array_pointer_descriptions(
+ {
+ unsigned int increment_size;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2741,20 +2767,20 @@ static int write_varying_array_pointer_descriptions(
+ {
+ unsigned int align = 0, padding;
+
+- if (is_array(v->type) && type_array_has_variance(v->type))
++ if (is_array(v->declspec.type) && type_array_has_variance(v->declspec.type))
+ {
+ *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
+ /* skip over variance and offset in buffer */
+ *offset_in_buffer += 8;
+ }
+
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ pointer_count += write_varying_array_pointer_descriptions(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2773,9 +2799,10 @@ static int write_varying_array_pointer_descriptions(
+ return pointer_count;
+ }
+
+-static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type,
++static void write_pointer_description(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int offset_in_buffer;
+ unsigned int offset_in_memory;
+
+@@ -2786,7 +2813,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_no_repeat_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+ }
+
+@@ -2794,7 +2821,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_fixed_array_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+
+ /* pass 3: search for pointers in conformant only arrays (but don't descend
+@@ -2806,7 +2833,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ else if (type_get_type(type) == TYPE_STRUCT &&
+ get_struct_fc(type) == FC_CPSTRUCT)
+ {
+- type_t *carray = find_array_or_string_in_struct(type)->type;
++ type_t *carray = find_array_or_string_in_struct(type)->declspec.type;
+ write_conformant_array_pointer_descriptions( file, NULL, carray,
+ type_memsize(type), typestring_offset);
+ }
+@@ -2820,9 +2847,10 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ }
+
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset;
+ unsigned char rtype;
+ type_t *elem_type;
+@@ -2836,7 +2864,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ int pointer_type = get_pointer_fc_context(type, attrs, context);
+ if (!pointer_type)
+ pointer_type = FC_RP;
+- print_start_tfs_comment(file, type, *typestring_offset);
++ print_start_tfs_comment(file, declspec, *typestring_offset);
+ print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
+ pointer_type, flag, string_of_type(pointer_type),
+ flag ? " [simple_pointer]" : "");
+@@ -2850,12 +2878,12 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+
+ if (is_array(type))
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ else
+- elem_type = type_pointer_get_ref(type);
++ elem_type = type_pointer_get_ref_type(type);
+
+ if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
+- return write_array_tfs(file, attrs, type, name, typestring_offset);
++ return write_array_tfs(file, attrs, declspec, name, typestring_offset);
+
+ if (type_get_type(elem_type) != TYPE_BASIC)
+ {
+@@ -2929,34 +2957,31 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+ }
+
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ const expr_t *length_is = type_array_get_variance(type);
+ const expr_t *size_is = type_array_get_conformance(type);
+ unsigned int align;
+ unsigned int size;
+ unsigned int start_offset;
+ unsigned char fc;
+- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+ unsigned int baseoff
+ = !type_array_is_decl_as_ptr(type) && current_structure
+ ? type_memsize(current_structure)
+ : 0;
+
+- if (!pointer_type)
+- pointer_type = FC_RP;
+-
+- if (!is_string_type(attrs, type_array_get_element(type)))
++ if (!is_string_type(attrs, type_array_get_element_type(type)))
+ write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
+
+- size = type_memsize(is_conformant_array(type) ? type_array_get_element(type) : type);
+- align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element(type) : type);
++ size = type_memsize(is_conformant_array(type) ? type_array_get_element_type(type) : type);
++ align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element_type(type) : type);
+ fc = get_array_fc(type);
+
+ start_offset = *typestring_offset;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ *typestring_offset += 2;
+@@ -2982,7 +3007,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+
+ if (fc == FC_SMVARRAY || fc == FC_LGVARRAY)
+ {
+- unsigned int elsize = type_memsize(type_array_get_element(type));
++ unsigned int elsize = type_memsize(type_array_get_element_type(type));
+ unsigned int dim = type_array_get_dim(type);
+
+ if (fc == FC_LGVARRAY)
+@@ -3005,13 +3030,13 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+ += write_conf_or_var_desc(file, current_structure, baseoff,
+ type, length_is);
+
+- if (type_has_pointers(type_array_get_element(type)) &&
++ if (type_has_pointers(type_array_get_element_type(type)) &&
+ (type_array_is_decl_as_ptr(type) || !current_structure))
+ {
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+- write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
++ write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, declspec, typestring_offset);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *typestring_offset += 1;
+ }
+@@ -3048,7 +3073,7 @@ static const var_t *find_array_or_string_in_struct(const type_t *type)
+ return NULL;
+
+ last_field = LIST_ENTRY( list_tail(fields), const var_t, entry );
+- ft = last_field->type;
++ ft = last_field->declspec.type;
+
+ if (is_conformant_array(ft) && !type_array_is_decl_as_ptr(ft))
+ return last_field;
+@@ -3071,7 +3096,7 @@ static void write_struct_members(FILE *file, const type_t *type,
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- type_t *ft = field->type;
++ type_t *ft = field->declspec.type;
+ unsigned int align = 0;
+ unsigned int size = type_memsize_and_alignment(ft, &align);
+ align = clamp_align(align);
+@@ -3100,7 +3125,7 @@ static void write_struct_members(FILE *file, const type_t *type,
+ offset = ROUND_SIZE(offset, align);
+ *typestring_offset += 1;
+ }
+- write_member_type(file, type, is_complex, field->attrs, field->type, corroff,
++ write_member_type(file, type, is_complex, field->attrs, field->declspec.type, corroff,
+ typestring_offset);
+ offset += size;
+ }
+@@ -3118,9 +3143,10 @@ static void write_struct_members(FILE *file, const type_t *type,
+ write_end(file, typestring_offset);
+ }
+
+-static unsigned int write_struct_tfs(FILE *file, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec,
+ const char *name, unsigned int *tfsoff)
+ {
++ type_t *type = declspec->type;
+ const type_t *save_current_structure = current_structure;
+ unsigned int total_size;
+ const var_t *array;
+@@ -3143,15 +3169,15 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ name, USHRT_MAX, total_size - USHRT_MAX);
+
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+- write_embedded_types(file, f->attrs, f->type, f->name, FALSE, tfsoff);
++ write_embedded_types(file, f->attrs, &f->declspec, f->name, FALSE, tfsoff);
+
+ array = find_array_or_string_in_struct(type);
+- if (array && !processed(array->type))
++ if (array && !processed(array->declspec.type))
+ {
+- if(is_string_type(array->attrs, array->type))
+- write_string_tfs(file, array->attrs, array->type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
++ if(is_string_type(array->attrs, array->declspec.type))
++ write_string_tfs(file, array->attrs, &array->declspec, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
+ else
+- write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
++ write_array_tfs(file, array->attrs, &array->declspec, array->name, tfsoff);
+ }
+
+ corroff = *tfsoff;
+@@ -3159,7 +3185,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
+@@ -3167,7 +3193,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+
+ if (array)
+ {
+- unsigned int absoff = array->type->typestring_offset;
++ unsigned int absoff = array->declspec.type->typestring_offset;
+ short reloff = absoff - *tfsoff;
+ print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
+ reloff, reloff, absoff);
+@@ -3198,7 +3224,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *tfsoff += 2;
+- write_pointer_description(file, NULL, type, tfsoff);
++ write_pointer_description(file, NULL, declspec, tfsoff);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *tfsoff += 1;
+ }
+@@ -3213,15 +3239,16 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ type->ptrdesc = *tfsoff;
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
+ {
+- type_t *ft = f->type;
++ const decl_spec_t *fds = &f->declspec;
++ type_t *ft = fds->type;
+ switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_POINTER:
+ if (is_string_type(f->attrs, ft))
+- write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
++ write_string_tfs(file, f->attrs, fds, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
+ else
+- write_pointer_tfs(file, f->attrs, ft,
+- type_pointer_get_ref(ft)->typestring_offset,
++ write_pointer_tfs(file, f->attrs, fds,
++ type_pointer_get_ref_type(ft)->typestring_offset,
+ TYPE_CONTEXT_CONTAINER, tfsoff);
+ break;
+ case TGT_ARRAY:
+@@ -3283,8 +3310,9 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
+ }
+
+ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int *tfsoff)
++ const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
++ type_t* type = declspec->type;
+ unsigned int start_offset;
+ unsigned int size;
+ var_list_t *fields;
+@@ -3309,17 +3337,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
+ if (cases)
+ nbranch += list_count(cases);
+- if (f->type)
+- write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff);
++ if (f->declspec.type)
++ write_embedded_types(file, f->attrs, &f->declspec, f->name, TRUE, tfsoff);
+ }
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ if (type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ const var_t *sv = type_union_get_switch_value(type);
+- const type_t *st = sv->type;
++ const type_t *st = sv->declspec.type;
+ unsigned int align = 0;
+ unsigned char fc;
+
+@@ -3351,8 +3379,8 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ type_memsize_and_alignment(st, &align);
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+ {
+- if (f->type)
+- type_memsize_and_alignment(f->type, &align);
++ if (f->declspec.type)
++ type_memsize_and_alignment(f->declspec.type, &align);
+ }
+
+ print_file(file, 2, "0x%x,\t/* FC_ENCAPSULATED_UNION */\n", FC_ENCAPSULATED_UNION);
+@@ -3407,7 +3435,7 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
+ int deflt = is_attr(f->attrs, ATTR_DEFAULT);
+ expr_t *c;
+@@ -3448,16 +3476,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int i;
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+ expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
+
+ if (!iid && processed(type)) return type->typestring_offset;
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ update_tfsoff(type, start_offset, file);
+
+ if (iid)
+@@ -3469,7 +3498,7 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+ }
+ else
+ {
+- const type_t *base = is_ptr(type) ? type_pointer_get_ref(type) : type;
++ const type_t *base = is_ptr(type) ? type_pointer_get_ref_type(type) : type;
+ const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
+
+ if (! uuid)
+@@ -3493,18 +3522,19 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+
+ static unsigned int write_contexthandle_tfs(FILE *file,
+ const attr_list_t *attrs,
+- type_t *type,
+- int toplevel_param,
++ const decl_spec_t *declspec,
++ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+- unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
++ unsigned char flags = get_contexthandle_flags( current_iface, attrs, type, context == TYPE_CONTEXT_RETVAL );
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+
+ if (flags & 0x80) /* via ptr */
+ {
+- int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
++ int pointer_type = get_pointer_fc( type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM );
+ if (!pointer_type) pointer_type = FC_RP;
+ *typeformat_offset += 4;
+ print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
+@@ -3514,8 +3544,7 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+
+ print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", FC_BIND_CONTEXT);
+ print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
+- /* return and can't be null values overlap */
+- if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
++ if (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL)
+ print_file(file, 0, "can't be null, ");
+ if (flags & NDR_CONTEXT_HANDLE_SERIALIZE)
+ print_file(file, 0, "serialize, ");
+@@ -3523,13 +3552,13 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+ print_file(file, 0, "no serialize, ");
+ if (flags & NDR_STRICT_CONTEXT_HANDLE)
+ print_file(file, 0, "strict, ");
+- if ((flags & 0x21) == 0x20)
+- print_file(file, 0, "out, ");
+- if ((flags & 0x21) == 0x21)
++ if (flags & HANDLE_PARAM_IS_RETURN)
+ print_file(file, 0, "return, ");
+- if (flags & 0x40)
++ if (flags & HANDLE_PARAM_IS_OUT)
++ print_file(file, 0, "out, ");
++ if (flags & HANDLE_PARAM_IS_IN)
+ print_file(file, 0, "in, ");
+- if (flags & 0x80)
++ if (flags & HANDLE_PARAM_IS_VIA_PTR)
+ print_file(file, 0, "via ptr, ");
+ print_file(file, 0, "*/\n");
+ print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
+@@ -3568,24 +3597,23 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_type_tfs(FILE *file, int indent,
+- const attr_list_t *attrs, type_t *type,
+- const char *name,
++static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
++ const decl_spec_t *declspec, const char *name,
+ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int offset;
++ type_t *type = declspec->type;
+
+ switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
+ {
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
+- return write_contexthandle_tfs(file, attrs, type,
+- context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
++ return write_contexthandle_tfs(file, attrs, declspec, context, typeformat_offset);
+ case TGT_USER_TYPE:
+- return write_user_tfs(file, type, typeformat_offset);
++ return write_user_tfs(file, declspec, typeformat_offset);
+ case TGT_STRING:
+- return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
++ return write_string_tfs(file, attrs, declspec, context, name, typeformat_offset);
+ case TGT_ARRAY:
+ {
+ unsigned int off;
+@@ -3593,15 +3621,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if ((context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) ||
+ !is_conformant_array(type) || type_array_is_decl_as_ptr(type))
+- off = write_array_tfs(file, attrs, type, name, typeformat_offset);
++ off = write_array_tfs(file, attrs, declspec, name, typeformat_offset);
+ else
+ off = 0;
+ if (context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ {
+ int ptr_type;
+- ptr_type = get_pointer_fc(type, attrs,
+- context == TYPE_CONTEXT_TOPLEVELPARAM);
++ ptr_type = get_pointer_fc_context(type, attrs, context);
+ if (ptr_type != FC_RP || type_array_is_decl_as_ptr(type))
+ {
+ unsigned int absoff = type->typestring_offset;
+@@ -3615,14 +3642,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if (ptr_type != FC_RP) update_tfsoff( type, off, file );
+ *typeformat_offset += 4;
+ }
+- type->details.array.ptr_tfsoff = off;
++ type_get_details(type)->array.ptr_tfsoff = off;
+ }
+ return off;
+ }
+ case TGT_STRUCT:
+- return write_struct_tfs(file, type, name, typeformat_offset);
++ return write_struct_tfs(file, declspec, name, typeformat_offset);
+ case TGT_UNION:
+- return write_union_tfs(file, attrs, type, typeformat_offset);
++ return write_union_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_ENUM:
+ case TGT_BASIC:
+ /* nothing to do */
+@@ -3635,11 +3662,11 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
+ }
+ case TGT_IFACE_POINTER:
+- return write_ip_tfs(file, attrs, type, typeformat_offset);
++ return write_ip_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_POINTER:
+ {
+ enum type_context ref_context;
+- type_t *ref = type_pointer_get_ref(type);
++ const decl_spec_t *ref = type_pointer_get_ref(type);
+
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM)
+ ref_context = TYPE_CONTEXT_PARAM;
+@@ -3648,22 +3675,22 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ else
+ ref_context = context;
+
+- if (is_string_type(attrs, ref))
++ if (is_string_type(attrs, ref->type))
+ {
+ if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+- write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
++ write_pointer_tfs(file, attrs, declspec, *typeformat_offset + 4, context, typeformat_offset);
+
+- offset = write_type_tfs(file, indent, attrs, ref, name, ref_context, typeformat_offset);
++ offset = write_type_tfs(file, attrs, ref, name, ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+ return offset;
+ }
+
+- offset = write_type_tfs( file, indent, attrs, type_pointer_get_ref(type), name,
++ offset = write_type_tfs( file, attrs, type_pointer_get_ref(type), name,
+ ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+- return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
++ return write_pointer_tfs(file, attrs, declspec, offset, context, typeformat_offset);
+ }
+ case TGT_INVALID:
+ break;
+@@ -3672,10 +3699,10 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return 0;
+ }
+
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff)
+ {
+- return write_type_tfs(file, 2, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
++ return write_type_tfs(file, attrs, declspec, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
+ }
+
+ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
+@@ -3693,21 +3720,21 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
+ {
+ const var_t *func = stmt->u.var;
+
+- if(stmt->u.var->stgclass != STG_NONE
+- || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
++ if(stmt->u.var->declspec.stgclass != STG_NONE
++ || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
+ continue;
+
+ current_func = func;
+ if (is_local(func->attrs)) continue;
+
+- var = type_function_get_retval(func->type);
+- if (!is_void(var->type))
+- var->typestring_offset = write_type_tfs( file, 2, func->attrs, var->type, func->name,
+- TYPE_CONTEXT_PARAM, offset);
++ var = type_function_get_retval(func->declspec.type);
++ if (!is_void(var->declspec.type))
++ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, func->name,
++ TYPE_CONTEXT_RETVAL, offset);
+
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), var_t, entry )
+- var->typestring_offset = write_type_tfs( file, 2, var->attrs, var->type, var->name,
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
++ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, var->name,
+ TYPE_CONTEXT_TOPLEVELPARAM, offset );
+ break;
+
+@@ -3719,9 +3746,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
+ {
+ if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
+ || is_attr(type_entry->type->attrs, ATTR_DECODE))
+- type_entry->type->typestring_offset = write_type_tfs( file, 2,
+- type_entry->type->attrs, type_entry->type, type_entry->type->name,
++ {
++ decl_spec_t ds;
++ type_entry->type->typestring_offset = write_type_tfs( file,
++ type_entry->type->attrs, init_declspec(&ds, type_entry->type), type_entry->type->name,
+ TYPE_CONTEXT_CONTAINER, offset);
++ }
+ }
+ break;
+ }
+@@ -3842,7 +3872,7 @@ static unsigned int get_required_buffer_size_type(
+ case TGT_POINTER:
+ {
+ unsigned int size, align;
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (is_string_type( attrs, ref )) break;
+ if (!(size = get_required_buffer_size_type( ref, name, NULL, FALSE, &align ))) break;
+ if (get_pointer_fc(type, attrs, toplevel_param) != FC_RP)
+@@ -3862,7 +3892,7 @@ static unsigned int get_required_buffer_size_type(
+ case FC_SMFARRAY:
+ case FC_LGFARRAY:
+ return type_array_get_dim(type) *
+- get_required_buffer_size_type(type_array_get_element(type), name,
++ get_required_buffer_size_type(type_array_get_element_type(type), name,
+ NULL, FALSE, alignment);
+ }
+ }
+@@ -3893,8 +3923,8 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
+ return 20;
+ }
+
+- if (!is_string_type(var->attrs, var->type))
+- return get_required_buffer_size_type(var->type, var->name,
++ if (!is_string_type(var->attrs, var->declspec.type))
++ return get_required_buffer_size_type(var->declspec.type, var->name,
+ var->attrs, TRUE, alignment);
+ }
+ return 0;
+@@ -3905,19 +3935,19 @@ static unsigned int get_function_buffer_size( const var_t *func, enum pass pass
+ const var_t *var;
+ unsigned int total_size = 0, alignment;
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ total_size += get_required_buffer_size(var, &alignment, pass);
+ total_size += alignment;
+ }
+ }
+
+- if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->type)))
++ if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->declspec.type)))
+ {
+ var_t v = *func;
+- v.type = type_function_get_rettype(func->type);
++ v.declspec.type = type_function_get_rettype(func->declspec.type);
+ total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
+ total_size += alignment;
+ }
+@@ -3953,9 +3983,9 @@ static void print_phase_function(FILE *file, int indent, const char *type,
+ print_file(file, indent, "&__frame->_StubMsg,\n");
+ print_file(file, indent, "%s%s%s%s%s,\n",
+ (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)",
+- (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "",
++ (phase == PHASE_UNMARSHAL || decl_indirect(var->declspec.type)) ? "&" : "",
+ local_var_prefix,
+- (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "",
++ (phase == PHASE_UNMARSHAL && decl_indirect(var->declspec.type)) ? "_p_" : "",
+ var->name);
+ print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
+ type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
+@@ -3968,7 +3998,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ enum remoting_phase phase, enum pass pass, const var_t *var,
+ const char *varname)
+ {
+- type_t *type = var->type;
++ const decl_spec_t *declspec = &var->declspec;
++ type_t *type = declspec->type;
+ unsigned int alignment = 0;
+
+ /* no work to do for other phases, buffer sizing is done elsewhere */
+@@ -3999,8 +4030,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ }
+ else
+ {
+- const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
+- switch (get_basic_fc(ref))
++ const decl_spec_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : declspec;
++ switch (get_basic_fc(ref->type))
+ {
+ case FC_BYTE:
+ case FC_CHAR:
+@@ -4037,7 +4068,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+
+ default:
+ error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
+- var->name, get_basic_fc(ref));
++ var->name, get_basic_fc(ref->type));
+ }
+
+ if (phase == PHASE_MARSHAL && alignment > 1)
+@@ -4048,7 +4079,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ if (phase == PHASE_MARSHAL)
+ {
+ print_file(file, indent, "*(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ if (is_ptr(type))
+ fprintf(file, " *)__frame->_StubMsg.Buffer = *");
+ else
+@@ -4059,7 +4090,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ else if (phase == PHASE_UNMARSHAL)
+ {
+ print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
+ print_file(file, indent, "{\n");
+ print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
+@@ -4071,12 +4102,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ fprintf(file, " = (");
+ else
+ fprintf(file, " = *(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
+ }
+
+ print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ");\n");
+ }
+ }
+@@ -4092,7 +4123,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
+ {
+ expr_t *x = NULL;
+
+- for ( ; is_array(t); t = type_array_get_element(t))
++ for ( ; is_array(t); t = type_array_get_element_type(t))
+ if (type_array_has_conformance(t) &&
+ type_array_get_conformance(t)->type != EXPR_VOID)
+ {
+@@ -4110,7 +4141,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
+ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local_var_prefix,
+ enum remoting_phase phase, const var_t *var, int valid_variance)
+ {
+- const type_t *type = var->type;
++ const type_t *type = var->declspec.type;
+ /* get fundamental type for the argument */
+ for (;;)
+ {
+@@ -4162,7 +4193,7 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ continue;
+ case TGT_INVALID:
+ case TGT_USER_TYPE:
+@@ -4184,7 +4215,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ {
+ int in_attr, out_attr, pointer_type;
+ const char *type_str = NULL;
+- const type_t *type = var->type;
++ const type_t *type = var->declspec.type;
+ unsigned int alignment, start_offset = type->typestring_offset;
+
+ if (is_ptr(type) || is_array(type))
+@@ -4237,19 +4268,20 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ print_file(file, indent, "NdrServerContextNewMarshall(\n");
+ print_file(file, indent + 1, "&__frame->_StubMsg,\n");
+ print_file(file, indent + 1, "(NDR_SCONTEXT)%s%s,\n", local_var_prefix, var->name);
+- print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->type));
++ print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->declspec.type));
+ print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
+ }
+ }
+ else if (phase == PHASE_UNMARSHAL)
+ {
+- if (pass == PASS_OUT)
++ if (pass == PASS_OUT || pass == PASS_RETURN)
+ {
+ if (!in_attr)
+ print_file(file, indent, "*%s%s = 0;\n", local_var_prefix, var->name);
+ print_file(file, indent, "NdrClientContextUnmarshall(\n");
+ print_file(file, indent + 1, "&__frame->_StubMsg,\n");
+- print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s,\n", local_var_prefix, var->name);
++ print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s%s,\n",
++ pass == PASS_RETURN ? "&" : "", local_var_prefix, var->name);
+ print_file(file, indent + 1, "__frame->_Handle);\n");
+ }
+ else
+@@ -4343,10 +4375,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
+ (tc == FC_CARRAY && !in_attr))
+ {
+- if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
++ if (type_array_is_decl_as_ptr(type) && type_get_const_details(type)->array.ptr_tfsoff)
+ {
+ print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
+- type->details.array.ptr_tfsoff);
++ type_get_const_details(type)->array.ptr_tfsoff);
+ break;
+ }
+ print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
+@@ -4380,9 +4412,9 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
+
+ print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
+- write_type_decl(file, var->type, NULL);
++ write_declspec_decl(file, &var->declspec, NULL);
+ fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
+- write_type_decl(file, var->type, NULL);
++ write_declspec_decl(file, &var->declspec, NULL);
+ fprintf(file, ")0x%x))\n", range_max->cval);
+ print_file(file, indent, "{\n");
+ print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
+@@ -4428,7 +4460,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ }
+ case TGT_POINTER:
+ {
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (pointer_type == FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
+ {
+ case TGT_BASIC:
+@@ -4549,14 +4581,14 @@ void write_remoting_arguments(FILE *file, int indent, const var_t *func, const c
+ if (pass == PASS_RETURN)
+ {
+ write_remoting_arg( file, indent, func, local_var_prefix, pass, phase,
+- type_function_get_retval(func->type) );
++ type_function_get_retval(func->declspec.type) );
+ }
+ else
+ {
+ const var_t *var;
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
+ }
+ }
+@@ -4597,57 +4629,62 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
+ {
+ int in_attr, out_attr;
+ int i = 0;
+- const var_t *var = type_function_get_retval(func->type);
++ const var_t *var = type_function_get_retval(func->declspec.type);
+
+ /* declare return value */
+- if (!is_void(var->type))
++ if (!is_void(var->declspec.type))
+ {
+- print_file(file, indent, "%s", "");
+- write_type_decl(file, var->type, var->name);
+- fprintf(file, ";\n");
++ if (is_context_handle(var->declspec.type))
++ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
++ else
++ {
++ print_file(file, indent, "%s", "");
++ write_declspec_decl(file, &var->declspec, var->name);
++ fprintf(file, ";\n");
++ }
+ }
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+ if (!out_attr && !in_attr)
+ in_attr = 1;
+
+- if (is_context_handle(var->type))
++ if (is_context_handle(var->declspec.type))
+ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
+ else
+ {
+- if (!in_attr && !is_conformant_array(var->type))
++ if (!in_attr && !is_conformant_array(var->declspec.type))
+ {
+- type_t *type_to_print;
++ const decl_spec_t *declspec_to_print;
+ char name[16];
+ print_file(file, indent, "%s", "");
+- if (type_get_type(var->type) == TYPE_ARRAY &&
+- !type_array_is_decl_as_ptr(var->type))
+- type_to_print = var->type;
++ if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
++ !type_array_is_decl_as_ptr(var->declspec.type))
++ declspec_to_print = &var->declspec;
+ else
+- type_to_print = type_pointer_get_ref(var->type);
++ declspec_to_print = type_pointer_get_ref(var->declspec.type);
+ sprintf(name, "_W%u", i++);
+- write_type_decl(file, type_to_print, name);
++ write_declspec_decl(file, declspec_to_print, name);
+ fprintf(file, ";\n");
+ }
+
+ print_file(file, indent, "%s", "");
+- write_type_decl_left(file, var->type);
++ write_declspec_decl_left(file, &var->declspec);
+ fprintf(file, " ");
+- if (type_get_type(var->type) == TYPE_ARRAY &&
+- !type_array_is_decl_as_ptr(var->type)) {
++ if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
++ !type_array_is_decl_as_ptr(var->declspec.type)) {
+ fprintf(file, "(*%s)", var->name);
+ } else
+ fprintf(file, "%s", var->name);
+- write_type_right(file, var->type, FALSE);
++ write_type_right(file, var->declspec.type, FALSE);
+ fprintf(file, ";\n");
+
+- if (decl_indirect(var->type))
++ if (decl_indirect(var->declspec.type))
+ print_file(file, indent, "void *_p_%s;\n", var->name);
+ }
+ }
+@@ -4661,10 +4698,10 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ const var_t *var;
+ type_t *ref;
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+@@ -4675,7 +4712,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ {
+ print_file(file, indent, "%s%s", local_var_prefix, var->name);
+
+- switch (typegen_detect_type(var->type, var->attrs, TDT_IGNORE_STRINGS))
++ switch (typegen_detect_type(var->declspec.type, var->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_CTXT_HANDLE_POINTER:
+ fprintf(file, " = NdrContextHandleInitialize(\n");
+@@ -4684,15 +4721,15 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ var->typestring_offset);
+ break;
+ case TGT_ARRAY:
+- if (type_array_has_conformance(var->type))
++ if (type_array_has_conformance(var->declspec.type))
+ {
+ unsigned int size;
+ type_t *type;
+
+ fprintf(file, " = NdrAllocate(&__frame->_StubMsg, ");
+- for (type = var->type;
++ for (type = var->declspec.type;
+ is_array(type) && type_array_has_conformance(type);
+- type = type_array_get_element(type))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4702,9 +4739,9 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ fprintf(file, "%u);\n", size);
+
+ print_file(file, indent, "memset(%s%s, 0, ", local_var_prefix, var->name);
+- for (type = var->type;
++ for (type = var->declspec.type;
+ is_array(type) && type_array_has_conformance(type);
+- type = type_array_get_element(type))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4718,7 +4755,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ break;
+ case TGT_POINTER:
+ fprintf(file, " = &%s_W%u;\n", local_var_prefix, i);
+- ref = type_pointer_get_ref(var->type);
++ ref = type_pointer_get_ref_type(var->declspec.type);
+ switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_BASIC:
+@@ -4738,7 +4775,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
+ break;
+ }
+- ref = type_array_get_element(ref);
++ ref = type_array_get_element_type(ref);
+ /* fall through */
+ case TGT_STRUCT:
+ case TGT_UNION:
+@@ -4771,14 +4808,14 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+ const char *var_decl, int add_retval )
+ {
+ var_t *retval = type_function_get_retval( func );
+- const var_list_t *args = type_get_function_args( func );
++ const var_list_t *args = type_function_get_args( func );
+ const var_t *arg;
+ int needs_packing;
+ unsigned int align = 0;
+
+ if (args)
+ LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+- if (!is_array( arg->type )) type_memsize_and_alignment( arg->type, &align );
++ if (!is_array( arg->declspec.type )) type_memsize_and_alignment( arg->declspec.type, &align );
+
+ needs_packing = (align > pointer_size);
+
+@@ -4790,26 +4827,26 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+ if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+ {
+ print_file(file, 2, "%s", "");
+- write_type_left( file, (type_t *)arg->type, NAME_DEFAULT, TRUE );
+- if (needs_space_after( arg->type )) fputc( ' ', file );
+- if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
++ write_declspec_left( file, &arg->declspec, NAME_DEFAULT, TRUE );
++ if (needs_space_after( arg->declspec.type )) fputc( ' ', file );
++ if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
+
+ /* FIXME: should check for large args being passed by pointer */
+ align = 0;
+- if (is_array( arg->type ) || is_ptr( arg->type )) align = pointer_size;
+- else type_memsize_and_alignment( arg->type, &align );
++ if (is_array( arg->declspec.type ) || is_ptr( arg->declspec.type )) align = pointer_size;
++ else type_memsize_and_alignment( arg->declspec.type, &align );
+
+ if (align >= pointer_size)
+ fprintf( file, "%s;\n", arg->name );
+ else
+ fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
+ }
+- if (add_retval && !is_void( retval->type ))
++ if (add_retval && !is_void( retval->declspec.type ))
+ {
+ print_file(file, 2, "%s", "");
+- write_type_decl( file, retval->type, retval->name );
+- if (is_array( retval->type ) || is_ptr( retval->type ) ||
+- type_memsize( retval->type ) == pointer_size)
++ write_declspec_decl( file, &retval->declspec, retval->name );
++ if (is_array( retval->declspec.type ) || is_ptr( retval->declspec.type ) ||
++ type_memsize( retval->declspec.type ) == pointer_size)
+ fprintf( file, ";\n" );
+ else
+ fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
+@@ -4821,7 +4858,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+
+ void write_pointer_checks( FILE *file, int indent, const var_t *func )
+ {
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+ const var_t *var;
+
+ if (!args) return;
+@@ -4854,10 +4891,11 @@ int write_expr_eval_routines(FILE *file, const char *iface)
+ }
+ else
+ {
++ decl_spec_t declspec;
+ print_file(file, 1, "%s", "");
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *%s = (", var_name);
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
+ }
+ print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
+@@ -4951,9 +4989,10 @@ error:
+ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *func,
+ const char *prefix, unsigned int proc_offset )
+ {
+- type_t *rettype = type_function_get_rettype( func->type );
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *rettype = retdeclspec->type;
+ int has_ret = !is_void( rettype );
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+ const var_t *arg;
+ int len, needs_params = 0;
+
+@@ -4964,7 +5003,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
+ if (needs_params)
+ {
+ if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n" );
+- write_func_param_struct( file, iface, func->type, "__params", FALSE );
++ write_func_param_struct( file, iface, func->declspec.type, "__params", FALSE );
+ if (is_object( iface )) print_file( file, 1, "__params.This = This;\n" );
+ if (args)
+ LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+@@ -5001,7 +5040,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
+ if (has_ret)
+ {
+ print_file( file, 1, "return (" );
+- write_type_decl_left(file, rettype);
++ write_declspec_decl_left(file, retdeclspec);
+ fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
+ }
+ print_file( file, 0, "}\n\n");
+@@ -5029,7 +5068,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
+ fprintf( file, " __filter_func filter; \\\n");
+ fprintf( file, " __finally_func finally; \\\n");
+- fprintf( file, " sigjmp_buf jmp; \\\n");
++ fprintf( file, " __wine_jmp_buf jmp; \\\n");
+ fprintf( file, " DWORD code; \\\n");
+ fprintf( file, " unsigned char abnormal_termination; \\\n");
+ fprintf( file, " unsigned char filter_level; \\\n");
+@@ -5049,13 +5088,13 @@ void write_exceptions( FILE *file )
+ fprintf( file, " __wine_pop_frame( &exc_frame->frame );\n");
+ fprintf( file, " }\n");
+ fprintf( file, " exc_frame->filter_level = 0;\n");
+- fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
++ fprintf( file, " __wine_longjmp( &exc_frame->jmp, 1 );\n");
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+- fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
+- fprintf( file, " CONTEXT *context,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
++ fprintf( file, "static DWORD __cdecl __widl_exception_handler( EXCEPTION_RECORD *record,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
++ fprintf( file, " CONTEXT *context,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
+ fprintf( file, "{\n");
+ fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
+ fprintf( file, "\n");
+@@ -5075,7 +5114,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+ fprintf( file, "#define RpcTryExcept \\\n");
+- fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
++ fprintf( file, " if (!__wine_setjmpex( &__frame->jmp, &__frame->frame )) \\\n");
+ fprintf( file, " { \\\n");
+ fprintf( file, " if (!__frame->finally_level) \\\n" );
+ fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
+diff --git a/mingw-w64-tools/widl/src/typelib.c b/mingw-w64-tools/widl/src/typelib.c
+index 9b1de2c8..2c2b1276 100644
+--- a/mingw-w64-tools/widl/src/typelib.c
++++ b/mingw-w64-tools/widl/src/typelib.c
+@@ -97,9 +97,9 @@ static unsigned short builtin_vt(const type_t *t)
+ {
+ const type_t *elem_type;
+ if (is_array(t))
+- elem_type = type_array_get_element(t);
++ elem_type = type_array_get_element_type(t);
+ else
+- elem_type = type_pointer_get_ref(t);
++ elem_type = type_pointer_get_ref_type(t);
+ if (type_get_type(elem_type) == TYPE_BASIC)
+ {
+ switch (type_basic_get_type(elem_type))
+@@ -129,7 +129,8 @@ unsigned short get_type_vt(type_t *t)
+ if (vt) return vt;
+ }
+
+- if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
++ if (type_is_alias(t) &&
++ (is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
+ return VT_USERDEFINED;
+
+ switch (type_get_type(t)) {
+@@ -169,7 +170,7 @@ unsigned short get_type_vt(type_t *t)
+ else
+ return VT_I8;
+ case TYPE_BASIC_INT3264:
+- if (typelib_kind == SYS_WIN64)
++ if (pointer_size == 8)
+ {
+ if (type_basic_get_sign(t) > 0)
+ return VT_UI8;
+@@ -198,7 +199,7 @@ unsigned short get_type_vt(type_t *t)
+ case TYPE_ARRAY:
+ if (type_array_is_decl_as_ptr(t))
+ {
+- if (match(type_array_get_element(t)->name, "SAFEARRAY"))
++ if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
+ return VT_SAFEARRAY;
+ return VT_PTR;
+ }
+diff --git a/mingw-w64-tools/widl/src/typetree.c b/mingw-w64-tools/widl/src/typetree.c
+index b93806be..f52b785f 100644
+--- a/mingw-w64-tools/widl/src/typetree.c
++++ b/mingw-w64-tools/widl/src/typetree.c
+@@ -30,12 +30,16 @@
+ #include "typetree.h"
+ #include "header.h"
+
+-type_t *duptype(type_t *t, int dupname)
++/* this function is only used in declare_var in parser.y, see FIXME note */
++type_t *dup_pointer_type(type_t *t)
+ {
+- type_t *d = alloc_type();
++ type_t *d;
+
++ assert(is_ptr(t) && t->details.pointer.def_fc != FC_RP);
++
++ d = alloc_type();
+ *d = *t;
+- if (dupname && t->name)
++ if (t->name)
+ d->name = xstrdup(t->name);
+
+ return d;
+@@ -49,7 +53,6 @@ type_t *make_type(enum type_type type)
+ t->type_type = type;
+ t->attrs = NULL;
+ t->c_name = NULL;
+- t->orig = NULL;
+ memset(&t->details, 0, sizeof(t->details));
+ t->typestring_offset = 0;
+ t->ptrdesc = 0;
+@@ -137,7 +140,7 @@ type_t *type_new_function(var_list_t *args)
+ if (args)
+ {
+ arg = LIST_ENTRY(list_head(args), var_t, entry);
+- if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID)
++ if (list_count(args) == 1 && !arg->name && arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
+ {
+ list_remove(&arg->entry);
+ free(arg);
+@@ -147,7 +150,7 @@ type_t *type_new_function(var_list_t *args)
+ }
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+- if (arg->type && type_get_type(arg->type) == TYPE_VOID)
++ if (arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
+ error_loc("argument '%s' has void type\n", arg->name);
+ if (!arg->name)
+ {
+@@ -178,35 +181,29 @@ type_t *type_new_function(var_list_t *args)
+ return t;
+ }
+
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref)
+ {
+ type_t *t = make_type(TYPE_POINTER);
+ t->details.pointer.def_fc = pointer_default;
+- t->details.pointer.ref = ref;
+- t->attrs = attrs;
++ t->details.pointer.ref.type = ref;
+ return t;
+ }
+
+-type_t *type_new_alias(type_t *t, const char *name)
++type_t *type_new_alias(const decl_spec_t *ds, const char *name)
+ {
+- type_t *a = duptype(t, 0);
+-
++ type_t *a = make_type(ds->type->type_type);
+ a->name = xstrdup(name);
+ a->attrs = NULL;
+- a->orig = t;
++ a->details.alias.aliasee = *ds;
+ a->is_alias = TRUE;
+- /* for pointer types */
+- a->details = t->details;
+- init_loc_info(&a->loc_info);
+-
+ return a;
+ }
+
+ type_t *type_new_module(char *name)
+ {
+ type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
+- if (type->type_type != TYPE_MODULE || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_MODULE || type_is_defined(type))
++ error_loc("BAZ %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+@@ -215,15 +212,15 @@ type_t *type_new_module(char *name)
+ type_t *type_new_coclass(char *name)
+ {
+ type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
+- if (type->type_type != TYPE_COCLASS || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_COCLASS || type_is_defined(type))
++ error_loc("BING %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+ }
+
+
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc)
+ {
+@@ -235,7 +232,9 @@ type_t *type_new_array(const char *name, type_t *element, int declptr,
+ t->details.array.size_is = size_is;
+ else
+ t->details.array.dim = dim;
+- t->details.array.elem = element;
++ if (element) {
++ t->details.array.elem = *element;
++ }
+ t->details.array.ptr_def_fc = ptr_default_fc;
+ return t;
+ }
+@@ -273,80 +272,99 @@ type_t *type_new_void(void)
+
+ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
+- type_t *t = make_type(TYPE_ENUM);
+- t->name = name;
+- t->namespace = namespace;
+-
+- if (tag_type && tag_type->details.enumeration)
+- t->details.enumeration = tag_type->details.enumeration;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, namespace, tsENUM);
++
++ if (!t)
+ {
+- t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
+- t->details.enumeration->enums = enums;
+- t->defined = TRUE;
++ t = make_type(TYPE_ENUM);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsENUM);
+ }
+
+- if (name)
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsENUM);
++ {
++ t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
++ t->details.enumeration->enums = enums;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL;
+- type_t *t;
+-
+- /* avoid creating duplicate typelib type entries */
+- if (tag_type && do_typelib) return tag_type;
++ type_t *t = NULL;
+
+- t = make_type(TYPE_STRUCT);
+- t->name = name;
+- t->namespace = namespace;
++ if (name)
++ t = find_type(name, namespace, tsSTRUCT);
+
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_STRUCT);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsSTRUCT);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsSTRUCT);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
+- type_t *t = make_type(TYPE_UNION);
+- t->name = name;
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, NULL, tsUNION);
++
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_UNION);
++ t->name = name;
++ if (name)
++ reg_type(t, name, NULL, tsUNION);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, NULL, tsUNION);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+@@ -354,7 +372,7 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
+ {
+ type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION);
+ if (!union_field) union_field = make_var( xstrdup("tagged_union") );
+- union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
++ union_field->declspec.type = type_new_nonencapsulated_union(NULL, TRUE, cases);
+ t->details.structure = xmalloc(sizeof(*t->details.structure));
+ t->details.structure->fields = append_var( NULL, switch_field );
+ t->details.structure->fields = append_var( t->details.structure->fields, union_field );
+@@ -430,7 +448,7 @@ static int compute_method_indexes(type_t *iface)
+ {
+ var_t *func = stmt->u.var;
+ if (!is_callas(func->attrs))
+- func->type->details.function->idx = idx++;
++ func->declspec.type->details.function->idx = idx++;
+ }
+
+ return idx;
+@@ -438,6 +456,7 @@ static int compute_method_indexes(type_t *iface)
+
+ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
+@@ -451,6 +470,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
+
+ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = props;
+ iface->details.iface->disp_methods = methods;
+@@ -465,6 +485,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
+
+ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
+ dispiface->details.iface->disp_props = NULL;
+ dispiface->details.iface->disp_methods = NULL;
+@@ -479,6 +500,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+
+ void type_module_define(type_t *module, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (module->details.module) error_loc("multiple definition error\n");
+ module->details.module = xmalloc(sizeof(*module->details.module));
+ module->details.module->stmts = stmts;
+@@ -487,6 +509,7 @@ void type_module_define(type_t *module, statement_list_t *stmts)
+
+ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
+ {
++ assert(type_get_type_detect_alias(coclass) == TYPE_COCLASS);
+ coclass->details.coclass.ifaces = ifaces;
+ coclass->defined = TRUE;
+ return coclass;
+diff --git a/mingw-w64-tools/widl/src/typetree.h b/mingw-w64-tools/widl/src/typetree.h
+index fc134cd5..96fcae8d 100644
+--- a/mingw-w64-tools/widl/src/typetree.h
++++ b/mingw-w64-tools/widl/src/typetree.h
+@@ -30,10 +30,10 @@ enum name_type {
+ };
+
+ type_t *type_new_function(var_list_t *args);
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
+-type_t *type_new_alias(type_t *t, const char *name);
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref);
++type_t *type_new_alias(const decl_spec_t *aliasee, const char *name);
+ type_t *type_new_module(char *name);
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char* name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc);
+ type_t *type_new_basic(enum type_basic_type basic_type);
+@@ -53,14 +53,38 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
+ int type_is_equal(const type_t *type1, const type_t *type2);
+ const char *type_get_name(const type_t *type, enum name_type name_type);
+
+-/* FIXME: shouldn't need to export this */
+-type_t *duptype(type_t *t, int dupname);
++/* copy pointer type to deal with need for duplicate typeformat strings */
++type_t *dup_pointer_type(type_t *t);
++
++#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
++ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
++ if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
++ type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
++
++static inline enum type_type type_get_type_detect_alias(const type_t *type)
++{
++ if (type->is_alias)
++ return TYPE_ALIAS;
++ return type->type_type;
++}
++
++static inline int statements_has_func(const statement_list_t *stmts)
++{
++ const statement_t *stmt;
++ int has_func = 0;
++ STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
++ {
++ has_func = 1;
++ break;
++ }
++ return has_func;
++}
+
+ /* un-alias the type until finding the non-alias type */
+ static inline type_t *type_get_real_type(const type_t *type)
+ {
+ if (type->is_alias)
+- return type_get_real_type(type->orig);
++ return type_get_real_type(type->details.alias.aliasee.type);
+ else
+ return (type_t *)type;
+ }
+@@ -105,9 +129,14 @@ static inline var_t *type_function_get_retval(const type_t *type)
+ return type->details.function->retval;
+ }
+
++static inline const decl_spec_t *type_function_get_retdeclspec(const type_t *type)
++{
++ return &type_function_get_retval(type)->declspec;
++}
++
+ static inline type_t *type_function_get_rettype(const type_t *type)
+ {
+- return type_function_get_retval(type)->type;
++ return type_function_get_retdeclspec(type)->type;
+ }
+
+ static inline var_list_t *type_enum_get_values(const type_t *type)
+@@ -142,7 +171,7 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
+ if (type_type == TYPE_ENCAPSULATED_UNION)
+ {
+ const var_t *uv = LIST_ENTRY(list_tail(type->details.structure->fields), const var_t, entry);
+- return uv->type->details.structure->fields;
++ return uv->declspec.type->details.structure->fields;
+ }
+ else
+ return type->details.structure->fields;
+@@ -250,11 +279,16 @@ static inline expr_t *type_array_get_variance(const type_t *type)
+ return type->details.array.length_is;
+ }
+
+-static inline type_t *type_array_get_element(const type_t *type)
++static inline const decl_spec_t *type_array_get_element(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_ARRAY);
+- return type->details.array.elem;
++ return &type->details.array.elem;
++}
++
++static inline type_t *type_array_get_element_type(const type_t *type)
++{
++ return type_array_get_element(type)->type;
+ }
+
+ static inline int type_array_is_decl_as_ptr(const type_t *type)
+@@ -276,10 +310,15 @@ static inline int type_is_alias(const type_t *type)
+ return type->is_alias;
+ }
+
+-static inline type_t *type_alias_get_aliasee(const type_t *type)
++static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
+ {
+ assert(type_is_alias(type));
+- return type->orig;
++ return &type->details.alias.aliasee;
++}
++
++static inline type_t *type_alias_get_aliasee_type(const type_t *type)
++{
++ return type_alias_get_aliasee(type)->type;
+ }
+
+ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+@@ -289,11 +328,16 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+ return type->details.coclass.ifaces;
+ }
+
+-static inline type_t *type_pointer_get_ref(const type_t *type)
++static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_POINTER);
+- return type->details.pointer.ref;
++ return &type->details.pointer.ref;
++}
++
++static inline type_t *type_pointer_get_ref_type(const type_t *type)
++{
++ return type_pointer_get_ref(type)->type;
+ }
+
+ static inline unsigned char type_pointer_get_default_fc(const type_t *type)
+@@ -317,4 +361,54 @@ static inline const expr_t *type_bitfield_get_bits(const type_t *type)
+ return type->details.bitfield.bits;
+ }
+
++/* gets pointer to details_t union with the assumption the caller wants to write to it
++ * so assert if we're actually dealing with an alias and writing to the details would
++ * overwrite the alias_details
++ */
++static inline details_t *type_get_details(type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++/* const overload of type_get_details */
++
++static inline const details_t *type_get_const_details(const type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++static inline int type_is_pointerish(const type_t *type)
++{
++ type = type_get_real_type(type);
++ return type_get_type(type) == TYPE_ARRAY || type_get_type(type) == TYPE_POINTER;
++}
++
++static inline type_t * type_get_pointer_chain_tail(const type_t *type)
++{
++ type_t *pointee = NULL;
++ type_t *pointer = type_get_real_type(type);
++
++ if (type_get_type(pointer) == TYPE_ARRAY)
++ {
++ pointee = type_array_get_element_type(pointer);
++ }
++ else if (type_get_type(pointer) == TYPE_POINTER)
++ {
++ pointee = type_pointer_get_ref_type(pointer);
++ }
++ else
++ {
++ assert(FALSE);
++ }
++
++ if (type_is_pointerish(pointee))
++ {
++ return type_get_pointer_chain_tail(pointee);
++ }
++
++ return pointee;
++}
++
+ #endif /* WIDL_TYPE_TREE_H */
+diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c
+index 1af42509..8542e518 100644
+--- a/mingw-w64-tools/widl/src/widl.c
++++ b/mingw-w64-tools/widl/src/widl.c
+@@ -44,11 +44,6 @@
+ #include "header.h"
+ #include "pathtools.h"
+
+-/* future options to reserve characters for: */
+-/* A = ACF input filename */
+-/* J = do not search standard include path */
+-/* w = select win16/win32 output (?) */
+-
+ static const char usage[] =
+ "Usage: widl [options...] infile.idl\n"
+ " or: widl [options...] --dlldata-only name1 [name2...]\n"
+@@ -64,7 +59,7 @@ static const char usage[] =
+ " -H file Name of header file (default is infile.h)\n"
+ " -I path Set include search dir to path (multiple -I allowed)\n"
+ " --local-stubs=file Write empty stubs for call_as/local methods to file\n"
+-" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n"
++" -m32, -m64 Set the target architecture (Win32 or Win64)\n"
+ " -N Do not preprocess input\n"
+ " --oldnames Use old naming conventions\n"
+ " -o, --output=NAME Set the output file name\n"
+@@ -82,8 +77,7 @@ static const char usage[] =
+ " -u Generate interface identifiers file\n"
+ " -V Print version and exit\n"
+ " -W Enable pedantic warnings\n"
+-" --win32 Only generate 32-bit code\n"
+-" --win64 Only generate 64-bit code\n"
++" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
+ " --win32-align n Set win32 structure alignment to 'n'\n"
+ " --win64-align n Set win64 structure alignment to 'n'\n"
+ "Debug level 'n' is a bitmask with following meaning:\n"
+@@ -98,6 +92,20 @@ static const char usage[] =
+ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
+ "Copyright 2002 Ove Kaaven\n";
+
++#ifdef __i386__
++enum target_cpu target_cpu = CPU_x86;
++#elif defined(__x86_64__)
++enum target_cpu target_cpu = CPU_x86_64;
++#elif defined(__powerpc__)
++enum target_cpu target_cpu = CPU_POWERPC;
++#elif defined(__arm__)
++enum target_cpu target_cpu = CPU_ARM;
++#elif defined(__aarch64__)
++enum target_cpu target_cpu = CPU_ARM64;
++#else
++#error Unsupported CPU
++#endif
++
+ int debuglevel = DEBUGLEVEL_NONE;
+ int parser_debug, yy_flex_debug;
+
+@@ -114,8 +122,6 @@ int do_idfile = 0;
+ int do_dlldata = 0;
+ static int no_preprocess = 0;
+ int old_names = 0;
+-int do_win32 = 1;
+-int do_win64 = 1;
+ int win32_packing = 8;
+ int win64_packing = 8;
+ int winrt_mode = 0;
+@@ -148,7 +154,6 @@ int line_number = 1;
+ static FILE *idfile;
+
+ unsigned int pointer_size = 0;
+-syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
+
+ time_t now;
+
+@@ -188,6 +193,7 @@ static const struct option long_options[] = {
+ { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
+ { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
+ { "robust", 0, NULL, ROBUST_OPTION },
++ { "target", 0, NULL, 'b' },
+ { "winrt", 0, NULL, RT_OPTION },
+ { "win32", 0, NULL, WIN32_OPTION },
+ { "win64", 0, NULL, WIN64_OPTION },
+@@ -269,20 +275,25 @@ static void set_target( const char *target )
+ {
+ static const struct
+ {
+- const char *name;
+- syskind_t kind;
++ const char *name;
++ enum target_cpu cpu;
+ } cpu_names[] =
+ {
+- { "i386", SYS_WIN32 },
+- { "i486", SYS_WIN32 },
+- { "i586", SYS_WIN32 },
+- { "i686", SYS_WIN32 },
+- { "i786", SYS_WIN32 },
+- { "amd64", SYS_WIN64 },
+- { "x86_64", SYS_WIN64 },
+- { "powerpc", SYS_WIN32 },
+- { "arm", SYS_WIN32 },
+- { "aarch64", SYS_WIN64 }
++ { "i386", CPU_x86 },
++ { "i486", CPU_x86 },
++ { "i586", CPU_x86 },
++ { "i686", CPU_x86 },
++ { "i786", CPU_x86 },
++ { "amd64", CPU_x86_64 },
++ { "x86_64", CPU_x86_64 },
++ { "powerpc", CPU_POWERPC },
++ { "arm", CPU_ARM },
++ { "armv5", CPU_ARM },
++ { "armv6", CPU_ARM },
++ { "armv7", CPU_ARM },
++ { "armv7a", CPU_ARM },
++ { "arm64", CPU_ARM64 },
++ { "aarch64", CPU_ARM64 },
+ };
+
+ unsigned int i;
+@@ -296,7 +307,7 @@ static void set_target( const char *target )
+ {
+ if (!strcmp( cpu_names[i].name, spec ))
+ {
+- typelib_kind = cpu_names[i].kind;
++ target_cpu = cpu_names[i].cpu;
+ free( spec );
+ return;
+ }
+@@ -484,6 +495,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
+ uuid = get_attrp(type->attrs, ATTR_UUID);
+ write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
+ type->name, uuid);
++ assert(type_get_type_detect_alias(type) == TYPE_INTERFACE);
+ if (type->details.iface->async_iface)
+ {
+ uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
+@@ -606,12 +618,10 @@ int main(int argc,char *argv[])
+ use_abi_namespace = 1;
+ break;
+ case WIN32_OPTION:
+- do_win32 = 1;
+- do_win64 = 0;
++ pointer_size = 4;
+ break;
+ case WIN64_OPTION:
+- do_win32 = 0;
+- do_win64 = 1;
++ pointer_size = 8;
+ break;
+ case WIN32_ALIGN_OPTION:
+ win32_packing = strtol(optarg, NULL, 0);
+@@ -664,8 +674,8 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(optarg);
+ break;
+ case 'm':
+- if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
+- else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
++ if (!strcmp( optarg, "32" )) pointer_size = 4;
++ else if (!strcmp( optarg, "64" )) pointer_size = 8;
+ break;
+ case 'N':
+ no_preprocess = 1;
+@@ -726,6 +736,7 @@ int main(int argc,char *argv[])
+ }
+
+ #ifdef DEFAULT_INCLUDE_DIR
++ wpp_add_include_path(DEFAULT_INCLUDE_DIR);
+ char exe_path[PATH_MAX];
+ get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
+ char * rel_to_includedir = get_relative_path (DEFAULT_BINDIR, DEFAULT_INCLUDE_DIR);
+@@ -739,6 +750,26 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(relocated_default_include_dir);
+ #endif
+
++ switch (target_cpu)
++ {
++ case CPU_x86:
++ if (pointer_size == 8) target_cpu = CPU_x86_64;
++ else pointer_size = 4;
++ break;
++ case CPU_x86_64:
++ if (pointer_size == 4) target_cpu = CPU_x86;
++ else pointer_size = 8;
++ break;
++ case CPU_ARM64:
++ if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
++ pointer_size = 8;
++ break;
++ default:
++ if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
++ pointer_size = 4;
++ break;
++ }
++
+ /* if nothing specified, try to guess output type from the output file name */
+ if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
+ !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)
+diff --git a/mingw-w64-tools/widl/src/widl.h b/mingw-w64-tools/widl/src/widl.h
+index 118e2245..4f4252e3 100644
+--- a/mingw-w64-tools/widl/src/widl.h
++++ b/mingw-w64-tools/widl/src/widl.h
+@@ -45,8 +45,6 @@ extern int do_regscript;
+ extern int do_idfile;
+ extern int do_dlldata;
+ extern int old_names;
+-extern int do_win32;
+-extern int do_win64;
+ extern int win32_packing;
+ extern int win64_packing;
+ extern int winrt_mode;
+@@ -76,6 +74,13 @@ extern time_t now;
+ extern int line_number;
+ extern int char_number;
+
++enum target_cpu
++{
++ CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
++};
++
++extern enum target_cpu target_cpu;
++
+ enum stub_mode
+ {
+ MODE_Os, /* inline stubs */
+diff --git a/mingw-w64-tools/widl/src/widltypes.h b/mingw-w64-tools/widl/src/widltypes.h
+index 08584de5..b9c5a07d 100644
+--- a/mingw-w64-tools/widl/src/widltypes.h
++++ b/mingw-w64-tools/widl/src/widltypes.h
+@@ -40,6 +40,7 @@ typedef struct _attr_t attr_t;
+ typedef struct _expr_t expr_t;
+ typedef struct _type_t type_t;
+ typedef struct _var_t var_t;
++typedef struct _decl_spec_t decl_spec_t;
+ typedef struct _declarator_t declarator_t;
+ typedef struct _ifref_t ifref_t;
+ typedef struct _typelib_entry_t typelib_entry_t;
+@@ -80,7 +81,6 @@ enum attr_type
+ ATTR_CASE,
+ ATTR_CODE,
+ ATTR_COMMSTATUS,
+- ATTR_CONST, /* const pseudo-attribute */
+ ATTR_CONTEXTHANDLE,
+ ATTR_CONTROL,
+ ATTR_DECODE,
+@@ -115,7 +115,6 @@ enum attr_type
+ ATTR_IMMEDIATEBIND,
+ ATTR_IMPLICIT_HANDLE,
+ ATTR_IN,
+- ATTR_INLINE,
+ ATTR_INPUTSYNC,
+ ATTR_LENGTHIS,
+ ATTR_LIBLCID,
+@@ -234,6 +233,18 @@ enum storage_class
+ STG_REGISTER,
+ };
+
++enum type_qualifier
++{
++ TYPE_QUALIFIER_NONE = 0,
++ TYPE_QUALIFIER_CONST = 1,
++};
++
++enum function_specifier
++{
++ FUNCTION_SPECIFIER_NONE,
++ FUNCTION_SPECIFIER_INLINE,
++};
++
+ enum statement_type
+ {
+ STMT_LIBRARY,
+@@ -293,6 +304,14 @@ struct str_list_entry_t
+ struct list entry;
+ };
+
++struct _decl_spec_t
++{
++ type_t *type;
++ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
++};
++
+ struct _attr_t {
+ enum attr_type type;
+ union {
+@@ -356,7 +375,7 @@ struct array_details
+ {
+ expr_t *size_is;
+ expr_t *length_is;
+- struct _type_t *elem;
++ struct _decl_spec_t elem;
+ unsigned int dim;
+ unsigned char ptr_def_fc;
+ unsigned char declptr; /* if declared as a pointer */
+@@ -376,7 +395,7 @@ struct basic_details
+
+ struct pointer_details
+ {
+- struct _type_t *ref;
++ struct _decl_spec_t ref;
+ unsigned char def_fc;
+ };
+
+@@ -386,6 +405,11 @@ struct bitfield_details
+ const expr_t *bits;
+ };
+
++struct alias_details
++{
++ struct _decl_spec_t aliasee;
++};
++
+ #define HASHMAX 64
+
+ struct namespace {
+@@ -414,26 +438,28 @@ enum type_type
+ TYPE_BITFIELD,
+ };
+
++typedef union _details_t
++{
++ struct struct_details *structure;
++ struct enumeration_details *enumeration;
++ struct func_details *function;
++ struct iface_details *iface;
++ struct module_details *module;
++ struct array_details array;
++ struct coclass_details coclass;
++ struct basic_details basic;
++ struct pointer_details pointer;
++ struct bitfield_details bitfield;
++ struct alias_details alias;
++} details_t;
++
+ struct _type_t {
+ const char *name;
+ struct namespace *namespace;
+ enum type_type type_type;
+ attr_list_t *attrs;
+- union
+- {
+- struct struct_details *structure;
+- struct enumeration_details *enumeration;
+- struct func_details *function;
+- struct iface_details *iface;
+- struct module_details *module;
+- struct array_details array;
+- struct coclass_details coclass;
+- struct basic_details basic;
+- struct pointer_details pointer;
+- struct bitfield_details bitfield;
+- } details;
++ details_t details;
+ const char *c_name;
+- type_t *orig; /* dup'd types */
+ unsigned int typestring_offset;
+ unsigned int ptrdesc; /* used for complex structs */
+ int typelib_idx;
+@@ -449,14 +475,20 @@ struct _type_t {
+
+ struct _var_t {
+ char *name;
+- type_t *type;
++ decl_spec_t declspec;
+ attr_list_t *attrs;
+ expr_t *eval;
+- enum storage_class stgclass;
+ unsigned int procstring_offset;
+ unsigned int typestring_offset;
+
+ struct _loc_info_t loc_info;
++ /* this flag indicates that this var's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this var
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+
+ /* parser-internal */
+ struct list entry;
+@@ -464,7 +496,7 @@ struct _var_t {
+
+ struct _declarator_t {
+ var_t *var;
+- type_t *type;
++ decl_spec_t declspec;
+ type_t *func_type;
+ expr_t *bits;
+
+@@ -497,6 +529,7 @@ struct _importinfo_t {
+ };
+
+ struct _importlib_t {
++ int offset;
+ char *name;
+
+ int version;
+@@ -539,6 +572,13 @@ struct _statement_t {
+ typelib_t *lib;
+ type_list_t *type_list;
+ } u;
++ /* this flag indicates that this statement's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this statement
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+ };
+
+ struct _warning_t {
+@@ -553,11 +593,10 @@ typedef enum {
+ SYS_WIN64
+ } syskind_t;
+
+-extern syskind_t typelib_kind;
+ extern user_type_list_t user_type_list;
+ extern context_handle_list_t context_handle_list;
+ extern generic_handle_list_t generic_handle_list;
+-void check_for_additional_prototype_types(const var_list_t *list);
++void check_for_additional_prototype_types(type_t *type);
+
+ void init_types(void);
+ type_t *alloc_type(void);
+@@ -568,6 +607,12 @@ void clear_all_offsets(void);
+ #define tsSTRUCT 2
+ #define tsUNION 3
+
++static inline const char* ts_to_str(int t)
++{
++ static const char* strings[] = {"tsNULL", "tsENUM", "tsSTRUCT", "tsUNION"};
++ return strings[t];
++}
++
+ var_t *find_const(const char *name, int f);
+ type_t *find_type(const char *name, struct namespace *namespace, int t);
+ type_t *make_type(enum type_type type);
+@@ -582,38 +627,18 @@ void init_loc_info(loc_info_t *);
+
+ char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
+
+-static inline var_list_t *type_get_function_args(const type_t *func_type)
+-{
+- return func_type->details.function->args;
+-}
+-
+-static inline enum type_type type_get_type_detect_alias(const type_t *type)
+-{
+- if (type->is_alias)
+- return TYPE_ALIAS;
+- return type->type_type;
+-}
+-
+-#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
+- if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
+- if (stmt->type == STMT_DECLARATION && stmt->u.var->stgclass == STG_NONE && \
+- type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
+-
+-static inline int statements_has_func(const statement_list_t *stmts)
++static inline int is_global_namespace(const struct namespace *namespace)
+ {
+- const statement_t *stmt;
+- int has_func = 0;
+- STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
+- {
+- has_func = 1;
+- break;
+- }
+- return has_func;
++ return !namespace->name;
+ }
+
+-static inline int is_global_namespace(const struct namespace *namespace)
++static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
+ {
+- return !namespace->name;
++ declspec->type = type;
++ declspec->stgclass = STG_NONE;
++ declspec->typequalifier=TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier=FUNCTION_SPECIFIER_NONE;
++ return declspec;
+ }
+
+ #endif
+diff --git a/mingw-w64-tools/widl/src/write_msft.c b/mingw-w64-tools/widl/src/write_msft.c
+index 88a80d12..da7ce89d 100644
+--- a/mingw-w64-tools/widl/src/write_msft.c
++++ b/mingw-w64-tools/widl/src/write_msft.c
+@@ -702,15 +702,15 @@ static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
+
+ guid_idx = ctl2_alloc_guid(typelib, &guid);
+
+- alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
+- importlib->version>>16, importlib->name);
++ importlib->offset = alloc_importfile(typelib, guid_idx, importlib->version & 0xffff,
++ importlib->version >> 16, importlib->name);
+ }
+
+ if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
+ MSFT_ImpInfo impinfo;
+
+ impinfo.flags = importinfo->flags;
+- impinfo.oImpFile = 0;
++ impinfo.oImpFile = importlib->offset;
+
+ if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+ MSFT_GuidEntry guid;
+@@ -763,7 +763,7 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
+ static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion);
+ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
+ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
+-
++static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef);
+
+ /****************************************************************************
+ * encode_type
+@@ -862,8 +862,8 @@ static int encode_type(
+ case VT_PTR:
+ {
+ int next_vt;
+- for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref(type)) {
+- next_vt = get_type_vt(type_pointer_get_ref(type));
++ for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref_type(type)) {
++ next_vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (next_vt != 0)
+ break;
+ }
+@@ -871,7 +871,7 @@ static int encode_type(
+ if (next_vt == 0)
+ next_vt = VT_VOID;
+
+- encode_type(typelib, next_vt, type_pointer_get_ref(type),
++ encode_type(typelib, next_vt, type_pointer_get_ref_type(type),
+ &target_type, &child_size);
+ /* these types already have an implicit pointer, so we don't need to
+ * add another */
+@@ -912,10 +912,10 @@ static int encode_type(
+
+ case VT_SAFEARRAY:
+ {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
+ int next_vt = get_type_vt(element_type);
+
+- encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
++ encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
+ &target_type, &child_size);
+
+ for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
+@@ -966,33 +966,61 @@ static int encode_type(
+ }
+ else
+ {
+- /* typedef'd types without public attribute aren't included in the typelib */
+- while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
+- type = type_alias_get_aliasee(type);
++ /* typedef'd types without public attribute aren't included in the typelib
++ * typedef'd types with a wire_marshal attribute must be included
++ */
++ while (type_is_alias(type))
++ {
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL))
++ {
++ type = get_attrp(type->attrs, ATTR_WIREMARSHAL);
++ break;
++ }
++ else if(!is_attr(type->attrs, ATTR_PUBLIC))
++ {
++ type = type_alias_get_aliasee_type(type);
++ }
++ else
++ {
++ break;
++ }
++ }
+
+ chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
+ type->name, type_get_type(type));
+
+- switch (type_get_type(type))
++ /* we've either fully resolved the typedef down to an actual type or
++ * we must include the typedef because it's a wiremarshal (or public) type
++ */
++ if (type_is_alias(type))
+ {
+- case TYPE_STRUCT:
+- add_structure_typeinfo(typelib, type);
+- break;
+- case TYPE_INTERFACE:
+- add_interface_typeinfo(typelib, type);
+- break;
+- case TYPE_ENUM:
+- add_enum_typeinfo(typelib, type);
+- break;
+- case TYPE_UNION:
+- add_union_typeinfo(typelib, type);
+- break;
+- case TYPE_COCLASS:
+- add_coclass_typeinfo(typelib, type);
+- break;
+- default:
+- error("encode_type: VT_USERDEFINED - unhandled type %d\n",
+- type_get_type(type));
++ add_typedef_typeinfo(typelib, type);
++ }
++ else
++ {
++ switch (type_get_type(type))
++ {
++ case TYPE_STRUCT:
++ add_structure_typeinfo(typelib, type);
++ break;
++ case TYPE_INTERFACE:
++ add_interface_typeinfo(typelib, type);
++ break;
++ case TYPE_ENUM:
++ add_enum_typeinfo(typelib, type);
++ break;
++ /* fallthrough */
++ case TYPE_UNION:
++ case TYPE_ENCAPSULATED_UNION:
++ add_union_typeinfo(typelib, type);
++ break;
++ case TYPE_COCLASS:
++ add_coclass_typeinfo(typelib, type);
++ break;
++ default:
++ error("encode_type: VT_USERDEFINED - unhandled type %d\n",
++ type_get_type(type));
++ }
+ }
+
+ typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
+@@ -1056,7 +1084,7 @@ static int encode_var(
+ num_dims = 0;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ ++num_dims;
+
+ chat("array with %d dimensions\n", num_dims);
+@@ -1071,7 +1099,7 @@ static int encode_var(
+ arraydata += 2;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ {
+ arraydata[0] = type_array_get_dim(atype);
+ arraydata[1] = 0;
+@@ -1093,7 +1121,7 @@ static int encode_var(
+ vt = get_type_vt(type);
+ if (vt == VT_PTR) {
+ type_t *ref = is_ptr(type) ?
+- type_pointer_get_ref(type) : type_array_get_element(type);
++ type_pointer_get_ref_type(type) : type_array_get_element_type(type);
+ int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
+
+ if(skip_ptr == 2) {
+@@ -1114,7 +1142,7 @@ static int encode_var(
+ if (target_type & 0x80000000) {
+ mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
+ } else if (get_type_vt(ref) == VT_SAFEARRAY) {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
+ mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
+ } else {
+ typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
+@@ -1204,7 +1232,7 @@ static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *e
+ if (type_get_type(type) == TYPE_ENUM) {
+ vt = VT_I4;
+ } else if (is_ptr(type)) {
+- vt = get_type_vt(type_pointer_get_ref(type));
++ vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (vt == VT_USERDEFINED)
+ vt = VT_I4;
+ if (expr->cval)
+@@ -1301,8 +1329,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ return S_FALSE;
+ }
+
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ num_params++;
+ if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
+@@ -1444,7 +1472,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+
+ /* fill out the basic type information */
+ typedata[0] = typedata_size | (index << 16);
+- encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func,
++ encode_var(typeinfo->typelib, type_function_get_rettype(func->declspec.type), func,
+ &typedata[1], &decoded_size);
+ typedata[2] = funcflags;
+ typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
+@@ -1471,10 +1499,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ warning("unknown number of optional attrs\n");
+ }
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ i = 0;
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ int paramflags = 0;
+ int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
+@@ -1482,13 +1510,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+
+ if(defaultdata) *defaultdata = -1;
+
+- encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size);
++ encode_var(typeinfo->typelib, arg->declspec.type, arg, paramdata, &decoded_size);
+ if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
+ switch(attr->type) {
+ case ATTR_DEFAULTVALUE:
+ {
+ paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
+- write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
++ write_default_value(typeinfo->typelib, arg->declspec.type, (expr_t *)attr->u.pval, defaultdata);
+ break;
+ }
+ case ATTR_IN:
+@@ -1572,10 +1600,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ if(typeinfo->typekind == TKIND_MODULE)
+ namedata[9] |= 0x20;
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ i = 0;
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ /* don't give the last arg of a [propput*] func a name */
+ if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
+@@ -1697,8 +1725,8 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
+ typeinfo->var_offsets[var_num] = offset;
+
+ /* figure out type widths and whatnot */
+- var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
+- encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
++ var_datawidth = type_memsize_and_alignment(var->declspec.type, &var_alignment);
++ encode_var(typeinfo->typelib, var->declspec.type, var, &typedata[1], &var_type_size);
+
+ /* pad out starting position to data width */
+ typeinfo->datawidth += var_alignment - 1;
+@@ -1977,6 +2005,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
+ var_t *var;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(dispinterface) == TYPE_INTERFACE);
+ if (-1 < dispinterface->typelib_idx)
+ return;
+
+@@ -2181,7 +2210,7 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
+ if (-1 < tdef->typelib_idx)
+ return;
+
+- type = type_alias_get_aliasee(tdef);
++ type = type_alias_get_aliasee_type(tdef);
+
+ if (!type->name || strcmp(tdef->name, type->name) != 0)
+ {
+@@ -2297,6 +2326,7 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
+ const statement_t *stmt;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (-1 < module->typelib_idx)
+ return;
+
+@@ -2364,7 +2394,7 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
+ if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
+ add_typedef_typeinfo(typelib, type_entry->type);
+ else
+- add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type));
++ add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type));
+ }
+ break;
+ }
+@@ -2653,8 +2683,6 @@ int create_msft_typelib(typelib_t *typelib)
+ GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
+ char info_string[128];
+
+- pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
+-
+ msft = xmalloc(sizeof(*msft));
+ memset(msft, 0, sizeof(*msft));
+ msft->typelib = typelib;
+@@ -2662,7 +2690,7 @@ int create_msft_typelib(typelib_t *typelib)
+ ctl2_init_header(msft);
+ ctl2_init_segdir(msft);
+
+- msft->typelib_header.varflags |= typelib_kind;
++ msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
+
+ /*
+ * The following two calls return an offset or -1 if out of memory. We
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index 4be660d..faa5997 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -52,6 +52,9 @@ cd /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
make -j[% c("buildconf/num_procs") %]
make install
+# patch mingw with widl fixes for #27503 ( https://trac.torproject.org/projects/tor/ticket/27503 )
+patch -p1 -d /var/tmp/build/[% project %]-[% c("version") %] < $rootdir/27503.patch
+
mkdir -p /var/tmp/build/builddir/mingw-w64/widl32
cd /var/tmp/build/builddir/mingw-w64/widl32
/var/tmp/build/[% project %]-[% c("version") %]/mingw-w64-tools/widl/configure \
diff --git a/projects/mingw-w64/config b/projects/mingw-w64/config
index d0268cb..a2f0701 100644
--- a/projects/mingw-w64/config
+++ b/projects/mingw-w64/config
@@ -35,3 +35,4 @@ input_files:
- name: binutils
project: binutils
- filename: libtool-sort.patch
+ - filename: 27503.patch
1
0
commit 1d1731f54208a82b21b28ae517664637a3b34c34
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 18:19:37 2019 +0000
Update translations
---
src/chrome/locale/de/aboutTor.dtd | 4 ++--
src/chrome/locale/es-ES/aboutTor.dtd | 2 +-
src/chrome/locale/fa/aboutTor.dtd | 4 ++--
src/chrome/locale/fr/aboutTor.dtd | 4 ++--
src/chrome/locale/he/aboutTor.dtd | 4 ++--
src/chrome/locale/it/aboutTor.dtd | 4 ++--
src/chrome/locale/nl/aboutTor.dtd | 4 ++--
src/chrome/locale/tr/aboutTor.dtd | 4 ++--
src/chrome/locale/zh-CN/aboutTor.dtd | 4 ++--
9 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/chrome/locale/de/aboutTor.dtd b/src/chrome/locale/de/aboutTor.dtd
index ef055f13..33e9be15 100644
--- a/src/chrome/locale/de/aboutTor.dtd
+++ b/src/chrome/locale/de/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mache Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Spende jetzt">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische monatliche Spenden halten Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Werde noch heute ein Verteidiger der Privatsphäre.">
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index 325e10a9..f2fbb4c5 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
diff --git a/src/chrome/locale/fa/aboutTor.dtd b/src/chrome/locale/fa/aboutTor.dtd
index f6ad0773..77999b0c 100644
--- a/src/chrome/locale/fa/aboutTor.dtd
+++ b/src/chrome/locale/fa/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "تور را محکم نگه دارید.">
<!ENTITY aboutTor.donationBanner.buttonA "اکنون اهداء کنید">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "کمک های مالی ماهانه خودکار تور را قوی نگه میدارند.">
+<!ENTITY aboutTor.donationBanner3.line2 "امروز تبدیل به یک مدافع حریم خصوصی شوید.">
diff --git a/src/chrome/locale/fr/aboutTor.dtd b/src/chrome/locale/fr/aboutTor.dtd
index c44b3ddd..e83f750c 100644
--- a/src/chrome/locale/fr/aboutTor.dtd
+++ b/src/chrome/locale/fr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Assurez la robustesse de Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Faites un don maintenant">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Les dons mensuels automatiques assurent la robustesse de Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Devenez dès aujourd'hui un défenseur de la vie privée et de sa protection.">
diff --git a/src/chrome/locale/he/aboutTor.dtd b/src/chrome/locale/he/aboutTor.dtd
index b42fdfc4..dfa2fbae 100644
--- a/src/chrome/locale/he/aboutTor.dtd
+++ b/src/chrome/locale/he/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "שמור על Tor חזק.">
<!ENTITY aboutTor.donationBanner.buttonA "תרום עכשיו">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "תרומות חודשיות אוטומטיות שומרות על Tor חזק.">
+<!ENTITY aboutTor.donationBanner3.line2 "הפוך אל מגן של פרטיות היום.">
diff --git a/src/chrome/locale/it/aboutTor.dtd b/src/chrome/locale/it/aboutTor.dtd
index 7cd090e7..a1477463 100644
--- a/src/chrome/locale/it/aboutTor.dtd
+++ b/src/chrome/locale/it/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantieni Tor forte.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona Ora">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Le donazioni mensili automatiche mantengono forte Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Diventa un Difensore della Privacy oggi.">
diff --git a/src/chrome/locale/nl/aboutTor.dtd b/src/chrome/locale/nl/aboutTor.dtd
index d72342e2..3e78eb8b 100644
--- a/src/chrome/locale/nl/aboutTor.dtd
+++ b/src/chrome/locale/nl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Houd Tor sterk.">
<!ENTITY aboutTor.donationBanner.buttonA "Nu doneren">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische maandelijkse donaties houden Tor sterk.">
+<!ENTITY aboutTor.donationBanner3.line2 "Word vandaag nog voorvechter van privacy.">
diff --git a/src/chrome/locale/tr/aboutTor.dtd b/src/chrome/locale/tr/aboutTor.dtd
index 7bf9012c..8ddbea88 100644
--- a/src/chrome/locale/tr/aboutTor.dtd
+++ b/src/chrome/locale/tr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Tor uygulamasının gücünü koruyun.">
<!ENTITY aboutTor.donationBanner.buttonA "Bağış Yapın">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Aylık otomatik bağışlar Tor projesinin gücünü korumasına yardımcı olur.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bugün kişisel gizliliği savunmak için destek olmaya başlayın.">
diff --git a/src/chrome/locale/zh-CN/aboutTor.dtd b/src/chrome/locale/zh-CN/aboutTor.dtd
index 01e438b4..c0a8bb61 100644
--- a/src/chrome/locale/zh-CN/aboutTor.dtd
+++ b/src/chrome/locale/zh-CN/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "让 Tor 网络保持健壮。">
<!ENTITY aboutTor.donationBanner.buttonA "立即捐助">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "每个月自动捐款来使Tor保持强大">
+<!ENTITY aboutTor.donationBanner3.line2 "今天就成为隐私的捍卫者">
1
0
commit 208b1131bf0a5d91a66a4df98a93c08253c87b26
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:25:27 2019 +0000
Update translations
---
src/chrome/locale/es-ES/aboutTor.dtd | 4 ++--
src/chrome/locale/pl/aboutTor.dtd | 4 ++--
src/chrome/locale/pt-BR/aboutTor.dtd | 8 ++++----
src/chrome/locale/sv-SE/aboutTor.dtd | 4 ++--
src/chrome/locale/sv-SE/browserOnboarding.properties | 2 +-
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index f2fbb4c5..26c792d2 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donaciones mensuales automáticas mantienen a Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Conviértete en un Defensor de la Privacidad, hoy.">
diff --git a/src/chrome/locale/pl/aboutTor.dtd b/src/chrome/locale/pl/aboutTor.dtd
index 2b93c099..138c73e1 100644
--- a/src/chrome/locale/pl/aboutTor.dtd
+++ b/src/chrome/locale/pl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Utrzymuj Tor silnym.">
<!ENTITY aboutTor.donationBanner.buttonA "Wesprzyj teraz">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatyczne comiesięczne darowizny trzymają Tora silnym.">
+<!ENTITY aboutTor.donationBanner3.line2 "Zostań dzisiaj Obrońcą Prywatności.">
diff --git a/src/chrome/locale/pt-BR/aboutTor.dtd b/src/chrome/locale/pt-BR/aboutTor.dtd
index fb64963a..e5a512fc 100644
--- a/src/chrome/locale/pt-BR/aboutTor.dtd
+++ b/src/chrome/locale/pt-BR/aboutTor.dtd
@@ -22,15 +22,15 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "M">
<!ENTITY aboutTor.torbrowser_user_manual.label "Manual do Navegador Tor">
-<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implantando tecnologias de privacidade e anonimato, de fonte aberta e livre, apoiando sua disponibilidade e uso irrestritos e promovendo seu entendimento científico e popular">
+<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implementando tecnologias de privacidade e anonimato, de código aberto e livre, apoiando a sua disponibilidade e uso irrestrito e promovendo o seu entendimento científico e popular">
<!ENTITY aboutTor.getInvolved.label "Envolva-se »
">
<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
<!ENTITY aboutTor.newsletter.tagline "Receba as últimas notícias do Tor diretamente na sua caixa de e-mail.">
<!ENTITY aboutTor.newsletter.link_text "Inscreva-se para receber Notícias do Tor.">
-<!ENTITY aboutTor.donationBanner.line2e "Manter a força do Tor.">
+<!ENTITY aboutTor.donationBanner.line2e "Fortaleça o Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Doar Agora">
-<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas mantem Tor forte.">
-<!ENTITY aboutTor.donationBanner3.line2 "Se torne hoje um Defensor da Privacidade.">
+<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas fortalecem o Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Torne-se hoje um Defensor da Privacidade.">
diff --git a/src/chrome/locale/sv-SE/aboutTor.dtd b/src/chrome/locale/sv-SE/aboutTor.dtd
index 6b8094fa..ee567e6d 100644
--- a/src/chrome/locale/sv-SE/aboutTor.dtd
+++ b/src/chrome/locale/sv-SE/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Håll Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Donera nu">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatiska månatliga donationer håller Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bli en försvarare av privatlivet idag.">
diff --git a/src/chrome/locale/sv-SE/browserOnboarding.properties b/src/chrome/locale/sv-SE/browserOnboarding.properties
index 61779ce7..5da6b093 100644
--- a/src/chrome/locale/sv-SE/browserOnboarding.properties
+++ b/src/chrome/locale/sv-SE/browserOnboarding.properties
@@ -25,7 +25,7 @@ onboarding.tour-tor-circuit-display.next-button=Gå till Säkerhet
onboarding.tour-tor-security=Säkerhet
onboarding.tour-tor-security.title=Välj din upplevelse.
-onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att stöta upp din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
+onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att höja din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
onboarding.tour-tor-security.description-suffix=Observera: Som standard ingår inte NoScript och HTTPS Everywhere i verktygsfältet, men du kan anpassa verktygsfältet för att lägga till dem.
onboarding.tour-tor-security-level.button=Se din säkerhetsnivå
onboarding.tour-tor-security-level.next-button=Gå till Erfarenhets tips
1
0

04 Jul '19
commit 94aa3c732f00da573c45ff5236096f090439d5dc
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Jul 4 02:03:27 2019 +0200
Bug 31079: Update Mozilla gpg key
Add the new subkey F1A6668FBB7D572E, and remove expired subkeys.
---
keyring/firefox.gpg | Bin 13463 -> 2995 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/keyring/firefox.gpg b/keyring/firefox.gpg
index 9c71261..53e62b2 100644
Binary files a/keyring/firefox.gpg and b/keyring/firefox.gpg differ
1
0
commit a553430d13d73b93cc81ce080d0fa3adafc1b02d
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:34:14 2019 +0000
Prepare 8.5.4 build2
Pick up new Mozilla signing key and updated translations
---
projects/firefox/config | 2 +-
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 2 +-
projects/torbutton/config | 2 +-
rbm.conf | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index ce43836..195bed3 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: 'firefox-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build1'
+git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build2'
tag_gpg_id: 1
git_url: https://git.torproject.org/tor-browser.git
git_submodule: 1
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 1438da2..682b309 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,7 +1,7 @@
Tor Browser 8.5.4 -- July 9 2019
* All platforms
* Update Firefox to 60.8.0esr
- * Update Torbutton to 2.1.11
+ * Update Torbutton to 2.1.12
* Bug 30577: Add Fundraising Banner
* Bug 31041: Stop syncing network.cookie.lifetimePolicy
* Translations update
diff --git a/projects/torbutton/config b/projects/torbutton/config
index a0df00a..af17cd5 100644
--- a/projects/torbutton/config
+++ b/projects/torbutton/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 2.1.11
+version: 2.1.12
git_url: https://git.torproject.org/torbutton.git
git_hash: '[% c("version") %]'
gpg_keyring: torbutton.gpg
diff --git a/rbm.conf b/rbm.conf
index 2271cef..831f918 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -25,7 +25,7 @@ buildconf:
var:
torbrowser_version: '8.5.4'
- torbrowser_build: 'build1'
+ torbrowser_build: 'build2'
torbrowser_incremental_from:
- 8.5.3
project_name: tor-browser
1
0

04 Jul '19
commit ebcb855eef3bd09f9a1b438c312b9c5d5259d8df
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:28:34 2019 +0000
Pick up Torbutton 2.1.12
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index e5fa8370b103..40b7d1375031 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit e5fa8370b1036b878112152627314619f300e8a2
+Subproject commit 40b7d13750313a702a044db430622d933b09fb9e
1
0
commit 00e063e7f2e6a97851f5f916e041c365aec53338
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:25:27 2019 +0000
Update translations
---
src/chrome/locale/es-ES/aboutTor.dtd | 4 ++--
src/chrome/locale/pl/aboutTor.dtd | 4 ++--
src/chrome/locale/pt-BR/aboutTor.dtd | 8 ++++----
src/chrome/locale/sv-SE/aboutTor.dtd | 4 ++--
src/chrome/locale/sv-SE/browserOnboarding.properties | 2 +-
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index f2fbb4c5..26c792d2 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donaciones mensuales automáticas mantienen a Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Conviértete en un Defensor de la Privacidad, hoy.">
diff --git a/src/chrome/locale/pl/aboutTor.dtd b/src/chrome/locale/pl/aboutTor.dtd
index 2b93c099..138c73e1 100644
--- a/src/chrome/locale/pl/aboutTor.dtd
+++ b/src/chrome/locale/pl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Utrzymuj Tor silnym.">
<!ENTITY aboutTor.donationBanner.buttonA "Wesprzyj teraz">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatyczne comiesięczne darowizny trzymają Tora silnym.">
+<!ENTITY aboutTor.donationBanner3.line2 "Zostań dzisiaj Obrońcą Prywatności.">
diff --git a/src/chrome/locale/pt-BR/aboutTor.dtd b/src/chrome/locale/pt-BR/aboutTor.dtd
index fb64963a..e5a512fc 100644
--- a/src/chrome/locale/pt-BR/aboutTor.dtd
+++ b/src/chrome/locale/pt-BR/aboutTor.dtd
@@ -22,15 +22,15 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "M">
<!ENTITY aboutTor.torbrowser_user_manual.label "Manual do Navegador Tor">
-<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implantando tecnologias de privacidade e anonimato, de fonte aberta e livre, apoiando sua disponibilidade e uso irrestritos e promovendo seu entendimento científico e popular">
+<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implementando tecnologias de privacidade e anonimato, de código aberto e livre, apoiando a sua disponibilidade e uso irrestrito e promovendo o seu entendimento científico e popular">
<!ENTITY aboutTor.getInvolved.label "Envolva-se »
">
<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
<!ENTITY aboutTor.newsletter.tagline "Receba as últimas notícias do Tor diretamente na sua caixa de e-mail.">
<!ENTITY aboutTor.newsletter.link_text "Inscreva-se para receber Notícias do Tor.">
-<!ENTITY aboutTor.donationBanner.line2e "Manter a força do Tor.">
+<!ENTITY aboutTor.donationBanner.line2e "Fortaleça o Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Doar Agora">
-<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas mantem Tor forte.">
-<!ENTITY aboutTor.donationBanner3.line2 "Se torne hoje um Defensor da Privacidade.">
+<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas fortalecem o Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Torne-se hoje um Defensor da Privacidade.">
diff --git a/src/chrome/locale/sv-SE/aboutTor.dtd b/src/chrome/locale/sv-SE/aboutTor.dtd
index 6b8094fa..ee567e6d 100644
--- a/src/chrome/locale/sv-SE/aboutTor.dtd
+++ b/src/chrome/locale/sv-SE/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Håll Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Donera nu">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatiska månatliga donationer håller Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bli en försvarare av privatlivet idag.">
diff --git a/src/chrome/locale/sv-SE/browserOnboarding.properties b/src/chrome/locale/sv-SE/browserOnboarding.properties
index 61779ce7..5da6b093 100644
--- a/src/chrome/locale/sv-SE/browserOnboarding.properties
+++ b/src/chrome/locale/sv-SE/browserOnboarding.properties
@@ -25,7 +25,7 @@ onboarding.tour-tor-circuit-display.next-button=Gå till Säkerhet
onboarding.tour-tor-security=Säkerhet
onboarding.tour-tor-security.title=Välj din upplevelse.
-onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att stöta upp din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
+onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att höja din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
onboarding.tour-tor-security.description-suffix=Observera: Som standard ingår inte NoScript och HTTPS Everywhere i verktygsfältet, men du kan anpassa verktygsfältet för att lägga till dem.
onboarding.tour-tor-security-level.button=Se din säkerhetsnivå
onboarding.tour-tor-security-level.next-button=Gå till Erfarenhets tips
1
0
commit 40b7d13750313a702a044db430622d933b09fb9e
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:26:27 2019 +0000
Release preparations for 2.1.12
---
src/CHANGELOG | 2 +-
src/install.rdf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index 29c6cd8a..e3cfa026 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,4 +1,4 @@
-2.1.11
+2.1.12
* Bug 30577: Add Fundraising Banner
* Bug 31041: Stop syncing network.cookie.lifetimePolicy
* Translations update
diff --git a/src/install.rdf b/src/install.rdf
index b340faeb..267b1c6c 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>2.1.11</em:version>
+ <em:version>2.1.12</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0

04 Jul '19
commit 702bb68507a94fb3aaf2a145188428a0f72a1de0
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Jul 4 02:03:27 2019 +0200
Bug 31079: Update Mozilla gpg key
Add the new subkey F1A6668FBB7D572E, and remove expired subkeys.
---
keyring/firefox.gpg | Bin 13463 -> 2995 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/keyring/firefox.gpg b/keyring/firefox.gpg
index 9c71261..53e62b2 100644
Binary files a/keyring/firefox.gpg and b/keyring/firefox.gpg differ
1
0

03 Jul '19
commit ca6f2b2731a9dd96eb75aa696379c63e5fa0ed3a
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 18:37:20 2019 +0000
Pick up Torbutton 2.1.11
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index fc1b50e42123..e5fa8370b103 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit fc1b50e42123a5850098cd58e6a8889e28be8ae6
+Subproject commit e5fa8370b1036b878112152627314619f300e8a2
1
0
commit e5fa8370b1036b878112152627314619f300e8a2
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 18:21:36 2019 +0000
Release preparations for 2.1.11
CHANGELOG update and version bump
---
src/CHANGELOG | 5 +++++
src/install.rdf | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index fe236b2c..29c6cd8a 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,3 +1,8 @@
+2.1.11
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Translations update
+
2.1.10
* Bug 30565: sync nocertdb with privatebrowsing.autostart at startup
* Translations update
diff --git a/src/install.rdf b/src/install.rdf
index aa03c8dc..b340faeb 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>2.1.10</em:version>
+ <em:version>2.1.11</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0
commit 213407175ffcdc13408e50ad275947c23fded301
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 18:19:37 2019 +0000
Update translations
---
src/chrome/locale/de/aboutTor.dtd | 4 ++--
src/chrome/locale/es-ES/aboutTor.dtd | 2 +-
src/chrome/locale/fa/aboutTor.dtd | 4 ++--
src/chrome/locale/fr/aboutTor.dtd | 4 ++--
src/chrome/locale/he/aboutTor.dtd | 4 ++--
src/chrome/locale/it/aboutTor.dtd | 4 ++--
src/chrome/locale/nl/aboutTor.dtd | 4 ++--
src/chrome/locale/tr/aboutTor.dtd | 4 ++--
src/chrome/locale/zh-CN/aboutTor.dtd | 4 ++--
9 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/chrome/locale/de/aboutTor.dtd b/src/chrome/locale/de/aboutTor.dtd
index ef055f13..33e9be15 100644
--- a/src/chrome/locale/de/aboutTor.dtd
+++ b/src/chrome/locale/de/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mache Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Spende jetzt">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische monatliche Spenden halten Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Werde noch heute ein Verteidiger der Privatsphäre.">
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index 325e10a9..f2fbb4c5 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
diff --git a/src/chrome/locale/fa/aboutTor.dtd b/src/chrome/locale/fa/aboutTor.dtd
index f6ad0773..77999b0c 100644
--- a/src/chrome/locale/fa/aboutTor.dtd
+++ b/src/chrome/locale/fa/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "تور را محکم نگه دارید.">
<!ENTITY aboutTor.donationBanner.buttonA "اکنون اهداء کنید">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "کمک های مالی ماهانه خودکار تور را قوی نگه میدارند.">
+<!ENTITY aboutTor.donationBanner3.line2 "امروز تبدیل به یک مدافع حریم خصوصی شوید.">
diff --git a/src/chrome/locale/fr/aboutTor.dtd b/src/chrome/locale/fr/aboutTor.dtd
index c44b3ddd..e83f750c 100644
--- a/src/chrome/locale/fr/aboutTor.dtd
+++ b/src/chrome/locale/fr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Assurez la robustesse de Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Faites un don maintenant">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Les dons mensuels automatiques assurent la robustesse de Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Devenez dès aujourd'hui un défenseur de la vie privée et de sa protection.">
diff --git a/src/chrome/locale/he/aboutTor.dtd b/src/chrome/locale/he/aboutTor.dtd
index b42fdfc4..dfa2fbae 100644
--- a/src/chrome/locale/he/aboutTor.dtd
+++ b/src/chrome/locale/he/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "שמור על Tor חזק.">
<!ENTITY aboutTor.donationBanner.buttonA "תרום עכשיו">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "תרומות חודשיות אוטומטיות שומרות על Tor חזק.">
+<!ENTITY aboutTor.donationBanner3.line2 "הפוך אל מגן של פרטיות היום.">
diff --git a/src/chrome/locale/it/aboutTor.dtd b/src/chrome/locale/it/aboutTor.dtd
index 7cd090e7..a1477463 100644
--- a/src/chrome/locale/it/aboutTor.dtd
+++ b/src/chrome/locale/it/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantieni Tor forte.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona Ora">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Le donazioni mensili automatiche mantengono forte Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Diventa un Difensore della Privacy oggi.">
diff --git a/src/chrome/locale/nl/aboutTor.dtd b/src/chrome/locale/nl/aboutTor.dtd
index d72342e2..3e78eb8b 100644
--- a/src/chrome/locale/nl/aboutTor.dtd
+++ b/src/chrome/locale/nl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Houd Tor sterk.">
<!ENTITY aboutTor.donationBanner.buttonA "Nu doneren">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische maandelijkse donaties houden Tor sterk.">
+<!ENTITY aboutTor.donationBanner3.line2 "Word vandaag nog voorvechter van privacy.">
diff --git a/src/chrome/locale/tr/aboutTor.dtd b/src/chrome/locale/tr/aboutTor.dtd
index 7bf9012c..8ddbea88 100644
--- a/src/chrome/locale/tr/aboutTor.dtd
+++ b/src/chrome/locale/tr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Tor uygulamasının gücünü koruyun.">
<!ENTITY aboutTor.donationBanner.buttonA "Bağış Yapın">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Aylık otomatik bağışlar Tor projesinin gücünü korumasına yardımcı olur.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bugün kişisel gizliliği savunmak için destek olmaya başlayın.">
diff --git a/src/chrome/locale/zh-CN/aboutTor.dtd b/src/chrome/locale/zh-CN/aboutTor.dtd
index 01e438b4..c0a8bb61 100644
--- a/src/chrome/locale/zh-CN/aboutTor.dtd
+++ b/src/chrome/locale/zh-CN/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "让 Tor 网络保持健壮。">
<!ENTITY aboutTor.donationBanner.buttonA "立即捐助">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "每个月自动捐款来使Tor保持强大">
+<!ENTITY aboutTor.donationBanner3.line2 "今天就成为隐私的捍卫者">
1
0

03 Jul '19
commit 613b9ad999967e6bad4270f0f1ef8b06b7f4ba44
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 14:14:12 2019 +0000
Bump tba translation commit
---
projects/tba-translation/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tba-translation/config b/projects/tba-translation/config
index 9dd3375..1b3274a 100644
--- a/projects/tba-translation/config
+++ b/projects/tba-translation/config
@@ -3,5 +3,5 @@ filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
git_url: https://git.torproject.org/translation.git
# We need to bump the commit before releasing but just pointing to a branch
# might cause too much rebuidling of the Firefox part.
-git_hash: 0a14ba0a2ad2c4cc46f926dc1a5aeaa709e270d4
+git_hash: 21677307d87d3216eede51a6ad36bf26e7937667
version: '[% c("abbrev") %]'
1
0